From 81a735167aa9cf46446c9651c3251ae7ae953016 Mon Sep 17 00:00:00 2001 From: yutingshih Date: Tue, 21 Apr 2020 16:03:55 +0800 Subject: [PATCH 01/78] The LED setting and ramp timing modified for upgrade from android P Root cause: Code base upgrade How to fix: Upgrade from Android P RiskArea: LED Change-Id: I36732b9b701400832a0a4975626cd933e608fc4e --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 50 ++++++++++++++++++++++++++++ drivers/leds/leds-qti-tri-led.c | 15 +++++++++ 2 files changed, 65 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index 6919e741e006..d2b16882d905 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -565,30 +565,80 @@ nvmem = <&pmi632_sdam7>; qcom,pbs-client = <&pmi632_pbs_client3>; qcom,lut-sdam-base = <0x80>; + //<2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]Modified for breath ramp and timing. + #if 1 + 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>; + #else + /* Code default */ qcom,lut-patterns = <0 0 0 14 28 42 56 70 84 100 100 84 70 56 42 28 14 0 0 0>; + #endif + //>2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]. lpg@1 { qcom,lpg-chan-id = <1>; + //<2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]Modified for breath ramp and timing. + #if 1 + 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 = <35>; + //qcom,ramp-toggle; /* ramp from high to low */ + //qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; + #else + /* Code default */ qcom,ramp-step-ms = <200>; qcom,ramp-low-index = <0>; qcom,ramp-high-index = <19>; qcom,ramp-pattern-repeat; + #endif + //>2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]. qcom,lpg-sdam-base = <0x48>; }; lpg@2 { qcom,lpg-chan-id = <2>; + //<2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]Modified for breath ramp and timing. + #if 1 + 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 = <35>; + //qcom,ramp-toggle; /* ramp from high to low */ + //qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; + #else + /* Code default */ qcom,ramp-step-ms = <200>; qcom,ramp-low-index = <0>; qcom,ramp-high-index = <19>; qcom,ramp-pattern-repeat; + #endif + //>2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]. qcom,lpg-sdam-base = <0x56>; }; lpg@3 { qcom,lpg-chan-id = <3>; + //<2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]Modified for breath ramp and timing. + #if 1 + 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 = <35>; + //qcom,ramp-toggle; /* ramp from high to low */ + //qcom,ramp-from-low-to-high; + qcom,ramp-pattern-repeat; + #else + /* Code default */ qcom,ramp-step-ms = <200>; qcom,ramp-low-index = <0>; qcom,ramp-high-index = <19>; qcom,ramp-pattern-repeat; + #endif + //>2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]. qcom,lpg-sdam-base = <0x64>; }; }; diff --git a/drivers/leds/leds-qti-tri-led.c b/drivers/leds/leds-qti-tri-led.c index c49465532f83..a0790091e1be 100644 --- a/drivers/leds/leds-qti-tri-led.c +++ b/drivers/leds/leds-qti-tri-led.c @@ -475,6 +475,21 @@ static int qpnp_tri_led_parse_dt(struct qpnp_tri_led_chip *chip) of_get_property(child_node, "label", NULL) ? : child_node->name; + //<2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]Add for flag initial. + 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; + //>2020/04/21-Yuting Shih.[FAIRPHONE-Q][MISC][COMMON][LED][][]. + led->pwm_dev = devm_of_pwm_get(chip->dev, child_node, NULL); if (IS_ERR(led->pwm_dev)) { -- GitLab From 0330b0ea4f55ed3427c2995c7336ae3af4f11ec5 Mon Sep 17 00:00:00 2001 From: michaellin Date: Tue, 29 Jan 2019 15:08:29 +0800 Subject: [PATCH 02/78] [NFC]Reassign ESE Enable gpio in case of collision Root cause: ESE Enable reserved gpio141 is used for RF variant. How to fix: Reassign ESE Enable gpio to gpio134 in case of collision RiskArea: NFC Change-Id: Ic8d29c92c4fc85ea3d340be7d7cde3d7129c5ae6 (cherry picked from commit 251ef03387a16a754835ce9a48f9e604865f9117) --- arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 4 +++- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi index 69cf52ebc606..a9f87e1bd63b 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -44,7 +44,9 @@ 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>; +/*<<2019-01-29-Michael Lin-[FairPhone][NFC]Reassign ESE Enable gpio in case of collision*/ + qcom,nq-esepwr = <&tlmm 134 0x00>; +/*>>2019-01-29-Michael Lin-[FairPhone][NFC]Reassign ESE Enable gpio in case of collision*/ interrupt-parent = <&tlmm>; qcom,clk-src = "BBCLK2"; interrupts = <17 0>; diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 9da42f99b317..5b27d035b161 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -939,17 +939,18 @@ }; }; +/*<<2019-01-29-Michael Lin-[FairPhone][NFC]Reassign ESE Enable gpio in case of collision*/ nfc_disable_active: nfc_disable_active { /* 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,18 +960,19 @@ /* 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; }; }; }; +/*>>2019-01-29-Michael Lin-[FairPhone][NFC]Reassign ESE Enable gpio in case of collision*/ wcnss_pmux_5wire { /* Active configuration of bus pins */ -- GitLab From 7dfbf876eefc88fd5c2e691efaddf7ec346a1bce Mon Sep 17 00:00:00 2001 From: jialongjhan Date: Tue, 21 Apr 2020 20:24:23 +0800 Subject: [PATCH 03/78] display driver porting Root cause: How to fix: Feature: Issue: Depends-On: Change-Id: Idd7fdf53a98f1917649f48da10de99f3d09145a7 RiskArea: --- .../dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi | 164 ++++++++++++++++++ .../qcom/dsi-hx83112b-truly-1080p-video.dtsi | 158 +++++++++++++++++ .../boot/dts/qcom/msm8953-mdss-panels.dtsi | 48 +++++ arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 31 +++- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 23 ++- arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi | 12 +- .../boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi | 6 +- arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi | 2 + drivers/regulator/qpnp-lcdb-regulator.c | 10 ++ drivers/video/fbdev/msm/mdss_dsi.c | 93 ++++++++++ drivers/video/fbdev/msm/mdss_dsi_panel.c | 70 +++++++- drivers/video/fbdev/msm/mdss_io_util.c | 15 ++ 12 files changed, 609 insertions(+), 23 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi create mode 100644 arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi 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 100644 index 000000000000..222d47fb75f9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi @@ -0,0 +1,164 @@ +/* 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"; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 Start + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 End + 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>; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 Start + 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; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 End + //Qcom + 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 + 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"; + //[Arima][8901][Jialong]LCM initial code from IC firmware Start + 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]; + //[Arima][8901][Jialong]LCM initial code from IC firmware End + 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 100644 index 000000000000..10f4b6d28ab8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi @@ -0,0 +1,158 @@ +/* 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"; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 Start + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 End + 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>; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 Start + 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; + //[Arima][8901][JialongJhan] enable LCM Command mode 20190403 End + 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"; + //[Arima][8901][Jialong]LCM initial code from IC firmware Start + 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]; + //[Arima][8901][Jialong]LCM initial code from IC firmware End + 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/msm8953-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi index fa218ca617eb..fe240715ccc6 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi @@ -28,6 +28,10 @@ #include "dsi-panel-boent51021-1200p-video.dtsi" #include "dsi-panel-hx8394d-wxga-video.dtsi" #include "dsi-panel-inxnt51021-1200p-video.dtsi" +/*[Arima_8901][Jialong] lcm driver porting begin*/ +#include "dsi-hx83112b-truly-1080p-video.dtsi" +#include "dsi-hx83112b-djn-1080p-cmd.dtsi" +/*[Arima_8901][Jialong] lcm driver porting end*/ &soc { dsi_panel_pwr_supply: dsi_panel_pwr_supply { @@ -71,6 +75,50 @@ }; }; +/*[Arima_8901][Jialong] lcm driver porting begin*/ +&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,esd-check-enabled; + //qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + //qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + //qcom,mdss-dsi-panel-status-value = <0x9c>; + //qcom,mdss-dsi-panel-on-check-value = <0x9c>; + //qcom,mdss-dsi-panel-status-read-length = <1>; + //qcom,mdss-dsi-panel-max-error-count = <3>; +}; +/*[Arima_8901][Jialong] lcm driver porting end*/ + +//[Arima][8901][JialongJhan] Command mode 20190516 Start +&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,esd-check-enabled; + //qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + //qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + //qcom,mdss-dsi-panel-status-value = <0x9c>; + //qcom,mdss-dsi-panel-on-check-value = <0x9c>; + //qcom,mdss-dsi-panel-status-read-length = <1>; + //qcom,mdss-dsi-panel-max-error-count = <3>; +}; +//[Arima][8901][JialongJhan] Command mode 20190516 End + &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 index a9f87e1bd63b..c053cac507d6 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -128,16 +128,27 @@ hw-config = "single_dsi"; }; +/*[Arima_8901][Jialong] lcm driver porting begin*/ &mdss_dsi0 { + #if 1 + //[Arima][8901][JialongJhan] Command mode 20190516 Start + qcom,dsi-pref-prim-pan = <&dsi_djn_hx83112b_1080p_cmd>; + //qcom,dsi-pref-prim-pan = <&dsi_hx83112b_truly_1080p_video>; + //[Arima][8901][JialongJhan] Command mode 20190516 End + #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>; + //not config yet... + //qcom,platform-id-gpio = <&tlmm 59 0>; }; +/*[Arima_8901][Jialong] lcm driver porting end*/ &mdss_dsi1 { status = "disabled"; @@ -152,6 +163,22 @@ qcom,platform-bklight-en-gpio = <&tlmm 59 0>; }; +/*[Arima_8901][Jialong] lcm driver porting begin*/ +&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>; +}; +/*[Arima_8901][Jialong] lcm driver porting end*/ + &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 index 5b27d035b161..3dad2f277490 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -400,14 +400,16 @@ }; pmx_mdss: pmx_mdss { + + /*[Arima_8901][Jialong] lcm driver porting begin*/ mdss_dsi_active: mdss_dsi_active { mux { - pins = "gpio61", "gpio59"; + pins = "gpio61", "gpio96"; function = "gpio"; }; config { - pins = "gpio61", "gpio59"; + pins = "gpio61", "gpio96"; drive-strength = <8>; /* 8 mA */ bias-disable = <0>; /* no pull */ output-high; @@ -416,16 +418,19 @@ 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 */ + //output-high; }; }; + /*[Arima_8901][Jialong] lcm driver porting end*/ + mdss_dsi_gpio: mdss_dsi_gpio { mux { pins = "gpio141"; @@ -1262,12 +1267,12 @@ wsa_reset { wsa_reset_on: wsa_reset_on { mux { - pins = "gpio96"; + //pins = "gpio96"; function = "gpio"; }; config { - pins = "gpio96"; + //pins = "gpio96"; drive-strength = <2>; /* 2 MA */ output-high; }; @@ -1275,14 +1280,14 @@ wsa_reset_off: wsa_reset_off { mux { - pins = "gpio96"; + //pins = "gpio96"; function = "gpio"; }; config { - pins = "gpio96"; + //pins = "gpio96"; drive-strength = <2>; /* 2 MA */ - output-low; + output-high; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi index 86f5323779e7..61a41878c3ae 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi @@ -20,27 +20,31 @@ #size-cells = <0>; wsa881x_211: wsa881x@20170211 { + status = "disabled"; compatible = "qcom,wsa881x"; reg = <0x00 0x20170211>; - qcom,spkr-sd-n-gpio = <&tlmm 96 0>; + //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>; + //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>; + //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>; + //qcom,spkr-sd-n-gpio = <&tlmm 96 0>; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi index 1afea684eaeb..58240be45ffd 100644 --- 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,10 @@ &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>; + //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>; + //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 index 6e3932790614..fbe4e7f8e6ba 100644 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi @@ -373,6 +373,7 @@ }; }; +/* &tlmm { pmx_mdss { mdss_dsi_active: mdss_dsi_active { @@ -393,3 +394,4 @@ }; }; }; +*/ \ No newline at end of file diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c index 0ea743ee05ec..12fdd0603cbf 100644 --- a/drivers/regulator/qpnp-lcdb-regulator.c +++ b/drivers/regulator/qpnp-lcdb-regulator.c @@ -12,6 +12,9 @@ */ #define pr_fmt(fmt) "LCDB: %s: " fmt, __func__ +//[Arima][8901][Jialongjhan]Add delay time between VSN and VSP 20191104 Start +#define LCDB_PWRUP_PWRDN_CTL_REG 0x66 +//[Arima][8901][Jialongjhan]Add delay time between VSN and VSP 20191104 End #include #include @@ -2306,6 +2309,9 @@ static int qpnp_lcdb_regulator_probe(struct platform_device *pdev) int rc; struct device_node *node; struct qpnp_lcdb *lcdb; + //[Arima][8901][Jialongjhan]Add delay time between VSN and VSP 20191104 Start + u8 val = 0xF; // 0xF==1111==VSN delay 8ms; VSP delay 8ms + //[Arima][8901][Jialongjhan]Add delay time between VSN and VSP 20191104 End node = pdev->dev.of_node; if (!node) { @@ -2358,6 +2364,10 @@ static int qpnp_lcdb_regulator_probe(struct platform_device *pdev) lcdb->lcdb_enabled, lcdb->ldo.voltage_mv, lcdb->ncp.voltage_mv, lcdb->bst.voltage_mv); + //[Arima][8901][Jialongjhan]Add delay time between VSN and VSP 20191104 Start + rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_PWRUP_PWRDN_CTL_REG , &val, 1); + //[Arima][8901][Jialongjhan]Add delay time between VSN and VSP 20191104 End + return rc; } diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 1164e6f2f9af..6876894bcafe 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -36,6 +36,11 @@ #include "mdss_dsi_phy.h" #include "mdss_dba_utils.h" +//[Arima_8901][LCM][Jialongjhan] Add LCM_vendor file node for PCBA function test begin +#include +//[Arima_8901][LCM][Jialongjhan] Add LCM_vendor file node for PCBA function test end + + #define XO_CLK_RATE 19200000 #define CMDLINE_DSI_CTL_NUM_STRING_LEN 2 @@ -410,6 +415,11 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata) int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + /*[Fairphone_8901][Jialong]To avoid fuzzy screen,pull high Touch reset pin when panel on start*/ + gpio_direction_output(64, 1); + /*[Fairphone_8901][Jialong]To avoid fuzzy screen,pull high Touch reset pin when panel on end*/ + + if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; @@ -3268,6 +3278,81 @@ static int mdss_dsi_get_bridge_chip_params(struct mdss_panel_info *pinfo, return rc; } +/*[Arima_8901][Jialongjhan] Add LCM_vendor file node for PCBA function test 20181114 begin*/ +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, +}; +/*[Arima_8901][Jialongjhan] Add LCM_vendor file node for PCBA function test 20181114 End*/ + +/*[Arima_8901][Jialongjhan] Expose display revision 20190326 begin*/ + +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, +}; + +/*[Arima_8901][Jialongjhan] Expose display revision 20190326 end*/ + static int mdss_dsi_ctrl_probe(struct platform_device *pdev) { int rc = 0; @@ -3459,6 +3544,14 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) mdss_dsi_debug_bus_init(mdss_dsi_res); + //[Arima_8901][LCM][Jialongjhan] Add LCM_vendor file node for PCBA function test begin + proc_create("lcm_vendor", 0, NULL, &proc_lcm_vendor_fops); + //[Arima_8901][LCM][Jialongjhan] Add LCM_vendor file node for PCBA function test end + + //[Arima_8901][Jialongjhan] Expose display revision 20190326 begin + proc_create("lcm_revision", 0666, NULL, &proc_lcm_revision_fops); + //[Arima_8901][Jialongjhan] Expose display revision 20190326 end + return 0; error_shadow_clk_deinit: diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 7d3009bd34e3..c453452174e3 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -212,18 +212,21 @@ static void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl, mdss_dsi_cmdlist_put(ctrl, &cmdreq); } - -static char led_pwm1[2] = {0x51, 0x0}; /* DTYPE_DCS_WRITE1 */ +//[Arima][8901][20181105]Jialong modify backlight range is 1~4095 for control cmd range(2 bytes) Start +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 }; +//[Arima][8901][20181105]Jialong modify backlight range is 1~4095 for control cmd range(2 bytes) END 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; +//[Arima][8901][20181105]Jialong modify backlight range is 1~4095 for control cmd range(2 bytes) Start +int para_1,para_2; + pinfo = &(ctrl->panel_data.panel_info); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -232,7 +235,14 @@ static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level) 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; +//[Arima][8901][20181105]Jialong modify backlight range is 1~4095 for control cmd range(2 bytes) End + memset(&cmdreq, 0, sizeof(cmdreq)); cmdreq.cmds = &backlight_cmd; @@ -523,6 +533,19 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) gpio_free(ctrl_pdata->disp_en_gpio); } gpio_set_value((ctrl_pdata->rst_gpio), 0); + + //[Arima][8901][Jialongjhan]Modify pull TP reset Pin position 20191104 Start + //Move "pull low TP reset pin" from mdss_dsi.c, + //it have to same with LCM reset pin pull low + + /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off start*/ + //TP reset pin pull low with LCD reset pin at same time. + gpio_direction_output(64, 0); + /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off end*/ + + msleep(1); + //[Arima][8901][Jialongjhan]Modify pull TP reset Pin position 20191104 End + gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->mode_gpio)) gpio_free(ctrl_pdata->mode_gpio); @@ -824,11 +847,22 @@ static void mdss_dsi_panel_switch_mode(struct mdss_panel_data *pdata, mdss_dsi_panel_dsc_pps_send(ctrl_pdata, &pdata->panel_info); } +/*[Arima_8901][Jialongjhan] Expose display revision 20190326 begin*/ +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; +/*[Arima_8901][Jialongjhan] Expose display revision 20190326 end*/ + 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; + /*[Arima_8901][Jialongjhan] Expose display revision 20190326 begin*/ + struct dcs_cmd_req cmdreq2; + /*[Arima_8901][Jialongjhan] Expose display revision 20190326 end*/ if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); @@ -838,6 +872,32 @@ static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); + /*[Arima_8901][Jialongjhan] Expose display revision 20190326 begin*/ + 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++; + } + } + /*[Arima_8901][Jialongjhan] Expose display revision 20190326 end*/ + + //[Arima][8901][JialongJhan] Command mode debug fuzzy screen 20190516 Start + mdelay(1); + //[Arima][8901][JialongJhan] Command mode debug fuzzy screen 20190516 End + /* * 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 index 2f70ad37e227..27491559e576 100644 --- a/drivers/video/fbdev/msm/mdss_io_util.c +++ b/drivers/video/fbdev/msm/mdss_io_util.c @@ -286,6 +286,14 @@ int msm_mdss_enable_vreg(struct mdss_vreg *in_vreg, int num_vreg, int enable) goto vreg_set_opt_mode_fail; } rc = regulator_enable(in_vreg[i].vreg); + + //[Arima][8901][Jialongjhan]Modify Power on/off sequence 20191104 Start + if(!strcmp(in_vreg[i].vreg_name,"vddio")){ + msleep(10); + } + //[Arima][8901][Jialongjhan]Modify Power on/off sequence 20191104 End + + 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 +312,13 @@ int msm_mdss_enable_vreg(struct mdss_vreg *in_vreg, int num_vreg, int enable) regulator_set_load(in_vreg[i].vreg, in_vreg[i].load[DSS_REG_MODE_DISABLE]); + //[Arima][8901][Jialongjhan]Modify Power on/off sequence 20191104 Start + if(!strcmp(in_vreg[i].vreg_name,"vddio")){ + msleep(10); + } + //[Arima][8901][Jialongjhan]Modify Power on/off sequence 20191104 End + + if (regulator_is_enabled(in_vreg[i].vreg)) regulator_disable(in_vreg[i].vreg); -- GitLab From 727f754b5f8aaed9b30d31675573c3e89a882a94 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Wed, 22 Apr 2020 15:13:49 +0800 Subject: [PATCH 04/78] Add Fuji & Kayo battery profiles Change-Id: I23fd580e7abbc4ff8dc7ac87575dcbb5dca5cf56 --- ...ydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi | 1063 +++++++++++++++++ ...rydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi | 1039 ++++++++++++++++ arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi | 7 + 3 files changed, 2109 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi create mode 100644 arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi 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 100644 index 000000000000..a09f2d80a648 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi @@ -0,0 +1,1063 @@ +/* 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. + */ +//<--[FairPhone][Charging][JasonHsing] Add battery parameter for battery spec for charging 20181228 BEGIN -- +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>; + +//<--[FairPhone][Charging][JasonHsing] Battery ID change to 10 kohm 20181107 BEGIN -- +#if 1 + qcom,batt-id-kohm = <10>; +#else + qcom,batt-id-kohm = <82>; +#endif +//-->[FairPhone][Charging][JasonHsing] Battery ID change to 10 kohm 20181107 END -- + qcom,battery-beta = <4100>; + qcom,battery-therm-kohm = <100>; + qcom,battery-type = + "Fuji_3000mAH_FG_averaged_MasterSlave_Jan22th2019"; + qcom,qg-batt-profile-ver = <100>; + +//<2019/08/19-JessicaTseng, Modify FCC is 1500mA at 40 ~ 45 degree, 500mA at 45 ~ 60 degree. +//<--[FairPhone][Charging][JasonHsing] Fix SW jeita is not correct 20190716 BEGIN -- + 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>; +//-->[FairPhone][Charging][JasonHsing] Fix SW jeita is not correct 20190716 END -- +//>2019/08/19-JessicaTseng + +//-->[FairPhone][Charging][JasonHsing] Add battery parameter for battery spec for charging 20181228 END -- +//<--[FairPhone][Charging][JasonHsing] Setting jeita cold/cool/warm/hot threshold for charging 20190115 BEGIN -- + /* COOL = 15 DegC, WARM = 45 DegC */ + qcom,jeita-soft-thresholds = <0x44FF 0x2204>; + /* COLD = 0 DegC, HOT = 55 DegC */ + qcom,jeita-hard-thresholds = <0x5675 0x1987>; +//-->[FairPhone][Charging][JasonHsing] Setting jeita cold/cool/warm/hot threshold for charging 20190115 END -- + + 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>; + }; + +}; \ No newline at end of file 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 100644 index 000000000000..9d4b5fbf54f1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi @@ -0,0 +1,1039 @@ + +qcom,4184448_Arima_8902EU_3000mAh { + /* 4184448_Arima_8902EU_3000mAh_averaged_MasterSlave_Nov4th2019 */ + 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>; + }; + +}; \ No newline at end of file diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi index fbe4e7f8e6ba..2319b3eb7a3b 100644 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi @@ -36,8 +36,15 @@ /{ mtp_batterydata: qcom,battery-data { qcom,batt-id-range-pct = <15>; +//<20202/04/22-JessicaTseng, Add Fuji & Kayo battery profiles +#if 1 + #include "qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi" + #include "qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi" +#else #include "qg-batterydata-ascent-3450mah.dtsi" #include "qg-batterydata-mlp356477-2800mah.dtsi" +#endif +//>2020/04/22-JessicaTseng }; }; -- GitLab From 1d8583b80470e0c96283d05d70eca3018473fe86 Mon Sep 17 00:00:00 2001 From: michaellin Date: Tue, 21 Apr 2020 18:39:32 +0800 Subject: [PATCH 05/78] Introduce firmware download fail recovery mechanism Root cause: To avoid from recovery fail and then NFC always in download mode How to fix: To let NFC IRQ stay enabled while in download mode Change-Id: Icbd45691e6b1aeebe2f694c04ae1573837913c3b RiskArea: NFC --- drivers/nfc/nq-nci.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index bae7f5b8d5cc..cc90a36b1971 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -29,6 +29,11 @@ #include #endif +#define PFX "[NFC][NQ]" +// 20181116 Michael Lin - Introduce firmware download fail recovery mechanism +/* 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 +481,11 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) * interrupts to avoid spurious notifications to upper * layers. */ + //< 20181116 Michael Lin - Mask where firmware download fail recovery is used + #if !defined( NFC_FW_DOWNLOAD_MODE ) nqx_disable_irq(nqx_dev); + #endif + //> 20181116 Michael Lin - Mask where firmware download fail recovery is used dev_dbg(&nqx_dev->client->dev, "gpio_set_value disable: %s: info: %p\n", __func__, nqx_dev); @@ -533,6 +542,12 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) return -EBUSY; /* Device or resource busy */ } } + //< 20181116 Michael Lin - Add where firmware download fail recovery is used + #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 + //< 20181116 Michael Lin - Add where firmware download fail recovery is used gpio_set_value(nqx_dev->en_gpio, 1); usleep_range(10000, 10100); if (gpio_is_valid(nqx_dev->firm_gpio)) { @@ -1187,8 +1202,14 @@ static int nqx_probe(struct i2c_client *client, if (r) { /* make sure NFCC is not enabled */ gpio_set_value(platform_data->en_gpio, 0); + //< 20181116 Michael Lin - Mask where firmware download fail recovery is used + #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 + //> 20181116 Michael Lin - Mask where firmware download fail recovery is used } /* Register reboot notifier here */ @@ -1350,6 +1371,7 @@ static int nfcc_reboot(struct notifier_block *notifier, unsigned long val, */ static int __init nqx_dev_init(void) { + pr_info( PFX "[%s]Enter...\n", __func__ ); return i2c_add_driver(&nqx); } module_init(nqx_dev_init); -- GitLab From 923d32043079c5f002e00f04ab222cf57a8b9dcd Mon Sep 17 00:00:00 2001 From: louisliu Date: Thu, 23 Apr 2020 16:01:11 +0800 Subject: [PATCH 06/78] Fingerprint. Driver porting. Root cause: N/A How to fix: N/A RiskArea: Fingerprint Change-Id: Id231c4ee49de5cd25fbdc452bfc4e806f4429597 --- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 56 ++ arch/arm64/boot/dts/qcom/msm8953.dtsi | 13 + arch/arm64/configs/msm8953-perf_defconfig | 3 + arch/arm64/configs/msm8953_defconfig | 3 + drivers/input/Kconfig | 11 + drivers/input/Makefile | 4 + drivers/input/fingerprint/Makefile | 2 + drivers/input/fingerprint/elan_fp_qcom_tee.c | 697 ++++++++++++++++++ drivers/input/fingerprint/elan_fp_qcom_tee.h | 25 + 9 files changed, 814 insertions(+) create mode 100644 drivers/input/fingerprint/Makefile create mode 100644 drivers/input/fingerprint/elan_fp_qcom_tee.c create mode 100644 drivers/input/fingerprint/elan_fp_qcom_tee.h diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 3dad2f277490..957f6ac742bd 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -399,6 +399,62 @@ }; +//<2020/04/23-louisliu, Fingerprint. Driver porting. + fps { + fps_int_active: fps_int_active { + mux { + pins = "gpio48"; + function = "gpio"; + }; + + config { + 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; + }; + }; + }; +//>2020/04/23-louisliu + pmx_mdss: pmx_mdss { /*[Arima_8901][Jialong] lcm driver porting begin*/ diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index 1d78b6b36aa7..cd084cafecef 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -2319,3 +2319,16 @@ &gdsc_usb30 { status = "okay"; }; + +// //<2020/04/23-louisliu, Fingerprint. Driver porting. +&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>; + }; +}; +// //>2020/04/23-louisliu \ No newline at end of file diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index 78f1f9753551..221622cee555 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -684,3 +684,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y +# //<2020/04/23-louisliu, Fingerprint. Driver porting. +CONFIG_ELAN_FINGERPRINT=y +# //>2020/04/23-louisliu diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index f30592c3b936..ad12e1955d05 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -748,3 +748,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y +# //<2020/04/23-louisliu, Fingerprint. Driver porting. +CONFIG_ELAN_FINGERPRINT=y +# //>2020/04/23-louisliu diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index de41b16afe65..0d4866675d94 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -200,6 +200,17 @@ config INPUT_KEYCOMBO ---help--- Say Y here if you want to take action when some keys are pressed; +# //<2020/04/23-louisliu, Fingerprint. Driver porting. +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. +# //>2020/04/23-louisliu + comment "Input Device Drivers" source "drivers/input/keyboard/Kconfig" diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 7ff1b70fd8cb..50a5f9436ed6 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -34,3 +34,7 @@ obj-$(CONFIG_RMI4_CORE) += rmi4/ obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o obj-$(CONFIG_INPUT_KEYCOMBO) += keycombo.o obj-$(CONFIG_SMI130) += sensors/smi130/ + +# //<2020/04/23-louisliu, Fingerprint. Driver porting. +obj-$(CONFIG_ELAN_FINGERPRINT) +=fingerprint/ +# //>2020/04/23-louisliu \ No newline at end of file diff --git a/drivers/input/fingerprint/Makefile b/drivers/input/fingerprint/Makefile new file mode 100644 index 000000000000..4b4eb3a794b2 --- /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 100644 index 000000000000..34d35171520a --- /dev/null +++ b/drivers/input/fingerprint/elan_fp_qcom_tee.c @@ -0,0 +1,697 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#endif + +#if defined(CONFIG_FB) +#include +#include +#include +#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 +//[Z20][fingerprint][Kent][17111801][begin]add power gpio for vdd +#define VDD_POWER_GPIO 1 +//[Z20][fingerprint][Kent][17111801][end]add power gpio for vdd +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; +//[Z20][fingerprint][Kent][17111802][begin]add power gpio for vdd +#if VDD_POWER_GPIO + int vdd_gpio; +#endif +//[Z20][fingerprint][Kent][17111802][end]add power gpio for vdd +}; + +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 ; + + //[Z20][fingerprint][180123begin]void fb system crash + if (event != 0x10) + return 0; + //[Z20][fingerprint][180123end]void fb system crash + +//[Z20][fingerprint][180123begin]check the null pointer + 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; + } +//[Z20][fingerprint][180123end]check the null pointer + 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); +//[Z20][fingerprint][Kent][17111803][begin]add power gpio for vdd +#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 +//[Z20][fingerprint][Kent][17111803][end]add power gpio for vdd + 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; +//[Z20][fingerprint][Kent][17111804][begin]add power gpio for vdd +#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 +//[Z20][fingerprint][Kent][17111804][end]add power gpio for vdd + 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); +//[Z20][fingerprint][Kent][17111805][begin]add power gpio for vdd +#if VDD_POWER_GPIO + gpio_free(fp->vdd_gpio); +#endif +//[Z20][fingerprint][Kent][17111805][end]add power gpio for vdd + 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 100644 index 000000000000..1c6f9aa6884a --- /dev/null +++ b/drivers/input/fingerprint/elan_fp_qcom_tee.h @@ -0,0 +1,25 @@ +#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 */ -- GitLab From b38099973dcc0ce9558c812aad48e92c457c5528 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Fri, 24 Apr 2020 16:03:07 +0800 Subject: [PATCH 07/78] Battery re-charging voltage is 4.3V Change-Id: Ie9c967e895ddca03a8a5a499b728fab0e62e8c57 --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index d2b16882d905..d2aab5544a66 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -314,7 +314,10 @@ qcom,pmic-revid = <&pmi632_revid>; dpdm-supply = <&qusb_phy>; - qcom,auto-recharge-soc = <98>; +//<2020/04/24-JessicaTseng, Re-charge condition for battery to 4.3V + qcom,auto-recharge-vbat-mv = <4300>; + //qcom,auto-recharge-soc = <98>; +//>2020/04/24-JessicaTseng qcom,chg-vadc = <&pmi632_vadc>; qcom,flash-disable-soc = <10>; qcom,sw-jeita-enable; @@ -484,8 +487,10 @@ #size-cells = <1>; qcom,qg-iterm-ma = <100>; - qcom,hold-soc-while-full; - qcom,linearize-soc; +//<2020/04/24-JessicaTseng, Re-charge condition for battery to 4.3V + //qcom,hold-soc-while-full; + //qcom,linearize-soc; +//>2020/04/24-JessicaTseng qcom,qg-vadc = <&pmi632_vadc>; qcom,pmic-revid = <&pmi632_revid>; -- GitLab From b78f378e03dd36e12b64828286b3d7b3697f7f55 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 27 Apr 2020 16:06:56 +0800 Subject: [PATCH 08/78] Fill the correct NTC table for battery Change-Id: I7155d49c94adff3743aaef45a234db62c761d218 --- drivers/hwmon/qpnp-adc-common.c | 144 ++++++++++++++++---------------- 1 file changed, 73 insertions(+), 71 deletions(-) diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c index 24564b34014e..e3e49e03ed66 100644 --- a/drivers/hwmon/qpnp-adc-common.c +++ b/drivers/hwmon/qpnp-adc-common.c @@ -604,78 +604,80 @@ static const struct qpnp_vadc_map_pt adcmap_ncp03wf683[] = { }; /* Voltage to temperature */ +//<2020/04/27-JessicaTseng, Fill the correct NTC table for 8901 battery 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} }; +//>2020/04/27-JessicaTseng /* Voltage to temperature */ static const struct qpnp_vadc_map_pt adcmap_batt_therm_qrd[] = { @@ -2398,7 +2400,7 @@ int32_t qpnp_adc_scale_die_temp_1390(struct qpnp_vadc_chip *chip, 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); -- GitLab From 2adac6f0eb721a5664ddb7a72bbc3c17c24471c9 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 27 Apr 2020 18:23:44 +0800 Subject: [PATCH 09/78] Add condition of charging current for thermal-mitigation Change-Id: If9dab24562fb9fda76a50ad4f4f75b0891189c25 --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index d2aab5544a66..c1078fc6134f 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -326,9 +326,11 @@ qcom,hw-connector-mitigation; qcom,connector-internal-pull-kohm = <100>; +//<2020/04/28-JessicaTseng, Add condition of charging current for thermal-mitigation qcom,thermal-mitigation - = <3000000 2500000 2000000 1500000 - 1000000 500000>; + = <2000000 1500000 1000000 500000 + 500000 500000>; +//>2020/04/28-JessicaTseng qcom,chgr@1000 { reg = <0x1000 0x100>; -- GitLab From 240bd29f38f0d12f4b48b3eb36d9335b9d821a03 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 27 Apr 2020 19:09:56 +0800 Subject: [PATCH 10/78] Setting jeita fv re-charge voltage for warm temp Root cause: Jeita fv stop charging when battery temp is warm, but without use HW re-charge. How to fix: Add a dynamic re-charge function for warm temp's HW re-charge Change-Id: I9343ab687113f03d93cecb8baa5e8ac794cf7f7b --- drivers/power/supply/qcom/smb5-lib.c | 42 ++++++++++++++++++++++ drivers/power/supply/qcom/smb5-lib.h | 3 ++ drivers/power/supply/qcom/step-chg-jeita.c | 16 +++++++++ 3 files changed, 61 insertions(+) diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 7d9c7bac816b..a5c32544cecf 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -1236,6 +1236,38 @@ static int smblib_usb_irq_enable_vote_callback(struct votable *votable, return 0; } +//<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp +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; +} +//>2020/04/28-JessicaTseng + /******************* * VCONN REGULATOR * * *****************/ @@ -4428,6 +4460,16 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } +//<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp + 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; + } +//>2020/04/28-JessicaTseng + return rc; } diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index 63061dae6271..c00db850b43e 100644 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -341,6 +341,9 @@ struct smb_charger { struct votable *chg_disable_votable; struct votable *pl_enable_votable_indirect; struct votable *usb_irq_enable_votable; +//<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp + struct votable *rechg_vol_votable; +//>2020/04/28-JessicaTseng /* 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 index 3e8b46b9e12b..63b3950dcbc6 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -80,6 +80,9 @@ struct step_chg_info { struct votable *fcc_votable; struct votable *fv_votable; struct votable *usb_icl_votable; +//<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp + struct votable *rechg_vol_votable; +//>2020/04/28-JessicaTseng struct wakeup_source *step_chg_ws; struct power_supply *batt_psy; struct power_supply *bms_psy; @@ -500,6 +503,10 @@ static int handle_step_chg_config(struct step_chg_info *chip) } #define JEITA_SUSPEND_HYST_UV 50000 +//<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp +#define JEITA_RECHG_HYST_UV 200000//100000 +//>2020/04/28-JessicaTseng + static int handle_jeita(struct step_chg_info *chip) { union power_supply_propval pval = {0, }; @@ -561,6 +568,11 @@ static int handle_jeita(struct step_chg_info *chip) if (rc < 0) fv_uv = 0; +//<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp + if (!chip->rechg_vol_votable) + chip->rechg_vol_votable = find_votable("RECHG_VOL"); +//>2020/04/28-JessicaTseng + chip->fv_votable = find_votable("FV"); if (!chip->fv_votable) goto update_time; @@ -597,6 +609,10 @@ static int handle_jeita(struct step_chg_info *chip) set_jeita_fv: vote(chip->fv_votable, JEITA_VOTER, fv_uv ? true : false, fv_uv); +//<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp + vote(chip->rechg_vol_votable, + JEITA_VOTER, true, (fv_uv -JEITA_RECHG_HYST_UV)); +//>2020/04/28-JessicaTseng update_time: chip->jeita_last_update_time = ktime_get(); -- GitLab From bab38f014101355a9636c56f9871958195047823 Mon Sep 17 00:00:00 2001 From: tracychui Date: Wed, 29 Apr 2020 16:24:36 +0800 Subject: [PATCH 11/78] Touch driver porting Root cause:N/A How to fix:N/A Feature:Touch driver porting on Android 10 Change-Id: I410640b03f15c06b9f67e6096aea4daa19a23a30 RiskArea:Touch --- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 120 +- arch/arm64/boot/dts/qcom/msm8953.dtsi | 63 +- arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi | 20 +- arch/arm64/configs/msm8953-perf_defconfig | 15 +- arch/arm64/configs/msm8953_defconfig | 15 +- drivers/input/touchscreen/Kconfig | 13 +- drivers/input/touchscreen/Makefile | 5 +- .../FP_DJN_Arima_CID0804_D02_C14_20190903.i | 4096 +++++++++++++++++ .../input/touchscreen/hxchipset83112b/Kconfig | 27 + .../touchscreen/hxchipset83112b/Makefile | 4 + .../hxchipset83112b/himax_common.c | 2464 ++++++++++ .../hxchipset83112b/himax_common.h | 467 ++ .../touchscreen/hxchipset83112b/himax_debug.c | 3361 ++++++++++++++ .../touchscreen/hxchipset83112b/himax_debug.h | 213 + .../touchscreen/hxchipset83112b/himax_ic.c | 3289 +++++++++++++ .../touchscreen/hxchipset83112b/himax_ic.h | 82 + .../hxchipset83112b/himax_platform.c | 828 ++++ .../hxchipset83112b/himax_platform.h | 130 + 18 files changed, 15110 insertions(+), 102 deletions(-) create mode 100644 drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i create mode 100644 drivers/input/touchscreen/hxchipset83112b/Kconfig create mode 100644 drivers/input/touchscreen/hxchipset83112b/Makefile create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_common.c create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_common.h create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_debug.c create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_debug.h create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_ic.c create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_ic.h create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_platform.c create mode 100644 drivers/input/touchscreen/hxchipset83112b/himax_platform.h diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 957f6ac742bd..908cdd0095e3 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -1432,65 +1432,67 @@ }; }; - 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>; - }; - }; - }; +/*[20200429][TracyChui]Touch driver porting start*/ +// 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>; +// }; +// }; +// }; +/*[20200429][TracyChui]Touch driver porting end*/ spi6 { spi6_default: spi6_default { diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index cd084cafecef..f42b0f733f73 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -188,7 +188,9 @@ i2c2 = &i2c_2; i2c3 = &i2c_3; i2c5 = &i2c_5; - spi3 = &spi_3; +/*[20200429][TracyChui]Touch driver porting start*/ +// spi3 = &spi_3; +/*[20200429][TracyChui]Touch driver porting end*/ spi6 = &spi_6; }; @@ -687,31 +689,33 @@ 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"; - }; +/*[20200429][TracyChui]Touch driver porting start*/ +// 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"; +// }; +/*[20200429][TracyChui]Touch driver porting end*/ spi_6: spi@7af6000 { /* BLSP2 QUP2 */ compatible = "qcom,spi-qup-v2"; @@ -813,7 +817,10 @@ dmas = <&dma_blsp1 8 64 0x20000020 0x20>, <&dma_blsp1 9 32 0x20000020 0x20>; dma-names = "tx", "rx"; - status = "disabled"; +/*[20200429][TracyChui]Touch driver porting start*/ + //status = "disabled"; + status = "ok"; +/*[20200429][TracyChui]Touch driver porting end*/ }; i2c_5: i2c@7af5000 { /* BLSP2 QUP1 */ @@ -2331,4 +2338,4 @@ elan,vdd-gpio = <&tlmm 90 0>; }; }; -// //>2020/04/23-louisliu \ No newline at end of file +// //>2020/04/23-louisliu diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi index 2319b3eb7a3b..b4870b6627da 100644 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi @@ -401,4 +401,22 @@ }; }; }; -*/ \ No newline at end of file +*/ +/*[20200429][TracyChui]Touch driver porting start */ +&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>; + }; +}; +/*[20200429][TracyChui]Touch driver porting end */ diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index 221622cee555..4ff6c5bc6f2e 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -321,12 +321,17 @@ CONFIG_KEYBOARD_GPIO=y # 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 +#[20200429][TracyChui]Touch driver porting start +#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 +#[20200429][TracyChui]Touch driver porting end CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_SERPORT is not set diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index ad12e1955d05..830d3dbb3a01 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -328,12 +328,17 @@ CONFIG_KEYBOARD_GPIO=y # 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 +#[20200429][TracyChui]Touch driver porting start +#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 +#[20200429][TracyChui]Touch driver porting end CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_SERPORT is not set diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 1e620a99b386..daf4203d1bc1 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,7 +11,9 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN -source "drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig" +#[20200429][TracyChui]Touch driver porting start +#source "drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig" +#[20200429][TracyChui]Touch driver porting end config TOUCHSCREEN_PROPERTIES def_tristate INPUT @@ -1373,7 +1375,9 @@ config TOUCHSCREEN_SYNAPTICS_DSX If unsure, say N. -source "drivers/input/touchscreen/synaptics_dsx/Kconfig" +#[20200429][TracyChui]Touch driver porting start +#source "drivers/input/touchscreen/synaptics_dsx/Kconfig" +#[20200429][TracyChui]Touch driver porting end source "drivers/input/touchscreen/focaltech_touch/Kconfig" config TOUCHSCREEN_FT5X06 @@ -1432,7 +1436,10 @@ config TOUCHSCREEN_HIMAX_CHIPSET If unsure, say N. -source "drivers/input/touchscreen/hxchipset/Kconfig" +#[20200429][TracyChui]Touch driver porting start +#source "drivers/input/touchscreen/hxchipset/Kconfig" +source "drivers/input/touchscreen/hxchipset83112b/Kconfig" +#[20200429][TracyChui]Touch driver porting end config TOUCHSCREEN_EKTF3XXX_CHIPSET bool "Elan EKTF3XXX touchpanel CHIPSET" diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 59cf96765296..a164c9979129 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -106,6 +106,9 @@ obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o 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/ +#[20200429][TracyChui]Touch driver porting start +# obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset/ +obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset83112b/ +#[20200429][TracyChui]Touch driver porting end 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 100644 index 000000000000..fdb82bfacb2a --- /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 100644 index 000000000000..2efd9c3eea89 --- /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 100644 index 000000000000..522907a48956 --- /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 100644 index 000000000000..24dd7a2b8e56 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.c @@ -0,0 +1,2464 @@ +/* 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 +/*[Arima_8901][jinjia] Upgrade himax fw CID0804_D02_C14 for 0.9mm CG performance 20190903 begin*/ +/*[Arima_8901][TracyChui]Add usb plug detect function and updated FW CID0804_D02_C13 20190816 start */ +/*[Arima_8901][jinjia] Upgrade himax fw CID0804_D02_C12 for 0.9mm CG performance 20190812 begin*/ +/*[Arima_8901][allen_yu] Upgrade himax fw CID0802_D02_C06 for DQA low ground issue 20190530 begin*/ +/*[Arima_8901][allen_yu] Modify to edge trigger and upgrade fw to CID0802_D02_C05 20190322 begin*/ +/*[Arima_8901][allen_yu] Upgrade himax fw CID0802_D02_C04 20190116 begin*/ +/*[Arima_8901][allen_yu] Upgrade himax fw CID0802_D02_C03 20181226 begin*/ +/*[Arima_8901][allen_yu] Modify to edge trigger and upgrade himax fw CIDFF00_D01_C02 20181128 begin*/ +/*[Arima_8901][allen_yu] Upgrade himax first fw CIDFF00_D01_C01 20181122 begin*/ +#if defined(HX_AUTO_UPDATE_FW) + +unsigned char i_CTPM_FW_HX83112A[]= +{ + 0 +//#include "Yandex_Truly_Arima_CIDFF04_D02_C04_20180801.i" +}; +unsigned char i_CTPM_FW_HX83112B[]= +{ +#include "FP_DJN_Arima_CID0804_D02_C14_20190903.i" +}; + +#endif +/*[Arima_8901][allen_yu] 20181122 end*/ +/*[Arima_8901][allen_yu] 20181128 end*/ +/*[Arima_8901][allen_yu] 20181226 end*/ +/*[Arima_8901][allen_yu] 20190116 end*/ +/*[Arima_8901][allen_yu] 20190322 end*/ +/*[Arima_8901][allen_yu] 20190530 end*/ +/*[Arima_8901][jinjia] 20190812 end*/ +/*[Arima_8901][TracyChui] 20190816 end */ +/*[Arima_8901][jinjia] 20190812 end*/ + +/*[Arima_8710][allen_yu] Solve the report point issue 20180619 begin*/ +static void himax_release_all_finger(void); +/*[Arima_8710][allen_yu] 20180619 end*/ + +#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +extern void himax_resend_cmd_func(bool suspended); +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +extern void himax_rst_cmd_recovery_func(bool suspended); +/*[Arima_7947][allen_yu] 20171221 end*/ +#endif + +/*[Arima_8710][allen_yu] Fix TP I2C error in suspend 20180423 begin*/ +#ifdef HX_RST_PIN_FUNC +int reset_flag =1; +#endif +/*[Arima_8710][allen_yu] 20180423 end*/ + +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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#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 +/*[Arima_7947][allen_yu] 20171221 end*/ + +#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; +/*[Arima_8901][TracyChui]Add usb plug detect function and updated FW CID0804_D02_C13 20190816 start */ +#ifdef HX_USB_DETECT_GLOBAL +//bool USB_detect_flag = 0; +#endif +/*[Arima_8901][TracyChui] 20190816 end */ + +#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; +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ + //unsigned char* ImageBuffer = i_CTPM_FW; + //int fullFileLength = sizeof(i_CTPM_FW); + unsigned char* ImageBuffer = NULL; + int fullFileLength = 0; +/*[Arima_8710][allen_yu] 20180828 end*/ + uint8_t ret = 0, result = 0; + +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ +if(IC_TYPE == HX_83112A_SERIES_PWON) + { + ImageBuffer = i_CTPM_FW_HX83112A; + fullFileLength = sizeof(i_CTPM_FW_HX83112A); + } + else/*HX_83112B_SERIES_PWON*/ + { +/*[Arima_8710][allen_yu] Modify the touch fw dynamic auto upgtade rule 20180830 begin*/ + //printk("%s: (%d)No upgrade 2nd source fw\n", __func__, __LINE__); + //return false; + ImageBuffer = i_CTPM_FW_HX83112B; + fullFileLength = sizeof(i_CTPM_FW_HX83112B); +/*[Arima_8710][allen_yu] 20180830 end*/ + } +/*[Arima_8710][allen_yu] 20180828 end*/ + 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; igest_pt_x[i]) + tmp_min_x=gest_pt_x[i]; + if(tmp_max_ygest_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) +/*[Arima_8901][TracyChui]Add usb plug detect function and updated FW CID0804_D02_C13 20190816 start */ +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); + } + } +} +/*[Arima_8901][TracyChui] 20190816 end */ +#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) + { +/*[Arima_8710][allen_yu] close touch driver log 20180411 begin*/ + //printk("allenyu_010\n"); +/*[Arima_8710][allen_yu] 20180411 end*/ + 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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#if 0 + himax_resend_cmd_func(ts->suspended); +#endif + himax_rst_cmd_recovery_func(ts->suspended); +/*[Arima_7947][allen_yu] 20171221 end*/ +#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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#if 0 + himax_resend_cmd_func(ts->suspended); +#endif + himax_rst_cmd_recovery_func(ts->suspended); +/*[Arima_7947][allen_yu] 20171221 end*/ +#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; +/*[Arima_7947][allen_yu] Modify Mutex initialization in callback function 20180305 begin*/ +//ParisKuong modified Mutex initialization +++ + mutex_init(&ts->ops_lock); +//ParisKuong modified Mutex initialization --- +/*[Arima_7947][allen_yu] 20180305 end*/ + 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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#ifdef HX_TP_PROC_GUEST_INFO +static void himax_ts_guest_info_work_func(struct work_struct *work) +{ + + himax_read_project_id(); + +} +#endif +/*[Arima_7947][allen_yu] 20171221 end*/ +#ifdef HX_TP_PROC_DIAG +static void himax_ts_diag_work_func(struct work_struct *work) +{ + himax_ts_diag_func(); +} +#endif + +/*[Arima_8710][allen_yu] Solve the report point issue 20180619 begin*/ +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__); +} +/*[Arima_8710][allen_yu] 20180619 end*/ + +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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#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 +/*[Arima_7947][allen_yu] 20171221 end*/ +#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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#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)); +/*[Arima_8710][allen_yu] Modify the touch fw dynamic auto upgtade rule 20180830 begin*/ + 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; + } + } +/*[Arima_8710][allen_yu] 20180830 end*/ +/*[Arima_7947][allen_yu] 20171221 end*/ + 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 + +/*[Arima_8710][allen_yu] Solve the report point issue 20180619 begin*/ + mutex_init(&ts->report_mutex); +/*[Arima_8710][allen_yu] 20180619 end*/ + +#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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#ifdef HX_TP_PROC_GUEST_INFO +err_create_guest_info_wq_failed: +#endif +/*[Arima_7947][allen_yu] 20171221 end*/ +#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 +/*[Arima_7947][allen_yu] Change the rule of upgrading fw 20171221 begin*/ +#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 +/*[Arima_7947][allen_yu] 20171221 end*/ +#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); +/*[Arima_8710][allen_yu] Fix TP I2C error in suspend 20180423 begin*/ +#ifdef HX_RST_PIN_FUNC + reset_flag = 0; +#endif +/*[Arima_8710][allen_yu] 20180423 end*/ + 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); + +/*[Arima_8710][allen_yu] Solve the report point issue 20180619 begin*/ + himax_release_all_finger(); +/*[Arima_8710][allen_yu] 20180619 end*/ + + 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); +/*[Arima_8710][allen_yu] Fix TP I2C error in suspend 20180423 begin*/ +#ifdef HX_RST_PIN_FUNC + reset_flag = 1; +#endif +/*[Arima_8710][allen_yu] 20180423 end*/ +#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 100644 index 000000000000..2a134988cdd7 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.h @@ -0,0 +1,467 @@ +/* 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include "himax_platform.h" +/*[Arima_8901][TracyChui]Add usb plug detect function and updated FW CID0804_D02_C13 20190816 start */ +#include +/*[Arima_8901][TracyChui] 20190816 end */ +#if defined(CONFIG_FB) +#include +#include +/*[Arima_7947][allen_yu] Add mutex in callback function 20180131 begin*/ +#include +/*[Arima_7947][allen_yu] 20180131 end*/ +#elif defined(CONFIG_HAS_EARLYSUSPEND) +#include +#endif + +#ifdef CONFIG_OF +#include +#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 +/*[Arima_8901][allen_yu] Upgrade himax first fw CIDFF00_D01_C01 20181122 begin*/ +#define HX_AUTO_UPDATE_FW +/*[Arima_8901][allen_yu] 20181122 end*/ +//#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 +/*[Arima_8901][TracyChui]Add usb plug detect function and updated FW CID0804_D02_C13 20190816 start */ +#define HX_USB_DETECT_GLOBAL +/*[Arima_8901][TracyChui]20190816 end */ +//#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 +/*[Arima_7947][allen_yu] Define the value of collecting raw_data and delta_data 20171221 begin*/ +#define HX_FIX_TOUCH_INFO /* if open, you need to change the touch info in the fix_touch_info*/ +/*[Arima_7947][allen_yu] 20171221 end*/ +//#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 + +/*[Arima_8901][TracyChui]Add usb plug detect function and updated FW CID0804_D02_C13 20190816 start */ +#ifdef HX_USB_DETECT_GLOBAL +#define POWER_SUPPLY_BATTERY_STATUS_PATCH "/sys/class/power_supply/battery/status" +#endif +/*[Arima_8901][TracyChui] 20190816 end */ + +#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 +/*[Arima_7947][allen_yu] Define the value of collecting raw_data and delta_data 20171221 begin*/ +#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, +/*[Arima_7947][allen_yu] Modify Int trigger way and upgrade himax fw to CID0404_D01_C02 20171228 begin*/ + FIX_HX_INT_IS_EDGE = false, +/*[Arima_7947][allen_yu] 20171228 end*/ +#ifdef HX_TP_PROC_2T2R + FIX_HX_RX_NUM_2 = 0, + FIX_HX_TX_NUM_2 = 0, +#endif +/*[Arima_8710][allen_yu] Dynamic detect touch golden value 20180929 begin*/ + 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, +/*[Arima_8901][allen_yu] Modify to edge trigger and upgrade fw to CID0802_D02_C05 20190322 begin*/ +/*[Arima_8901][allen_yu] Modify to edge trigger and upgrade himax first fw CIDFF00_D01_C02 20181128 begin*/ + SEC_FIX_HX_INT_IS_EDGE = false, +/*[Arima_8901][allen_yu] 20181128 end*/ +/*[Arima_8901][allen_yu] 20190322 end*/ +#ifdef HX_TP_PROC_2T2R + SEC_FIX_HX_RX_NUM_2 = 0, + SEC_FIX_HX_TX_NUM_2 = 0 +#endif +/*[Arima_8710][allen_yu] 20180929 end*/ +}; +#endif +/*[Arima_7947][allen_yu] 20171221 end*/ +#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; +/*[Arima_8710][allen_yu] Modify the touch fw dynamic auto upgtade rule 20180830 begin*/ + int vendor_hx_ic_id; +/*[Arima_8710][allen_yu] 20180830 end*/ + 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; +/*[Arima_8710][allen_yu] Solve the report point issue 20180619 begin*/ + struct mutex report_mutex; +/*[Arima_8710][allen_yu] 20180619 end*/ + +#if defined(CONFIG_FB) + struct notifier_block fb_notif; + struct workqueue_struct *himax_att_wq; + struct delayed_work work_att; +/*[Arima_7947][allen_yu] Add mutex in callback function 20180131 begin*/ + struct mutex ops_lock; +/*[Arima_7947][allen_yu] 20180131 end*/ +#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 100644 index 000000000000..01e83fc79d1e --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_debug.c @@ -0,0 +1,3361 @@ +/* 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) + { +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ +/*[Arima_7947][allen_yu] Show the Himax firmware version 20180123 begin*/ +#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"); + } +/*[Arima_8710][allen_yu] 20180828 end*/ +#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 +/*[Arima_7947][allen_yu] 20180123 end*/ + 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='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; +/*[Arima_7947][allen_yu] Upgrade himax fw to CID101 and modify node of manual update 20171121 begin*/ + struct inode *inode; + loff_t file_len = 0; +/*[Arima_7947][allen_yu] 20171121 end*/ + + 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; + } +/*[Arima_7947][allen_yu] Upgrade himax fw to CID101 and modify node of manual update 20171121 begin*/ + inode = filp->f_inode; + file_len = inode->i_size; +/*[Arima_7947][allen_yu] 20171121 end*/ + oldfs = get_fs(); + set_fs(get_ds()); + +/*[Arima_7947][allen_yu] Upgrade himax fw to CID101 and modify node of manual update 20171121 begin*/ + // 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; + } +/*[Arima_7947][allen_yu] 20171121 end*/ + + 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 100644 index 000000000000..925d5e0f43e2 --- /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 100644 index 000000000000..b81f7260cb14 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_ic.c @@ -0,0 +1,3289 @@ +/* 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" +/*[Arima_8710][allen_yu] Fix TP I2C error in suspend 20180423 begin*/ +#include "himax_common.h" +/*[Arima_8710][allen_yu] 20180423 end*/ + +extern int i2c_error_count; +/*[Arima_8710][allen_yu] Fix TP I2C error in suspend 20180419 begin*/ +extern int reset_flag; +/*[Arima_8710][allen_yu] 20180419 end*/ + +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; +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ +//extern unsigned char i_CTPM_FW[]; +extern unsigned char i_CTPM_FW_HX83112A[]; +extern unsigned char i_CTPM_FW_HX83112B[]; +/*[Arima_8710][allen_yu] 20180828 end*/ +#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); +/*[Arima_7947][allen_yu] Enter safe mode when i2c fail 20180129 begin*/ +#if 0 + msleep(20); +#endif +/*[Arima_7947][allen_yu] 20180129 end*/ +} + +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) +{ +/*[Arima_8710][allen_yu] Fix TP I2C error in suspend 20180423 begin*/ +#ifdef HX_RST_PIN_FUNC +if (reset_flag ==1){ +/*[Arima_8710][allen_yu] 20180423 end*/ + 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); + } + } +/*[Arima_8710][allen_yu] Fix TP I2C error in suspend 20180423 begin*/ +} +#endif +/*[Arima_8710][allen_yu] 20180423 end*/ +} +#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); +/*[Arima_8710][allen_yu] Set touch golden value for ATS 20180620 begin*/ + //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; +/*[20190822][TracyChui]Modify touch self test criteria for 0.9 glass start */ +/*[20190815][TracyChui]Modify touch self test criteria start */ +/*[Arima_8901][allen_yu] Modify touch golden value 20190527 begin*/ +/*[Arima_8710][allen_yu] Dynamic detect touch golden value 20180929 begin*/ +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ + 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; + } +/*[Arima_8710][allen_yu] 20180929 end*/ +/*[Arima_8710][allen_yu] 20180828 end*/ +/*[Arima_8901][allen_yu] 20190527 end*/ +/*[20190815][TracyChui]Modify touch self test criteria end */ +/*[20190822][TracyChui]Modify touch self test criteria for 0.9 glass end */ + himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 8); +/*[Arima_8710][allen_yu] 20180620 end*/ + // 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]; +/*[Arima_7947][allen_yu] Modify Int trigger way and upgrade himax fw to CID0404_D01_C02 20171228 begin*/ + /*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*/ +/*[Arima_7947][allen_yu] 20171228 end*/ + 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; +} +/*[Arima_7947][allen_yu] Enter safe mode when i2c fail 20180129 begin*/ +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; +} +/*[Arima_7947][allen_yu] 20180129 end*/ +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; + } +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ + else if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && (tmp_data[1] == 0x2b)) + { + IC_TYPE = HX_83112B_SERIES_PWON; + ret_data = true; + break; + } +/*[Arima_8710][allen_yu] 20180828 end*/ + 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 + +/*[Arima_7947][allen_yu] Enter safe mode when i2c fail 20180129 begin*/ + himax_enter_safe_mode(client); +/*[Arima_7947][allen_yu] 20180129 end*/ + 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 +/*[Arima_7947][allen_yu] Upgrade himax fw to CID0404_D01_C06 and modify the node to access fw_ver 20180118 begin*/ + himax_ic_reset(true,false); +/*[Arima_7947][allen_yu] 20180118 end*/ +#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 +/*[Arima_7947][allen_yu] Upgrade himax fw to CID0404_D01_C06 and modify the node to access fw_ver 20180118 begin*/ + msleep(800); + himax_read_FW_ver(private_ts->client); +/*[Arima_7947][allen_yu] 20180118 end*/ + 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); + +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ + //if(IC_TYPE == HX_83112A_SERIES_PWON) + if((IC_TYPE == HX_83112A_SERIES_PWON)||(IC_TYPE == HX_83112B_SERIES_PWON)) +/*[Arima_8710][allen_yu] 20180828 end*/ + { + 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 +/*[Arima_8710][allen_yu] Dynamic detect touch golden value 20180929 begin*/ + 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; + } +/*[Arima_8710][allen_yu] 20180929 end*/ +#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]; +/*[Arima_7947][allen_yu] Upgrade himax fw to CID0404_D01_C06 and modify the node to access fw_ver 20180118 begin*/ + uint8_t cmd_2[4]; + uint8_t data_2[64]; +/*[Arima_7947][allen_yu] 20180118 end*/ +/*[Arima_7947][allen_yu] Modify Int trigger way and upgrade himax fw to CID0404_D01_C02 20171228 begin*/ + int retry = 20; +/*[Arima_7947][allen_yu] 20171228 end*/ + 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); + +/*[Arima_7947][allen_yu] Upgrade himax fw to CID0404_D01_C06 and modify the node to access fw_ver 20180118 begin*/ + 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 )) +/*[Arima_7947][allen_yu] 20180118 end*/ + { + 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 + { +/*[Arima_7947][allen_yu] Upgrade himax fw to CID0404_D01_C06 and modify the node to access fw_ver 20180118 begin*/ + 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]); + +/*[Arima_7947][allen_yu] 20180118 end*/ + 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]; +/*[Arima_8710][allen_yu] Modify the touch fw dynamic auto upgtade rule 20180830 begin*/ + ic_data->vendor_hx_ic_id = data[3]; +/*[Arima_8710][allen_yu] 20180830 end*/ + + I("PANEL_VER : %X \n",ic_data->vendor_panel_ver); + I("FW_VER : %X \n",ic_data->vendor_fw_ver); +/*[Arima_8710][allen_yu] Modify the touch fw dynamic auto upgtade rule 20180830 begin*/ + I("IC_ID : %X \n",ic_data->vendor_hx_ic_id); +/*[Arima_8710][allen_yu] 20180830 end*/ + + 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; + +/*[Arima_7947][allen_yu] Enter safe mode when i2c fail 20180129 begin*/ + himax_enter_safe_mode(client); +/*[Arima_7947][allen_yu] 20180129 end*/ + 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))) +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ + { +/*[Arima_8710][allen_yu] Modify the touch fw dynamic auto upgtade rule 20180830 begin*/ +/*[Arima_8710][allen_yu] 20180828 end*/ + 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; +/*[Arima_8710][allen_yu] 20180830 end*/ + 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 + } +/*[Arima_8710][allen_yu] Modify the touch fw dynamic auto upgtade rule 20180830 begin*/ +#if 0 +/*[Arima_8710][allen_yu] 20180828 end*/ + 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 +/*[Arima_8710][allen_yu] 20180830 end*/ +/*[Arima_8710][allen_yu] Dynamic detect Yandex LCM/TP 2nd source and add PCBA node 20180828 begin*/ +#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 +/*[Arima_8710][allen_yu] 20180828 end*/ + I("Himax IC package 83112_in\n"); + ret_data = true; +/*[Arima_7947][allen_yu] Enter save mode when i2c fail 20180129 begin*/ + himax_sense_on(client, 0); +/*[Arima_7947][allen_yu] 20180129 end*/ + 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;idata[j]); + } + for(i = 0;iclient,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 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 100644 index 000000000000..32414275efde --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_ic.h @@ -0,0 +1,82 @@ +/* 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 + +#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 +/*[Arima_7947][allen_yu] Enter safe mode when i2c fail 20180129 begin*/ +bool himax_enter_safe_mode(struct i2c_client *client); +/*[Arima_7947][allen_yu] 20180129 end*/ +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); \ No newline at end of file diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_platform.c b/drivers/input/touchscreen/hxchipset83112b/himax_platform.c new file mode 100644 index 000000000000..08cf2eccd0d1 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_platform.c @@ -0,0 +1,828 @@ +/* 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; + } + } +/*[Arima_7947][allen_yu] Enter safe mode when i2c fail 20180129 begin*/ +#if 0 + msleep(20); +#endif +/*[Arima_7947][allen_yu] 20180129 end*/ +#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; +/*[Arima_7947][allen_yu] Add mutex in callback function 20180131 begin*/ + if (event != FB_EVENT_BLANK) + return 0; + + ts=container_of(self, struct himax_ts_data, fb_notif); +/*[Arima_7947][allen_yu] Modify Mutex initialization in callback function 20180305 begin*/ +//ParisKuong modified Mutex initialization +++ +#if 0 + mutex_init(&ts->ops_lock); +#endif +//ParisKuong modified Mutex initialization --- +/*[Arima_7947][allen_yu] 20180305 end*/ + mutex_lock(&ts->ops_lock); + +/*[Arima_7947][allen_yu] 20180131 end*/ +/*[Arima_7947][allen_yu] Add error handling in callback function 20180123 begin*/ + if(evdata == NULL) + { + E("%s(%d) evdata is NULL\n",__func__, __LINE__); + } + //I(" %s(%d)\n", __func__, __LINE__); +/*[Arima_7947][allen_yu] 20180123 end*/ + if (evdata && evdata->data && event == FB_EVENT_BLANK && ts && ts->client) + { +/*[Arima_7947][allen_yu] Add error handling in callback function 20180123 begin*/ + //I(" %s(%d)\n", __func__, __LINE__); +/*[Arima_7947][allen_yu] 20180123 end*/ + blank = evdata->data; +/*[Arima_7947][allen_yu] Add error handling in callback function 20180123 begin*/ + if(blank == NULL) + { + E("%s(%d) blank is NULL\n",__func__, __LINE__); + } +/*[Arima_7947][allen_yu] 20180123 end*/ +/*[Arima_7947][allen_yu] fix the Ambient display issue 20180227 begin*/ +//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; + } +/*[Arima_7947][allen_yu] 20180227 end*/ + } +/*[Arima_7947][allen_yu] Add mutex in callback function 20180131 begin*/ + mutex_unlock(&ts->ops_lock); +/*[Arima_7947][allen_yu] 20180131 end*/ + 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 100644 index 000000000000..70def61909fa --- /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 +#include +#include +#include +#include +#include +#if defined(CONFIG_HMX_DB) +#include +#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 -- GitLab From 049cc9eed30c59c19090e67a59a3f0f7172ffb2c Mon Sep 17 00:00:00 2001 From: frankcheng Date: Sat, 9 May 2020 20:59:58 +0800 Subject: [PATCH 12/78] Camera kernel patching from P codebase Change-Id: Iecba04814a03123628c4a634d59834c395a5dd72 --- .../dts/qcom/msm8953-camera-sensor-mtp.dtsi | 293 ++++++++---------- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 108 ++++++- .../camera_v2/sensor/actuator/msm_actuator.c | 19 +- .../msm/camera_v2/sensor/msm_sensor_driver.c | 20 ++ 4 files changed, 272 insertions(+), 168 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi index f3e13c0a1949..270515a0b532 100644 --- 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,7 @@ reg = <0x0>; compatible = "qcom,actuator"; qcom,cci-master = <0>; - cam_vaf-supply = <&pm8953_l17>; +// cam_vaf-supply = <&pm8953_l17>; qcom,cam-vreg-name = "cam_vaf"; qcom,cam-vreg-min-voltage = <2850000>; qcom,cam-vreg-max-voltage = <2850000>; @@ -44,113 +44,110 @@ 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>; }; +/*<2018/10/18-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Modified for new front camera device driver S5K4H7YX. */ 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>; - 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>; + reg = <0x1>; + +#if 0 + qcom,eeprom-name = "samsung_s5k4h7yx"; + qcom,slave-addr = <0x20>; + qcom,num-blocks = <2>; + + qcom,page0 = <1 0x0100 2 0x01 1 1>; + qcom,poll0 = <0 0x0 2 0x0 1 0>; + qcom,mem0 = <0 0x0 2 0x0 1 0>; +#endif + + /* cam_vio-supply = <&cam_vio_gpio_regulator>; */ /* IOVDD */ + cam_vana-supply = <&pm8953_l22>; /* AVDD */ + /* cam_vdig-supply = <&cam_front_dvdd_gpio_regulator>; */ /* DVDD */ + /* cam_vaf-supply = <&pm8953_l17>; */ /* AFVDD is not usage */ + qcom,cam-vreg-name = "cam_vana"; /* "cam_vio", "cam_vana", "cam_vdig"; */ + 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>; + +/*<2018/11/14-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]VOI control pin.PCBA EP0 is GPIO123;EP1 and above is GPIO130 */ gpios = <&tlmm 27 0>, - <&tlmm 129 0>, - <&tlmm 130 0>; + <&tlmm 129 0>, + <&tlmm 46 0>, +#if 1 + <&tlmm 130 0>; +#else /* PCBA EP0 */ + <&tlmm 123 0>; +#endif +/*>2018/11/14-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][] */ 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"; - 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_RESET2", + "CAM_VDIG2", + "CAM_VIO2"; - 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>; - 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"; status = "ok"; - clocks = <&clock_gcc clk_mclk2_clk_src>, - <&clock_gcc clk_gcc_camss_mclk2_clk>; +#if 1 + 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>; /* <1 1 1 1 1 10>; */ +#endif 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>; }; +/*>2018/10/18-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]. */ camera0: qcom,camera@0 { cell-index = <0>; @@ -162,16 +159,15 @@ 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_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 +176,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 +197,65 @@ 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 { +/*<2018/10/18-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Modified for new front camera device driver S5K4H7YX. */ + 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>; /* SDM450 support 2 CSID cores. MSM8953 is 3 CSID cores */ + qcom,mount-angle = <270>; /* <90>; */ qcom,eeprom-src = <&eeprom1>; - qcom,actuator-src = <&actuator1>; - cam_vdig-supply = <&pm8953_l23>; - cam_vio-supply = <&pm8953_l6>; + /* qcom,actuator-src = <&actuator1>; */ /* The auto focus is not support */ + + /* cam_vio-supply = <&cam_vio_gpio_regulator>; */ 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>; + /* cam_vdig-supply = <&cam_front_dvdd_gpio_regulator>; */ + /* cam_vaf-supply = <&pm8953_l17>; */ /* The AFVDD is not support */ + 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>; + +/*<2018/11/14-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]VOI control pin.PCBA EP0 is GPIO123;EP1 and above is GPIO130 */ gpios = <&tlmm 27 0>, - <&tlmm 129 0>, - <&tlmm 130 0>; + <&tlmm 129 0>, + <&tlmm 46 0>, +#if 1 + <&tlmm 130 0>; +#else /* PCBA EP0 */ + <&tlmm 123 0>; +#endif +/*>2018/11/14-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][] */ 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>; }; +/*>2018/10/18-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]. */ }; diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 908cdd0095e3..7cbb7ed05fda 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -118,7 +118,9 @@ config { pins = "gpio31", "gpio32"; - drive-strength = <2>; /* 2 MA */ + /*<2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Pull up the strength level when camera cannot detected sometimes */ + drive-strength = <4>; /* 2 MA */ + /*>2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][] */ bias-disable; /* No PULL */ }; }; @@ -229,12 +231,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 +245,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 +267,9 @@ config { pins = "gpio27"; bias-disable; /* No PULL */ - drive-strength = <2>; /* 2 MA */ + /*<2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Pull up the MIPI CLK strength level when camera cannot detected sometimes */ + drive-strength = <8>; /* <2>; */ /* 2 MA */ + /*>2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][] */ }; }; @@ -342,15 +346,98 @@ }; }; +/*<2018/10/18-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Modified for new front camera device driver S5K4H7YX. */ +/*<2018/11/14-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]VOI control pin.PCBA EP0 is GPIO123;EP1 and above is GPIO130 */ + cam_sensor_front1_vio_default: cam_sensor_front1_vio_default { + /* CAM IOVDD */ + mux { + #if 1 + pins = "gpio130"; + #else /* PCBA EP0 */ + pins = "gpio123"; + #endif + function = "gpio"; + }; + + config { + #if 1 + pins = "gpio130"; + #else /* PCBA EP0 */ + pins = "gpio123"; + #endif + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_front1_vio_sleep: cam_sensor_front1_vio_sleep { + /* CAM IOVDD */ + mux { + #if 1 + pins = "gpio130"; + #else /* PCBA EP0 */ + pins = "gpio123"; + #endif + function = "gpio"; + }; + + config { + #if 1 + pins = "gpio130"; + #else /* PCBA EP0 */ + pins = "gpio123"; + #endif + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; +/*>2018/11/14-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][] */ + + 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 { + #if 1 + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ + #else /* Qualcomm default */ pins = "gpio129", "gpio130"; + #endif function = "gpio"; }; config { + #if 1 + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ + #else /* Qualcomm default */ pins = "gpio129", "gpio130"; + #endif bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ }; @@ -359,16 +446,25 @@ cam_sensor_front1_sleep: cam_sensor_front1_sleep { /* RESET, STANDBY */ mux { + #if 1 + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ + #else /* Qualcomm default */ pins = "gpio129", "gpio130"; + #endif function = "gpio"; }; config { + #if 1 + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ + #else /* Qualcomm default */ pins = "gpio129", "gpio130"; + #endif bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ }; }; +/*>2018/10/18-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]. */ pmx_adv7533_int: pmx_adv7533_int { adv7533_int_active: adv7533_int_active { 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 index 2806132c09b8..66349116e8e7 100644 --- 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_MSM_MUTEX(msm_actuator_mutex); #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,21 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, write_arr[i].data_shift) | ((hw_dword & write_arr[i].hw_mask) >> write_arr[i].hw_shift); - +//[Camera] Modify for IMX363 module AF Person Liu 20190509 S +//[Camera] Modify for IMX363 module AF Frank Cheng 20191225 S +//[Camera] Modify for S5KGM1SP module AF Frank Cheng 20200427 S + /* + pr_err("%s:%d nActuatorAK7374: %d\n", + __func__, __LINE__, + nActuatorAK7374); + pr_err("%s:%d nActuatorDW9800: %d\n", + __func__, __LINE__, + nActuatorDW9800); + */ + if(nActuatorAK7374 == 0 && nActuatorDW9800 == 0)value = abs(1023-value); +//[Camera] Modify for S5KGM1SP module AF Frank Cheng 20200427 E +//[Camera] Modify for IMX363 module AF Frank Cheng 20191225 E +//[Camera] Modify for IMX363 module AF Person Liu 20190509 E 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/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c index 4bc13d03d36d..1dbacdda637e 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c @@ -18,6 +18,7 @@ #include "msm_cci.h" #include "msm_camera_dt_util.h" #include "msm_sensor_driver.h" +#include "../actuator/msm_actuator.h" /* Logging macro */ #undef CDBG @@ -25,6 +26,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,7 +1140,23 @@ int32_t msm_sensor_driver_probe(void *setting, 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); + if(strcmp(slave_info->sensor_name, "imx363") == 0)pr_err("imx363 compare success"); s_ctrl->bypass_video_node_creation = slave_info->bypass_video_node_creation; -- GitLab From 18afffd1bb745e4b3833ed603653d4ffb538e6cb Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Fri, 8 May 2020 17:36:49 +0800 Subject: [PATCH 13/78] To fix phone can not charge fully Change-Id: I5cf21af81ca3ceb84e56cb5c9c2c6f39bfae10b1 --- drivers/power/supply/qcom/qpnp-smb5.c | 9 +++++++++ drivers/power/supply/qcom/step-chg-jeita.c | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index a4410734f6c5..615fdb1123b4 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -2075,6 +2075,15 @@ static int smb5_init_hw(struct smb5 *chip) } } +//<2020/05/07-JessicaTseng, Enable AICL rerun periodically + /* 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; + } +//>2020/05/07-JessicaTseng + /* enable the charging path */ rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0); if (rc < 0) { diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index 63b3950dcbc6..f800b85f0105 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -502,10 +502,12 @@ static int handle_step_chg_config(struct step_chg_info *chip) return (STEP_CHG_HYSTERISIS_DELAY_US - elapsed_us + 1000); } -#define JEITA_SUSPEND_HYST_UV 50000 +//<2020/05/07-JessicaTseng, Modify recharging voltage from 4.05V to 3.9V at battery temperature over 45 degree +#define JEITA_SUSPEND_HYST_UV 200000//50000 //<2020/04/28-JessicaTseng, Setting jeita fv re-charge voltage for warm temp #define JEITA_RECHG_HYST_UV 200000//100000 //>2020/04/28-JessicaTseng +//>2020/05/07-JessicaTseng static int handle_jeita(struct step_chg_info *chip) { -- GitLab From 69e5c8df0039ae7876ea0e47dbb7b4795d25d5f5 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 11 May 2020 09:31:08 +0800 Subject: [PATCH 14/78] Enable step-charging for Kayo battery 1.Add step-charging parameters in battery profile (case:156287) 2.Set hysteresis of voltage to "0" Change-Id: I1e3eeab77cc5cb5c25ca037ad8d332bcee21f660 --- drivers/power/supply/qcom/step-chg-jeita.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index f800b85f0105..3a7b00930201 100644 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -788,7 +788,7 @@ int qcom_step_chg_init(struct device *dev, 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; //<2020/05/11-JessicaTseng, Enable step-charging for Kayo battery chip->jeita_fcc_config = devm_kzalloc(dev, sizeof(struct jeita_fcc_cfg), GFP_KERNEL); -- GitLab From 74d1d601bfe3eb80de4f92e31b34b749f8b6d2f8 Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Thu, 14 May 2020 18:02:17 +0800 Subject: [PATCH 15/78] Merge audio function from 8901_P. Root cause: N/A How to fix: N/A Change-Id: I96364baea71fe221eaa9086a312e131e66f1d75c RiskArea:Audio --- arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi | 17 +- arch/arm64/boot/dts/qcom/msm8953-audio.dtsi | 75 +- arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 15 + arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 115 +- arch/arm64/boot/dts/qcom/msm8953.dtsi | 92 +- arch/arm64/configs/msm8953-perf_defconfig | 4 + arch/arm64/configs/msm8953_defconfig | 4 + drivers/base/firmware_class.c | 3 + sound/soc/codecs/Kconfig | 8 + sound/soc/codecs/Makefile | 4 + sound/soc/codecs/aw/aw8898.c | 1612 +++++++++++++++++ sound/soc/codecs/aw/aw8898.h | 72 + sound/soc/codecs/aw/aw8898_reg.h | 448 +++++ 13 files changed, 2308 insertions(+), 161 deletions(-) create mode 100644 sound/soc/codecs/aw/aw8898.c create mode 100644 sound/soc/codecs/aw/aw8898.h create mode 100644 sound/soc/codecs/aw/aw8898_reg.h diff --git a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi index bb05a2e86926..2013ec1d34da 100644 --- a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi +++ b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi @@ -115,19 +115,22 @@ qcom,msm-mi2s-tx-lines = <2>; }; - dai_mi2s4: qcom,msm-dai-q6-mi2s-quin { +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s + 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>; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e + }; 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 index f862a07a2374..0b64af21e964 100644 --- 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,12 @@ "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>; +//[FairPhone][Audio][jinjia]=2019.02.01=Remove the config of us-eu-gpios. -s + //qcom,cdc-us-euro-gpios = <&tlmm 63 0>; + //qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>; +//[FairPhone][Audio][jinjia]=2019.02.01=Remove the config of us-eu-gpios. -e + //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; @@ -134,14 +136,19 @@ qcom,msm-vdd-wsa-switch-current = <10000>; }; +//[FairPhone][Audio][jinjia]=2019.02.01=Remove the config of us-eu-gpios. -s +/* 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>; }; +*/ +//[FairPhone][Audio][jinjia]=2019.02.01=Remove the config of us-eu-gpios. -e 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>; @@ -149,6 +156,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>; @@ -168,7 +176,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>; @@ -177,7 +185,7 @@ <&wsa881x_analog_reset_gpio>; }; wsa881x_i2c_45: wsa881x-i2c-codec@45 { - status = "okay"; + status = "disabled"; compatible = "qcom,wsa881x-i2c-codec"; reg = <0x45>; }; @@ -196,25 +204,35 @@ 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>; }; +//[FairPhone][Audio][jinjia]=2018.11.21=Audio porting. -s 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", @@ -252,10 +270,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>, @@ -298,22 +314,23 @@ "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293", "msm-dai-q6-dev.16396"; - 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", "SpkrLeft", "SpkrRight"; }; +//[FairPhone][Audio][jinjia]=2018.11.21=Audio porting. -e cpe: qcom,msm-cpe-lsm { compatible = "qcom,msm-cpe-lsm"; }; wcd9xxx_intc: wcd9xxx-irq { - status = "disabled"; + status = "okay"; compatible = "qcom,wcd9xxx-irq"; interrupt-controller; #interrupt-cells = <1>; @@ -324,7 +341,7 @@ }; clock_audio: audio_ext_clk { - status = "disabled"; + status = "okay"; compatible = "qcom,audio-ref-clk"; clock-names = "osr_clk"; qcom,node_has_rpm_clock; @@ -337,7 +354,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>; @@ -346,16 +363,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]; @@ -381,7 +398,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>; @@ -438,7 +455,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-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi index c053cac507d6..10c7195bba99 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -60,6 +60,21 @@ }; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s +&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 */ +}; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e + &sdhc_1 { /* device core power supply */ vdd-supply = <&pm8953_l8>; diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 7cbb7ed05fda..975e00a5f5ca 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -51,6 +51,8 @@ }; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s +/* uart1_console_active: uart1_console_active { mux { pins = "gpio20", "gpio21"; @@ -76,6 +78,9 @@ bias-pull-down; }; }; +*/ +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e + }; cci { cci0_active: cci0_active { @@ -785,6 +790,8 @@ }; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s +/* blsp2_uart1_active: blsp2_uart1_active { mux { pins = "gpio20", "gpio21", "gpio22", "gpio23"; @@ -810,6 +817,8 @@ bias-disable; }; }; +*/ +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e /* SDC pin type */ sdc1_clk_on: sdc1_clk_on { @@ -1065,6 +1074,38 @@ }; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s + 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; + }; + }; + }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e + nfc { nfc_int_active: nfc_int_active { /* active state */ @@ -1357,6 +1398,8 @@ }; }; +//[FairPhone][Audio][jinjia]=2019.02.01=Remove the config of us-eu-gpios. -s +/* cross-conn-det { cross_conn_det_act: lines_on { mux { @@ -1385,6 +1428,8 @@ }; }; }; +*/ +//[FairPhone][Audio][jinjia]=2019.02.01=Remove the config of us-eu-gpios. -e /* WSA VI sense */ wsa-vi { @@ -1474,27 +1519,28 @@ }; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s 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; }; @@ -1527,6 +1573,7 @@ }; }; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e /*[20200429][TracyChui]Touch driver porting start*/ // spi3 { @@ -1590,66 +1637,6 @@ // }; /*[20200429][TracyChui]Touch driver porting end*/ - 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.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index f42b0f733f73..beae5e048ad3 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -169,6 +169,7 @@ }; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s aliases { /* smdtty devices */ smd1 = &smdtty_apps_fm; @@ -188,11 +189,12 @@ i2c2 = &i2c_2; i2c3 = &i2c_3; i2c5 = &i2c_5; + i2c6 = &i2c_6; /*[20200429][TracyChui]Touch driver porting start*/ // spi3 = &spi_3; /*[20200429][TracyChui]Touch driver porting end*/ - spi6 = &spi_6; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e soc: soc { /* @@ -627,41 +629,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"; @@ -717,31 +684,6 @@ // }; /*[20200429][TracyChui]Touch driver porting end*/ - 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"; @@ -849,6 +791,34 @@ status = "disabled"; }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s + 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"; + }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e + slim_msm: slim@c140000{ cell-index = <1>; compatible = "qcom,slim-ngd"; diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index 4ff6c5bc6f2e..b416dcd7bf6f 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -692,3 +692,7 @@ CONFIG_QMI_ENCDEC=y # //<2020/04/23-louisliu, Fingerprint. Driver porting. CONFIG_ELAN_FINGERPRINT=y # //>2020/04/23-louisliu +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s +#add aw8898 smartpa +CONFIG_SND_SMARTPA_AW8898=y +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index 830d3dbb3a01..4ea54017a8b7 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -756,3 +756,7 @@ CONFIG_QMI_ENCDEC=y # //<2020/04/23-louisliu, Fingerprint. Driver porting. CONFIG_ELAN_FINGERPRINT=y # //>2020/04/23-louisliu +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s +#add aw8898 smartpa +CONFIG_SND_SMARTPA_AW8898=y +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 813a191febd8..566a7456da5e 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -290,15 +290,18 @@ static void fw_free_buf(struct firmware_buf *buf) spin_unlock(&fwc->lock); } +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s /* direct firmware loading support */ 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, "/lib/firmware" }; +//[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e /* * Typical usage is that passing 'firmware_class.path=$CUSTOMIZED_PATH' diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b4c914cf6635..9eab03445c67 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1097,6 +1097,14 @@ config SND_SOC_AW8896 help Enables support for aw8896 series Smart PA. +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s +config SND_SMARTPA_AW8898 + tristate "SoC Audio for awinic aw8898 series" + depends on I2C + help + This option enables support for aw8898 series Smart PA. +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e + config SND_SOC_TFA98XX tristate "NXP Semiconductors TFA98XX amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index cf30a193cc0f..459e5fd36410 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -447,3 +447,7 @@ obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o 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 +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -s +#for AWINIC AW8898 Smart PA +obj-y += aw/aw8898.o +#[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e diff --git a/sound/soc/codecs/aw/aw8898.c b/sound/soc/codecs/aw/aw8898.c new file mode 100644 index 000000000000..dc565ed012cc --- /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 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; ilen; 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; isize; 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 100644 index 000000000000..2042f5ecf57b --- /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 100644 index 000000000000..c66927c8277e --- /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 -- GitLab From 9a33e1ca20ef1e5242319c999f9a931885f4f4dd Mon Sep 17 00:00:00 2001 From: tracychui Date: Tue, 19 May 2020 18:11:32 +0800 Subject: [PATCH 16/78] Implement AB partition on Android Q Root cause:N/A How to fix:N/A Feature:AB partition Change-Id: I92ac6cda48ad468c087ba8b63f61225cfd413f4a RiskArea:partition --- arch/arm64/boot/dts/qcom/msm8953.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index beae5e048ad3..8458d8702db0 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -37,12 +37,14 @@ compatible = "simple-bus"; }; +//[20200520][TracyChui]Implement AB partition on Android Q start firmware: firmware { android { compatible = "android,firmware"; vbmeta { compatible = "android,vbmeta"; - parts = "vbmeta,boot,system,vendor,dtbo,recovery"; + parts = "vbmeta,boot,system,vendor,dtbo"; + //parts = " vbmeta,boot,system,vendor,dtbo,recovery"; }; fstab { @@ -52,13 +54,15 @@ 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"; + //fsmgr_flags = "wait,avb"; status = "ok"; }; }; }; }; +//[20200520][TracyChui]Implement AB partition on Android Q end reserved-memory { #address-cells = <2>; -- GitLab From 7db9b542f9bc95ae70d206680ff5c5f5f4ae6909 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Tue, 27 Nov 2018 16:14:44 +0800 Subject: [PATCH 17/78] System can't enter VDD minimization Root cause: RID IRQ is triggered to wake up system How to fix: Merge Qualcomm's patch [PATCH] power: smb5: Disable unused rid change interrupt sources RiskArea: Change-Id: Ia4e733a80cb29cb8f2d3507b91eb0a87e52c7313 (cherry picked from commit 5c010f118669e4b14e2baa532193b3cff486244e) --- drivers/power/supply/qcom/qpnp-smb5.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index 615fdb1123b4..0a2d0f59f103 100644 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -1671,10 +1671,11 @@ static int smb5_init_vconn_regulator(struct smb5 *chip) /*************************** * HARDWARE INITIALIZATION * ***************************/ +//<2018/11/27-JessicaTseng, Qualcomm's patch is to fix current consumption 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) { @@ -1740,6 +1741,16 @@ static int smb5_configure_typec(struct smb_charger *chg) 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 */ @@ -1752,6 +1763,7 @@ static int smb5_configure_typec(struct smb_charger *chg) return rc; } +//>2018/11/27-JessicaTseng static int smb5_configure_micro_usb(struct smb_charger *chg) { -- GitLab From 1d90b7ad7ca900b90fa5c6adf5fa6f7a13ee7af3 Mon Sep 17 00:00:00 2001 From: shermanwei Date: Thu, 5 Sep 2019 11:27:27 +0800 Subject: [PATCH 18/78] Qualcomm KBA-180725024109 to solve Far the Proximity and the screen will never light on sometimes Change-Id: I445c5026369fad21c26a56833110c190d64822d3 (cherry picked from commit 32b311163e8954d8f7d738bfb45a02c4d01f91b9) --- net/ipc_router/ipc_router_core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c index 90f10241f5b4..e28eb8b228a2 100644 --- a/net/ipc_router/ipc_router_core.c +++ b/net/ipc_router/ipc_router_core.c @@ -239,6 +239,12 @@ static int is_sensor_port(struct msm_ipc_router_remote_port *rport) if (rport && rport->server) { svcid = rport->server->name.service; + //<2019/09/05,ShermanWei for Qualcomm KBA-180725024109 patch + //to solve that far Proximity the screen can not light on sometimes. + //// hold wakelock for thresh(proximity) algo sensor and OEM1(e.g: pick up gesture sensor) + if (svcid == 277 || svcid == 287) + return false; + //>2019/09/05,ShermanWei if (svcid == 400 || (svcid >= 256 && svcid <= 320)) return true; } -- GitLab From 53e1968251151065e112f96c2247fbba6ae5ba2d Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Thu, 4 Jun 2020 09:42:07 +0800 Subject: [PATCH 19/78] Modify charging termination current Change-Id: Id6c08ccb32aa03bf2e8eab18d34bc2ed6ba5e8ab --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index c1078fc6134f..390ba0de8e9d 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -332,6 +332,11 @@ 500000 500000>; //>2020/04/28-JessicaTseng +//<2020/06/04-JessicaTseng, modify charging termination current + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-100)>; +//>2020/06/04-JessicaTseng + qcom,chgr@1000 { reg = <0x1000 0x100>; interrupts = @@ -488,7 +493,11 @@ #address-cells = <1>; #size-cells = <1>; - qcom,qg-iterm-ma = <100>; +//<2020/06/04-JessicaTseng, modify charging termination current + //qcom,qg-iterm-ma = <100>; + qcom,qg-iterm-ma = <150>; +//>2020/06/04-JessicaTseng + //<2020/04/24-JessicaTseng, Re-charge condition for battery to 4.3V //qcom,hold-soc-while-full; //qcom,linearize-soc; -- GitLab From d046f95ad11421a760143e0002a4f7f7e9d156d0 Mon Sep 17 00:00:00 2001 From: jialongjhan Date: Fri, 5 Jun 2020 15:01:21 +0800 Subject: [PATCH 20/78] Let LCM reduce power consumption when suspend Root cause: Some patch I miss to add Android Q form Android P http://review3.arimacomm.com.tw:8080/c/kernel/msm-4.9/+/98211 How to fix: Feature: Issue: Depends-On: Change-Id: Ieaca233d9ef78cb2df8eaf6c016b3aee7a35660a RiskArea: --- drivers/video/fbdev/msm/mdss_dsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 6876894bcafe..24969fd1aa5c 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -405,6 +405,9 @@ static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata) if (ret) pr_err("%s: failed to disable vregs for %s\n", __func__, __mdss_dsi_pm_name(DSI_PANEL_PM)); + /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off start*/ + gpio_direction_output(64, 0); + /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off end*/ end: return ret; @@ -419,7 +422,6 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata) gpio_direction_output(64, 1); /*[Fairphone_8901][Jialong]To avoid fuzzy screen,pull high Touch reset pin when panel on end*/ - if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; -- GitLab From df985d98ecb593890bfda94bad96628bdf8abea0 Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Thu, 28 May 2020 14:58:48 +0800 Subject: [PATCH 21/78] Audio porting for smart amp TAS2557. Root cause: Audio porting for smart amp TAS2557. How to fix: N/A Change-Id: I9b9ea4f13ac2432fd3e2104438ff7362406a1428 RiskArea:speaker (cherry picked from commit 55d13014376b9950ada458d4e16b26a6a28f67f9) (cherry picked from commit bde46d6932cf950e4e671647c57e5628fd9b890e) --- arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 11 + arch/arm64/configs/msm8953-perf_defconfig | 6 + arch/arm64/configs/msm8953_defconfig | 6 + sound/soc/codecs/Kconfig | 2 + sound/soc/codecs/Makefile | 1 + sound/soc/codecs/tas2557/Kconfig | 15 + sound/soc/codecs/tas2557/Makefile | 2 + sound/soc/codecs/tas2557/tas2557-codec.c | 639 +++++++ sound/soc/codecs/tas2557/tas2557-codec.h | 30 + sound/soc/codecs/tas2557/tas2557-core.c | 2120 +++++++++++++++++++++ sound/soc/codecs/tas2557/tas2557-core.h | 79 + sound/soc/codecs/tas2557/tas2557-misc.c | 597 ++++++ sound/soc/codecs/tas2557/tas2557-misc.h | 57 + sound/soc/codecs/tas2557/tas2557-regmap.c | 917 +++++++++ sound/soc/codecs/tas2557/tas2557.h | 489 +++++ sound/soc/codecs/tas2557/tiload.c | 409 ++++ sound/soc/codecs/tas2557/tiload.h | 65 + 17 files changed, 5445 insertions(+) create mode 100644 sound/soc/codecs/tas2557/Kconfig create mode 100644 sound/soc/codecs/tas2557/Makefile create mode 100644 sound/soc/codecs/tas2557/tas2557-codec.c create mode 100644 sound/soc/codecs/tas2557/tas2557-codec.h create mode 100644 sound/soc/codecs/tas2557/tas2557-core.c create mode 100644 sound/soc/codecs/tas2557/tas2557-core.h create mode 100644 sound/soc/codecs/tas2557/tas2557-misc.c create mode 100644 sound/soc/codecs/tas2557/tas2557-misc.h create mode 100644 sound/soc/codecs/tas2557/tas2557-regmap.c create mode 100644 sound/soc/codecs/tas2557/tas2557.h create mode 100644 sound/soc/codecs/tas2557/tiload.c create mode 100644 sound/soc/codecs/tas2557/tiload.h diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi index 10c7195bba99..7b4d8b289b38 100644 --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -72,6 +72,17 @@ 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"; + }; }; //[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index b416dcd7bf6f..f444ba2b3826 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -696,3 +696,9 @@ CONFIG_ELAN_FINGERPRINT=y #add aw8898 smartpa CONFIG_SND_SMARTPA_AW8898=y #[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e +#[FairPhone][Audio][jinjia]=2020.05.19=2nd smart amp porting. -s +CONFIG_SND_SOC_TAS2557=y +CONFIG_TAS2557_REGMAP=y +CONFIG_TAS2557_CODEC=y +CONFIG_TAS2557_MISC=y +#[FairPhone][Audio][jinjia]=2020.05.19=2nd smart amp porting. -e diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index 4ea54017a8b7..71df90cfcd69 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -760,3 +760,9 @@ CONFIG_ELAN_FINGERPRINT=y #add aw8898 smartpa CONFIG_SND_SMARTPA_AW8898=y #[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e +#[FairPhone][Audio][jinjia]=2020.05.19=2nd smart amp porting. -s +CONFIG_SND_SOC_TAS2557=y +CONFIG_TAS2557_REGMAP=y +CONFIG_TAS2557_CODEC=y +CONFIG_TAS2557_MISC=y +#[FairPhone][Audio][jinjia]=2020.05.19=2nd smart amp porting. -e diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9eab03445c67..6613ff48f001 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1105,6 +1105,8 @@ config SND_SMARTPA_AW8898 This option enables support for aw8898 series Smart PA. #[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e +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 index 459e5fd36410..3352c8c93148 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -451,3 +451,4 @@ obj-$(CONFIG_SND_SOC_TFA98XX) += snd-soc-tfa98xx.o #for AWINIC AW8898 Smart PA obj-y += aw/aw8898.o #[FairPhone][Audio][jinjia]=2018.11.21=smart amp porting. -e +obj-$(CONFIG_SND_SOC_TAS2557) += tas2557/ diff --git a/sound/soc/codecs/tas2557/Kconfig b/sound/soc/codecs/tas2557/Kconfig new file mode 100644 index 000000000000..74ba53d27cd8 --- /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 100644 index 000000000000..128737242e7d --- /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 100644 index 000000000000..af0728553525 --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-codec.c @@ -0,0 +1,639 @@ +/* +** ============================================================================= +** 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); + printk("[tas2557] %s\n", __func__); //[jinjia]Trace + + 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); + + printk("[tas2557] %s\n", __func__); //[jinjia]Trace + 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); + + printk("[tas2557] %s\n", __func__); //[jinjia]Trace + 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); + + printk("[tas2557] %s\n", __func__); //[jinjia]Trace + 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); + + printk("[tas2557] %s\n", __func__); //[jinjia]Trace + 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 100644 index 000000000000..8e20270c6b92 --- /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 100644 index 000000000000..9109f8d94c7f --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-core.c @@ -0,0 +1,2120 @@ +/* +** ============================================================================= +** 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 "/data/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<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: //[FairPhone][Audio][jinjia]=2020.05.19=Fix the build error with TI sample code. + 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 + + printk("[tas2557] tas2557_fw_ready +++++ \n"); //[jinjia]Trace + 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); + + printk("[tas2557] tas2557_fw_ready ----- \n"); //[jinjia]Trace +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 100644 index 000000000000..cb46eee35320 --- /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 100644 index 000000000000..925a3227a114 --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-misc.c @@ -0,0 +1,597 @@ +/* +** ============================================================================= +** 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2557.h" +#include "tas2557-core.h" +#include "tas2557-misc.h" +#include + +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: + { + printk("[tas2557] SMARTPA_SPK_POWER_ON \n"); //[jinjia]Trace + tas2557_enable(pTAS2557, true); + } + break; + + case SMARTPA_SPK_POWER_OFF: + { + printk("[tas2557] SMARTPA_SPK_POWER_OFF \n"); //[jinjia]Trace + 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 100644 index 000000000000..38bfa64910cd --- /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 100644 index 000000000000..cd260afc0cd7 --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-regmap.c @@ -0,0 +1,917 @@ +/* +** ============================================================================= +** 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//[FairPhone][Audio][jinjia]=2020.05.19=Fix the build error with TI sample code. -s +#include +//[FairPhone][Audio][jinjia]=2020.05.19=Fix the build error with TI sample code. -e +#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); + printk("[tas2557] tas2557_dev_read +++++\n"); //[jinjia]Trace + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only reads from TILoad pass. */ + nRegister &= ~0x80000000; + printk("[tas2557] [tas2557_dev_read] mbTILoadActive \n"); //[jinjia]Trace + 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; + } + printk("[tas2557] tas2557_dev_read -----\n"); //[jinjia]Trace +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) +{ + printk("[tas2557] tas2557_hw_reset ++++++\n"); //[jinjia]Trace + if (gpio_is_valid(pTAS2557->mnResetGPIO)) { + printk("[tas2557][tas2557_hw_reset] gpio_is_valid(mnResetGPIO) \n"); //[jinjia]Trace + 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; + printk("[tas2557] tas2557_hw_reset ------\n"); //[jinjia]Trace +} + +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; + + printk("[tas2557] tas2557_i2c_probe +++++\n"); //[jinjia]Trace + 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)) { + printk("[tas2557] gpio_is_valid (mnResetGPIO) +++++ \n "); //[jinjia]Trace + 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; + } + + printk("[tas2557] gpio_is_valid(mnGpioINT) +\n"); //[jinjia]Trace + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + printk("[tas2557] gpio_is_valid(mnGpioINT) ++\n"); //[jinjia]Trace + 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); + + printk("[tas2557] tas2557_i2c_probe -----\n"); //[jinjia]Trace +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 100644 index 000000000000..a45c4ec1420c --- /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 +#include +#include + +/* 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 100644 index 000000000000..1719bc4ce706 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 100644 index 000000000000..7468acfa3964 --- /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 +#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 -- GitLab From 3d56ab1c75f6990ebdec05781fba5943b0093edc Mon Sep 17 00:00:00 2001 From: "yidechen(170422)" Date: Tue, 14 Apr 2020 09:32:18 +0800 Subject: [PATCH 22/78] [CTS]Fix for CTS testProcStatsPkgProcStats CTS-10.0_r4 CtsStatsdHostTestCases: android.cts.statsd.validation.ProcStatsValidationTests #testProcStatsPkgProcStats RiskArea: CTS, kernel Issue: PRJ6901-2423 Change-Id: I9db8f85558e5ae8f1b455088e236f76f2f6b2f91 (cherry picked from commit 837399b80d9461157b48b936f1c3fc4d91b251be) --- mm/vmstat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmstat.c b/mm/vmstat.c index 67c229324086..98811ced3b56 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1790,7 +1790,7 @@ static int __init setup_vmstat(void) #endif #ifdef CONFIG_PROC_FS proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations); - proc_create("pagetypeinfo", 0400, NULL, &pagetypeinfo_file_ops); + proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops); proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations); proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations); #endif -- GitLab From 312da520d3c9cff22137c5c1bb7103e3e2d8db44 Mon Sep 17 00:00:00 2001 From: tracychui Date: Fri, 12 Jun 2020 17:46:51 +0800 Subject: [PATCH 23/78] Expose power up/down reason and memory info Root cause:N/A How to fix:N/A Feature:ARFP3-91: Expose power up and power down reason ARFP3-77: Expose main memory hardware revision RiskArea: power on,memory Change-Id: I62242576e233d5c92025a97f46246b924b19bba8 --- arch/arm64/include/asm/processor.h | 5 +++ drivers/input/misc/qpnp-power-on.c | 18 ++++++++ drivers/soc/qcom/socinfo.c | 67 ++++++++++++++++++++++++++++++ kernel/sysctl.c | 48 +++++++++++++++++++++ 4 files changed, 138 insertions(+) diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index e9ba70ab4a38..6c48116f32ae 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -81,7 +81,12 @@ extern phys_addr_t arm64_dma_phys_limit; #define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1) extern unsigned int boot_reason; +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ +extern unsigned int qpnp_pon_reason_extern; +extern unsigned int qpnp_poff_reason_extern; extern unsigned int cold_boot; +extern char ddr_vendor[32]; +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ struct debug_info { /* Have we suspended stepping by a debugger? */ diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c index 65379ed8ed35..02b3c15a077a 100644 --- a/drivers/input/misc/qpnp-power-on.c +++ b/drivers/input/misc/qpnp-power-on.c @@ -313,6 +313,10 @@ static const char * const qpnp_poff_reason[] = { [39] = "Triggered from S3_RESET_KPDPWR_ANDOR_RESIN (power key and/or reset line)", }; +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ +unsigned int qpnp_pon_reason_extern=0; +unsigned int qpnp_poff_reason_extern=0; +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ static int qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val) { @@ -2287,8 +2291,17 @@ static int qpnp_pon_probe(struct platform_device *pdev) goto err_out; } +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ +#if 1 + if (sys_reset) { + boot_reason = ffs(pon_sts); + qpnp_pon_reason_extern = ffs(pon_sts); + } +#else if (sys_reset) boot_reason = ffs(pon_sts); +#endif +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ index = ffs(pon_sts) - 1; cold_boot = !qpnp_pon_is_warm_reset(); @@ -2322,6 +2335,11 @@ static int qpnp_pon_probe(struct platform_device *pdev) } poff_sts = buf[0] | (buf[1] << 8); } +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ + if (sys_reset) { + qpnp_poff_reason_extern = ffs(poff_sts); + } +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ 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/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 7dee6074a493..661544cb3796 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -2007,6 +2007,67 @@ static void socinfo_select_format(void) } } +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ +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; + +//uint32_t smem_get_ddr_manufacturer_id() +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); +} +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ + int __init socinfo_init(void) { static bool socinfo_init_done; @@ -2036,6 +2097,12 @@ int __init socinfo_init(void) arch_read_hardware_id = msm_read_hardware_id; socinfo_init_done = true; +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ + 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); +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ + return 0; } subsys_initcall(socinfo_init); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index f3a22c903ddb..81e0209ecdad 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -66,6 +66,9 @@ #include #include #include +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ +#include +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ #include #include @@ -230,6 +233,10 @@ static struct ctl_table vm_table[]; static struct ctl_table fs_table[]; static struct ctl_table debug_table[]; static struct ctl_table dev_table[]; +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ +static struct ctl_table qpnp_power_on_table[]; +static struct ctl_table ddr_table[]; +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ extern struct ctl_table random_table[]; #ifdef CONFIG_EPOLL extern struct ctl_table epoll_table[]; @@ -267,6 +274,13 @@ static struct ctl_table sysctl_base_table[] = { .mode = 0555, .child = dev_table, }, +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ + { + .procname = "qpnp-power-on", + .mode = 0555, + .child = qpnp_power_on_table, + }, +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ { } }; @@ -2089,8 +2103,42 @@ static struct ctl_table debug_table[] = { }; static struct ctl_table dev_table[] = { + { + .procname = "ddr", + .mode = 0555, + .child = ddr_table, + }, + { } +}; +/*[TracyChui] Expose power up/down reason and memory info 20200615 start */ +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, + }, { } }; +/*[TracyChui] Expose power up/down reason and memory info 20200615 end */ int __init sysctl_init(void) { -- GitLab From 1248c7e1aa80e7a6ceee8f207a4c00499f177948 Mon Sep 17 00:00:00 2001 From: shermanwei Date: Mon, 15 Jun 2020 10:20:27 +0800 Subject: [PATCH 24/78] Revert Qualcomm CR to fix the issue that failed to real suspend after powering on screen Change-Id: I74722116a43101f8e2d042d4d7b0254759974c42 --- drivers/misc/qseecom.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index a64e44589c73..9aed29ea34db 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -444,6 +444,10 @@ static int __qseecom_scm_call2_locked(uint32_t smc_id, struct scm_desc *desc) { int ret = 0; int retry_count = 0; +///<<20200615 revert Qualcomm patch:CR# 2402609 and 2478458 + if (qseecom.support_bus_scaling) + return scm_call2(smc_id, desc); +///>>20200615 revert Qualcomm patch do { ret = scm_call2_noretry(smc_id, desc); @@ -1519,14 +1523,20 @@ static int __qseecom_decrease_clk_ref_count(enum qseecom_ce_hw_instance ce) qclk = &qseecom.qsee; else qclk = &qseecom.ce_drv; - - if (qclk->clk_access_cnt > 0) { - qclk->clk_access_cnt--; - } else { +///<<20200615 revert Qualcomm patch:CR# 2402609 and 2478458 +/// if (qclk->clk_access_cnt > 0) { +/// qclk->clk_access_cnt--; +/// } else { + if (qclk->clk_access_cnt > 2) { pr_err("Invalid clock ref count %d\n", qclk->clk_access_cnt); ret = -EINVAL; + goto err_dec_ref_cnt; } + if (qclk->clk_access_cnt == 2) + qclk->clk_access_cnt--; +err_dec_ref_cnt: +///>>20200615 revert Qualcomm patch mutex_unlock(&clk_access_lock); return ret; } -- GitLab From 5be659ac41dccd79dbdb524b755f8da63d30dee2 Mon Sep 17 00:00:00 2001 From: tracychui Date: Fri, 12 Jun 2020 14:42:13 +0800 Subject: [PATCH 25/78] Add product image and mount partition Root cause:N/A How to fix:N/A Feature:Add product image and mount partition for keep customer app RiskArea: Memory Change-Id: I82e99852936bc7fc8fab2034a097f943a6422f63 --- arch/arm64/boot/dts/qcom/msm8953.dtsi | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index 8458d8702db0..4fa79705c49c 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -37,13 +37,14 @@ compatible = "simple-bus"; }; +//#[TracyChui] Add product image and mount partition 20200612 start //[20200520][TracyChui]Implement AB partition on Android Q start firmware: firmware { android { compatible = "android,firmware"; vbmeta { compatible = "android,vbmeta"; - parts = "vbmeta,boot,system,vendor,dtbo"; + parts = "vbmeta,boot,system,vendor,dtbo,product"; //parts = " vbmeta,boot,system,vendor,dtbo,recovery"; }; @@ -58,11 +59,19 @@ //fsmgr_flags = "wait,avb"; status = "ok"; }; - + product { + compatible = "android,product"; + dev = "/dev/block/platform/soc/7824900.sdhci/by-name/product"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait,slotselect,avb"; + status = "ok"; + }; }; }; }; //[20200520][TracyChui]Implement AB partition on Android Q end +//[TracyChui] Add product image and mount partition 20200612 end reserved-memory { #address-cells = <2>; -- GitLab From 18459af5bf97b384b72ea70f17fdcc3e2f75ebfc Mon Sep 17 00:00:00 2001 From: tracychui Date: Mon, 29 Jun 2020 16:51:39 +0800 Subject: [PATCH 26/78] Add memory detect node for service menu Root cause:N/A How to fix:N/A Feature:add memory vendor detect node RiskArea: Memory Change-Id: I0e3aa68cdeca14fe304fcdeef216c6349953a5dc --- drivers/mmc/core/mmc.c | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 0831456c3c52..1ff4a8e63b11 100755 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -27,10 +27,22 @@ #include "bus.h" #include "mmc_ops.h" #include "sd_ops.h" +/*[TracyChui]Add memory detect node for service menu 20200629 start */ +#include +/*[TracyChui]Add memory detect node for service menu 20200629 end */ #define DEFAULT_CMD6_TIMEOUT_MS 500 #define MIN_CACHE_EN_TIMEOUT_MS 1600 +/*[TracyChui]Add memory detect node for service menu 20200629 start */ +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 u32 memory_cid; +/*[TracyChui]Add memory detect node for service menu 20200629 end */ + static const unsigned int tran_exp[] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 @@ -3156,6 +3168,33 @@ static const struct mmc_bus_ops mmc_ops = { .post_hibernate = mmc_post_hibernate }; +/*[TracyChui]Add memory detect node for service menu 20200629 start */ +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, +}; +/*[TracyChui]Add memory detect node for service menu 20200629 end */ + /* * Starting point for MMC card init. */ @@ -3219,6 +3258,14 @@ int mmc_attach_mmc(struct mmc_host *host) register_reboot_notifier(&host->card->reboot_notify); + /*[TracyChui]Add memory detect node for service menu 20200629 start */ + proc_create("memory_vendor", 0, NULL, &proc_memory_vendor_fops); + if(host->card->type == MMC_TYPE_MMC) + { + memory_cid=host->card->raw_cid[0]; + } + /*[TracyChui]Add memory detect node for service menu 20200629 end */ + return 0; remove_card: -- GitLab From 57e29b1d48a43f69962fc1b4591137c1d8dc0af8 Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Thu, 2 Jul 2020 12:07:33 +0800 Subject: [PATCH 27/78] Add the detection for read the calibration data to adjust speaker performance. Root cause: Need to detect calibration data for speaker component differences. How to fix: 1. Read the calibration data from persist to adjust speaker performance. RiskArea: speaker Change-Id: Ib3e9aaa3bc8a55fe4bbf99061c7d71b8ace810ac --- sound/soc/codecs/tas2557/tas2557-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2557/tas2557-core.c b/sound/soc/codecs/tas2557/tas2557-core.c index 9109f8d94c7f..693065a610a6 100644 --- a/sound/soc/codecs/tas2557/tas2557-core.c +++ b/sound/soc/codecs/tas2557/tas2557-core.c @@ -46,7 +46,10 @@ #define PPC_DRIVER_MTPLLSRC 0x00000400 #define PPC_DRIVER_CFGDEV_NONCRC 0x00000101 -#define TAS2557_CAL_NAME "/data/tas2557_cal.bin" +//[FairPhone][Audio][jinjia]=2020.07.01=Read the calibration data from persist to adjust speaker performance. -s +//#define TAS2557_CAL_NAME "/data/tas2557_cal.bin" +#define TAS2557_CAL_NAME "/mnt/vendor/persist/tas2557_cal.bin" +//[FairPhone][Audio][jinjia]=2020.07.01=Read the calibration data from persist to adjust speaker performance. -e #define RESTART_MAX 3 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, -- GitLab From 2a872675dbd102854dda5b22a94eadbbe9debd1f Mon Sep 17 00:00:00 2001 From: frankcheng Date: Thu, 2 Jul 2020 22:52:43 +0800 Subject: [PATCH 28/78] [Camera] The define declare and common message modified Change-Id: I0d995ee5d197e071a138ba82ba68a4ee54383a55 --- .../camera_v2/sensor/io/msm_camera_dt_util.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 a33436e72ba9..a37b0cc258d4 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,26 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) +//<2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Add for camera power re-open control when multicamera operate. +#if defined( MULTI_CAMERA_POWER_ON ) + #undef MULTI_CAMERA_POWER_ON +#endif + #define MULTI_CAMERA_POWER_ON + +#if defined( CAM_DBG ) + #undef CAM_DBG +#endif + +#if defined( MULTI_CAMERA_POWER_ON ) +//#define CAM_DBG(fmt, args...) pr_debug(fmt, ##args) +#define CAM_DBG(fmt, args...) pr_err(fmt, ##args) + +int iovdd_count = 0; +#else +#define CAM_DBG(fmt, args...) do{}while(0) +#endif /* End..(MULTI_CAMERA_POWER_ON) */ +//>2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]. + 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) -- GitLab From b088588d4465f6bcd2cedaf61d5509deae7a571d Mon Sep 17 00:00:00 2001 From: Allen Lu Date: Mon, 6 Jul 2020 14:07:48 +0800 Subject: [PATCH 29/78] Disable ramdump in user build Issue: PRJ8901-1292 Change-Id: I4feb021e2b1ea9420c032df740212b250492e9a5 --- arch/arm64/configs/msm8953-perf_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index f444ba2b3826..88ddbc7411c9 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -362,7 +362,7 @@ CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y CONFIG_POWER_RESET_QCOM=y -CONFIG_QCOM_DLOAD_MODE=y +CONFIG_QCOM_DLOAD_MODE=n CONFIG_QPNP_FG=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1355_SLAVE_CHARGER=y -- GitLab From a0bd9ddb5188450aff4adaaeadfa8629753b3eb8 Mon Sep 17 00:00:00 2001 From: frankcheng Date: Sat, 4 Jul 2020 15:23:33 +0800 Subject: [PATCH 30/78] [Camera] Add a flag for VIO turn on and off if multi-camera operate Change-Id: If9a0803a21e5ec7af40d6e23d7f47b2546120234 --- .../camera_v2/sensor/io/msm_camera_dt_util.c | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) 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 a37b0cc258d4..6cd977e17445 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 @@ -1532,10 +1532,32 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, CDBG("%s:%d gpio set val %d\n", __func__, __LINE__, ctrl->gpio_conf->gpio_num_info->gpio_num [power_setting->seq_val]); + //<2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Add for camera power re-open control when multicamera operate. + #if defined( MULTI_CAMERA_POWER_ON ) + if( power_setting->seq_val == SENSOR_GPIO_VIO ) + { + CAM_DBG("[%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 /** Default **/ gpio_set_value_cansleep( ctrl->gpio_conf->gpio_num_info->gpio_num [power_setting->seq_val], (int) power_setting->config_val); + #endif /* End..(MULTI_CAMERA_POWER_ON) */ + //>2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]. break; case SENSOR_VREG: if (power_setting->seq_val == INVALID_VREG) @@ -1608,9 +1630,31 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, if (!ctrl->gpio_conf->gpio_num_info->valid [power_setting->seq_val]) continue; + //<2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Add for camera power re-open control when multicamera operate. + #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 ); + } + CAM_DBG("[%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 /** Default **/ gpio_set_value_cansleep( ctrl->gpio_conf->gpio_num_info->gpio_num [power_setting->seq_val], GPIOF_OUT_INIT_LOW); + #endif /* end..(MULTI_CAMERA_POWER_ON) */ + //>2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]. break; case SENSOR_VREG: if (power_setting->seq_val < ctrl->num_vreg) @@ -1735,10 +1779,32 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl, if (!ctrl->gpio_conf->gpio_num_info->valid [pd->seq_val]) continue; + //<2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]Add for camera power re-open control when multicamera operate. + #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 ); + } + CAM_DBG("[%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 /** Default **/ gpio_set_value_cansleep( ctrl->gpio_conf->gpio_num_info->gpio_num [pd->seq_val], (int) pd->config_val); + #endif /* end..(MULTI_CAMERA_POWER_ON) */ + //>2019/05/10-Yuting Shih.[FAIRPHONE][MISC][COMMON][CAMERA][][]. break; case SENSOR_VREG: if (pd->seq_val == INVALID_VREG) -- GitLab From 1146d1f633e57f5b9526a9f503b19a8dd2c70f30 Mon Sep 17 00:00:00 2001 From: weikao Date: Fri, 28 Aug 2020 13:49:39 +0800 Subject: [PATCH 31/78] Fix issue "During video recording, still picture captured shows full green screen." Root cause: N/A How to fix: N/A Issue:PRJ8901-1488 Change-Id: I482ca772e5bad60e47b06dfb625db1417eba593f (cherry picked from commit 75bcf6833da5769814e7dfe9547f628cc33fca68) --- .../platform/msm/camera_v2/isp/msm_buf_mgr.c | 60 +++++++++++++++++++ .../platform/msm/camera_v2/isp/msm_buf_mgr.h | 3 + .../msm/camera_v2/isp/msm_isp_axi_util.c | 2 +- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index 7a0a0696f24e..ba4d4f090ed8 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -757,6 +757,65 @@ static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr, return 0; } + +static int msm_isp_buf_err(struct msm_isp_buf_mgr *buf_mgr, + uint32_t bufq_handle, uint32_t buf_index, + struct timeval *tv, uint32_t frame_id, uint32_t output_format) +{ + int rc = 0; + unsigned long flags; + struct msm_isp_bufq *bufq = NULL; + struct msm_isp_buffer *buf_info = NULL; + enum msm_isp_buffer_state state; + + bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); + if (!bufq) { + pr_err("Invalid bufq\n"); + return -EINVAL; + } + + buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); + if (!buf_info) { + pr_err("%s: buf not found\n", __func__); + return -EINVAL; + } + + spin_lock_irqsave(&bufq->bufq_lock, flags); + state = buf_info->state; + + if (BUF_SRC(bufq->stream_id) == MSM_ISP_BUFFER_SRC_HAL) { + if (state == MSM_ISP_BUFFER_STATE_DEQUEUED) { + buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED; + spin_unlock_irqrestore(&bufq->bufq_lock, flags); + buf_mgr->vb2_ops->buf_error(buf_info->vb2_v4l2_buf, + bufq->session_id, bufq->stream_id, + frame_id, tv, output_format); + } else { + spin_unlock_irqrestore(&bufq->bufq_lock, flags); + } + goto done; + } + + /* + * For native buffer put the diverted buffer back to queue since caller + * is not going to send it to CPP, this is error case like + * drop_frame/empty_buffer + */ + if (state == MSM_ISP_BUFFER_STATE_DIVERTED) { + buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED; + rc = msm_isp_put_buf_unsafe(buf_mgr, buf_info->bufq_handle, + buf_info->buf_idx); + if (rc < 0) + pr_err("%s: Buf put failed\n", __func__); + } + spin_unlock_irqrestore(&bufq->bufq_lock, flags); +done: + return rc; +} + + + + static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) @@ -1505,6 +1564,7 @@ static struct msm_isp_buf_ops isp_buf_ops = { .buf_mgr_debug = msm_isp_buf_mgr_debug, .get_bufq = msm_isp_get_bufq, .buf_divert = msm_isp_buf_divert, + .buf_err = msm_isp_buf_err, }; int msm_isp_create_isp_buf_mgr( diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h index 4ea6dd6c2210..fa20a95a39a3 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h @@ -180,6 +180,9 @@ struct msm_isp_buf_ops { int (*buf_divert)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id); + int (*buf_err)(struct msm_isp_buf_mgr *buf_mgr, + uint32_t bufq_handle, uint32_t buf_index, + struct timeval *tv, uint32_t frame_id, uint32_t output_format); }; struct msm_isp_buf_mgr { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 63ae9d1ea71a..54812dc8c41b 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -3600,7 +3600,7 @@ static int msm_isp_return_empty_buffer(struct vfe_device *vfe_dev, buf->buf_debug.put_state[buf->buf_debug.put_state_last] = MSM_ISP_BUFFER_STATE_DROP_REG; buf->buf_debug.put_state_last ^= 1; - rc = vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr, + rc = vfe_dev->buf_mgr->ops->buf_err(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx, ×tamp.buf_time, frame_id, stream_info->runtime_output_format); -- GitLab From 4a423b3f24e07360b557fb054dc2b9eab3f64fcd Mon Sep 17 00:00:00 2001 From: michaellin Date: Mon, 16 Nov 2020 16:11:02 +0800 Subject: [PATCH 32/78] Modify chip ID for PN553 A0 Change-Id: Ia9343e7f28d2672283a453ed38d77bf6f9530b22 (cherry picked from commit 65fed4b7968b556536bc3154d02d36e51a1bf318) --- drivers/nfc/nq-nci.c | 1 + drivers/nfc/nq-nci.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index cc90a36b1971..2a8f8b224d99 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -846,6 +846,7 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) dev_dbg(&client->dev, "%s: ## NFCC == NQ220 ##\n", __func__); break; + case NFCC_PN553_A0: case NFCC_NQ_310: dev_dbg(&client->dev, "%s: ## NFCC == NQ310 ##\n", __func__); diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h index d17897db7bab..b25aeeaa73ec 100644 --- a/drivers/nfc/nq-nci.h +++ b/drivers/nfc/nq-nci.h @@ -46,7 +46,8 @@ enum nfcc_initial_core_reset_ntf { enum nfcc_chip_variant { NFCC_NQ_210 = 0x48, /**< NFCC NQ210 */ NFCC_NQ_220 = 0x58, /**< NFCC NQ220 */ - NFCC_NQ_310 = 0x40, /**< NFCC NQ310 */ + NFCC_PN553_A0 = 0x40, /**< NFCC PN553_A0 */ + NFCC_NQ_310 = 0x41, /**< NFCC NQ310 */ NFCC_NQ_330 = 0x51, /**< NFCC NQ330 */ NFCC_SN100_A = 0xa3, /**< NFCC SN100_A */ NFCC_SN100_B = 0xa4, /**< NFCC SN100_B */ -- GitLab From 7ec5b250625f185c3061a393aff4ed49a5832a7e Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Wed, 9 Dec 2020 18:30:05 +0800 Subject: [PATCH 33/78] Upgrade himax fw CID0804_D02_C15 for Ghost touch. Root cause: Improve ghost touch issue by new feature in auto calibration. How to fix: Upgrade himax fw. RiskArea: Touch Change-Id: Ife345a6b35b2c7f770bc7d0c360b6199ec56ef2d (cherry picked from commit 0206504f21256d73b1f10aa5162429262932e25d) --- .../FP_DJN_Arima_CID0804_D02_C15_20201209.i | 4096 +++++++++++++++++ .../hxchipset83112b/himax_common.c | 4 +- 2 files changed, 4099 insertions(+), 1 deletion(-) create mode 100644 drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.i diff --git a/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.i b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.i new file mode 100644 index 000000000000..e902408d3f6d --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.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,0x83,0x70, +0x3E,0x0F,0xF4,0xB4,0x42,0x0E,0x00,0x21,0x3F,0xC8,0x00,0x00,0x3F,0xF8,0x0C,0x90, +0x49,0x00,0x00,0x1E,0x49,0x00,0x00,0x18,0x49,0x00,0x11,0xAD,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,0x5D,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,0x5D,0xDD,0x9E,0xFC,0x00, +0x49,0x00,0x45,0x70,0xFC,0x80,0xFC,0x00,0x49,0x00,0x4A,0x9A,0xFC,0x80,0x40,0x00, +0x00,0x09,0xDD,0x9E,0xFC,0x00,0x49,0x00,0x45,0xC7,0xFC,0x80,0x40,0x00,0x00,0x09, +0xDD,0x9E,0xFC,0x00,0x49,0x00,0x48,0x68,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,0x6D,0xD5,0xFB,0xFC,0x81,0xFC,0x01,0xF0,0x81,0xF0,0x01, +0x8E,0x01,0xF0,0x81,0xC0,0x05,0xEA,0x36,0xC0,0x03,0xEA,0x6D,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,0x50,0x9A,0x08,0x5C,0xF0, +0x00,0x3D,0xE8,0x05,0x3C,0x1F,0xFF,0x6D,0x84,0x01,0xDD,0x9E,0x3E,0x08,0x0C,0x90, +0x8A,0x01,0x3C,0x1D,0xFF,0x6D,0xE2,0x20,0xE8,0x03,0x3C,0x0F,0xFF,0x6D,0x84,0x00, +0xDD,0x9E,0xFC,0x00,0xDD,0x4D,0x5A,0x00,0x08,0x18,0x5A,0x00,0x06,0x16,0xEA,0xB1, +0xEB,0x24,0xEB,0x32,0xEB,0x58,0xEA,0x68,0xDD,0x48,0x2E,0x07,0xFD,0x29,0x3E,0x07, +0xFD,0x2F,0x46,0x21,0x00,0x05,0x58,0x21,0x08,0x88,0xEA,0x5B,0x46,0x11,0x00,0x05, +0x58,0x10,0x86,0xD8,0xD5,0x06,0xEA,0x5B,0xEB,0x24,0xEB,0x32,0xEB,0x58,0xEA,0x68, +0xDD,0x48,0x84,0x00,0xDD,0x58,0xDD,0x4D,0x5A,0x00,0x08,0x17,0x5A,0x00,0x06,0x15, +0x84,0xA0,0x80,0x05,0xEB,0x70,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,0x90,0x84,0x00, +0x3E,0x07,0xFC,0xC2,0x49,0x00,0x4C,0x36,0x3E,0x07,0xFC,0xCF,0x84,0x20,0xF1,0x81, +0x4E,0x02,0x00,0xB6,0xEB,0x5B,0x02,0x50,0x80,0x00,0x44,0x10,0xA5,0x5A,0x46,0x71, +0x00,0x00,0x58,0x73,0x80,0x00,0x4C,0x50,0x80,0xAB,0xEB,0x5B,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,0xFC,0xC2,0x5A,0x08,0x01,0x0E,0xB8,0x00, +0x5A,0x00,0x08,0x07,0x5A,0x00,0x06,0x05,0xEB,0x55,0xEA,0xAD,0xD5,0x03,0xEB,0x52, +0xEA,0xFC,0xF0,0x81,0xD5,0x0E,0x54,0x10,0x00,0xF7,0x5A,0x18,0x02,0x05,0xEB,0x55, +0xEA,0x74,0xD5,0xF8,0x5A,0x18,0x03,0x04,0xB8,0x1A,0xD5,0xF4,0x5A,0x00,0x08,0xFE, +0xB0,0x41,0x3E,0x0F,0xFC,0xCF,0x49,0x00,0x07,0x11,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,0x7A,0xEA,0xEB,0x84,0x20,0xFE,0x84,0xEB,0x82,0x58,0x00, +0x00,0x04,0x94,0x91,0xDD,0x42,0xB8,0x00,0x5A,0x08,0x08,0x08,0xEA,0x5B,0xEB,0x5B, +0xEB,0x33,0xF2,0x01,0xDD,0x48,0xD5,0x46,0x5A,0x00,0x06,0xFA,0x84,0x00,0xF1,0x01, +0x49,0x00,0x07,0x20,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,0xC6, +0x14,0x9F,0x80,0x01,0xD5,0x09,0xEB,0x55,0xEA,0x74,0x4C,0x10,0x3F,0xF2,0x84,0x01, +0x49,0x00,0x07,0x08,0xC8,0xED,0x2F,0x37,0xFF,0xC9,0x2F,0x17,0xFF,0xC8,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,0x7A,0x2E,0x17,0xFF,0xC8,0x42,0x01,0x04,0x24,0x88,0x41,0x8C,0x02, +0x40,0x03,0x80,0x20,0x84,0x20,0x94,0x91,0xDD,0x42,0xEA,0x9E,0x54,0x00,0x00,0xF7, +0x5A,0x08,0x01,0x04,0x49,0x00,0x00,0xCC,0x49,0x00,0x4B,0xE4,0xFC,0xC1,0xFC,0x00, +0xDD,0x4C,0x96,0x04,0xC0,0x09,0xEA,0x36,0xC0,0x08,0x2E,0x07,0xFE,0x31,0xC8,0x05, +0x49,0x00,0x4A,0xEC,0xD5,0x02,0xEA,0x6B,0xFC,0x80,0x2E,0x17,0xFC,0xD4,0xFE,0x0C, +0x96,0x01,0xDD,0x9E,0xFC,0x60,0xDD,0x56,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,0xED,0x96,0x31,0x40,0x90,0x20,0x09,0x97,0xB0,0xEA,0x48, +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,0x3B,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,0x62,0x00,0x30,0x0F,0x80,0x80,0x29,0x80,0x0A,0x80,0x46, +0xDD,0x4E,0xEA,0x3C,0x83,0x81,0xB8,0x3F,0x46,0x2B,0xB0,0x00,0xEA,0xB0,0x40,0x01, +0x01,0x15,0xB8,0xBF,0xFC,0xE0,0xFC,0x00,0xDD,0x53,0x4E,0x00,0x4C,0x83,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,0x3B, +0x3E,0x07,0xFC,0xD3,0xF8,0x13,0x84,0x41,0xDD,0x4E,0x4E,0x00,0x4C,0x74,0xFA,0x64, +0xDD,0x4E,0xF8,0x0C,0x84,0x43,0xDD,0x4E,0x84,0x20,0x84,0x44,0x44,0x30,0x00,0x80, +0xDD,0x52,0x83,0xFF,0xDD,0x4E,0x84,0x0A,0xDD,0x50,0x84,0x20,0x80,0x61,0xDD,0x52, +0x83,0xFF,0x84,0x44,0xDD,0x4E,0x84,0x20,0x84,0x45,0xDD,0x52,0x83,0xFF,0xEA,0x3B, +0x3E,0x07,0xFC,0xBC,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,0x27,0x02,0x00,0x80,0x9C,0x02,0x10,0x80,0x0A,0x8A,0x01,0x44,0x10, +0x06,0x5C,0xFE,0x0C,0x84,0x2A,0xEA,0xDF,0x92,0x04,0xFC,0x80,0xFC,0x40,0x3F,0xCF, +0xFD,0x90,0xEB,0x52,0x00,0x20,0x02,0xC0,0xC2,0x04,0xEB,0x52,0x10,0x20,0x02,0xC1, +0xBD,0x11,0x5A,0x58,0x05,0x06,0x84,0x00,0xEB,0x79,0x10,0x00,0x82,0xC1,0x2E,0x47, +0xFD,0x03,0xEB,0x26,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,0x85,0x96,0x01, +0x12,0x00,0x87,0xA2,0x2E,0x57,0xFD,0x1D,0xEB,0x62,0x00,0x00,0x00,0x80,0xEA,0x2A, +0xFE,0x24,0x42,0x02,0x84,0x73,0x2E,0x57,0xFD,0x08,0x96,0x91,0x88,0x05,0x96,0x01, +0xEB,0x60,0x12,0x02,0x87,0xA3,0xEB,0x4F,0xEA,0xA8,0xEB,0x60,0x12,0x02,0x87,0xA5, +0xEB,0x65,0x02,0x00,0x00,0x5E,0xEB,0x60,0x92,0x01,0x12,0x02,0x87,0xA6,0xEB,0x65, +0x02,0x00,0x00,0x64,0xEB,0x60,0x92,0x01,0x12,0x02,0x87,0xA7,0xEA,0x40,0xEB,0x60, +0x12,0x02,0x87,0xA8,0xB8,0x19,0xEB,0x60,0x96,0x01,0x12,0x02,0x87,0xA9,0x3C,0x03, +0xFE,0xF6,0xEB,0x60,0x12,0x02,0x87,0xAA,0xEB,0x1A,0xEB,0x60,0x12,0x02,0x87,0xAB, +0xEB,0x09,0xEB,0x60,0x12,0x02,0x87,0xAC,0x3C,0x03,0xFE,0xDA,0xEB,0x60,0x12,0x02, +0x87,0xB0,0x2E,0x07,0xFC,0xFB,0xEB,0x60,0x12,0x02,0x87,0xB1,0xEB,0x62,0x12,0x20, +0x07,0xB2,0xEB,0x52,0x00,0x00,0x02,0xC1,0xEB,0x73,0x12,0x01,0x07,0xB3,0x2E,0x27, +0xFC,0xE1,0xEA,0xE0,0xEB,0x00,0xEB,0x73,0x12,0x01,0x07,0xB4,0x2E,0x27,0xFD,0x24, +0xEB,0x62,0x02,0x00,0x07,0xB5,0xEB,0x00,0xEB,0x73,0x96,0x01,0x12,0x01,0x07,0xB5, +0x2E,0x27,0xFD,0x26,0xEA,0x29,0xFE,0x1C,0x42,0x01,0x10,0x73,0xEB,0x73,0x96,0x01, +0x12,0x01,0x07,0xB6,0x3C,0x03,0xFF,0x14,0xEB,0x73,0x12,0x01,0x07,0xB7,0x3C,0x03, +0xFF,0x12,0xEB,0x73,0x12,0x01,0x07,0xB8,0xBA,0x10,0x2E,0x07,0xFC,0xDA,0xEB,0x00, +0xEB,0x73,0x96,0x01,0x12,0x01,0x07,0xB9,0xEB,0x62,0x02,0x20,0x07,0xBA,0x2E,0x47, +0xFD,0x20,0x2E,0x07,0xFD,0x0D,0xFE,0x0C,0x42,0x02,0x0C,0x73,0x88,0x02,0x96,0x01, +0xEB,0x73,0x12,0x01,0x07,0xBA,0xEB,0x73,0x3C,0x03,0xFE,0xD8,0x12,0x01,0x07,0xBE, +0x3C,0x03,0xFE,0x9F,0x12,0x01,0x07,0xBE,0x2E,0x27,0xFF,0x5C,0x42,0x01,0x18,0x0B, +0xC0,0x0B,0x2E,0x38,0x02,0x8C,0x2E,0x08,0x02,0x8D,0x42,0x01,0x84,0x73,0xEB,0x85, +0x96,0x01,0x12,0x00,0x87,0xBF,0xEB,0x4F,0x02,0x00,0x02,0xD5,0xEB,0x85,0x12,0x00, +0x81,0xD8,0x3C,0x03,0xFE,0xBD,0xEB,0x85,0x8C,0x0F,0x96,0x01,0x96,0x92,0x12,0x00, +0x81,0xEB,0x4E,0x25,0x00,0x17,0x2E,0x00,0x00,0x1D,0x92,0x07,0x4E,0x02,0x00,0x76, +0xEB,0x3E,0xEA,0xEB,0xEB,0x58,0x58,0x21,0x00,0x00,0xFE,0x44,0xEB,0x4E,0x8C,0x22, +0x40,0x11,0x04,0x20,0xEB,0x73,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,0x67,0xFF,0xC8,0xB8,0x00,0x46,0x41,0x00,0x00,0x58,0x42,0x00,0x00, +0x5A,0x08,0x08,0x0C,0x2E,0x37,0xFF,0xC9,0x42,0x21,0x98,0x24,0x9C,0x52,0x8A,0x46, +0x40,0x12,0x04,0x20,0x8C,0x42,0xD5,0x09,0x2E,0x00,0x00,0x1D,0x96,0x37,0xFE,0x34, +0x8C,0x02,0x40,0x12,0x00,0x20,0x98,0x86,0x40,0x62,0x08,0x20,0xEB,0x4E,0xEB,0x73, +0x58,0x21,0x0F,0x44,0xDD,0x48,0x46,0x97,0xFF,0xFF,0x80,0x26,0xEB,0x4E,0xEB,0x73, +0x58,0x21,0x03,0xB0,0xDD,0x48,0x84,0xC0,0x50,0x94,0x8F,0xFF,0x46,0xA1,0x00,0x00, +0x58,0xA5,0x00,0x04,0xEA,0x77,0xE2,0xC0,0x4E,0xF2,0xFF,0x97,0xEA,0x31,0x40,0x70, +0x24,0x00,0x42,0x73,0x00,0x73,0x80,0x06,0x40,0x75,0x1C,0x20,0x49,0x00,0x24,0x5F, +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,0x62, +0x04,0x50,0x03,0xC0,0xEB,0x03,0x97,0x69,0x4C,0x50,0x00,0xDA,0xEB,0x7F,0x00,0x00, +0x08,0x3B,0xEB,0x5E,0x10,0x00,0x8B,0x8B,0xEB,0x7F,0x00,0x00,0x08,0x3C,0xEB,0x5E, +0x10,0x00,0x8B,0x8C,0xEB,0x7F,0x00,0x00,0x08,0x3D,0xEB,0x5E,0x10,0x00,0x8B,0x8D, +0xEB,0x7F,0x00,0x00,0x08,0x3E,0xEB,0x5E,0x10,0x00,0x8B,0x8E,0xEB,0x7F,0x00,0x00, +0x08,0x3F,0xEB,0x5E,0x10,0x00,0x8B,0x8F,0xEB,0x7F,0x02,0x00,0x04,0x0F,0xEB,0x5E, +0x12,0x00,0x85,0xB7,0xEB,0x7F,0x02,0x00,0x04,0x10,0xEB,0x5E,0x12,0x00,0x85,0xB8, +0xEB,0x7F,0x02,0x00,0x04,0x11,0xEB,0x5E,0x12,0x00,0x85,0xB9,0xEB,0x7F,0x04,0x00, +0x01,0xF8,0xEB,0x5E,0x14,0x00,0x82,0xCC,0xEB,0x7F,0x02,0x00,0x04,0x0D,0xEB,0x5E, +0x12,0x00,0x85,0xB5,0xEB,0x7F,0x02,0x00,0x04,0x0E,0xEB,0x5E,0x12,0x00,0x85,0xB6, +0xEB,0x7F,0x00,0x00,0x09,0xE7,0xEB,0x5E,0x10,0x00,0x8D,0x37,0xEB,0x7F,0x00,0x00, +0x09,0xE8,0xEB,0x5E,0x10,0x00,0x8D,0x38,0xEB,0x7F,0x00,0x00,0x09,0xE9,0xEB,0x5E, +0x10,0x00,0x8D,0x39,0xEB,0x7F,0x00,0x00,0x09,0xEA,0xEB,0x5E,0x10,0x00,0x8D,0x3A, +0xEB,0x7F,0x00,0x00,0x09,0xEB,0xEB,0x5E,0x10,0x00,0x8D,0x3B,0xEB,0x7F,0x02,0x00, +0x04,0xE5,0xEB,0x5E,0x12,0x00,0x86,0x8D,0xEB,0x7F,0x02,0x00,0x04,0xE6,0xEB,0x5E, +0x12,0x00,0x86,0x8E,0xEB,0x7F,0x02,0x00,0x04,0xE7,0xEB,0x5E,0x12,0x00,0x86,0x8F, +0xEB,0x7F,0x04,0x00,0x02,0x63,0xEB,0x5E,0x14,0x00,0x83,0x37,0xEB,0x7F,0x02,0x00, +0x04,0xE3,0xEB,0x5E,0x12,0x00,0x86,0x8B,0xEB,0x7F,0x02,0x00,0x04,0xE4,0xEB,0x5E, +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,0x62,0x04,0x00, +0x00,0xA5,0x3C,0x0F,0xFF,0x76,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,0x07,0xFF,0xC9,0x3E,0x00, +0x00,0xE1,0x2E,0x17,0xFF,0xC8,0x88,0x01,0x3E,0x10,0x00,0xE0,0x2E,0x27,0xFF,0xCA, +0x84,0xA0,0x3E,0x00,0x00,0xE9,0x45,0x00,0xE0,0x00,0xEB,0x62,0x3E,0x20,0x00,0xE3, +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,0x8B,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,0x48,0xC8,0x20,0x12,0x73,0x00,0x08, +0x46,0x10,0x00,0x0C,0x00,0x10,0x81,0x03,0xEA,0x5C,0xC1,0x13,0xF0,0x81,0x49,0xFF, +0xFC,0xA4,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,0xCC, +0xEA,0xEA,0x12,0x13,0x00,0x08,0x96,0x00,0xD5,0x03,0x44,0x00,0x00,0xF0,0xFC,0xA1, +0xFC,0x00,0x46,0x09,0x00,0x08,0xEA,0xEA,0x12,0x10,0x00,0x08,0xEA,0xB7,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,0xDA,0xC9,0x2E,0x2E,0x17,0xFF,0x5B,0x42,0x00, +0x88,0x0B,0xC8,0x03,0xEB,0x2E,0xD5,0x06,0x49,0x00,0x3C,0x6E,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,0xB7,0xEB,0x2E, +0xD5,0x06,0x49,0x00,0x3C,0x62,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,0x00,0x00,0xFC,0x00,0x5C,0xF0,0x00,0x31,0x4E,0xF2, +0x01,0x56,0x3E,0xFF,0x5B,0x60,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,0x62,0xDD,0x5D,0xF8,0x5E,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x76,0xF7, +0xF8,0x59,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x66,0x67,0xF8,0xAB,0xEB,0x62,0xDD,0x5D, +0x50,0x00,0x7E,0xFF,0xF8,0x4F,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x7E,0x6F,0xF8,0x4A, +0xEB,0x62,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,0x62,0xDD,0x5D, +0x50,0x00,0x5D,0xDE,0xF8,0x37,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x5B,0xDC,0xF8,0x32, +0xEB,0x62,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,0x62,0xDD,0x44, +0x44,0x0F,0x55,0x56,0xF8,0x76,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x53,0x54,0xF8,0x71, +0xEB,0x62,0xDD,0x44,0x44,0x0F,0x33,0x34,0xF8,0x6C,0x84,0x0C,0xDD,0x40,0x80,0xC0, +0x84,0x0D,0xCE,0xD0,0xF8,0x60,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x6E,0xEF,0xF8,0x0A, +0xEB,0x62,0xDD,0x5D,0x50,0x00,0x6C,0xED,0xF8,0x05,0xEB,0x62,0xDD,0x5D,0x50,0x00, +0x4C,0xCD,0x48,0x00,0x00,0xAD,0xFA,0x00,0xDD,0x40,0x80,0xC0,0xC8,0xBB,0xFA,0x01, +0xF8,0x4A,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x88,0x89,0xF8,0x4B,0xEB,0x62,0xDD,0x44, +0x44,0x0F,0x87,0x88,0xF8,0x46,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x77,0x78,0xF8,0x41, +0xFA,0x04,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0xA6,0xFA,0x05,0xF8,0x34,0xEB,0x62, +0xDD,0x44,0x44,0x0F,0xAA,0xAB,0xF8,0x35,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xA9,0xAA, +0xF8,0x30,0xEB,0x62,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,0x62,0xDD,0x44,0x44,0x0F,0xAE,0xAF,0xF8,0x1B,0xEB,0x62,0xDD,0x44, +0x44,0x0F,0xAE,0x9F,0xF8,0x16,0xEB,0x62,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,0x62,0xDD,0x44,0x44,0x0F,0xAF,0xB0, +0x48,0x00,0x00,0x55,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xAF,0xA0,0xD5,0x4F,0xEB,0x62, +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,0x62, +0xDD,0x44,0x44,0x0F,0xAD,0xAE,0xD5,0x3A,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xAD,0x9E, +0xD5,0x35,0xEB,0x62,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,0x62,0xDD,0x44,0x44,0x0F,0xAC,0xAD,0xD5,0x20,0xEB,0x62,0xDD,0x44, +0x44,0x0F,0xAC,0x9D,0xD5,0x1B,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x9C,0x9D,0xD5,0x16, +0xFA,0x1A,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x26,0xFA,0x1B,0xD5,0x1C,0xEB,0x62, +0xDD,0x44,0x44,0x0F,0x44,0x45,0xD5,0x0A,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x40,0x41, +0xD5,0x05,0xEB,0x62,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,0x32,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xB0, +0xEB,0x82,0x58,0x00,0x06,0x04,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x84,0x00,0x3E,0x07, +0xFD,0x09,0x84,0x20,0xB9,0x80,0xEB,0x6B,0x46,0x27,0x2C,0x80,0x14,0x21,0x80,0xB2, +0x3E,0x17,0xFC,0xF7,0x3E,0x07,0xFD,0x1B,0xB8,0x0A,0x44,0x10,0x72,0xC8,0x40,0x50, +0x40,0x09,0xD9,0x07,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFC,0xF7,0xD5,0x09, +0x44,0x10,0x7F,0x0C,0xD9,0x06,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFD,0x1B, +0xB8,0x0A,0x44,0x10,0xFF,0xFE,0x8E,0x01,0xE2,0x20,0xE8,0x03,0x84,0x01,0xB8,0x8A, +0x84,0x0E,0xDD,0x40,0xC0,0x06,0xDD,0x4C,0x96,0x37,0x3E,0x07,0xFF,0x5B,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,0x65,0xDD,0x5C,0x84,0x20,0xDD,0x4F,0xEA,0xA9,0xEB,0x55,0xEA,0x74, +0x84,0x3F,0xDD,0x4F,0xEA,0xA9,0xFC,0x80,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC7, +0xEA,0x40,0x2E,0x17,0xFF,0xC6,0xE2,0x01,0x56,0x07,0x80,0x01,0xEA,0xBB,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,0x32,0x84,0x01,0xDD,0x58,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,0x28,0xD5,0x09, +0x84,0x06,0xDD,0x40,0xC0,0x04,0x44,0x00,0x91,0x91,0xD5,0x03,0x44,0x00,0x99,0x99, +0x46,0x11,0x00,0x07,0xEA,0x32,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,0x55,0xEA,0x74,0xD5,0x22,0x5A,0x08,0x0B,0x04,0xDD,0x47, +0xD5,0xF8,0x5A,0x08,0x0C,0x18,0xFA,0x0A,0xDD,0x40,0xC0,0x05,0xEB,0x65,0xDD,0x5C, +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,0x65,0xDD,0x5C, +0xD5,0x06,0x5A,0x08,0x0F,0x06,0xEB,0x82,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,0x65,0xDD,0x5C,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,0xFC,0xF7,0x9E,0x86,0xEB,0x5B,0x58,0x10,0x80,0x00, +0xEA,0xBD,0xEB,0x6B,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,0xD8,0xEA,0xBD,0x9E,0x82,0x3C,0x33,0xFE,0xEC,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,0xDF,0x50,0x00, +0x00,0x56,0x96,0x01,0xDD,0x9E,0xFC,0x00,0xFA,0x02,0xDD,0x40,0xC0,0x05,0x2E,0x10, +0x00,0x91,0xDD,0x5A,0xD5,0x0E,0xFA,0x06,0xDD,0x40,0xC0,0x0F,0x49,0x00,0x44,0x32, +0xEA,0x2A,0x5A,0x08,0x0C,0x05,0x2E,0x00,0x00,0x93,0xD5,0x03,0x2E,0x00,0x00,0x92, +0xFE,0x0C,0x49,0xFF,0xFF,0xDE,0xD5,0x03,0x49,0xFF,0xF9,0x47,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,0x1B,0x84,0x60,0xFB,0x94,0x2E,0x20,0x00,0xE1,0xE2,0x62, +0xE8,0x22,0x42,0x71,0xC0,0x24,0x84,0x40,0x2E,0x40,0x00,0xE0,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,0x90,0xB8,0x12,0xB9,0x08, +0xE2,0x20,0xE8,0x10,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05,0xEB,0x52, +0xEA,0xFC,0xD5,0x05,0xEB,0x41,0xC8,0x06,0xEB,0x55,0xEA,0xAD,0xEB,0x5B,0xEA,0x91, +0xEB,0x3D,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x02, +0xEA,0x50,0xFC,0x80,0xFC,0x00,0x3C,0x0D,0xFF,0x76,0x3C,0x2D,0xFF,0x6C,0xE2,0x40, +0xE8,0x19,0xEB,0x62,0x04,0x00,0x00,0xB2,0x96,0x81,0xE2,0x41,0xE8,0x13,0x96,0x49, +0x92,0x10,0xEB,0x4B,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB2,0xEB,0x41,0x5A,0x08, +0x01,0x0A,0xEA,0xB1,0xEB,0x5B,0xEA,0x91,0x46,0x21,0x00,0x03,0x58,0x21,0x0A,0x98, +0xDD,0x48,0xFC,0x80,0x46,0x38,0x00,0x30,0x4E,0x00,0x43,0x5F,0xCA,0xFE,0x4E,0x00, +0x43,0x62,0xDD,0x9E,0xFC,0x63,0x3F,0xCF,0xFD,0x8C,0x81,0x20,0xB1,0x81,0x3E,0x0F, +0xFA,0xD4,0x3B,0x00,0x4C,0x04,0x80,0xE1,0x80,0x26,0x3B,0x00,0xCC,0x24,0xA4,0x00, +0xAC,0x08,0x2E,0x80,0x00,0x8D,0x81,0x42,0x40,0x04,0x00,0x10,0x85,0x81,0x4E,0x04, +0x00,0x04,0x44,0xC0,0xFF,0xFF,0xEA,0x27,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,0x63,0xFE,0x02,0xB8,0x84,0x84,0x04,0x49,0xFF, +0xFF,0xC3,0xB9,0x04,0xEB,0x58,0xEA,0x68,0x80,0x09,0x49,0x00,0x43,0x35,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,0xCA,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,0xFA,0xE8,0x80,0xE0,0x50,0xAF,0x80,0x30,0x3E,0x0F,0xFB,0x0C,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,0x55,0x89,0x05,0x38,0x85,0x12,0x0A,0x39,0x25,0x32,0x0A, +0x50,0xC2,0x00,0x02,0xEA,0x55,0x39,0x15,0x32,0x0A,0x50,0xC2,0x00,0x03,0xEA,0x55, +0x39,0x05,0x32,0x0A,0x50,0xC2,0x00,0x04,0xEA,0x55,0x38,0x75,0x32,0x0A,0x50,0xD2, +0x00,0x05,0x50,0xC2,0x00,0x06,0xEA,0x55,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,0x46,0xEA,0x4F,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,0x09,0x96,0x00,0x40,0x27,0x88,0x20,0xEB,0x24,0xEB,0x32,0x96,0x90, +0x49,0xFF,0xFE,0xA2,0x5A,0x68,0x06,0x16,0xEA,0x4F,0x5A,0x08,0x11,0x13,0xEA,0x2B, +0x96,0x00,0xDD,0x58,0xD5,0x0E,0x5A,0x68,0x08,0x0D,0xEA,0x4F,0x8C,0x01,0x96,0x00, +0xE6,0x12,0xE9,0x02,0x84,0x00,0x3E,0x07,0xFD,0x09,0xEA,0x4F,0x49,0xFF,0xFF,0x10, +0xFC,0x80,0xFC,0x00,0x2E,0x17,0xFC,0xDC,0x2E,0x07,0xFF,0x93,0xFE,0x0C,0x3C,0x0F, +0xFF,0x7B,0x84,0x00,0x3C,0x0F,0xFF,0x75,0x49,0x00,0x2D,0x21,0xFC,0x80,0xFC,0x40, +0x2E,0x47,0xFF,0x61,0x84,0x20,0xFF,0x04,0x2F,0x20,0x00,0xE1,0x2F,0x30,0x00,0xE0, +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,0x6E, +0x2E,0x17,0xFF,0x67,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,0x7E,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,0x62, +0x00,0x70,0x0F,0x1C,0xEB,0x62,0x00,0x60,0x0F,0x1D,0xEB,0x62,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,0x25,0x02,0x3F,0x80,0x01,0xE2,0x60, +0xEA,0x25,0xE8,0x05,0x96,0x01,0x12,0x0F,0x80,0x01,0xD5,0x1F,0x02,0x3F,0x80,0x02, +0xE2,0x60,0xE8,0x0A,0xEA,0x22,0xEA,0xD6,0x4C,0x30,0x00,0x07,0xEA,0x25,0x96,0x01, +0x12,0x0F,0x80,0x02,0xD5,0x12,0xEA,0x25,0x02,0x3F,0x80,0x03,0xE2,0x60,0xE8,0x0D, +0xEA,0x22,0xEA,0xD6,0x4C,0x30,0x00,0x0A,0xEA,0x22,0xEA,0xD7,0x4C,0x30,0x00,0x06, +0xEA,0x25,0x96,0x01,0x12,0x0F,0x80,0x03,0xEA,0x22,0xEA,0x86,0xE2,0x60,0xE8,0x06, +0xEA,0x25,0x96,0x01,0x12,0x0F,0x80,0x04,0xD5,0x1F,0xEA,0x22,0xEA,0xE8,0xE2,0x60, +0xE8,0x0A,0xEA,0x22,0xEA,0x86,0x4C,0x30,0x00,0x07,0xEA,0x25,0x96,0x01,0x12,0x0F, +0x80,0x05,0xD5,0x12,0xEA,0x22,0x02,0x0F,0x80,0x06,0xE2,0x60,0xE8,0x0D,0xEA,0x22, +0xEA,0x86,0x4C,0x30,0x00,0x0A,0xEA,0x22,0xEA,0xE8,0x4C,0x30,0x00,0x06,0xEA,0x25, +0x96,0x01,0x12,0x0F,0x80,0x06,0x8C,0xA2,0xD9,0xAB,0x84,0x20,0xFA,0x44,0xEB,0x62, +0x58,0x00,0x0F,0x24,0xDD,0x42,0x49,0xFF,0xF6,0x58,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,0x62,0xEA,0xE6, +0x46,0x11,0x00,0x07,0xEA,0x37,0xEA,0xE3,0xEB,0x41,0xC0,0x05,0x80,0x09,0x49,0xFF, +0xFF,0x40,0xD5,0x04,0x80,0x09,0x49,0xFF,0xFF,0x04,0xC8,0x07,0xEB,0x62,0xEA,0xE6, +0x46,0x11,0x00,0x07,0xEB,0x04,0xEA,0xE3,0xEB,0x62,0xEA,0xE6,0xC8,0x06,0x44,0x0F, +0xAA,0xAA,0x46,0x11,0x00,0x07,0xEA,0xE3,0xEA,0xD6,0x46,0x11,0x00,0x07,0x96,0x01, +0x12,0x00,0x87,0x93,0xEA,0xD7,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,0x86, +0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x96,0xEA,0xE8,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,0x1D,0x4E,0x00,0x3D,0x9D,0x4E,0x00, +0x3D,0xA2,0x4E,0x00,0x3D,0x9E,0x44,0x10,0xFB,0xFF,0x4E,0x00,0x3D,0x9C,0x4E,0x00, +0x3D,0xA2,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,0x34,0x02,0x10,0x00,0x1E,0xEA,0xB2,0xEA,0x34,0x84,0x20, +0xEA,0x79,0xEA,0x60,0xEB,0x31,0xEA,0xE1,0xEA,0x3C,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,0x5A,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,0x5A,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,0x11,0x44,0x10,0xFF,0xDF,0x4E,0x00,0x3D,0x1B, +0x44,0x10,0xFE,0xFF,0x4E,0x00,0x3D,0x17,0x4E,0x00,0x3D,0x13,0x44,0x10,0xFB,0xFF, +0xFE,0x56,0xEA,0x34,0x51,0xC0,0x00,0x38,0xB9,0x7F,0x2E,0x20,0x00,0x77,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,0x79,0xB4,0x5C,0x46,0x1F,0xFE,0x3F,0xEA,0x81, +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,0x4F,0x49,0xFF,0xFC,0xE8, +0xDD,0x47,0xDD,0x40,0xEA,0x27,0xC0,0x02,0x84,0x01,0x10,0x00,0x80,0x68,0x10,0x00, +0x80,0x6C,0xFC,0x81,0xFC,0x00,0x84,0x07,0xDD,0x40,0xC0,0x1F,0xDD,0x4D,0x5A,0x00, +0x07,0x05,0x66,0x10,0x00,0x02,0xC9,0x04,0x49,0xFF,0xFD,0xC5,0xD5,0x1C,0x2E,0x10, +0x00,0x97,0xEA,0x5C,0xC1,0x0C,0x5A,0x00,0x06,0x0B,0xDD,0x43,0x84,0x26,0xEB,0x34, +0x84,0x20,0xEB,0x36,0x44,0x1F,0xFC,0x78,0x4E,0x00,0x41,0x1F,0x44,0x00,0x24,0x24, +0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x07,0x84,0x08,0xDD,0x40,0xC0,0x03,0xF9,0x85, +0xD5,0x02,0xF9,0x49,0xFC,0x80,0xEA,0x30,0x96,0x04,0xC0,0x09,0xFC,0x00,0x49,0x00, +0x34,0xBD,0xC8,0xFE,0x49,0x00,0x34,0x9F,0xC8,0xFE,0xFC,0x80,0xDD,0x9E,0xFC,0x00, +0xFA,0x13,0xDD,0x40,0xC0,0x0F,0xEB,0x52,0x58,0x00,0x04,0x74,0x3C,0x0F,0xFF,0x7E, +0x84,0x21,0x84,0x08,0xEA,0x3D,0x84,0x01,0xEB,0x10,0xEA,0xCF,0x84,0x00,0xEB,0x2C, +0xD5,0x0B,0xFA,0x18,0xDD,0x40,0xC8,0xF0,0xEB,0x65,0xEB,0x48,0x3C,0x0F,0xFF,0x7E, +0x84,0x07,0x84,0x21,0xEA,0x3D,0xFC,0x80,0xEA,0x30,0x96,0x04,0xC0,0x09,0xFC,0x00, +0x49,0x00,0x34,0x82,0xC8,0xFE,0x49,0x00,0x34,0x88,0xC8,0xFE,0xFC,0x80,0xDD,0x9E, +0xFC,0x00,0xEA,0x4C,0xA6,0x0B,0x58,0x00,0x00,0x10,0xAE,0x0B,0x4E,0x00,0x04,0xBF, +0x46,0x11,0x00,0x07,0xEA,0x6F,0xF8,0xBF,0xFC,0x80,0xFC,0x00,0x80,0xC0,0xFA,0x08, +0xDD,0x40,0xC0,0x0D,0xEA,0x30,0xEA,0x8D,0xC0,0x0A,0x40,0x03,0x10,0x09,0xEA,0x27, +0x12,0x00,0x82,0xB8,0x50,0x00,0x00,0x64,0x12,0x00,0x80,0xB6,0xFA,0x11,0xDD,0x40, +0xC0,0x0C,0xEA,0x30,0xEA,0x8D,0xC0,0x09,0x92,0xC1,0xDD,0x43,0x12,0x60,0x02,0xB8, +0x50,0x63,0x00,0x64,0x12,0x60,0x00,0xB6,0xFC,0x80,0xFC,0x00,0xEB,0x7C,0x58,0x10, +0x86,0x58,0xEA,0xB1,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0xFA,0x07,0xDD,0x40,0xC0,0x05,0xEA,0x59,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,0x55,0xEA,0xAD,0xEB,0x5B,0xEA,0x91, +0xEB,0x3D,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x1D, +0xEB,0x49,0xD5,0x11,0xFA,0x0B,0xDD,0x40,0xC0,0x08,0xEA,0x59,0x44,0x00,0x51,0x61, +0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x11,0xFA,0x0C,0xDD,0x40,0xC0,0x06,0xB8,0x00, +0x5A,0x08,0x07,0x0C,0xEA,0x50,0xD5,0x09,0xFA,0x0D,0xDD,0x40,0xC0,0xFC,0xB8,0x00, +0x5A,0x08,0x07,0x04,0x49,0xFF,0xFF,0xBB,0xFC,0x80,0xFC,0x00,0xEB,0x7C,0x58,0x10, +0x86,0x58,0xEA,0x5B,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0xFA,0x0F,0xDD,0x40,0xC0,0x05,0xEA,0x59,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,0xC8,0xEB,0x52,0xEA,0xFC, +0xEB,0x5B,0xEA,0x91,0xEB,0x3D,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x03,0x8C,0x01, +0xB8,0x88,0xBD,0x08,0xD9,0x1D,0xEB,0x49,0xD5,0x11,0xFA,0x14,0xDD,0x40,0xC0,0x08, +0xEA,0x59,0x44,0x00,0x52,0x62,0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x11,0xFA,0x16, +0xDD,0x40,0xC0,0x06,0xB8,0x00,0x5A,0x08,0x08,0x0C,0xEA,0x50,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,0x6F,0x49,0xFF,0xFF,0x01,0xF8,0x46,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0xFA,0x1D,0xDD,0x40,0xC0,0x0B,0xEA,0x30,0x96,0x04,0xC0,0x02,0xEA,0x59, +0x44,0x00,0xBF,0xBF,0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x30,0xFA,0x1E,0xDD,0x40, +0xC0,0x2C,0xEA,0x30,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,0x58,0xEA,0x68, +0x46,0x31,0x00,0x02,0x58,0x31,0x86,0x58,0x49,0xFF,0xFA,0x7F,0x84,0x00,0x44,0x10, +0x02,0x88,0xEB,0x58,0xEA,0x68,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,0x30,0x96,0x04,0xC0,0x02,0xEB,0x49,0xEA,0x50,0xFC,0x80,0xFC,0x00,0x84,0x0E, +0xDD,0x40,0xC0,0x03,0xEA,0x50,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,0x56,0x66,0x00,0x00,0x08,0x3E,0x07,0xFF,0x5A,0x84,0x00, +0xEB,0x10,0x84,0x00,0x3C,0x0F,0xFF,0x7B,0x49,0xFF,0xFA,0x67,0xEB,0x62,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,0x4C,0x96,0x04,0xC0,0x16,0xEA,0x36,0xC0,0x07, +0x2E,0x07,0xFE,0x31,0x2E,0x17,0xFF,0xA9,0xE2,0x01,0xE9,0x05,0x84,0x00,0x3E,0x07, +0xFE,0x31,0xD5,0x0C,0x8C,0x01,0x3E,0x07,0xFE,0x31,0x2E,0x07,0xFE,0x30,0x8C,0x01, +0x3E,0x07,0xFE,0x30,0xD5,0x03,0x84,0x02,0xEA,0x6B,0xFC,0x80,0xFC,0x40,0xEA,0x23, +0x84,0x24,0x9D,0x82,0x8E,0x01,0xEA,0xDF,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,0xFC,0xD2,0xFC,0xC0, +0xFC,0x60,0x80,0xC0,0x3C,0xCD,0xFF,0x81,0x2E,0x87,0xFC,0xE0,0x3C,0x9D,0xFF,0x70, +0xEA,0x4E,0xEA,0xED,0x3C,0x0D,0xFF,0x78,0xC0,0x04,0x00,0x73,0x00,0x92,0xC7,0x03, +0x2E,0x77,0xFD,0x20,0x85,0x60,0x81,0xA6,0x81,0xCB,0xEA,0x23,0x40,0xF7,0x00,0x06, +0xE8,0x33,0xEA,0xF8,0xEA,0xA5,0xC0,0x0B,0x04,0x16,0x80,0x01,0x96,0x09,0xEA,0xB0, +0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0xB4,0x2D,0xD5,0x0A,0xB4,0x2D,0x96,0x09, +0xEA,0xB0,0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0x04,0x16,0x80,0x01,0x96,0x09, +0xEA,0xB0,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,0xCB,0x00,0x03,0x00,0x20,0x00,0x23,0x00,0x14,0x00,0x13, +0x00,0x08,0xEA,0xE9,0x40,0x00,0x09,0x00,0x88,0x01,0x00,0x13,0x00,0x2C,0xEA,0x8A, +0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x23,0xE6,0x05,0xE9,0x11,0x00,0x03,0x00,0x50, +0x00,0x23,0x00,0x44,0x00,0x13,0x00,0x38,0xEA,0xE9,0x40,0x00,0x09,0x00,0x88,0x01, +0x00,0x13,0x00,0x5C,0xEA,0x8A,0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x23,0xE6,0x09, +0xE9,0x0A,0x00,0x13,0x00,0x74,0x00,0x03,0x00,0x68,0x40,0x00,0x05,0x00,0xDD,0x4A, +0x84,0x0A,0xDD,0x50,0xEB,0x39,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,0x57,0xEA,0x8D,0xC0,0x15,0xEA,0xE5,0xEA,0x29,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,0x16, +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,0x6C,0x5A,0x08, +0x01,0x04,0x49,0x00,0x2C,0x96,0x49,0x00,0x2C,0x8F,0x80,0xC0,0xEA,0x6C,0xC0,0x07, +0xEA,0x6C,0x5A,0x08,0x01,0x0A,0xEA,0x69,0x5A,0x08,0x01,0x07,0x3C,0x03,0xFE,0x9F, +0x8C,0x01,0x3C,0x0B,0xFE,0x9F,0xEA,0x9E,0xC8,0x1B,0xEA,0x6C,0xC0,0x07,0xEA,0x6C, +0x5A,0x08,0x01,0x17,0xEA,0x69,0x5A,0x08,0x01,0x14,0x84,0x01,0x3E,0x07,0xFC,0xBF, +0x49,0xFF,0xFE,0xEA,0xEA,0x36,0xC8,0x0C,0xEA,0xF0,0xC0,0x05,0x80,0x06,0x49,0xFF, +0xFF,0x21,0xD5,0x05,0x2E,0x07,0xFE,0x32,0xC0,0x03,0xEA,0x95,0xEA,0xC2,0xEA,0xF0, +0x3E,0x07,0xFE,0x32,0xFC,0x80,0xFC,0x40,0x3F,0xCF,0xFD,0x90,0x80,0xC0,0x49,0xFF, +0xFE,0xD3,0xEA,0x36,0x81,0x20,0x49,0x00,0x3D,0x51,0x4E,0x02,0x00,0xF3,0x5C,0x94, +0x80,0x01,0x4E,0x92,0x00,0x07,0x2E,0x07,0xFC,0xD2,0xC0,0x03,0xEA,0x95,0xEA,0xFB, +0xBA,0x00,0x9E,0x17,0xE6,0x02,0xEA,0x87,0xE8,0x08,0xC9,0x07,0x5A,0x20,0x07,0x03, +0xEA,0xFB,0x49,0x00,0x18,0xCD,0xEA,0xFB,0x4E,0x12,0x00,0x50,0x84,0x3F,0x3E,0x17, +0xFD,0xDC,0x2E,0x17,0xFC,0xC2,0xC9,0x49,0x4E,0x92,0x00,0x48,0xDD,0x4C,0x96,0x04, +0xC8,0x02,0xEA,0x6B,0x2E,0x07,0xFC,0xC0,0x44,0x10,0xA5,0x5A,0xEB,0x4B,0xEA,0x87, +0xEA,0x8A,0xDD,0x4A,0x2E,0x67,0xFC,0xC0,0x44,0x2F,0xA5,0x5A,0x44,0x10,0x00,0x3D, +0x88,0x46,0xEA,0x9E,0xFF,0x8C,0x40,0x21,0x01,0x00,0x8C,0xC2,0xEB,0x82,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,0xFC,0xC0,0x8C,0x01,0x96,0x00,0xEA,0xD9,0x2E,0x17,0xFC,0xC9,0xE2,0x01, +0xE9,0x21,0x84,0x00,0xEA,0xD9,0xD5,0x1E,0x00,0x23,0x00,0x92,0x4E,0x23,0x00,0x7A, +0xEA,0xCB,0xEA,0x5C,0xC1,0x09,0x2E,0x57,0xFD,0x1D,0x2E,0x17,0xFD,0x16,0xD1,0x04, +0xE6,0x02,0x4E,0xF2,0x00,0x6F,0xEA,0x69,0xC8,0x0D,0xB8,0x14,0xC8,0x04,0x2E,0x07, +0xFC,0xC2,0xC0,0x08,0x4E,0x92,0x00,0x04,0xEA,0x95,0xD5,0x04,0x84,0x01,0x3E,0x07, +0xFC,0xD2,0x2E,0x07,0xFC,0xC2,0x4E,0x02,0x00,0x6D,0x4E,0x92,0x00,0x6B,0xDD,0x4C, +0x96,0x04,0xC8,0x02,0xEA,0x6B,0x2E,0x07,0xFC,0xC1,0x8C,0x01,0x96,0x00,0x3E,0x07, +0xFC,0xC1,0x2E,0x17,0xFC,0xC4,0xE2,0x20,0xE8,0x04,0x84,0x01,0x3E,0x07,0xFC,0xC1, +0x2E,0x07,0xFC,0xC1,0x2E,0x77,0xFC,0xC8,0x9E,0x41,0x92,0xE1,0xFF,0xCC,0xEB,0x5B, +0xEB,0x33,0x40,0x70,0x9C,0x20,0x2E,0x17,0xFC,0xEC,0xC1,0x11,0x44,0x10,0xA3,0x3A, +0xEB,0x4B,0xEA,0x87,0xEA,0x8A,0xDD,0x4A,0x2E,0x17,0xFC,0xC1,0x44,0x0F,0xA3,0x3A, +0x88,0x01,0xEA,0x87,0x40,0x00,0x05,0x00,0x96,0x01,0xD5,0x07,0x46,0x00,0x40,0x30, +0x50,0x00,0x02,0x01,0xDD,0x4A,0x84,0x0A,0x2E,0x27,0xFC,0xC8,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,0xFC,0xC8,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,0x69,0x4E,0x03,0xFF,0x9C,0xB8,0x14, +0xC0,0x03,0x4E,0x22,0xFF,0x93,0x80,0x06,0x49,0xFF,0xFE,0x1C,0x48,0xFF,0xFF,0x93, +0xFC,0xC0,0xFC,0x20,0x80,0xE0,0x80,0xC1,0x49,0x00,0x28,0x2E,0xDD,0x4D,0x84,0x20, +0x49,0x00,0x2A,0x20,0xEA,0x7A,0x3E,0x20,0x00,0xE1,0x84,0x00,0xEA,0xF1,0x3E,0x07, +0xFC,0xCC,0xEB,0x5B,0x10,0x00,0x86,0x01,0xFA,0x00,0x3E,0x07,0xFC,0xBB,0xFA,0x14, +0xFA,0x30,0x49,0x00,0x3B,0x85,0xEB,0x39,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,0xFC,0xC8,0x2E,0x40,0x00,0xE1,0x2E,0x30, +0x00,0xE0,0x2E,0x10,0x00,0xE9,0x42,0x12,0x0C,0x73,0x92,0x41,0x40,0x20,0x88,0x17, +0x96,0x90,0xC0,0x02,0x8C,0x41,0x3E,0x27,0xFC,0xC4,0x44,0x20,0x00,0x3D,0x40,0x20, +0x88,0x37,0x96,0x90,0xC1,0x02,0x8C,0x41,0x3E,0x27,0xFC,0xC9,0x84,0x00,0xEA,0xD9, +0x2E,0x17,0xFF,0x67,0x3E,0x17,0xFC,0xD4,0x3E,0x07,0xFC,0xD2,0x2E,0x07,0xFF,0xCE, +0x2E,0x27,0xFF,0xCF,0x40,0x21,0x01,0x04,0x3C,0x2E,0x00,0x36,0x2E,0x07,0xFF,0xD0, +0x2E,0x17,0xFF,0xD1,0x40,0x10,0x81,0x04,0x3C,0x1E,0x00,0x37,0x40,0x21,0x0C,0x57, +0x40,0x10,0x90,0x37,0x3E,0x20,0x00,0xEA,0x3E,0x10,0x00,0xEB,0x8C,0x82,0x3E,0x47, +0xFC,0xCE,0x8C,0x62,0x3E,0x37,0xFC,0xBD,0x84,0x00,0x3C,0x0B,0xFE,0x9D,0xCF,0x21, +0xEB,0x62,0x14,0x70,0x03,0xF1,0xDD,0x4C,0x96,0x04,0xC0,0x05,0x84,0x01,0xEA,0xD0, +0x84,0x02,0xEA,0x6B,0xEB,0x62,0x58,0x00,0x0F,0x44,0x84,0x20,0x44,0x20,0x00,0x3C, +0xDD,0x42,0xCE,0x08,0xEB,0x62,0x58,0x00,0x03,0xB0,0x80,0x26,0x44,0x20,0x00,0x3C, +0xDD,0x42,0xEB,0x62,0x58,0x00,0x0F,0x80,0x84,0x20,0x44,0x20,0x00,0x40,0xDD,0x42, +0x46,0x19,0x00,0x08,0xA4,0x08,0x96,0x01,0x3C,0x0B,0xFE,0x9A,0x92,0x01,0x3C,0x0B, +0xFE,0x9B,0xA4,0x0A,0x3C,0x0B,0xFE,0x99,0x49,0x00,0x05,0x0C,0x84,0x1F,0x3E,0x07, +0xFD,0xDC,0x84,0x00,0xEB,0x0A,0x3E,0x07,0xFC,0xC3,0x84,0x00,0x3C,0x0B,0xFE,0x9F, +0xFC,0xA0,0xFC,0x61,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01, +0xDD,0x57,0xEA,0x37,0xDD,0x45,0x46,0x01,0x00,0x07,0x04,0x50,0x03,0xF0,0x44,0x00, +0xA1,0x1A,0x92,0xB0,0xD8,0x03,0x49,0x00,0x30,0x5A,0x49,0x00,0x3C,0x05,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0xEB,0x02,0xDD,0x45, +0x49,0x00,0x35,0x84,0xC8,0xFE,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07, +0x96,0x01,0xDD,0x57,0x58,0x00,0x00,0x03,0xDD,0x45,0x49,0x00,0x3C,0x2F,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,0x57,0xEB,0x04,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,0x57, +0x58,0x00,0x00,0x05,0xDD,0x45,0x84,0x01,0x44,0x10,0x01,0xE0,0x84,0x45,0x44,0x30, +0x02,0x58,0x49,0x00,0x34,0xFB,0x80,0xC0,0xC8,0xF7,0x84,0x45,0x84,0x01,0x44,0x10, +0x00,0x80,0x49,0x00,0x35,0x30,0x46,0x01,0x00,0x07,0xEA,0xB8,0x96,0x49,0xEA,0x6E, +0x58,0x10,0x80,0x06,0xEA,0x7E,0x49,0xFF,0xF4,0xFE,0x49,0xFF,0xF5,0x48,0x4E,0x00, +0x33,0xE5,0x80,0x06,0xEA,0x5C,0xEA,0xBA,0x84,0x21,0xEB,0x82,0x12,0x60,0x00,0x00, +0x80,0x41,0x44,0x00,0x00,0xE7,0xEA,0x3B,0x96,0x01,0x46,0x11,0x00,0x07,0x12,0x00, +0x87,0xAF,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57, +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,0x62,0x4E,0x00,0x33,0x7B,0xD8,0x08,0xEA,0x21,0xEA,0x20,0x83,0xFF, +0x46,0x11,0x00,0x07,0xEA,0x6F,0xD5,0x03,0x49,0xFF,0xF3,0x24,0x49,0x00,0x3C,0x1D, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0x58,0x00, +0x00,0x08,0xDD,0x45,0x84,0x00,0xDD,0x58,0x84,0xC0,0x3C,0x6F,0xFF,0x6A,0x46,0x01, +0x00,0x07,0xEA,0xB8,0x84,0x41,0x96,0x49,0xEA,0x6E,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,0x7E,0x3A,0x0F,0x84,0x00,0x49,0x00,0x2F,0xB2,0x80,0x06,0x84,0x26, +0x49,0x00,0x3A,0xD9,0x46,0x00,0x0E,0xD0,0x46,0x10,0x20,0x0C,0x50,0x00,0x00,0x40, +0x8C,0x26,0x49,0x00,0x3A,0xCB,0x46,0x09,0x00,0x20,0xB4,0x20,0x66,0x10,0x80,0x40, +0xB6,0x20,0xEA,0xCB,0xEA,0x8E,0xC1,0x05,0xA0,0x41,0x58,0x10,0x80,0x08,0xA8,0x41, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,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,0xCA,0x8C,0x05,0x46,0x11, +0x00,0x07,0x14,0x00,0x83,0xF9,0xEA,0x42,0x4E,0x02,0x00,0xC7,0xEA,0xB5,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0x58,0x00,0x00,0x0B, +0xDD,0x45,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x84,0x00,0xDD,0x58,0xD5,0x0C,0xFA,0x02, +0xDD,0x40,0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40,0xC8,0xF5, +0x49,0xFF,0xED,0xC9,0x49,0x00,0x02,0xD2,0xC8,0x1E,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0x58,0x00,0x00,0x0C,0xDD,0x45,0x84,0x0E, +0xDD,0x40,0xC0,0x04,0x49,0xFF,0xF4,0xE2,0xF8,0x0C,0xFA,0x02,0xDD,0x40,0xC8,0xFB, +0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40,0xC8,0xF5,0x49,0x00,0x02,0x0A, +0x48,0x00,0x00,0x83,0x84,0x00,0x3E,0x07,0xFC,0xB8,0x3E,0x07,0xFC,0xBF,0x46,0x01, +0x00,0x07,0xEA,0xB8,0x96,0x49,0xEA,0x6E,0x58,0x10,0x80,0x0D,0xEA,0x7E,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,0x4D,0x5A,0x00,0x08,0x15,0x5A,0x00,0x06,0x13, +0xDD,0x54,0x5A,0x08,0x01,0x06,0xF8,0x4C,0xC8,0x03,0x49,0x00,0x29,0xC2,0xEB,0x40, +0xC8,0x0D,0x49,0x00,0x11,0xE6,0x49,0x00,0x2A,0xF3,0x49,0x00,0x28,0x25,0x80,0xC0, +0xD5,0x05,0x49,0x00,0x25,0xBB,0x49,0x00,0x25,0x97,0xEB,0x40,0xC8,0x03,0x49,0x00, +0x02,0x49,0x49,0xFF,0xFB,0x65,0x49,0xFF,0xED,0xA9,0x84,0x01,0x3E,0x07,0xFC,0xB8, +0x80,0x06,0x49,0xFF,0xFC,0xD2,0xEA,0xF0,0x49,0x00,0x29,0x49,0xEA,0x69,0xC8,0x02, +0xEA,0xC2,0x49,0x00,0x01,0xA0,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,0x76,0x5A,0x08,0x01,0x18,0xEB,0x40,0xC8,0x13,0xEB,0x13, +0x5A,0x08,0x01,0x09,0x00,0x05,0x00,0x00,0x96,0x04,0xC8,0x04,0x49,0x00,0x25,0x00, +0xD5,0x07,0x00,0x05,0x00,0x00,0x96,0x0E,0xC8,0x03,0x49,0x00,0x24,0xB0,0x49,0x00, +0x25,0xBD,0x49,0x00,0x2A,0x5B,0x46,0x01,0x00,0x07,0xEA,0xB8,0x96,0x49,0xEA,0x6E, +0x58,0x10,0x80,0x0E,0xEA,0x7E,0xDD,0x4D,0x5A,0x08,0x07,0x07,0x00,0x53,0x83,0x40, +0xEA,0x64,0xD8,0x19,0xD5,0x0C,0x5A,0x08,0x08,0x17,0x00,0x53,0x83,0x40,0xEA,0x9D, +0xD8,0x12,0x00,0x05,0x80,0x00,0xC8,0xFE,0x49,0x00,0x34,0x0A,0x49,0x00,0x34,0xC5, +0x46,0x01,0x00,0x07,0xEA,0x62,0x4C,0x54,0xC0,0x07,0x84,0x21,0xDD,0x4D,0xEA,0x3D, +0x84,0x00,0xEB,0x0A,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,0xFC,0xC5,0x49,0x00,0x2F,0x0F,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,0x7D,0xFC,0x80,0xFC,0x20, +0x3F,0xCF,0xFD,0x90,0xB8,0x00,0x5A,0x00,0x08,0x05,0x84,0xC3,0x5A,0x08,0x06,0x03, +0x84,0xC1,0xB9,0x19,0x2E,0x27,0xFC,0xE7,0x2E,0x07,0xFC,0xF8,0x88,0x02,0xE2,0x20, +0x4E,0xF2,0x00,0x5B,0xB9,0x19,0xC9,0x05,0xEB,0x4F,0xEA,0x61,0xDD,0x4F,0xDD,0x42, +0xB9,0x19,0x2E,0x07,0xFC,0xE7,0x84,0x80,0xE2,0x20,0xE8,0x2D,0x2E,0x37,0xFF,0x61, +0x2E,0x07,0xFF,0x97,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,0xFC,0xE7,0x2E,0x07,0xFC,0xF8, +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,0xFC,0xDA,0x2E,0x10,0x00,0x28,0xE2,0x20,0xE8,0x05,0x84,0x01,0xB8,0x90, +0x84,0x00,0xD5,0x11,0x2E,0x2F,0xFF,0x5B,0x4E,0x24,0x00,0x10,0x3C,0x33,0xFE,0xBF, +0xBA,0x26,0xE2,0x62,0xE9,0x0A,0x3C,0x33,0xFE,0xC4,0xBA,0x25,0xE2,0x62,0xE9,0x05, +0xC1,0x04,0x8C,0x01,0x3E,0x07,0xFC,0xDA,0xFC,0xA0,0x00,0x00,0xFC,0x20,0x3C,0x1D, +0xFF,0x7E,0xEA,0x40,0x2E,0x37,0xFD,0x1C,0xE2,0x03,0xE8,0x48,0xEA,0xD4,0x5A,0x08, +0x01,0x2C,0x2E,0x57,0xFD,0x00,0x9E,0x19,0xD8,0x27,0x2E,0x77,0xFF,0xC2,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,0xFC,0xE8,0xD5,0x03,0x8C,0xA2,0xDE,0xEA,0xEA,0xD4,0x5A,0x08,0x01,0x05, +0x3E,0x37,0xFC,0xFD,0xD5,0x1D,0xEA,0xD4,0xC8,0x1B,0xDD,0x4D,0x8E,0x02,0xE6,0x07, +0xE8,0x17,0x3E,0xFF,0x79,0x70,0x38,0x07,0x80,0x00,0xEA,0xAF,0x4A,0x00,0x3C,0x00, +0x08,0x1E,0x1E,0x1E,0x0C,0x08,0x0C,0x00,0xEA,0xB1,0xD5,0x02,0xEA,0x5B,0x46,0x21, +0x00,0x03,0x58,0x21,0x00,0x78,0xDD,0x48,0xD5,0x03,0x49,0xFF,0xFF,0x02,0xFC,0xA0, +0x92,0x00,0xFC,0x00,0xEB,0x25,0xC0,0x1C,0x2E,0x07,0xFD,0x05,0x2E,0x17,0xFF,0x96, +0xE2,0x01,0xE9,0x10,0x84,0x00,0x3E,0x07,0xFC,0xF3,0x84,0x20,0x3C,0x1F,0xFF,0x7D, +0x2E,0x07,0xFC,0xFF,0x3E,0x07,0xFC,0xE7,0xEB,0x4F,0xEA,0x61,0xDD,0x4F,0xDD,0x42, +0xD5,0x07,0x3C,0x1D,0xFF,0x75,0xC9,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x05,0xFC,0x80, +0xFC,0x00,0x3F,0xCF,0xFD,0x90,0x2E,0x17,0xFD,0x00,0x2E,0x07,0xFC,0xFD,0xE2,0x20, +0xE9,0x05,0x84,0x01,0xEA,0xBB,0x84,0x0A,0xD5,0x03,0x84,0x00,0xEA,0xBB,0x3E,0x07, +0xFC,0xF8,0x2E,0x07,0xFC,0xEC,0xC0,0x2A,0x84,0x01,0xEB,0x16,0x84,0x01,0x3E,0x07, +0xFC,0xE8,0x84,0x02,0xEA,0xF9,0xBE,0x00,0x5A,0x68,0x02,0x18,0x2E,0x07,0xFD,0x17, +0x5A,0x08,0x01,0x14,0xEA,0x29,0xE6,0x01,0x3E,0xF7,0xFD,0x31,0x80,0x06,0x80,0x26, +0xEA,0x3D,0x3E,0x67,0xFD,0x17,0xEA,0x29,0xC0,0x04,0xEB,0x65,0xDD,0x5C,0xD5,0x03, +0xEB,0x65,0xEA,0xB4,0xB8,0x9A,0xD5,0x2B,0x84,0x00,0x3E,0x07,0xFD,0x11,0x2E,0x07, +0xFC,0xFB,0x8C,0x01,0x3E,0x07,0xFC,0xFB,0xD5,0x08,0x49,0xFF,0xFF,0x51,0x2E,0x07, +0xFD,0x11,0x8C,0x01,0x3E,0x07,0xFD,0x11,0xEB,0x82,0x02,0x50,0x03,0x01,0xEB,0x03, +0xD0,0x09,0x2E,0x0F,0xFF,0x5A,0x4E,0x04,0x00,0x06,0xB8,0x00,0x8E,0x07,0xE6,0x02, +0xE8,0x06,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC7,0xD5,0x09,0xEB,0x82,0x00,0x00, +0x06,0x01,0xEB,0x5B,0x8C,0x01,0x96,0x00,0x10,0x00,0x86,0x01,0xFC,0x80,0xFC,0x20, +0x3C,0x7D,0xFF,0x7E,0x84,0xA0,0xEB,0x1C,0xEB,0x27,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,0x74,0xFC,0xA0, +0xFC,0x00,0x3F,0xCF,0xFD,0x90,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05, +0xEB,0x4F,0xEA,0xA8,0xD5,0x04,0xB8,0x11,0xC8,0x04,0xEA,0x97,0xE6,0x01,0xD5,0x02, +0x85,0xE0,0x3E,0xF7,0xFD,0x08,0xEA,0x56,0xEA,0xA5,0xC0,0x0F,0x2E,0x07,0xFD,0x08, +0xC0,0x0C,0xB8,0x10,0x5A,0x00,0x02,0x0A,0x49,0xFF,0xFE,0x4B,0x84,0x00,0x3E,0x07, +0xFC,0xE5,0x84,0x00,0xEA,0x51,0xD5,0x10,0x84,0xC0,0xBE,0x99,0x80,0x26,0xEB,0x4F, +0xEA,0x61,0xDD,0x4F,0xDD,0x42,0xB8,0x10,0x5A,0x08,0x02,0x05,0x49,0xFF,0xFF,0xB9, +0xD5,0x03,0x3E,0x67,0xFC,0xDA,0xFC,0x80,0x2E,0x07,0xFC,0xEC,0xDD,0x9E,0xFC,0x60, +0x3D,0x3C,0x00,0x37,0x2E,0x90,0x00,0x42,0x2E,0x47,0xFF,0x5D,0x92,0x84,0x3C,0x2C, +0x00,0x36,0x4E,0x42,0x00,0xF1,0x3F,0x18,0x02,0x14,0x38,0x38,0x80,0x00,0x5A,0x38, +0x01,0x13,0xEA,0xC4,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,0xC4,0x42,0x30,0x10,0x24,0xEA,0x8C,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,0x1F,0xCC,0x71,0xEA,0x8C,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,0x14,0x38,0x00,0x80,0x00,0xDD,0x9E, +0xFC,0x20,0x3F,0xCF,0xFD,0xB8,0x3E,0x68,0x00,0xF8,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,0x33,0xB9,0x81,0xA6,0x42, +0xA6,0x83,0xEA,0x33,0xB9,0x8E,0xA6,0x45,0xA6,0x86,0xEA,0x33,0xB9,0x80,0xA6,0x47, +0xEB,0x0F,0xEA,0x33,0xB9,0x94,0x00,0x10,0x00,0x0A,0x00,0x20,0x00,0x0B,0xEA,0x33, +0xB9,0x96,0x00,0x10,0x00,0x0C,0x00,0x20,0x00,0x0D,0xEA,0x33,0xB9,0x97,0x00,0x10, +0x00,0x0F,0x00,0x20,0x00,0x10,0xEA,0x33,0xB9,0x8C,0x00,0x10,0x00,0x11,0x00,0x00, +0x00,0x12,0x40,0x00,0x05,0x04,0xB8,0x85,0x3C,0x7B,0xFE,0xB6,0x84,0x20,0x3E,0x08, +0x02,0x5C,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,0x75,0x84,0x28,0x3E,0x08,0x01,0xB4,0xEA,0x8C,0xEB,0x0F,0xC2,0x08,0xCB,0x04, +0x10,0x30,0x00,0x08,0xD5,0x04,0x8E,0x41,0x10,0x20,0x00,0x08,0xEB,0x0F,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,0xB4,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,0xEC,0xEA,0xFD,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,0xB4,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,0x25,0xC1,0x04,0x84,0x21, +0x84,0xA2,0xD5,0x03,0x84,0x22,0x84,0xA1,0x3E,0x48,0x00,0xF8,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,0xB0,0x3C,0x0B,0xFE,0xBC, +0x3C,0x0B,0xFE,0xBA,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,0x25,0x44,0x00,0x00,0x96,0x3C,0x0B, +0xFE,0xB9,0x44,0x00,0x00,0x32,0x3C,0x0B,0xFE,0xBB,0x3C,0x6B,0xFE,0xB4,0x3C,0x5B, +0xFE,0xB8,0x3C,0x4B,0xFE,0xAF,0x3C,0x3B,0xFE,0xB7,0x46,0x01,0x00,0x07,0x00,0x00, +0x02,0x82,0x3C,0x0B,0xFE,0xB1,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x83,0x94,0x01, +0x3C,0x0B,0xFE,0xB3,0x3C,0x2B,0xFE,0xB5,0x84,0x00,0xD5,0x21,0x84,0x21,0x3E,0x17, +0xFD,0x25,0x44,0x10,0x00,0x32,0x3C,0x1B,0xFE,0xB9,0x3C,0x1B,0xFE,0xBB,0x3C,0x6B, +0xFE,0xB4,0x3C,0x5B,0xFE,0xB8,0x3C,0x4B,0xFE,0xAF,0x3C,0x3B,0xFE,0xB7,0x46,0x11, +0x00,0x07,0x00,0x10,0x82,0x84,0x3C,0x1B,0xFE,0xB1,0x46,0x11,0x00,0x07,0x00,0x10, +0x82,0x85,0x94,0x49,0x3C,0x1B,0xFE,0xB3,0x3C,0x2B,0xFE,0xB5,0x3C,0x0B,0xFE,0xB2, +0xFC,0xA0,0xFC,0x01,0x3F,0xC8,0x00,0xD8,0x46,0x21,0x00,0x07,0x04,0x51,0x03,0xCF, +0x46,0x3A,0x11,0xAA,0xEA,0x38,0x50,0x31,0x81,0x1A,0x80,0x20,0x3C,0x23,0xFE,0xB3, +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,0xB1,0xE2,0x20,0xE8,0x0A,0xD5,0x0E,0xE2,0x02,0xE9,0x05, +0xBB,0x01,0x9A,0x9A,0xE2,0x40,0xE8,0x0A,0x3C,0x03,0xFE,0xB1,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,0xB6,0x40,0x20,0x1C,0x0C,0xFE,0x57, +0x3C,0x1B,0xFE,0xB6,0xD5,0x02,0x84,0x00,0xB4,0x5F,0x3E,0x18,0x02,0x44,0x38,0x20, +0x9D,0x09,0xA0,0xB1,0x3E,0x18,0x02,0x74,0x38,0x20,0x9D,0x09,0xFC,0xA1,0xEB,0x79, +0xEA,0x72,0x38,0x00,0x80,0x00,0x3E,0x18,0x01,0x84,0x40,0x10,0x80,0x40,0xA6,0x0A, +0xA6,0x4B,0x8A,0x01,0x96,0x01,0xDD,0x9E,0xEB,0x79,0xEA,0x72,0x38,0x20,0x80,0x00, +0x3E,0x18,0x01,0x84,0x40,0x00,0x88,0x40,0xA6,0x01,0x38,0x10,0x8A,0x00,0x8A,0x01, +0x96,0x01,0xDD,0x9E,0xEB,0x79,0xEA,0x72,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,0x55,0x22,0xF0,0x05,0x4C,0xF8,0x08, +0xEB,0x55,0x22,0xF0,0x05,0x70,0xF8,0x04,0xEB,0x55,0x22,0xF0,0x05,0x4D,0xDD,0x5F, +0x4E,0xF3,0x00,0x78,0x83,0xFF,0xEB,0x55,0x22,0xF0,0x05,0x71,0xD5,0x3C,0xEA,0x31, +0x9E,0x82,0xE0,0x22,0x4E,0xF3,0x00,0x6C,0x38,0x52,0x0D,0x00,0xE6,0xA2,0xE8,0x15, +0x46,0x11,0x00,0x02,0xEB,0x19,0x40,0x20,0x80,0x20,0x22,0xF1,0x0C,0xA9,0xDD,0x5F, +0xE9,0x60,0x22,0xF1,0x0C,0xCD,0xDD,0x5F,0xE9,0x5C,0x22,0xF1,0x0C,0xA8,0xDD,0x5F, +0xE9,0x58,0x22,0xF1,0x0C,0xCC,0xD5,0x1F,0xE6,0x22,0xE8,0x1F,0xEA,0x77,0x38,0x12, +0x0D,0x00,0x9F,0x42,0xE0,0x25,0xE9,0x4D,0x9E,0x41,0xEB,0x65,0x58,0x00,0x01,0x44, +0xEB,0x30,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,0x00,0xE1,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,0xAF, +0x84,0x00,0xDD,0x9E,0xFC,0x80,0xFC,0x62,0x3F,0xC8,0x00,0xD8,0xEA,0x38,0x81,0x20, +0x80,0x02,0x80,0xE2,0x81,0x41,0x49,0xFF,0xFF,0x44,0x54,0xB0,0x00,0xFF,0x80,0xC0, +0x80,0x07,0x49,0xFF,0xFF,0x4B,0x54,0xC0,0x00,0xFF,0x80,0x80,0x46,0xE1,0x00,0x01, +0x58,0xE7,0x0D,0x68,0x84,0x00,0x10,0x0F,0x80,0x0F,0xEA,0xC9,0x46,0xD1,0x00,0x01, +0x58,0xD6,0x8F,0xF4,0xEB,0x3C,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,0x9B,0x85,0x00, +0x40,0x84,0x00,0x06,0xEA,0x39,0x80,0x28,0xEA,0xC8,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,0xC9,0xEB,0x3C,0xE2,0x06, +0xE8,0x0F,0x9A,0x30,0xE6,0x03,0xE9,0x0C,0x80,0x07,0x49,0xFF,0xFF,0x0D,0xC0,0x08, +0xEA,0x39,0x80,0x27,0x80,0x4B,0x80,0x6C,0xEA,0x9B,0xC0,0x02,0x85,0x01,0xEA,0x39, +0x80,0x28,0xEA,0xC8,0x2E,0x07,0xFD,0x25,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,0x9B,0xC0,0x02,0x85,0x01,0xEA,0x39,0x80,0x28, +0xEA,0xC8,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,0xC9,0xEB,0x3C,0xE2,0x06,0xE8,0x0B,0x8A,0xC0,0xE6,0xC4,0xE9,0x08, +0xEA,0x39,0x80,0x27,0x80,0x4C,0x80,0x6B,0xEA,0x9B,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,0x00,0xF8, +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,0xBF,0x40,0x00,0x08,0x0C,0x96,0x03,0x80,0xC2,0xFE,0x47, +0x3C,0x18,0x00,0xBF,0x3C,0x10,0x00,0xBE,0x3E,0x98,0x00,0xF8,0xFE,0x0F,0x3C,0x08, +0x00,0xBE,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,0xEB,0x39,0x3C,0x83,0xFE,0xB6,0x46,0x01, +0x00,0x07,0x00,0xA0,0x02,0x7C,0xEB,0x1E,0x84,0xC0,0x40,0xC0,0x28,0x01,0xEA,0xA4, +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,0x55,0xC0,0x0B,0x3A,0x04,0x84,0x00,0xB4,0x5F, +0x49,0xFF,0xFD,0x20,0xC0,0x05,0x3E,0x0F,0xFD,0x6C,0xB4,0x3F,0xEA,0x41,0x80,0x06, +0xFC,0xE2,0xFC,0x63,0x3F,0xCF,0xFD,0xB8,0xEA,0xC5,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,0x9F,0x44,0xD0,0xFF,0xFF,0x49,0xFF,0xFD,0x26,0x3E,0x78,0x00,0xF8, +0x50,0xAF,0x80,0x10,0x46,0xE1,0x00,0x01,0x58,0xE7,0x0D,0x08,0xEA,0x23,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,0x44,0x80,0x29,0xDD,0x55,0xC0,0x1F, +0xEA,0xB6,0x80,0x29,0xDD,0x55,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,0x6A,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,0x6A, +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,0x45, +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,0x80,0xEB,0x43,0x80,0x29,0x3E,0x08, +0x01,0x82,0xEB,0x43,0x80,0x29,0x3E,0x08,0x01,0x7C,0xEA,0x41,0x80,0x29,0x3E,0x08, +0x01,0x7E,0xEA,0x41,0x3E,0x0F,0xFD,0x6C,0x80,0x29,0xEA,0x41,0x48,0x00,0x01,0x67, +0x96,0x30,0x3B,0x05,0xC4,0x00,0xF0,0x81,0x3C,0x00,0x00,0xC0,0xF1,0x01,0x3B,0x05, +0x44,0x20,0x81,0x11,0xDD,0x55,0xC0,0x1A,0x14,0x9F,0x80,0x04,0x14,0x8F,0x80,0x05, +0xEA,0x2D,0x49,0xFF,0xFC,0x48,0xC0,0x06,0xEA,0x2D,0xF2,0x01,0x84,0x61,0xEB,0x1F, +0xD5,0x0D,0xEA,0x2D,0xF2,0x01,0x49,0xFF,0xFE,0x18,0xC0,0x08,0xEA,0x2D,0xF2,0x01, +0x84,0x61,0xEB,0x1F,0xEA,0x2D,0x49,0xFF,0xFC,0x1C,0x2E,0x17,0xFD,0x25,0x46,0x01, +0x00,0x07,0x00,0x00,0x02,0x7C,0xC9,0x07,0xE2,0x09,0xE8,0x10,0xEA,0xC0,0x9A,0x08, +0xE3,0x20,0xD5,0x07,0xE2,0x08,0xE8,0x0A,0x3C,0x1C,0x00,0x37,0x9A,0x08,0xE3,0x00, +0xE8,0x05,0x3E,0x08,0x01,0x80,0xF1,0x01,0xEA,0x41,0x14,0x9F,0x80,0x04,0x14,0x8F, +0x80,0x05,0xEA,0x2D,0x49,0xFF,0xFC,0x17,0xEA,0xB6,0xF1,0x01,0xDD,0x55,0xC0,0x09, +0xEA,0x2D,0xF2,0x01,0x49,0xFF,0xFC,0x3E,0xC0,0x04,0xF0,0x01,0x49,0xFF,0xFE,0x97, +0x3C,0x00,0x00,0xC1,0xF1,0x01,0xDD,0x55,0xC0,0x44,0x3A,0x15,0x08,0x00,0xF0,0x01, +0x49,0xFF,0xFD,0x07,0xB9,0x01,0xE2,0x29,0xE8,0x08,0xB9,0x0E,0xE3,0x21,0xE8,0x05, +0x3C,0x13,0xFE,0xB4,0xE3,0x01,0xE9,0x26,0xB9,0x00,0xE2,0x29,0xE8,0x0B,0xB9,0x14, +0xE3,0x21,0xE8,0x08,0x3C,0x23,0xFE,0xB8,0x3C,0x1C,0x00,0x37,0x8A,0x22,0xE2,0x28, +0xE9,0x19,0xB9,0x16,0xE2,0x28,0xE8,0x08,0xB9,0x17,0xE3,0x01,0xE8,0x05,0x3C,0x13, +0xFE,0xAF,0xE3,0x21,0xE9,0x0F,0xB9,0x0C,0xE2,0x28,0xE8,0x0A,0xB9,0x05,0xE3,0x01, +0xE8,0x07,0x3C,0x23,0xFE,0xB7,0xEA,0xC0,0x8A,0x22,0xE2,0x29,0xE9,0x03,0x96,0x04, +0xC0,0x0C,0xEB,0x45,0xB7,0x20,0x14,0x80,0x00,0x01,0xF1,0x01,0x3E,0x08,0x01,0x7C, +0xEB,0x43,0x98,0x3E,0x84,0x20,0xEA,0x2F,0x3E,0x08,0x01,0x82,0xF1,0x01,0xEA,0x41, +0xEB,0x44,0xF1,0x01,0xDD,0x55,0xC0,0x33,0xEA,0xB6,0xF1,0x01,0xDD,0x55,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,0x45,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,0x2D,0xF2,0x01, +0x84,0x60,0xEB,0x1F,0xEB,0x44,0xF1,0x01,0xDD,0x55,0x80,0x80,0xC0,0x1A,0xF0,0x83, +0xEA,0xB6,0xF1,0x01,0xDD,0x55,0xF4,0x03,0xC8,0x14,0x3C,0x13,0xFE,0xB5,0xE3,0x01, +0xE9,0x0D,0xEA,0xA4,0x8A,0x01,0xE2,0x08,0xE9,0x09,0x3C,0x13,0xFE,0xB2,0xE3,0x21, +0xE9,0x05,0xEB,0x1E,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,0x36, +0x98,0x3B,0x40,0x28,0x94,0x01,0xA4,0x02,0x3D,0x0C,0x00,0x37,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,0x15,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xDF, +0x84,0x00,0x49,0xFF,0xFC,0x1B,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,0xBE,0x46,0x11, +0x00,0x07,0x3C,0x30,0x00,0xBF,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,0x58,0x46,0x11,0x00,0x07, +0x12,0x00,0x81,0xE4,0xFC,0xE3,0x3E,0x18,0x00,0xF8,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,0x00,0xE3,0x8C,0x04,0x84,0x80,0xEA,0xB3,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,0xEA,0xC5,0xEB,0x38,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, +0xEA,0xC5,0xEA,0x8E,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,0x70,0x5A,0x18,0x02,0x07,0x2E,0x37, +0xFD,0x0C,0x2E,0x47,0xFD,0x22,0xD5,0x05,0x2E,0x37,0xFD,0x12,0x2E,0x47,0xFC,0xD5, +0x2E,0x27,0xFD,0x03,0xC8,0x12,0x5A,0x28,0x01,0x22,0x2E,0x17,0xFE,0x34,0x8C,0x21, +0x96,0x48,0xE2,0x24,0x3E,0x17,0xFE,0x34,0xE9,0x19,0x3E,0x07,0xFD,0x03,0x3E,0x07, +0xFE,0x34,0x3E,0x07,0xFE,0x33,0xD5,0x12,0x5A,0x08,0x01,0x11,0xCA,0x0F,0x2E,0x17, +0xFE,0x33,0x8C,0x21,0x96,0x48,0xE2,0x23,0x3E,0x17,0xFE,0x33,0xE9,0x07,0x3E,0x07, +0xFD,0x03,0x3E,0x27,0xFE,0x34,0x3E,0x27,0xFE,0x33,0x2E,0x57,0xFD,0x03,0xD8,0x06, +0x84,0x00,0x3E,0x07,0xFE,0x34,0x3E,0x07,0xFE,0x33,0xDD,0x9E,0xFC,0x69,0x3F,0xCF, +0xFD,0xD4,0x2E,0x77,0xFD,0x03,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,0xAD,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,0x17,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,0x17,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,0x87,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,0xDE, +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,0xFC,0xED,0x3E,0x77,0xFD,0x02,0x3C,0x9C,0x00,0x36, +0xEA,0x31,0xF0,0x86,0x3C,0xAC,0x00,0x37,0xEA,0x77,0xF0,0x87,0x50,0x04,0xFF,0xFF, +0xF0,0x81,0x50,0x05,0x7F,0xFF,0xF0,0x82,0xEA,0xF8,0x46,0x81,0x00,0x01,0x58,0x84, +0x0D,0x98,0x96,0x44,0xEA,0x8D,0xF0,0x8A,0x2E,0x07,0xFD,0x14,0xF0,0x8B,0x2E,0x60, +0x00,0x43,0xF1,0x88,0x54,0x03,0x00,0xF0,0xF0,0x83,0x40,0x05,0x00,0x01,0xF0,0x8C, +0x95,0xB4,0x2E,0x07,0xFC,0xED,0x97,0xB0,0xF0,0x85,0x40,0x04,0x98,0x01,0xF0,0x8D, +0x2E,0x17,0xFD,0x23,0x2E,0x07,0xFD,0x02,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,0x67,0x80,0x4E,0x84,0x60,0xEA,0x67,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,0x67, +0x80,0x4E,0x84,0x60,0xEA,0x67,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,0x76,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,0x68,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,0xFC,0xED,0x00,0x1F,0x80,0x10,0x3E,0x17, +0xFD,0x02,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,0x28,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,0x00,0xE0,0xA7,0x21,0x8E,0x41,0xE6,0x82,0x96,0x90, +0x2E,0x10,0x00,0xE1,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,0xFD,0xC0,0x2E,0x07,0xFD,0x15,0xC0,0x05,0x84,0x00,0xB8,0x85, +0x48,0x00,0x00,0x83,0xBE,0x0F,0xCE,0x34,0xB9,0x05,0x8E,0x21,0xE6,0x23,0xE8,0x30, +0xDD,0x54,0x5A,0x08,0x01,0x0C,0x80,0x06,0x49,0xFF,0xFF,0xD0,0xC0,0x04,0x2E,0x07, +0xFF,0x6F,0xD5,0x06,0x2E,0x07,0xFF,0x6E,0xD5,0x03,0x2E,0x07,0xFF,0x72,0xB9,0x00, +0x5A,0x10,0x03,0x05,0xEA,0x98,0x5A,0x18,0x01,0x06,0x2E,0x17,0xFF,0x70,0x88,0x01, +0x96,0x01,0xDD,0x49,0xEA,0x82,0xC1,0x0B,0x84,0x00,0x49,0xFF,0xFF,0xB7,0x2E,0x10, +0x00,0x0C,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,0x97, +0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x2F,0xC8,0x07,0x3C,0x03,0xFE,0xAB,0x40,0x00, +0x80,0x17,0x3E,0x07,0xFC,0xFE,0xB8,0x05,0x92,0x21,0x49,0xFF,0xEA,0x05,0xB8,0x05, +0xE6,0x02,0xE9,0x3A,0xB9,0x0F,0xE2,0x20,0xE8,0x37,0x3C,0x63,0xFE,0xAE,0xEB,0x01, +0xC8,0x04,0x40,0x13,0x04,0x09,0xD5,0x03,0x94,0x71,0x96,0x49,0xEA,0x44,0xC0,0x09, +0x2E,0x07,0xFF,0x6C,0xDD,0x49,0x80,0xC0,0x2E,0x07,0xFF,0x6D,0xDD,0x49,0x80,0x20, +0xEA,0x4E,0xC0,0x0A,0x2E,0x00,0x00,0x19,0xDD,0x49,0x80,0xC0,0x2E,0x00,0x00,0x19, +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,0x18,0x5A,0x08, +0x01,0x0D,0x2E,0x07,0xFC,0xEF,0xE6,0x15,0xE9,0x05,0x84,0x00,0x3E,0x07,0xFD,0x18, +0xD5,0x04,0x8C,0x01,0x3E,0x07,0xFC,0xEF,0x3C,0x03,0xFE,0xA0,0xE6,0x1F,0x2F,0x30, +0x00,0xE3,0xE8,0x14,0x2E,0x47,0xFD,0x18,0x2E,0x37,0xFC,0xEF,0x84,0x00,0xEB,0x79, +0x58,0x10,0x8C,0xCC,0x46,0x51,0x00,0x01,0x58,0x52,0x8D,0x98,0xEA,0xB3,0x80,0xE0, +0x47,0x01,0x00,0x01,0x59,0x08,0x0D,0x74,0xD5,0x1B,0xEA,0xC3,0xC8,0xEC,0xEB,0x79, +0x58,0x10,0x8C,0x6C,0xEA,0xC6,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,0x18,0x46,0xA1,0x00,0x01,0x58,0xA5,0x0B,0xA0,0x3E,0x37,0xFC,0xEF,0xEB,0x79, +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,0xEC,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,0x00,0xEA, +0x2E,0x40,0x00,0xEB,0xFF,0x2C,0xE2,0x8F,0xE8,0x05,0x10,0x93,0x80,0x00,0x3E,0x97, +0xFD,0x18,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,0xFD,0xFC,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,0x23,0xE2,0xC0, +0xE8,0x52,0x96,0x30,0xF1,0x81,0xB6,0x7F,0x49,0xFF,0xF6,0x2F,0xB4,0x7F,0xF1,0x01, +0x5A,0x08,0x01,0x05,0x2E,0x07,0xFD,0x1F,0xEA,0x94,0xB4,0xA7,0x4C,0x54,0x40,0x1C, +0x00,0x04,0x80,0x00,0x2E,0x27,0xFD,0x1F,0xE2,0x02,0xE8,0x06,0x8C,0x01,0xEA,0x94, +0xB6,0x27,0xA8,0x79,0xD5,0x33,0x84,0x00,0x38,0x57,0x1B,0x02,0xEA,0xBF,0x84,0x1F, +0xEA,0x94,0x94,0x33,0x4C,0x54,0x00,0x2B,0x98,0x98,0x88,0x0E,0x3B,0x00,0x44,0x00, +0xEA,0xA2,0xD5,0x24,0xEA,0xE0,0xC0,0x0E,0xC6,0x0D,0x46,0x01,0x00,0x01,0x04,0x00, +0x03,0x36,0x5C,0xF0,0x00,0xC9,0xE9,0x06,0x2E,0x27,0xFF,0xB3,0x3E,0xD7,0xFD,0x10, +0xD5,0x03,0x2E,0x27,0xFC,0xDB,0x00,0x05,0x80,0x00,0xE2,0x02,0xE8,0x0B,0x8C,0x01, +0xEA,0xBF,0x84,0x5F,0x40,0x06,0x18,0x20,0xB7,0x07,0x14,0x83,0x80,0x01,0xAE,0x81, +0xD5,0x05,0x84,0x00,0xEA,0x94,0x84,0x1F,0xEA,0xBF,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,0xB3,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,0x6A,0x40,0x10,0x24,0x00,0xEA,0xA2, +0x10,0xB0,0x80,0x01,0xD5,0x07,0x39,0x23,0x81,0x0A,0x98,0x99,0x88,0x2A,0xEA,0x6A, +0xEA,0xA2,0x8C,0x02,0x5A,0x08,0x18,0xE7,0x49,0xFF,0xFE,0x90,0xFC,0xE1,0xFC,0x60, +0x3F,0xCF,0xFD,0xD4,0xB8,0x0B,0xC0,0x03,0x84,0x00,0xD5,0x04,0x2E,0x07,0xFF,0x5D, +0x92,0x04,0x3E,0x07,0xFC,0xE3,0xEB,0x46,0xB9,0x04,0x8C,0x01,0xE2,0x20,0x46,0x21, +0x00,0x01,0x58,0x21,0x09,0x48,0x2E,0x90,0x00,0xE3,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,0x79,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,0x8C,0xEA,0x8C,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,0x5C,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,0xFC,0xF2,0xE3,0xA3,0x40,0x38,0xBC,0x1B,0x89,0x8E,0x3B,0x08, +0x44,0x00,0xEA,0xA2,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,0x0A,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,0x23,0xE0,0xC0,0xE8,0x45,0x96,0x30, +0xEB,0x79,0x58,0x10,0x89,0x48,0x49,0xFF,0xF3,0xEC,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,0x00,0xEA,0x42,0xF7,0xBC,0x24,0x41,0x21,0x88,0x09,0x2E,0x30,0x00,0xEB, +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,0x03,0x2E,0x47,0xFF,0x7A,0x2E,0x07, +0xFF,0x79,0xC9,0x05,0xEA,0x98,0xC9,0x03,0xEA,0x82,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,0xFC,0xD7,0xE2,0x0A,0xE8,0x03,0x8C,0x01, +0xD5,0x04,0xE3,0x40,0xE8,0x03,0x8E,0x01,0xEA,0xED,0x40,0x05,0x04,0x09,0x96,0x00, +0xF0,0x82,0x84,0xC0,0x46,0x81,0x00,0x01,0x58,0x84,0x06,0x30,0x3C,0xDD,0xFE,0xC6, +0x46,0xE1,0x00,0x01,0x58,0xE7,0x06,0x24,0xEA,0x23,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,0x79,0x58,0x10,0x89,0x48,0xDD,0x47,0xEB,0x0E,0x38,0x44, +0x18,0x00,0x80,0x01,0x8C,0x0C,0xA1,0xCB,0x04,0x90,0x00,0x01,0xEA,0x28,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,0x73,0x2E,0x37, +0xFF,0x74,0xD5,0x05,0x2E,0x27,0xFF,0x77,0x2E,0x37,0xFF,0x78,0x2E,0xF7,0xFD,0x26, +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,0x01,0x39,0x08,0x3E,0x02,0xE3,0x70, +0xE9,0x04,0x2E,0xF7,0xFD,0x20,0xE8,0x07,0x86,0x03,0x42,0x21,0x40,0x24,0xEA,0xF2, +0x96,0x90,0x96,0xD8,0xC8,0x15,0xE2,0xE2,0xE9,0x09,0x3D,0x0C,0x00,0x36,0x8F,0x81, +0x8B,0x82,0xE3,0x87,0x40,0x20,0x3C,0x1B,0xD5,0x02,0x80,0x40,0xE3,0x23,0xE9,0x07, +0x3D,0x0C,0x00,0x37,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,0x46,0xC0,0x09,0xDD,0x47, +0x80,0x4D,0x42,0x23,0x00,0x73,0xEA,0x28,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,0x36,0xFF,0x44,0x40,0x73,0x88,0xF7,0x42,0x54,0x84,0x73,0x40,0x04, +0x90,0x08,0x3C,0x9C,0x00,0x37,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,0x0E,0xEA,0x28,0xA1,0x4E,0xD8,0x03,0xEB,0x46,0xC8,0x23,0x80,0x06,0xF4,0x83, +0x49,0xFF,0xF3,0x53,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,0x0E, +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,0xFC,0xD7,0xFC,0xE4,0xEA,0x57,0x42,0x00,0x18,0x0B,0x4E,0x02,0x01,0x68, +0x84,0x00,0x3E,0x18,0x02,0x8C,0x84,0x41,0x38,0x20,0x80,0x08,0x8C,0x01,0x5A,0x08, +0x0C,0xFD,0xFC,0x66,0xEA,0xC3,0xF0,0x83,0xEB,0x1E,0xF0,0x81,0xEA,0x31,0xF0,0x84, +0xEA,0xA4,0xF0,0x82,0xEA,0x77,0xF0,0x85,0x2E,0x00,0x00,0xBA,0xF0,0x86,0x2E,0x00, +0x00,0xBB,0x85,0x80,0xF0,0x87,0x3E,0x68,0x02,0x8C,0x3E,0xA8,0x01,0x84,0x84,0xE1, +0x81,0x6C,0xF0,0x03,0x4C,0xB0,0x01,0x43,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,0xEB,0x30,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,0x67,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,0x2D,0x7A, +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,0xEF,0xFD,0x20, +0xF0,0x88,0xF0,0x01,0xF5,0x89,0x49,0x00,0x2D,0x8B,0xF4,0x08,0xF5,0x09,0xFD,0x10, +0xFD,0x02,0x83,0xFF,0x49,0x00,0x2B,0xD2,0x49,0x00,0x2D,0x36,0xE3,0x00,0x40,0x04, +0x3C,0x1A,0x96,0x42,0xE4,0x34,0xE9,0x02,0x85,0x81,0xEB,0x79,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,0xBE,0xFC,0xE6,0xDD,0x9E,0xFC,0x60, +0x3F,0xCF,0xFD,0xC0,0x3E,0x08,0x02,0x98,0x84,0x20,0xEB,0x30,0xDD,0x42,0x3E,0x08, +0x02,0xE0,0x44,0x10,0x7F,0xFF,0xFA,0x54,0xEA,0xA9,0x46,0x01,0x00,0x01,0x58,0x00, +0x00,0x28,0x84,0x20,0xFA,0x54,0xDD,0x42,0xEA,0x56,0xEA,0xF3,0xC0,0x1F,0xDD,0x54, +0x5A,0x08,0x01,0x12,0xEB,0x25,0xC8,0x0C,0xEB,0x08,0x2E,0x07,0xFF,0x97,0xC1,0x03, +0x2E,0x00,0x00,0x2A,0xEA,0x82,0xC1,0x09,0x2E,0x00,0x00,0x0D,0xD5,0x06,0x2E,0x07, +0xFF,0x9A,0xD5,0x03,0x2E,0x07,0xFF,0x98,0xB9,0x00,0x5A,0x18,0x03,0x04,0x2E,0x07, +0xFF,0x9B,0xEA,0x98,0xC1,0x03,0x2E,0x00,0x00,0x2B,0xEA,0xCC,0xEA,0x8E,0xC1,0x18, +0xB9,0x00,0x5A,0x18,0x02,0x06,0x2E,0x27,0xFD,0x26,0x5A,0x20,0x01,0x05,0x2E,0x27, +0xFD,0x07,0xC2,0x04,0x2E,0x17,0xFF,0xA0,0xD5,0x0B,0x5A,0x10,0x03,0x05,0xEA,0x98, +0x5A,0x18,0x01,0x05,0x2E,0x17,0xFF,0x9F,0xD5,0x03,0x2E,0x17,0xFF,0x9E,0x46,0x21, +0x00,0x07,0x12,0x01,0x07,0xA4,0x2E,0x27,0xFC,0xFE,0x2E,0x30,0x00,0x9F,0xE2,0x62, +0xE8,0x03,0x8A,0x43,0xD5,0x02,0x84,0x40,0x3E,0x27,0xFC,0xFE,0x2F,0x17,0xFC,0xFE, +0x46,0x21,0x00,0x07,0x02,0x21,0x07,0xA4,0x41,0x28,0x80,0x13,0x88,0x52,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,0x2E,0x40,0x00,0xE1,0x2F,0x00,0x00,0xE0,0x3C,0x8D,0xFF,0x7E, +0x46,0x21,0x00,0x01,0x58,0x21,0x00,0x28,0x84,0x00,0x46,0xB1,0x00,0x03,0x58,0xB5, +0x80,0x78,0x3E,0x98,0x02,0xE0,0x82,0x62,0x44,0xD0,0x00,0x48,0x46,0xE1,0x00,0x07, +0x58,0xE7,0x05,0x00,0x45,0x40,0x00,0x4C,0x82,0xA0,0x51,0x65,0xF0,0xCC,0x82,0xE9, +0x3E,0xC8,0x02,0x98,0xE2,0x04,0xE8,0x4E,0x83,0x0E,0x43,0x80,0x34,0x73,0x43,0x90, +0x50,0x24,0x95,0xC2,0x84,0xC0,0xE2,0xD0,0xE8,0x3B,0x38,0x5C,0x19,0x01,0x40,0xAC, +0x98,0x20,0x38,0x35,0x95,0x01,0x38,0x54,0x15,0x01,0x89,0x56,0x9B,0x5D,0x97,0x69, +0x96,0xEB,0x12,0x35,0x14,0xB2,0x02,0xA1,0x00,0x00,0xE1,0x43,0xE8,0x02,0xAD,0x50, +0x38,0xA4,0x9C,0x02,0xE2,0x6A,0xE8,0x06,0x4E,0x37,0x00,0x07,0x38,0x34,0x9C,0x0A, +0xD5,0x06,0x4E,0x36,0x00,0x05,0x39,0x5B,0x9C,0x0A,0xD5,0x18,0x38,0xA6,0x1C,0x02, +0x89,0x43,0x38,0xA6,0x1C,0x0A,0x46,0xA1,0x00,0x05,0x02,0xA5,0x02,0xD6,0xE1,0x43, +0xE8,0x0D,0x46,0x31,0x00,0x05,0x12,0x51,0x82,0xD6,0x46,0x31,0x00,0x05,0x10,0x01, +0x85,0xAE,0x46,0x31,0x00,0x05,0x10,0x61,0x85,0xAF,0x8C,0xC1,0xD5,0xC5,0xC9,0x03, +0xAC,0x50,0xD5,0x05,0xA4,0xD0,0x40,0x31,0x84,0x77,0xAC,0xD0,0x8C,0x01,0x8C,0x42, +0xD5,0xB2,0x2E,0x30,0x00,0xBC,0x84,0x00,0x80,0x40,0x3E,0x58,0x02,0xE0,0xE2,0x44, +0xE8,0x0E,0xEB,0x79,0x02,0x10,0x80,0x12,0x38,0x62,0x8A,0x02,0x96,0x4B,0x88,0x23, +0xE2,0x26,0xE8,0x03,0x8C,0x01,0x96,0x01,0x8C,0x41,0xD5,0xF2,0xC0,0x08,0x2E,0x17, +0xFC,0xFF,0x84,0x03,0xFE,0x0C,0x8C,0x01,0x3C,0x0B,0xFE,0xBD,0x3C,0x23,0xFE,0xBD, +0xC2,0x16,0x2E,0x30,0x00,0xBE,0x3E,0x58,0x02,0xE0,0x84,0x00,0x3E,0x68,0x02,0x98, +0xE2,0x04,0xE8,0x0A,0x38,0x13,0x02,0x02,0x40,0x10,0xC0,0x37,0x88,0x23,0x38,0x12, +0x82,0x0A,0x8C,0x01,0xD5,0xF6,0x8E,0x41,0x3C,0x2B,0xFE,0xBD,0xEA,0xF8,0x96,0x1E, +0xC8,0x1F,0xEB,0x4F,0x46,0x21,0x00,0x05,0x02,0x10,0x02,0xD6,0x00,0x21,0x05,0xAE, +0x46,0x01,0x00,0x01,0x02,0x00,0x00,0x12,0x38,0x29,0x89,0x01,0x96,0x03,0x88,0x02, +0xE0,0x01,0xEB,0x1C,0xEB,0x27,0xE8,0x1F,0x46,0x01,0x00,0x01,0x02,0x00,0x00,0x12, +0x96,0x03,0x88,0x40,0x8A,0x22,0xEB,0x4F,0x12,0x10,0x02,0xD6,0xD5,0x19,0x84,0x00, +0x3E,0x28,0x02,0xE0,0x46,0x31,0x00,0x01,0x58,0x31,0x80,0x28,0xE2,0x04,0xE8,0xDA, +0x38,0x11,0x02,0x02,0x38,0x59,0x81,0x01,0xE2,0xA1,0xE8,0x03,0x38,0x11,0x81,0x09, +0x8C,0x01,0xD5,0xF5,0x84,0x00,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD6,0xEB,0x4F, +0xEB,0x21,0x84,0x40,0x40,0xB0,0x04,0x09,0x2E,0xE7,0xFF,0x64,0x2F,0x47,0xFF,0xCD, +0x46,0x01,0x00,0x01,0x00,0x90,0x02,0xC0,0x2E,0x87,0xFD,0x04,0x80,0xA2,0x80,0x62, +0x44,0xD0,0x00,0x4C,0x80,0xE2,0x53,0x58,0x80,0x00,0xE2,0x64,0xE8,0x52,0x80,0x06, +0x42,0x01,0xB4,0x73,0x40,0xC1,0x84,0x08,0x50,0x00,0x29,0x64,0x85,0x40,0xE3,0x50, +0xE8,0x46,0x22,0x10,0x00,0x00,0x4E,0x15,0x00,0x13,0xEA,0x89,0xEA,0x9C,0x39,0x69, +0xB0,0x01,0xEA,0x7F,0x40,0xFB,0x3C,0x00,0x40,0xF7,0x84,0x07,0xE8,0x14,0xEA,0x89, +0xEA,0x9C,0xEA,0x7F,0x40,0xFB,0x3C,0x00,0x8A,0x2F,0xD5,0x0B,0xEA,0x89,0xEA,0x9C, +0xEA,0x7F,0x52,0xF7,0x80,0x00,0xE0,0x2F,0xE8,0x06,0xEA,0x89,0xEA,0x9C,0x88,0x2F, +0xAC,0x40,0xD5,0x02,0xAD,0xC0,0x22,0x10,0x00,0x00,0x4E,0x17,0x00,0x08,0xE0,0x2B, +0xE8,0x0B,0xE1,0xA1,0xE8,0x08,0x8A,0x32,0xD5,0x04,0xE0,0x35,0xE8,0x04,0x88,0x32, +0xAC,0x40,0xD5,0x02,0xAD,0xC0,0x2A,0x10,0x00,0x01,0x40,0xF0,0xB8,0x00,0x4E,0xF4, +0x00,0x09,0x8C,0xA1,0x97,0x69,0xE2,0xB4,0xE9,0x04,0x58,0x94,0x80,0x01,0x85,0x01, +0x4E,0x14,0x00,0x04,0x8A,0x41,0x96,0x91,0x8D,0x41,0xD5,0xBA,0x8C,0x61,0xD5,0xAE, +0x46,0x01,0x00,0x01,0x10,0x90,0x02,0xC0,0x3E,0x87,0xFD,0x04,0x2E,0x07,0xFF,0xFE, +0x94,0x05,0xE0,0x02,0xE8,0x08,0x54,0x04,0x80,0xFF,0xEB,0x02,0xEB,0x79,0xEA,0xEE, +0x84,0x01,0xEA,0x75,0x46,0x01,0x00,0x07,0x04,0x10,0x03,0xF2,0xEB,0x4F,0xEB,0x21, +0xE2,0x20,0xE8,0x11,0x46,0x01,0x00,0x01,0x00,0x00,0x02,0xC0,0xEB,0x79,0xEB,0x04, +0xEA,0xEE,0x84,0x21,0x3E,0x17,0xFD,0x04,0x2E,0x07,0xFC,0xE0,0x8C,0x01,0xB8,0x91, +0x3E,0x17,0xFD,0x15,0xB8,0x00,0x5A,0x08,0x03,0x05,0x84,0xE1,0x86,0x24,0xD5,0x03, +0x84,0xE0,0x86,0x21,0xEB,0x01,0x5A,0x08,0x01,0x04,0x80,0xE0,0x86,0x22,0x40,0x08, +0x9C,0x20,0x54,0x90,0x00,0xFF,0x2F,0x67,0xFD,0x26,0x2F,0x37,0xFD,0x30,0x84,0xA0, +0x51,0x79,0xFF,0xFF,0x80,0x45,0x45,0x50,0x00,0x26,0x45,0x40,0x00,0x24,0x44,0xE0, +0x00,0x48,0x44,0xDF,0xFF,0xB8,0xE2,0x44,0xE8,0x41,0x42,0xA1,0x38,0x24,0x52,0x12, +0xA9,0x64,0x50,0x35,0x19,0x54,0x42,0xB1,0x54,0x24,0x42,0x81,0x50,0x24,0x88,0x26, +0x88,0x66,0x42,0xC1,0x34,0x24,0x86,0x40,0xE3,0xD0,0xE8,0x2C,0x40,0xF0,0x94,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,0x3C,0x22,0xF7,0xFA,0x80, +0x42,0x0C,0x44,0x73,0x42,0x07,0x9C,0x73,0x40,0x00,0x24,0x16,0x12,0x00,0xFD,0x2F, +0xA4,0x18,0x12,0x01,0x82,0x88,0x2A,0x00,0x80,0x01,0x1A,0x01,0x80,0x01,0x8D,0xC1, +0xD5,0xD4,0x8C,0x41,0x50,0x52,0xFF,0xB4,0xD5,0xBF,0x46,0x01,0x00,0x04,0x58,0x00, +0x0A,0xA8,0x44,0x10,0x00,0xFD,0x44,0x20,0x02,0xF8,0xEA,0xA9,0x2E,0x0F,0xFF,0xCC, +0x4E,0x04,0x00,0xAC,0x2E,0x07,0xFC,0xED,0xC8,0x04,0x2F,0x00,0x00,0x44,0xD5,0x03, +0x45,0x00,0x00,0xFF,0x2E,0x07,0xFD,0x02,0xC8,0x04,0x2E,0x70,0x00,0x44,0xD5,0x02, +0xEA,0xE7,0x2E,0x50,0x00,0xE1,0xEA,0x31,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,0xF2,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,0xF2,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,0x79,0x58,0x10,0x80,0x28, +0x38,0x00,0x81,0x01,0xDD,0x9E,0xFC,0x40,0x82,0x40,0x2E,0x47,0xFE,0x59,0x3D,0x0C, +0x00,0x36,0x3D,0x1C,0x00,0x37,0x84,0x00,0x80,0xE0,0x80,0x40,0x86,0x6C,0x44,0x90, +0xFF,0xFF,0x85,0x41,0x2E,0x30,0x00,0xE3,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,0x59,0xFC,0xC0,0xFC,0x00,0x84,0x1F,0x3E,0x07, +0xFE,0x59,0x84,0x00,0x3C,0x0B,0xFF,0x9D,0x3C,0x0B,0xFF,0x9C,0x84,0x3F,0x3C,0x1B, +0xFF,0x9B,0x3C,0x1B,0xFF,0x9A,0x3E,0x2F,0xFF,0x30,0xAC,0x10,0xAC,0x11,0x3E,0x2F, +0xFF,0x2C,0xAC,0x10,0xAC,0x11,0x3E,0x2F,0xFF,0x28,0xAC,0x50,0xAC,0x51,0x3E,0x2F, +0xFF,0x24,0xAC,0x50,0xAC,0x51,0x3E,0x07,0xFE,0xCC,0xEB,0x47,0x46,0x01,0x00,0x07, +0x58,0x00,0x03,0x80,0xA6,0x46,0xA6,0x87,0xEA,0x7C,0x3C,0x1B,0xFF,0x3D,0x00,0x10, +0x00,0x08,0x00,0x20,0x00,0x09,0xEA,0x7C,0x3C,0x1B,0xFF,0x3C,0x00,0x10,0x00,0x0A, +0x00,0x20,0x00,0x0B,0xEA,0x7C,0x3C,0x1B,0xFF,0x3B,0x00,0x10,0x00,0x0C,0x3E,0x17, +0xFE,0x75,0x00,0x10,0x00,0x0D,0x3E,0x17,0xFE,0x74,0x00,0x10,0x00,0x0E,0x3E,0x17, +0xFE,0x73,0x00,0x10,0x00,0x0F,0x3E,0x17,0xFE,0x72,0x3E,0x18,0x00,0xD8,0xA4,0x8A, +0x00,0x30,0x00,0x10,0x9B,0x13,0x3C,0x4B,0xFF,0x38,0x3C,0x3B,0xFF,0x37,0xA4,0x48, +0x00,0x30,0x00,0x11,0x9B,0x0B,0x3C,0x4B,0xFF,0x36,0x3C,0x3B,0xFF,0x35,0x00,0x30, +0x00,0x12,0x8A,0x43,0x3C,0x2B,0xFF,0x34,0x3C,0x3B,0xFF,0x33,0x00,0x20,0x00,0x13, +0x8A,0x22,0x3C,0x1B,0xFF,0x32,0x3C,0x2B,0xFF,0x31,0x00,0x10,0x00,0x14,0x00,0x20, +0x00,0x15,0xEA,0x7C,0x3C,0x1B,0xFF,0x30,0x00,0x10,0x00,0x16,0x3C,0x1B,0xFF,0x2F, +0x00,0x10,0x00,0x17,0x3C,0x1B,0xFF,0x2E,0x00,0x00,0x00,0x18,0x3C,0x0B,0xFF,0x2D, +0xFA,0x44,0x3E,0x0F,0xFE,0xB8,0x84,0x20,0xDD,0x42,0x3E,0x6F,0xFE,0xD8,0x3E,0x0F, +0xFE,0xA4,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,0xEB,0x29,0x84,0x20, +0xFA,0x56,0xDD,0x42,0x46,0x01,0x00,0x01,0xEA,0xDB,0x84,0x20,0xFA,0x43,0xDD,0x42, +0x3E,0x0F,0xFE,0xD0,0x84,0x20,0x84,0x48,0xDD,0x42,0xFC,0x80,0xFC,0x00,0xEA,0x36, +0x2E,0x67,0xFD,0xDC,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,0x55,0x3E,0x0F,0xFD,0xDC,0x84,0x3F,0x84,0x41,0xDD,0x42,0x84,0x01,0x3E,0x07, +0xFE,0x58,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,0x58,0xDD,0x9E,0x84,0x00,0x3E,0x07, +0xFE,0x58,0xDD,0x9E,0xE2,0x20,0xE8,0x03,0x8A,0x01,0xD5,0x02,0x9A,0x08,0x96,0x01, +0xDD,0x9E,0xFC,0x60,0x80,0xE0,0xEA,0x65,0x80,0xC1,0xE6,0x02,0xE8,0x0A,0x84,0x20, +0x3E,0x17,0xFE,0x57,0x3E,0x17,0xFE,0x56,0x3E,0x17,0xFE,0x55,0x3E,0x17,0xFE,0x54, +0x3C,0x13,0xFF,0x98,0xE2,0x27,0xE8,0x07,0x3C,0x7B,0xFF,0x98,0x3C,0x6B,0xFF,0x99, +0x3C,0x0B,0xFF,0x6B,0xEA,0xA7,0xE2,0xE1,0xE8,0x07,0x3C,0x7B,0xFF,0x94,0x3C,0x6B, +0xFF,0x95,0x3C,0x0B,0xFF,0x69,0x3C,0x13,0xFF,0x97,0xE2,0x26,0xE8,0x07,0x3C,0x7B, +0xFF,0x96,0x3C,0x6B,0xFF,0x97,0x3C,0x0B,0xFF,0x6A,0xEA,0xA6,0xE2,0xC1,0xE8,0x07, +0x3C,0x7B,0xFF,0x92,0x3C,0x6B,0xFF,0x93,0x3C,0x0B,0xFF,0x68,0x3C,0xA3,0xFF,0x9B, +0x80,0x07,0x80,0x2A,0xDD,0x41,0x81,0x60,0x3C,0x93,0xFF,0x9A,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,0x55,0xE8,0x0B,0x2E,0x37,0xFE,0x57, +0xEA,0xDE,0xEA,0xA0,0xE4,0x02,0x8C,0x21,0xEA,0xA3,0xE8,0x11,0x8C,0x01,0xD5,0x0D, +0xE2,0xEA,0xE8,0x0D,0x2E,0x37,0xFE,0x57,0xEA,0xDE,0xEA,0xA0,0x5E,0xF0,0x7F,0xFF, +0x8E,0x21,0xEA,0xA3,0xE9,0x04,0x8E,0x01,0x3E,0x07,0xFE,0x55,0xE3,0x26,0x2E,0x0F, +0xFE,0x54,0xE8,0x0C,0x2E,0x37,0xFE,0x56,0x3E,0x2F,0xFE,0xA4,0xEA,0xA0,0xE4,0x02, +0x8C,0x21,0xEA,0xA3,0xE8,0x12,0x8C,0x01,0xD5,0x0E,0xE2,0xC9,0xE8,0x0E,0x2E,0x37, +0xFE,0x56,0x3E,0x2F,0xFE,0xA4,0xEA,0xA0,0x5E,0xF0,0x7F,0xFF,0x8E,0x21,0xEA,0xA3, +0xE9,0x04,0x8E,0x01,0x3E,0x07,0xFE,0x54,0x2E,0x0F,0xFE,0x55,0xC8,0x0C,0x4C,0x75, +0x00,0x0B,0x2E,0x07,0xFE,0x57,0x8C,0x01,0x96,0x00,0xE6,0x0A,0xE9,0x02,0x84,0x09, +0x3E,0x07,0xFE,0x57,0x2E,0x0F,0xFE,0x54,0xC8,0x0C,0x4C,0x64,0x80,0x0B,0x2E,0x07, +0xFE,0x56,0x8C,0x01,0x96,0x00,0xE6,0x0A,0xE9,0x02,0x84,0x09,0x3E,0x07,0xFE,0x56, +0xFC,0xE0,0xFC,0x61,0x83,0x80,0xEA,0x65,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,0x40,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,0x40,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,0xDB,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,0x1C,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,0xE7,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,0xDB,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,0x9B,0x3C,0xA3,0xFF,0x9A, +0xEA,0x65,0x80,0xE1,0xE6,0x02,0xE8,0x04,0x84,0x1F,0x3E,0x07,0xFE,0x3F,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,0x3F, +0x5A,0x08,0xFF,0x06,0xE2,0x8B,0xE8,0x1D,0x3E,0x97,0xFE,0x3F,0xE2,0xCD,0x14,0xFF, +0x80,0x02,0x40,0x16,0x98,0x06,0xF1,0x83,0xE3,0x47,0x2E,0x07,0xFE,0x3F,0x14,0xFF, +0x80,0x04,0xE2,0xEA,0xF0,0x81,0x3E,0xCF,0xFE,0x7C,0x3F,0xCF,0xFE,0xD8,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,0x3F,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,0x80,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,0x80, +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,0x80,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,0x80,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,0x5B,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,0x3E,0xC0,0x20,0x5A,0x00,0x05,0x1F,0x5A,0x00,0x04,0x07,0x3C,0x03, +0xFF,0x1E,0x8C,0x01,0x3C,0x0B,0xFF,0x1E,0xEB,0x23,0x3C,0x13,0xFF,0x37,0xE2,0x20, +0x4E,0xF2,0x00,0xE1,0x3C,0x13,0xFF,0x38,0xE2,0x01,0x4E,0xF2,0x00,0xDC,0xEB,0x22, +0x3C,0x13,0xFF,0x35,0xE2,0x20,0x4E,0xF2,0x00,0xD6,0x3C,0x13,0xFF,0x36,0xE2,0x01, +0x4E,0xF2,0x00,0xD1,0x2E,0x27,0xFE,0x3E,0xCA,0x15,0x5A,0x90,0x01,0x03,0xF8,0x4E, +0xEA,0x28,0x4C,0x50,0x00,0xAE,0x3E,0x97,0xFE,0x3E,0x3C,0x5B,0xFF,0x1D,0x3C,0xAB, +0xFF,0x1C,0x3C,0x2B,0xFF,0x1E,0x3C,0x2B,0xFF,0x1B,0x84,0x1F,0x3E,0x07,0xFC,0xB0, +0xF8,0x3D,0x54,0x01,0x00,0xFD,0x5A,0x00,0x01,0x04,0x48,0x00,0x00,0x55,0x5A,0x98, +0x01,0x38,0x80,0x25,0xEB,0x23,0xDD,0x41,0x2E,0xB7,0xFE,0x72,0xE3,0x60,0xE9,0x06, +0xEB,0x22,0x80,0x2A,0xDD,0x41,0xE3,0x60,0xE8,0x13,0x84,0x05,0xDD,0x5B,0xDD,0x5A, +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,0x1E,0x3C,0x23,0xFF,0x1B,0x2E,0x07,0xFE,0x75,0x88,0x02,0xE0,0x01,0x4E,0xF2, +0x00,0x70,0x84,0x05,0xDD,0x5B,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,0x1E,0x3C,0x33,0xFF,0x1B,0xE2,0x60,0xE8,0x11,0x2E,0x17, +0xFE,0x75,0x88,0x23,0xE0,0x20,0xE9,0x0C,0x84,0x22,0x5A,0x20,0x01,0x05,0x5A,0x28, +0x03,0x05,0x84,0x24,0x3E,0x17,0xFE,0x3E,0x3C,0x0B,0xFF,0x1B,0xD5,0x49,0x84,0x05, +0xDD,0x5B,0xD5,0x46,0x5A,0x28,0x02,0x45,0x3C,0xB3,0xFF,0x1E,0x3C,0x83,0xFF,0x1B, +0xE3,0x68,0xE9,0x32,0x2E,0x07,0xFE,0x74,0x88,0x08,0xE1,0x60,0xE8,0x2D,0x5A,0x98, +0x01,0x38,0xEA,0x28,0xD0,0x35,0x80,0x25,0xEB,0x23,0xDD,0x41,0x2E,0xC7,0xFE,0x72, +0xE2,0x0C,0xE8,0x10,0xEB,0x22,0x80,0x2A,0xDD,0x41,0xE2,0x0C,0xE8,0x0B,0x2E,0x07, +0xFE,0x73,0x88,0x08,0xE1,0x60,0xE9,0x06,0x84,0x03,0xDD,0x5B,0x3C,0xBB,0xFF,0x1B, +0xD5,0x1F,0x84,0x05,0xDD,0x5B,0xDD,0x5A,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,0x5B,0x84,0x0A,0x40,0x23,0x80,0x37, +0x96,0x49,0x8A,0xE1,0x8C,0x21,0x40,0x00,0x80,0x36,0x88,0xE1,0x97,0xF9,0x2E,0x07, +0xFE,0x3E,0x5A,0x08,0x04,0x09,0x44,0x0F,0xFF,0x80,0x3E,0x07,0xFC,0xB0,0x84,0x00, +0xDD,0x5B,0xD5,0x07,0x5A,0x08,0x05,0x06,0x4E,0x93,0x00,0x04,0x3E,0x97,0xFE,0x3E, +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,0x5B,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,0xFE,0xB8,0x3E,0x5F,0xFE,0xA4,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,0x3A,0x3C,0x63,0xFF,0x9B,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,0x9C, +0xEA,0xAE,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,0xA7,0xDD,0x41,0x5C,0xF0,0x00,0x64,0xE8,0x08,0x80,0x06, +0x3C,0x13,0xFF,0x98,0xDD,0x41,0x5C,0xF0,0x00,0x64,0xE9,0x25,0x3C,0x43,0xFF,0x6B, +0x3C,0x33,0xFF,0x68,0x84,0x00,0x3E,0x2F,0xFE,0xD0,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,0xFE,0xCC, +0x84,0x08,0xD5,0x02,0xEA,0x92,0xFC,0x80,0xFC,0x60,0x80,0xE0,0x81,0x21,0x3C,0xA3, +0xFF,0x3B,0x5A,0x10,0x0B,0x04,0x5A,0x18,0x07,0x1F,0x3C,0x07,0xFF,0x5C,0xE4,0x05, +0xE9,0x15,0x3C,0xF7,0xFF,0x5D,0x5E,0xF7,0xFF,0xFC,0xE8,0x10,0x3C,0x07,0xFF,0x5E, +0xE4,0x05,0xE9,0x0C,0x3C,0x67,0xFF,0x5F,0xCE,0x09,0x3C,0x07,0xFF,0x60,0xC8,0x07, +0x3C,0x67,0xFF,0x61,0x5C,0x63,0x00,0x01,0xD5,0x02,0x84,0xC0,0xEA,0x3A,0xEA,0xE4, +0xE2,0x20,0xF8,0x71,0xEB,0x79,0x58,0x10,0x81,0x90,0x94,0x3C,0x98,0x81,0x80,0x81, +0x5A,0x98,0x0D,0x12,0x3C,0x13,0xFF,0x9D,0x3C,0x03,0xFF,0x9B,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,0x79,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,0x9A,0x3C,0x63,0xFF,0x97,0x80,0x08,0x80,0x26,0xDD,0x41, +0x81,0x80,0x3C,0xB3,0xFF,0x93,0x80,0x08,0x80,0x2B,0xDD,0x41,0xE2,0x0C,0xE9,0x0D, +0x3C,0x83,0xFF,0x9C,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,0xEB,0x2A, +0xE3,0x40,0xE8,0x04,0x40,0x05,0x00,0x11,0xD5,0x02,0x96,0x03,0x96,0x01,0xEA,0xA6, +0xDD,0x41,0xE6,0x1A,0x4E,0xF3,0x01,0xFA,0xF8,0x9A,0x5A,0x90,0x09,0x03,0xF9,0xAB, +0x3C,0xB3,0xFF,0x98,0x3C,0x93,0xFF,0x9D,0x80,0x0B,0x80,0x29,0xDD,0x41,0x81,0x80, +0x3C,0xA3,0xFF,0x94,0x80,0x29,0x80,0x0A,0xDD,0x41,0xE2,0x0C,0x4E,0xF3,0x01,0xE8, +0x3C,0x93,0xFF,0x9B,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,0x98, +0x3C,0x63,0xFF,0x9D,0x80,0x0A,0x80,0x26,0xDD,0x41,0x81,0x60,0x3C,0x93,0xFF,0x94, +0x80,0x26,0x80,0x09,0xDD,0x41,0xE2,0x0B,0x4E,0xF3,0x01,0xCA,0x3C,0x63,0xFF,0x9B, +0x80,0x0A,0x80,0x26,0xDD,0x41,0x81,0x40,0x80,0x26,0x80,0x09,0xDD,0x41,0xE3,0x40, +0x4E,0xF3,0x01,0xBE,0x3C,0x93,0xFF,0x93,0x3C,0x63,0xFF,0x9C,0x80,0x09,0x80,0x26, +0xDD,0x41,0x81,0x60,0x3C,0xA3,0xFF,0x97,0x80,0x26,0x80,0x0A,0xDD,0x41,0xE2,0x0B, +0x4E,0xF3,0x01,0xAE,0x3C,0x63,0xFF,0x9A,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,0xA4,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,0xEA,0xDE, +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,0x3A,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,0x9D,0xE2,0xC4,0x4E,0xF2,0x01,0x44,0xA5,0x1C,0xEA,0xE2,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,0x9D,0x38,0x42,0x00,0x01,0xE2,0x85,0x4E,0xF2, +0x01,0x27,0x3C,0x43,0xFF,0x9C,0xEA,0xE2,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,0x9B,0xE2,0x02,0x4E,0xF2, +0x01,0x0F,0x3C,0x03,0xFF,0x9A,0xE2,0x01,0x4E,0xF2,0x01,0x0A,0xE2,0x80,0x48,0x00, +0x00,0x64,0x5A,0x98,0x0C,0x29,0xEA,0xE2,0xA5,0x19,0x02,0xC1,0x80,0x02,0xE2,0x80, +0x3C,0xA3,0xFF,0x9D,0x3C,0x83,0xFF,0x9B,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,0x9C,0x80,0x2C,0x80,0x0B,0xDD,0x41,0x89,0x20,0x80,0x28,0x80,0x0A, +0xDD,0x41,0x81,0x40,0xEA,0xAE,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,0xFE,0xB8,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,0x17,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,0xA4,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,0xFE,0xB8,0x3E,0x5F,0xFE,0xA4,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,0xEB,0x29,0x38,0x10,0x1D,0x01,0x84,0x4C, +0x3E,0x0F,0xFB,0xB4,0x42,0x03,0x88,0x73,0x88,0x01,0x00,0x00,0x7F,0xFF,0x54,0x00, +0x00,0x60,0xC8,0x1B,0xEA,0xAE,0xEB,0x2A,0xE2,0x20,0x4E,0xF2,0x00,0x61,0xDD,0x41, +0x3C,0x13,0xFF,0x3C,0xE2,0x20,0x4E,0xF2,0x00,0x5B,0x3C,0x03,0xFF,0x98,0xEA,0xA7, +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,0xEB,0x2A,0xEA,0xAE, +0xE2,0x01,0x4E,0xF2,0x00,0x45,0xDD,0x41,0x3C,0x13,0xFF,0x3C,0xE2,0x20,0xE8,0x3F, +0x3C,0x03,0xFF,0x98,0xEA,0xA7,0xDD,0x41,0xE2,0x0A,0xE8,0x39,0xE5,0x04,0xE9,0x37, +0x84,0x20,0x40,0x60,0x98,0x06,0xD5,0x31,0x5A,0x08,0x60,0x17,0xEA,0xE4,0xEA,0x3A, +0xE2,0x01,0xE8,0x2D,0xDD,0x41,0x3C,0x13,0xFF,0x3D,0xE2,0x20,0xE8,0x28,0x3C,0x03, +0xFF,0x97,0xEA,0xA6,0xDD,0x41,0xE2,0x0A,0xE8,0x22,0xE5,0x64,0xE9,0x20,0x84,0x20, +0x40,0x60,0xA4,0x06,0xD5,0x1A,0x5A,0x08,0x40,0x20,0xEA,0x3A,0xEA,0xE4,0xE2,0x20, +0xE8,0x16,0xDD,0x41,0x3C,0x13,0xFF,0x3D,0xE2,0x20,0xE8,0x11,0x3C,0x03,0xFF,0x97, +0xEA,0xA6,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, +0xEB,0x29,0x38,0x10,0x1D,0x09,0xFC,0xE0,0xFC,0x64,0x84,0x20,0xB0,0x02,0xFA,0x48, +0xDD,0x42,0x84,0x00,0x3E,0x4F,0xFE,0x7C,0x3E,0x3F,0xFB,0xB4,0x84,0xAC,0x38,0x12, +0x01,0x01,0x3E,0xDF,0xFE,0x7C,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,0xE7,0x3F,0xCF,0xFE,0x7C,0x3E,0xBF,0xFB,0xB4,0x85,0xCC,0xD5,0x12, +0x8C,0x01,0x5A,0x08,0x18,0xF1,0xEA,0x92,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,0x3A,0xC8,0x15,0x3C,0x93, +0xFF,0x9C,0x4E,0x93,0x00,0x12,0xF8,0x5F,0x80,0x09,0x3E,0x1F,0xFE,0xD8,0x38,0x60, +0x80,0x09,0x98,0x81,0x8C,0x04,0xAD,0xD1,0x5A,0x08,0x4C,0xFB,0x3C,0x6B,0xFF,0x9D, +0x3C,0x7B,0xFF,0x9C,0xD5,0x19,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x9B,0x46,0x21, +0x00,0x07,0xEA,0x65,0x00,0x21,0x03,0x9C,0x40,0xF1,0x05,0x00,0xE0,0x0F,0xE8,0x03, +0x8C,0x01,0xEB,0x47,0xFD,0x03,0x49,0xFF,0xF9,0x06,0xFD,0x03,0x49,0xFF,0xFA,0x2C, +0xFD,0x03,0x49,0xFF,0xF9,0xA0,0x3C,0x6B,0xFF,0x9B,0x3C,0x7B,0xFF,0x9A,0xD5,0x1C, +0x4E,0xA3,0x00,0x1F,0xEA,0x97,0xC0,0x09,0x2E,0x07,0xFC,0xB0,0x5A,0x00,0xFF,0x16, +0x84,0x3F,0x3E,0x17,0xFC,0xB0,0xD5,0x11,0xEA,0x3A,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,0x92,0xEA,0xE5,0x5A,0x18,0x01,0x12,0x46,0x11, +0x00,0x07,0x00,0x10,0x83,0x9B,0x46,0x21,0x00,0x07,0xEA,0x65,0x00,0x21,0x03,0x9C, +0x40,0xF1,0x05,0x00,0xE0,0x0F,0xE8,0x03,0x8C,0x01,0xEB,0x47,0xEA,0x92,0x4E,0xA3, +0x00,0x06,0xB6,0x1F,0x49,0xFF,0xF7,0xCB,0xB4,0x1F,0xFC,0xC2,0x3E,0x1F,0xFE,0x1C, +0xA6,0x08,0xFA,0x56,0xA6,0x49,0x8E,0x01,0x42,0x10,0x08,0x73,0xEB,0x65,0x58,0x00, +0x01,0x44,0x50,0x40,0x91,0xB8,0x40,0x40,0x10,0x20,0xA5,0x62,0x3E,0x28,0x03,0x3C, +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, +0x03,0x28,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,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,0x3B,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,0x84,0x3B,0x01,0xC8,0x20,0x40,0x11,0x04,0x40,0xEA,0xDD,0x3A,0x10,0x84,0x00, +0x3A,0x10,0x04,0x20,0xDD,0x9E,0x92,0x00,0x84,0x20,0x46,0x21,0x00,0x01,0xEB,0x3B, +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,0xFC,0xBD,0x3E,0x28,0x01,0x84, +0x38,0x31,0x02,0x08,0xEA,0xDD,0xAE,0x41,0xAE,0x42,0x2E,0x17,0xFC,0xCE,0xAE,0x43, +0xDD,0x9E,0x92,0x00,0x3B,0xFF,0xFC,0xBC,0x51,0xFF,0xFF,0xFC,0x49,0xFF,0xFF,0x40, +0x3C,0x00,0x01,0xA2,0x96,0x03,0x4E,0x05,0x00,0xAF,0x3C,0x20,0x01,0xA2,0x80,0xA2, +0x46,0x11,0x00,0x01,0x2E,0x07,0xFE,0x1D,0x00,0x10,0x8F,0xF3,0xE2,0x20,0xE8,0x49, +0x9A,0x41,0xE4,0x22,0x4E,0xF3,0x00,0x4A,0x2E,0x17,0xFE,0x1C,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,0xB1,0xE2,0x40,0xE8,0x5D,0x3E,0x00,0x01,0xB1,0x2E,0x20,0x01,0xB2, +0xE2,0x41,0xE8,0x4F,0x3E,0x10,0x01,0xB2,0xFA,0x56,0x42,0x00,0x88,0x73,0x46,0x11, +0x00,0x02,0xEB,0x19,0x50,0x00,0x14,0xB0,0x94,0x01,0x88,0x01,0x22,0x10,0x00,0x02, +0x5A,0x10,0xFE,0x50,0xEA,0x4A,0x2E,0x27,0xFE,0x1C,0xAC,0xC2,0x2E,0x17,0xFE,0x1D, +0x3E,0x27,0xFE,0x18,0xEC,0x04,0x3E,0x17,0xFE,0x19,0x3B,0xFF,0xFC,0x84,0xDD,0x9E, +0x8A,0x20,0xE4,0x22,0x4E,0xF2,0xFF,0xBA,0x46,0x31,0x00,0x01,0x2E,0x17,0xFE,0x1C, +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,0xB3,0xE2,0x22,0xE8,0xB1,0x3E,0x10,0x01,0xB3,0x48,0xFF,0xFF,0xAE, +0x2E,0x20,0x01,0xB0,0xE2,0x02,0xE8,0xA3,0x3E,0x00,0x01,0xB0,0x48,0xFF,0xFF,0xA0, +0x2E,0x27,0xFC,0xEE,0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x08,0x8C,0x21,0xEA,0x4A, +0xAC,0xC2,0xE2,0x41,0xEB,0x65,0x14,0x10,0x00,0x08,0xE8,0x17,0x2E,0x17,0xFE,0x1C, +0x2E,0x07,0xFE,0x1D,0x3E,0x17,0xFE,0x18,0xEC,0x04,0x3E,0x07,0xFE,0x19,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,0x7F,0xC8,0xE8,0xDD,0x5E, +0xC1,0x1C,0x3C,0x00,0x01,0x94,0xEA,0x96,0x97,0x43,0xD2,0x17,0xDD,0x59,0xEA,0x84, +0xEA,0xD1,0x4E,0x00,0x00,0x56,0xE9,0x11,0x8E,0x21,0xDD,0x51,0x49,0xFF,0xFF,0x2C, +0x2E,0x07,0xFE,0x18,0x50,0x00,0x00,0x01,0x2E,0x17,0xFE,0x19,0x3E,0x07,0xFE,0x1C, +0xEA,0xAA,0xEA,0x2C,0x2E,0x17,0xFE,0x1C,0xEB,0x0C,0x8E,0x01,0xE0,0x20,0xE8,0x19, +0x3C,0x00,0x01,0x95,0xEA,0x96,0x97,0x43,0xD2,0x14,0xDD,0x59,0xEA,0x84,0xEA,0xD2, +0xF8,0x37,0xE9,0x0F,0x9C,0x49,0xDD,0x51,0x49,0xFF,0xFF,0x0E,0x2E,0x07,0xFE,0x18, +0x50,0x00,0x7F,0xFF,0x2E,0x17,0xFE,0x19,0x3E,0x07,0xFE,0x1C,0xEA,0xAA,0xEA,0x2C, +0xEB,0x15,0xC1,0x19,0x3C,0x00,0x01,0x96,0xEA,0x96,0x97,0x43,0xD2,0x14,0xDD,0x59, +0xEA,0x84,0x3C,0x30,0x01,0xA0,0xF8,0x1C,0xE9,0x0E,0x9E,0x49,0xEA,0xAA,0xEA,0x24, +0xEA,0x49,0xEA,0x45,0x50,0x00,0x00,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFE,0x30, +0x2E,0x17,0xFE,0x1D,0xEB,0x2F,0x8E,0x01,0xE0,0x20,0xE8,0x1B,0x3C,0x00,0x01,0x97, +0xEA,0x96,0x97,0x43,0xD2,0x16,0xDD,0x59,0xEA,0x84,0x3C,0x30,0x01,0xA1,0x96,0x03, +0x96,0xDB,0x88,0x02,0xE0,0x03,0x83,0xFF,0xE9,0x0C,0x9C,0x49,0xEA,0xAA,0xEA,0x24, +0xEA,0x49,0xEA,0x45,0x50,0x00,0x7F,0xFF,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFE,0x10, +0xDD,0x5E,0x4E,0x12,0x00,0x51,0xEA,0x85,0xC2,0x20,0x3C,0x00,0x01,0x99,0xEA,0x4A, +0x97,0x43,0xD3,0x1B,0xDD,0x59,0xEA,0x9F,0xEA,0xD1,0xF8,0x75,0xE9,0x16,0xEA,0x71, +0x3C,0x00,0x01,0xA0,0xF8,0x7A,0xE9,0x11,0x3C,0x00,0x01,0x9E,0x3C,0x40,0x01,0xA0, +0x3C,0x50,0x01,0xA3,0x97,0x23,0x96,0x03,0xEA,0x78,0x88,0x04,0x88,0x03,0x97,0x2B, +0x40,0xF0,0x10,0x07,0x4E,0xF2,0x00,0xA6,0xEB,0x2F,0x8E,0x01,0xE0,0x40,0xE8,0x2B, +0x3C,0x00,0x01,0x9A,0xEA,0x4A,0x97,0x43,0xD3,0x26,0xDD,0x59,0xEA,0x9F,0xEA,0xD1, +0xF8,0x52,0xE9,0x21,0xEA,0x71,0x3C,0x00,0x01,0xA1,0xF8,0x57,0xE9,0x1C,0x3C,0x00, +0x01,0x9E,0x3C,0x40,0x01,0xA1,0x3C,0x50,0x01,0xA4,0x97,0x23,0x96,0x03,0xEA,0x78, +0x4E,0x00,0x00,0x5C,0xE9,0x10,0x8E,0x21,0x8C,0x41,0xDD,0x51,0xEA,0x83,0xEA,0x24, +0xEA,0x45,0xEA,0x49,0x8C,0x21,0x8E,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFD,0xC0, +0x2E,0x17,0xFE,0x1C,0xEB,0x0C,0x8E,0x01,0xE0,0x20,0x4E,0xF2,0xFF,0x21,0xEA,0x85, +0xC2,0x1C,0x3C,0x00,0x01,0x9B,0xEA,0x4A,0x97,0x43,0xD3,0x17,0xDD,0x59,0xEA,0x9F, +0xEA,0xD2,0xF8,0x21,0xE9,0x12,0xEA,0x71,0x3C,0x00,0x01,0xA0,0xF8,0x26,0xE9,0x0D, +0x3C,0x00,0x01,0x9F,0x3C,0x40,0x01,0xA0,0x3C,0x50,0x01,0xA5,0x97,0x23,0x96,0x03, +0xEA,0x78,0x4E,0x00,0x00,0x2B,0xE8,0x3D,0xEB,0x2F,0x8E,0x01,0xE0,0x40,0x4E,0xF2, +0xFE,0xFF,0x3C,0x00,0x01,0x9C,0xEA,0x4A,0x97,0x43,0x4C,0x51,0xBE,0xF9,0xDD,0x59, +0xEA,0x9F,0xEA,0xD2,0x96,0x03,0x96,0xDB,0x88,0x04,0xE0,0x03,0x83,0xFF,0x4E,0xF3, +0xFE,0xEF,0xEA,0x71,0x3C,0x00,0x01,0xA1,0x96,0xDB,0x97,0x43,0x98,0x23,0xE0,0x05, +0x83,0xFF,0x4E,0xF3,0xFE,0xE5,0x3C,0x00,0x01,0x9F,0x3C,0x40,0x01,0xA1,0x3C,0x50, +0x01,0xA6,0x97,0x23,0x96,0x03,0xEA,0x78,0x88,0x04,0x88,0x03,0x97,0x2B,0xE0,0x04, +0x83,0xFF,0x4E,0xF3,0xFE,0xD5,0x8C,0x21,0x9C,0x91,0xDD,0x51,0xEA,0x83,0xEA,0x24, +0xEA,0x45,0xEA,0x49,0x8E,0x21,0x8E,0x01,0xDD,0x51,0xEA,0x3E,0x48,0xFF,0xFE,0xC8, +0x8C,0x21,0x8E,0x41,0xDD,0x51,0xEA,0x83,0x49,0xFF,0xFE,0x16,0xEA,0x45,0xEA,0x49, +0x8E,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFD,0x52,0xEB,0x0C,0xDD,0x5E, +0x8E,0x01,0x40,0x00,0x80,0x07,0x4E,0x02,0xFE,0xB3,0xEA,0x85,0x48,0xFF,0xFF,0xAE, +0x8E,0x21,0x50,0x21,0x7F,0xFF,0xDD,0x51,0xEA,0x83,0xEA,0x24,0xEA,0x45,0xEA,0x49, +0x8C,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFD,0x3A,0xDD,0x5E,0x4E,0x12, +0xFF,0x7B,0xEA,0x85,0x48,0xFF,0xFF,0x4A,0x84,0x00,0x46,0x11,0x00,0x05,0x12,0x00, +0x82,0xD4,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD5,0x2E,0x30,0x00,0xE1,0x2E,0x10, +0x00,0xE0,0x2E,0x27,0xFC,0xE2,0x3A,0x6F,0xB4,0x3C,0x2E,0x60,0x00,0xBD,0x2E,0x97, +0xFC,0xDE,0x3C,0x03,0xFE,0xBD,0x88,0xC2,0x40,0x61,0x00,0x1A,0x97,0xB1,0x84,0x80, +0x44,0xA0,0x00,0x48,0x47,0x21,0x00,0x02,0x59,0x29,0x01,0x44,0x44,0xB0,0x00,0x4C, +0x44,0x80,0x00,0xFE,0x47,0x31,0x00,0x01,0x59,0x39,0x8E,0xB0,0x96,0x20,0xE2,0x03, +0xE8,0x36,0x80,0xF2,0x82,0x12,0x42,0x72,0x28,0x73,0x43,0x02,0x2C,0x73,0x50,0x73, +0x99,0x54,0x51,0x08,0x29,0xB2,0x84,0xA0,0x51,0x10,0x00,0x01,0xD1,0x1E,0xA4,0x38, +0x8C,0xA1,0x96,0x03,0xE0,0xC0,0xE8,0x15,0x12,0x88,0x00,0x00,0xEB,0x4F,0xEA,0xA8, +0x40,0xC9,0x80,0x20,0x5C,0xF0,0x00,0x95,0x39,0x19,0x81,0x08,0x10,0x56,0x00,0x01, +0xE8,0x04,0x8C,0x01,0x40,0x00,0x00,0x13,0x46,0xC1,0x00,0x05,0x12,0x06,0x02,0xD4, +0x8C,0xE2,0x97,0x68,0x8D,0x82,0xD5,0xE3,0xEB,0x4F,0xEA,0xA8,0x8C,0x81,0xE2,0x09, +0xE9,0xCE,0x84,0x01,0xEA,0xFA,0x44,0x00,0x00,0x00,0xEA,0x51,0x2E,0x60,0x00,0xB7, +0x4E,0x63,0x00,0x0E,0xEB,0x4F,0x02,0x50,0x02,0xD5,0xEA,0xEB,0x9F,0x01,0x2E,0x07, +0xFF,0xC9,0x8E,0x01,0xFE,0x24,0xE0,0xA0,0xE9,0x26,0xD5,0x23,0x44,0x00,0x00,0x64, +0xFF,0x84,0x41,0x00,0x84,0x08,0xEB,0x55,0xEA,0xAD,0x84,0xA0,0xD3,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,0x0F,0xFF,0xCC,0x4E,0x04,0x00,0x4E,0x46,0x51,0x00,0x02, +0x58,0x52,0x81,0x44,0x9D,0xC9,0x84,0x00,0x8C,0x61,0x45,0x00,0x00,0x4C,0x82,0x25, +0x44,0x60,0x00,0xFC,0xFB,0xD6,0xE0,0x60,0xE9,0x1A,0x80,0x85,0x42,0x40,0x40,0x73, +0x22,0xF2,0x11,0xBA,0xE0,0x4F,0xE8,0x03,0x12,0x62,0x14,0xB2,0x80,0x87,0x42,0x40, +0x48,0x73,0x41,0x38,0x90,0x20,0x22,0xF9,0x91,0xBA,0xE0,0x4F,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,0xEC,0xE0,0x20,0xE9,0x18,0x40,0x52,0x00,0x20,0x22,0xF2,0x91,0xBA,0xE0,0x4F, +0xE8,0x03,0x12,0x62,0x94,0xB2,0x99,0x58,0x41,0x03,0x94,0x20,0x22,0xF8,0x11,0xBA, +0xE0,0x4F,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,0xFD,0xD4,0x84,0xC0,0x80,0x06,0x8C,0xC1,0x54,0x63,0x00,0xFF, +0x49,0xFF,0xFC,0xD4,0x5A,0x68,0x0C,0xFA,0x84,0x20,0xB9,0x80,0xB9,0x8E,0xEB,0x4F, +0x02,0x20,0x02,0xD4,0x2E,0x07,0xFC,0xEE,0x92,0x01,0xE2,0x40,0xE8,0x24,0x3C,0x03, +0xFE,0xA3,0x8C,0x01,0x96,0x01,0xEA,0x51,0x2E,0x47,0xFF,0x7B,0x84,0x6A,0xFE,0xE4, +0xE0,0x60,0xE8,0x19,0x3C,0x1B,0xFE,0xA3,0x3E,0x17,0xFD,0x0F,0x3E,0x17,0xFD,0x1D, +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,0x51,0x3E,0x07,0xFD,0x0F,0xEA,0xFA, +0xEA,0x97,0xC0,0xE8,0xEA,0x56,0x96,0x04,0xC0,0xE5,0x84,0x00,0x3E,0x07,0xFD,0x20, +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,0x1C, +0x3E,0x67,0xFE,0x1D,0x49,0xFF,0xFC,0x98,0x2E,0x17,0xFC,0xEE,0xEB,0x65,0x04,0x00, +0x00,0x08,0xE2,0x20,0xE8,0x06,0x84,0x01,0x3E,0x07,0xFD,0x0F,0x84,0x00,0xEA,0x51, +0x2E,0x07,0xFF,0x5A,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,0x75,0xB8,0x0E,0x8C,0x01,0xB8,0x8E,0x84,0x0B, +0x49,0xFF,0xFC,0x44,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,0x0F,0xC0,0xCE,0xEA,0x4E, +0x96,0x00,0xC8,0xCB,0xB8,0x80,0x84,0x01,0xEA,0xFA,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,0xF5,0x80,0x0D,0x44,0x10,0x00,0x0B,0xEA,0xF5, +0x54,0x06,0x80,0xFF,0xD5,0xC2,0x84,0x2B,0x49,0xFF,0xFB,0xD8,0x48,0xFF,0xFF,0xC0, +0x3C,0x2D,0xFF,0x75,0x2E,0x37,0xFD,0x01,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,0x07,0xEC,0x04,0x3A,0x6F, +0xBA,0x84,0xDD,0x9E,0xFC,0x60,0x51,0xFF,0xFB,0xA0,0x3D,0x3D,0xFF,0x75,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,0xC4,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,0x7F,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,0xFC,0xDF,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,0x12,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,0xC6,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,0x3A, +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,0x3A,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,0x3A,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,0x6A,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,0x75,0xE2,0xF3, +0x4E,0xF2,0x00,0xFA,0x2E,0x57,0xFD,0x19,0xB0,0x44,0x38,0x20,0x9E,0x02,0x3C,0x1D, +0xFF,0x7F,0x2E,0x37,0xFD,0x0E,0xE2,0x41,0x2E,0x00,0x00,0xEA,0x4E,0xF2,0x00,0x77, +0xEB,0x12,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,0x20,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,0x20, +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,0x00,0xE3,0x3C,0x23,0xFE,0xA5,0x84,0x80,0x41,0x21,0x04,0x08, +0x3C,0x23,0xFE,0xA1,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,0x06, +0x2E,0x47,0xFD,0x18,0xEB,0x79,0x58,0x10,0x8C,0xCC,0x9D,0x43,0x84,0x7D,0x38,0x10, +0x98,0x00,0x42,0x52,0x0C,0x73,0xE0,0x25,0xE9,0x30,0x84,0x00,0xEA,0xC6,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,0xEC, +0xEB,0x79,0xEA,0x72,0x38,0x70,0x80,0x08,0xEB,0x79,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, +0xE4,0xF4,0xB4,0x5F,0x05,0x4F,0x80,0x01,0x05,0x6F,0x80,0x02,0x05,0x5F,0x80,0x03, +0xC8,0xBD,0x3C,0x33,0xFE,0xA5,0x3C,0x13,0xFE,0xA1,0xFE,0x5C,0xFE,0x8C,0xE2,0x4B, +0xE8,0x09,0xEB,0x79,0x58,0x10,0x8C,0x0C,0x38,0x07,0x1A,0x0A,0x38,0x00,0x9A,0x0A, +0xD5,0xD7,0xB0,0x04,0x38,0x00,0x1E,0x02,0xEB,0x12,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,0xFC,0xDF,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,0x90, +0xB9,0x00,0x2E,0x07,0xFF,0x90,0x5A,0x18,0x07,0x03,0x92,0x01,0x3E,0x07,0xFC,0xDC, +0xB8,0x11,0xC0,0x05,0x2E,0x07,0xFC,0xD8,0x5A,0x08,0x01,0x37,0x2E,0x37,0xFC,0xDC, +0x2E,0x27,0xFF,0x93,0xB8,0x17,0xFE,0x9C,0xE2,0x02,0xE8,0x07,0xEA,0xCC,0x42,0x10, +0x8C,0x0B,0xC1,0x2C,0x8C,0x01,0xD5,0x29,0x84,0x01,0xEB,0x10,0x84,0x00,0xEA,0xCF, +0x84,0x00,0xB8,0x8E,0x84,0x01,0xB8,0x9C,0x84,0x08,0x5A,0x10,0x07,0x09,0x5A,0x18, +0x02,0x0A,0x2E,0x07,0xFF,0x5F,0x5A,0x08,0x03,0x06,0x84,0x06,0x2E,0x17,0xFC,0xE9, +0xEA,0x3D,0x84,0x00,0xEB,0x16,0x2E,0x07,0xFC,0xE9,0xC0,0x03,0x84,0x00,0xEB,0x2C, +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,0x90,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,0xFC,0xD8, +0x5A,0x18,0x01,0x32,0x84,0x20,0x3E,0x17,0xFC,0xF5,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,0xFC,0xD8,0xEA,0x3D,0x84,0x00,0xEB,0x16, +0xB8,0x00,0x5A,0x08,0x07,0x05,0xEB,0x65,0xEB,0x48,0xD5,0x05,0xEA,0x29,0xC8,0x05, +0xEB,0x65,0xEA,0xB4,0xB8,0x9A,0xD5,0x1E,0x5A,0x08,0x01,0x1D,0xEB,0x65,0xDD,0x5C, +0xD5,0xFA,0x8E,0x03,0xE6,0x03,0xE8,0x16,0xEA,0x43,0xB4,0x01,0x58,0x00,0x04,0x00, +0xB6,0x01,0xD5,0x10,0x2E,0x27,0xFF,0x92,0xFA,0x2E,0xFE,0x54,0x2E,0x27,0xFF,0x93, +0xB8,0x0E,0xFE,0x54,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x8E,0xD5,0x03,0x84,0x01, +0xEA,0xCF,0xFC,0x80,0xDD,0x4D,0x5A,0x08,0x08,0x05,0x2E,0x27,0xFF,0x66,0xD5,0x06, +0x84,0x40,0x5A,0x08,0x06,0x04,0x2E,0x27,0xFF,0x71,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,0x4D,0x5A,0x08,0x08,0x09, +0x2E,0x17,0xFF,0x66,0x94,0x49,0x96,0x4B,0x2E,0x57,0xFF,0x9D,0xD5,0x0C,0x5A,0x08, +0x06,0x09,0x2E,0x17,0xFF,0x71,0x94,0x49,0x96,0x4B,0x2E,0x57,0xFF,0x99,0xD5,0x03, +0x84,0x20,0x80,0xA1,0x84,0x40,0x3C,0x6D,0xFF,0x7E,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,0x07,0xFF,0xCD,0xE2,0x04,0xE8,0x0A, +0x46,0x01,0x00,0x01,0x00,0x00,0x02,0xC0,0xEB,0x79,0xEA,0x37,0xEA,0xEE,0x84,0x01, +0xEA,0x75,0xFC,0xA0,0xEB,0x26,0xDD,0x9E,0xEA,0xC3,0xC0,0x04,0x84,0x00,0x3C,0x0F, +0xFF,0x80,0xDD,0x9E,0xFC,0x40,0x3F,0xCF,0xFD,0xAC,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,0x20,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,0xEF,0xDD,0x42,0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x0C, +0x84,0x20,0xEA,0xEF,0xDD,0x42,0xC6,0x04,0x2E,0x07,0xFF,0xC3,0xD5,0x07,0xC7,0x04, +0x2E,0x07,0xFF,0xC5,0xD5,0x03,0x2E,0x07,0xFF,0xC7,0x8C,0x01,0xEA,0xF9,0x2E,0x07, +0xFD,0x1C,0x5A,0x08,0x01,0x04,0x84,0x02,0xEA,0xF9,0xEA,0xD3,0x85,0x20,0xEA,0xCD, +0x3E,0x97,0xFD,0x0F,0x3E,0x97,0xFD,0x1D,0x3E,0x97,0xFD,0x16,0x84,0x40,0x3E,0x97, +0xFC,0xDF,0xBA,0x8A,0xBA,0x98,0xEB,0x4F,0x12,0x20,0x02,0xD4,0xBA,0x94,0xBA,0x8D, +0xBA,0x96,0x3E,0x27,0xFD,0x08,0xBA,0x92,0x3E,0x97,0xFD,0x13,0xBA,0x90,0xEA,0xC0, +0x92,0x27,0x8C,0x21,0x96,0x48,0x3E,0x17,0xFD,0x23,0xEA,0xA4,0x92,0x07,0x8C,0x01, +0x96,0x00,0x3E,0x07,0xFD,0x14,0x2E,0x27,0xFF,0x76,0x2E,0x40,0x00,0xEA,0x3E,0x27, +0xFD,0x0E,0x54,0x31,0x00,0x0F,0x42,0x51,0x90,0x24,0x92,0x44,0x40,0x12,0x84,0x36, +0x3C,0x1B,0xFE,0xA2,0x2E,0x10,0x00,0xEB,0xFF,0x14,0xFE,0xCC,0xFE,0x8C,0x40,0x01, +0x80,0x16,0x3C,0x0B,0xFE,0xAA,0x3C,0x4B,0xFE,0xA5,0x3C,0x2B,0xFE,0xA1,0x2E,0x07, +0xFF,0x75,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x06,0x92,0x04,0x3E,0x07,0xFD,0x19, +0x2E,0x07,0xFF,0x5D,0x92,0x04,0x3E,0x07,0xFC,0xE3,0x84,0x02,0xB8,0x85,0x2E,0x07, +0xFF,0x60,0xDD,0x49,0x3C,0x0B,0xFE,0xA4,0x2E,0x07,0xFF,0x6A,0xDD,0x49,0x3C,0x0B, +0xFE,0xA8,0x2E,0x07,0xFF,0x6B,0xDD,0x49,0x3C,0x0B,0xFE,0xA9,0x3E,0x97,0xFC,0xF9, +0x3E,0x97,0xFD,0x1E,0x3E,0x97,0xFC,0xFA,0x2E,0x07,0xFF,0x7E,0xEA,0x73,0x2E,0x07, +0xFF,0x7F,0xEA,0xBC,0x2E,0x07,0xFF,0x81,0x40,0x10,0x10,0x09,0x3E,0x17,0xFD,0x0A, +0x96,0x1F,0x84,0x2A,0xFE,0x0C,0x3E,0x07,0xFC,0xF2,0x2E,0x07,0xFF,0x8B,0x3C,0x0B, +0xFE,0xAD,0xC7,0x0B,0x2E,0x07,0xFF,0x86,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFC,0xF0, +0x92,0x04,0x3E,0x07,0xFC,0xE4,0xD5,0x13,0x2E,0x07,0xFF,0x84,0x54,0x10,0x00,0x0F, +0x3E,0x17,0xFC,0xF0,0x92,0x04,0x3E,0x07,0xFC,0xE4,0x2E,0x07,0xFF,0x85,0x54,0x10, +0x00,0x0F,0x3E,0x17,0xFC,0xD9,0x92,0x04,0x3E,0x07,0xFC,0xF1,0x49,0xFF,0xEF,0x28, +0x46,0x01,0x00,0x01,0x58,0x00,0x0B,0x94,0x84,0x3F,0x84,0x4C,0xDD,0x42,0x84,0x00, +0x3E,0x07,0xFD,0x05,0x2E,0x17,0xFF,0x96,0x84,0x00,0x40,0x00,0x04,0x06,0x3E,0x07, +0xFC,0xF3,0x2E,0x27,0xFF,0x8E,0x3E,0x27,0xFC,0xE0,0x2E,0x37,0xFF,0x8F,0xFA,0x24, +0x42,0x21,0x84,0x73,0x96,0x90,0x3E,0x27,0xFC,0xFF,0xC0,0x02,0x84,0x44,0x3E,0x27, +0xFC,0xE7,0x2E,0x07,0xFF,0x90,0x84,0x40,0x3E,0x07,0xFC,0xDC,0x3E,0x27,0xFC,0xFE, +0x3E,0x27,0xFD,0x20,0x3E,0x27,0xFD,0x0D,0x3E,0x27,0xFC,0xD6,0x3E,0x27,0xFC,0xF6, +0x3E,0x27,0xFC,0xDD,0x84,0x00,0x3C,0x0B,0xFE,0xA7,0x3E,0x07,0xFD,0x07,0x2E,0x07, +0xFF,0x80,0x3E,0x07,0xFD,0x01,0x2E,0x00,0x00,0xB8,0x54,0x10,0x00,0x0F,0x3E,0x17, +0xFD,0x0C,0x92,0x04,0x3E,0x07,0xFD,0x22,0x2E,0x00,0x00,0xB9,0x54,0x10,0x00,0x0F, +0x3E,0x17,0xFD,0x12,0x92,0x04,0x3E,0x07,0xFC,0xD5,0x3E,0x27,0xFD,0x26,0xCE,0x03, +0x3E,0x27,0xFD,0x31,0x3E,0x27,0xFD,0x2A,0x3E,0x27,0xFD,0x2F,0x3E,0x27,0xFD,0x27, +0x3E,0x27,0xFD,0x29,0x3E,0x27,0xFD,0x2B,0x3E,0x27,0xFD,0x2E,0x84,0x00,0xB8,0x9F, +0xB8,0x9E,0x2E,0x4F,0xFF,0x5B,0x4E,0x45,0x00,0x03,0x84,0x02,0x84,0x40,0x3E,0x07, +0xFD,0x17,0x86,0x00,0x3E,0x27,0xFD,0x2C,0x84,0xA0,0x3D,0x0B,0xFE,0xC3,0xBD,0x9D, +0x2E,0x30,0x00,0x22,0xEA,0x2A,0xFE,0xCC,0x3C,0x3B,0xFE,0xC2,0x2E,0x30,0x00,0x23, +0xFE,0xCC,0x3C,0x3B,0xFE,0xC5,0x2E,0x30,0x00,0x24,0xFE,0xCC,0x3C,0x3B,0xFE,0xBF, +0x2E,0x30,0x00,0x25,0xFE,0x5C,0x3C,0x1B,0xFE,0xC4,0x2E,0x10,0x00,0x26,0x3C,0x1B, +0xFE,0xC0,0x2E,0x10,0x00,0x27,0x3E,0x17,0xFD,0x2D,0x2E,0x10,0x00,0x29,0x3E,0x17, +0xFD,0x30,0x3F,0x07,0xFD,0x28,0x3E,0x27,0xFC,0xDA,0xBD,0x89,0x3E,0x27,0xFD,0x21, +0x3E,0x27,0xFD,0x24,0x3E,0x27,0xFC,0xE1,0x2E,0x10,0x00,0x1A,0x40,0x30,0x90,0x09, +0x3E,0x37,0xFC,0xEA,0x96,0x5F,0x3E,0x17,0xFD,0x0B,0xCE,0x10,0x3E,0x27,0xFC,0xF5, +0xEB,0x79,0x10,0x20,0x82,0xC0,0xEB,0x79,0x10,0x20,0x82,0xC1,0x84,0x21,0x3E,0x17, +0xFC,0xE8,0x3E,0x27,0xFD,0x11,0xBE,0x80,0xBE,0x86,0xC7,0x04,0xEB,0x65,0xEB,0x48, +0xD5,0x12,0x4E,0x44,0x00,0x0C,0xC8,0x08,0xEA,0x29,0xE6,0x01,0x3E,0xF7,0xFD,0x31, +0x84,0x01,0x3E,0x07,0xFD,0x17,0xEA,0x29,0xC8,0x04,0xEB,0x65,0xEA,0xB4,0xD5,0x03, +0xEB,0x65,0xDD,0x5C,0xB8,0x93,0x84,0xE0,0x44,0x20,0x05,0x10,0x3E,0x77,0xFC,0xF8, +0x84,0x20,0xEB,0x4F,0xEA,0x61,0xDD,0x42,0x3E,0x77,0xFC,0xF5,0x84,0x01,0xEB,0x2C, +0x84,0xC0,0x3E,0x77,0xFC,0xD8,0xBE,0x87,0x49,0xFF,0xDB,0xB4,0xEB,0x4F,0x12,0x60, +0x02,0xD6,0x3C,0x6B,0xFE,0xA3,0x3E,0x67,0xFD,0x15,0x3C,0x6B,0xFE,0x9F,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,0x28,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,0x1C,0x5A,0x18,0x02,0x05,0x3E,0x27,0xFC,0xFD,0xD5,0x0E,0x8E,0x07, +0xE6,0x02,0xE8,0x05,0x2E,0x07,0xFF,0xC4,0xEA,0xDD,0xD5,0x05,0x2E,0x17,0xFF,0xC6, +0x40,0x01,0x04,0x40,0x3E,0x07,0xFC,0xFD,0x84,0x00,0x3E,0x07,0xFC,0xE6,0xEA,0xBB, +0xEA,0xC7,0xDD,0x9E,0xFC,0x0B,0x3F,0xCF,0xFD,0x90,0x2E,0x07,0xFD,0x03,0xC8,0x12, +0xB8,0x0C,0x5A,0x00,0x02,0x09,0x2E,0x07,0xFF,0x88,0xDD,0x49,0xEA,0x35,0x2E,0x07, +0xFF,0x89,0xD5,0x0E,0x2E,0x07,0xFF,0x8C,0xDD,0x49,0xEA,0x35,0x2E,0x07,0xFF,0x8D, +0xD5,0x07,0xEA,0xA1,0x96,0x1F,0xDD,0x49,0xEA,0x35,0xEA,0xA1,0x92,0x04,0xDD,0x49, +0xEA,0x53,0xEA,0x4E,0xC0,0x09,0x2E,0x00,0x00,0x1B,0xDD,0x49,0xEA,0x35,0x2E,0x00, +0x00,0x1B,0xDD,0x49,0xEA,0x53,0xEA,0x44,0xC0,0x07,0xEB,0x1A,0x94,0x01,0xEA,0x35, +0xEB,0x09,0x94,0x01,0xEA,0x53,0xDD,0x54,0x5A,0x08,0x01,0x04,0x49,0x00,0x03,0x31, +0xEB,0x07,0xEA,0xFF,0xDD,0x4C,0x42,0x00,0x18,0x0B,0xC0,0x06,0xDD,0x54,0x5A,0x08, +0x01,0x04,0x49,0x00,0x04,0x64,0xB8,0x1B,0xB9,0x11,0xE2,0x01,0xE8,0x0C,0xC0,0x0B, +0xEA,0x4E,0xC0,0x09,0xEB,0x1A,0x94,0x01,0xEA,0x35,0xEB,0x09,0x94,0x01,0xEA,0x53, +0xEB,0x07,0xEA,0xFF,0x84,0x00,0x3E,0x07,0xFD,0x10,0xDD,0x4C,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,0xB2,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,0x65, +0x04,0x00,0x00,0x2F,0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x32,0x92,0x01,0xE2,0x20, +0xE8,0x04,0x84,0x01,0x3E,0x07,0xFD,0x10,0xB8,0x1B,0xE2,0x40,0xE8,0x12,0x2E,0x07, +0xFD,0x03,0xC0,0x0F,0xEA,0x4E,0xC8,0x0D,0xEA,0xE0,0xC8,0x0B,0xEA,0xA1,0x96,0x1F, +0xDD,0x49,0xEA,0x35,0xEA,0xA1,0x92,0x04,0xDD,0x49,0xEA,0x53,0xEB,0x07,0xEA,0xFF, +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,0x19,0x40,0x00,0x80,0x20,0x22,0xF0,0x0C,0xA9,0x2E,0x07,0xFF,0x62,0x94,0x01, +0xE0,0x0F,0xE8,0x06,0x84,0x00,0xEA,0xCD,0xEA,0xE5,0xC1,0x11,0xD5,0x0E,0x3C,0x03, +0xFE,0xA0,0x5C,0xF0,0x03,0xE8,0xE8,0x0B,0x8C,0x01,0xEA,0xCD,0x3C,0x03,0xFE,0x9C, +0x5C,0xF0,0x00,0xC8,0xE8,0x04,0x8C,0x01,0x3C,0x0B,0xFE,0x9C,0x46,0x01,0x00,0x07, +0xEA,0x62,0xEA,0x21,0xEA,0x20,0xD8,0x17,0x49,0xFF,0xE2,0xEC,0x49,0xFF,0xE1,0x68, +0x49,0xFF,0xF9,0x12,0x49,0xFF,0xE7,0x79,0x49,0xFF,0xE4,0x2F,0x49,0xFF,0xE4,0xE1, +0xDD,0x54,0x5A,0x08,0x01,0x10,0x46,0x01,0x00,0x01,0x58,0x00,0x09,0x48,0x49,0xFF, +0xDE,0x62,0xD5,0x08,0xDD,0x4C,0xEA,0xF3,0xC8,0xE8,0xDD,0x54,0x5A,0x08,0x01,0x30, +0xD5,0xE4,0x46,0x01,0x00,0x05,0xEA,0x52,0x49,0xFF,0xE5,0xC8,0x46,0x01,0x00,0x05, +0xEA,0x52,0x49,0xFF,0xE0,0xA0,0xB8,0x00,0x5A,0x08,0x07,0x1F,0xB1,0x82,0x80,0x26, +0x46,0x21,0x00,0x01,0xEB,0x3B,0x46,0x01,0x00,0x05,0xEA,0x52,0x46,0x31,0x00,0x01, +0x58,0x31,0x8D,0x68,0x49,0xFF,0xEB,0xC1,0xF0,0x81,0xF2,0x01,0x3A,0x03,0x04,0x00, +0x49,0xFF,0xF3,0xBA,0x5A,0x00,0xFF,0x09,0x3E,0x07,0xFD,0xDC,0x96,0x01,0x46,0x11, +0x00,0x07,0x12,0x00,0x81,0xDB,0x84,0x00,0x3E,0x07,0xFC,0xDF,0x46,0x01,0x00,0x05, +0xEA,0x52,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,0x52,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,0x78,0xDD,0x9E, +0x3C,0x13,0xFE,0xC1,0x3C,0x53,0xFE,0xC0,0xD9,0x07,0x84,0x00,0x3E,0x07,0xFD,0x26, +0x84,0x00,0xEB,0x18,0xDD,0x9E,0xC8,0x06,0xEA,0x44,0xC0,0x04,0x8C,0x21,0x3C,0x1B, +0xFE,0xC1,0xDD,0x9E,0xFC,0x00,0x84,0x01,0x3E,0x07,0xFD,0x2A,0x3E,0x07,0xFD,0x2C, +0x84,0x00,0x3C,0x0B,0xFE,0xC3,0x84,0x21,0x3C,0x1F,0xFF,0x88,0xEB,0x18,0xFC,0x80, +0xFC,0x00,0x3C,0x1D,0xFF,0x88,0x5A,0x18,0x01,0x1F,0x2E,0x17,0xFD,0x2A,0x5A,0x18, +0x01,0x14,0x84,0x40,0x3E,0x27,0xFD,0x2A,0x2E,0x37,0xFD,0x31,0xCB,0x04,0x3E,0x17, +0xFD,0x31,0xD5,0x06,0x5A,0x38,0x01,0x09,0x3E,0x27,0xFD,0x31,0x84,0x20,0x49,0x00, +0x06,0xAB,0x49,0x00,0x0A,0xF1,0x2E,0x07,0xFD,0x2B,0x8C,0x01,0x3E,0x07,0xFD,0x2B, +0x84,0x02,0xD5,0x07,0x84,0x03,0x5A,0x10,0x02,0x05,0x5A,0x18,0x03,0x05,0x84,0x00, +0x3C,0x0F,0xFF,0x88,0xFC,0x80,0xFC,0x00,0x3C,0x1F,0xFF,0x7E,0x84,0x20,0x3C,0x1F, +0xFF,0x7D,0xDD,0x4F,0x46,0x01,0x00,0x05,0xEA,0x61,0xDD,0x42,0xFC,0x80,0xFC,0x00, +0x3F,0xCF,0xFD,0xD0,0xEB,0x08,0xC9,0x04,0x3C,0x63,0xFE,0xC2,0xD5,0x07,0x5A,0x18, +0x01,0x05,0x3C,0x63,0xFE,0xC5,0xD5,0x02,0xEA,0xB3,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,0x2F,0xCA,0x03,0xB8,0x96,0xD5,0x02,0xB8,0x95,0x2E,0x07,0xFD,0x2E,0xE6,0x0A, +0xE8,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x2E,0x2E,0x07,0xFD,0x2E,0xE6,0x02,0x4E,0xF3, +0x00,0x7C,0xC9,0x43,0x3C,0x23,0xFE,0xBF,0xB8,0x16,0xE2,0x40,0xE8,0x07,0x84,0x01, +0x3E,0x07,0xFD,0x26,0x3C,0x1B,0xFE,0xC1,0xD5,0x04,0xB8,0x01,0x49,0xFF,0xFF,0x6A, +0xB8,0x15,0x88,0xC0,0xB8,0x16,0xE2,0xC0,0xE8,0x03,0xEA,0x44,0xC8,0x05,0xB8,0x00, +0xEB,0x14,0x5A,0x08,0x01,0x12,0x2E,0x0F,0xFF,0x5B,0x4E,0x04,0x00,0x0E,0x46,0x01, +0x00,0x07,0xEA,0x26,0xEA,0x47,0xEA,0x3F,0xD0,0x07,0x46,0x01,0x00,0x07,0xEA,0x26, +0xEA,0x21,0xEA,0x20,0xD8,0x08,0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x21,0xEA,0x20, +0x4C,0x50,0x40,0x4B,0xEB,0x35,0x46,0x01,0x00,0x02,0xEA,0xB4,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,0xC4, +0xB8,0x15,0xE2,0x40,0xE8,0x06,0x3E,0x17,0xFD,0x26,0x84,0x00,0xEB,0x18,0xD5,0x04, +0xB8,0x01,0x49,0xFF,0xFF,0x27,0xB8,0x16,0x88,0xC0,0xB8,0x15,0xE2,0xC0,0xE8,0x03, +0xEA,0x44,0xC8,0x05,0xB8,0x00,0xEB,0x14,0x5A,0x08,0x01,0x12,0x2E,0x0F,0xFF,0x5B, +0x4E,0x04,0x00,0x0E,0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x47,0xEA,0x3F,0xD0,0x07, +0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x21,0xEA,0x20,0xD8,0x07,0x46,0x01,0x00,0x07, +0xEA,0x26,0xEA,0x47,0xEA,0x3F,0xD8,0x08,0xEB,0x35,0x46,0x01,0x00,0x02,0xDD,0x5C, +0x50,0x10,0x7A,0xF0,0xD5,0xBE,0xB8,0x04,0xC8,0x2F,0xEA,0x29,0x5A,0x08,0x01,0x2D, +0x2E,0x17,0xFC,0xF5,0xC9,0x29,0x3C,0x03,0xFE,0xBF,0xBA,0x16,0xE2,0x40,0xE8,0x24, +0x3C,0x03,0xFE,0xC4,0xBA,0x15,0xE2,0x40,0xE8,0x1F,0x46,0x01,0x00,0x07,0xEA,0x26, +0xEA,0x21,0xEA,0x20,0xD0,0x19,0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x47,0xEA,0x3F, +0xD0,0x13,0x2E,0x07,0xFD,0x28,0x5C,0xF0,0x00,0xC8,0xE8,0x03,0x8C,0x01,0xD5,0x0D, +0x3E,0x17,0xFD,0x28,0xEB,0x35,0x46,0x01,0x00,0x02,0xDD,0x5C,0x50,0x10,0x7A,0xF0, +0x49,0xFF,0xFF,0x1B,0xD5,0x04,0x84,0x00,0x3E,0x07,0xFD,0x28,0xB9,0x01,0x2E,0x07, +0xFD,0x2C,0xC0,0x0F,0xC9,0x0E,0x3C,0x03,0xFE,0xC3,0x2E,0x27,0xFD,0x2D,0xE2,0x40, +0xE8,0x06,0x3E,0x17,0xFD,0x2C,0x3C,0x1B,0xFE,0xC3,0xD5,0x06,0x8C,0x01,0xD5,0x02, +0x84,0x00,0x3C,0x0B,0xFE,0xC3,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xD4,0x3C,0x13, +0xFE,0xBF,0xB8,0x15,0xE2,0x20,0xE9,0x06,0x3C,0x13,0xFE,0xC4,0xB8,0x14,0xE2,0x20, +0xE8,0x05,0x2E,0x07,0xFD,0x15,0xC8,0x02,0xEA,0x75,0x2E,0x07,0xFD,0x04,0xC0,0x2D, +0x84,0x00,0xEA,0x75,0x2E,0x17,0xFC,0xE0,0xB8,0x0C,0xE2,0x20,0xEA,0xCC,0xE8,0x22, +0x42,0x20,0x84,0x0B,0xC2,0x1F,0xBA,0x00,0xC2,0x04,0x2E,0x27,0xFD,0x15,0xC2,0x1A, +0xDD,0x54,0x5C,0x10,0x00,0x01,0x84,0x01,0xEA,0xBA,0xDD,0x54,0x5A,0x00,0x01,0x04, +0x84,0x07,0xD5,0x02,0x84,0x02,0x84,0x22,0xEA,0x3D,0xDD,0x54,0x80,0xC0,0x5A,0x08, +0x01,0x0E,0xEA,0x36,0xC8,0x04,0xEA,0x95,0xEA,0xC2,0xD5,0x08,0x3E,0x67,0xFC,0xD2, +0xD5,0x05,0xEA,0x5C,0xC1,0x03,0x8C,0x01,0xB8,0x8C,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0x46,0x01,0x00,0x07,0x04,0x50,0x03,0xCE,0xEA,0x21,0xEA,0x20,0xD8,0x03, +0x84,0x03,0xD5,0x1E,0x46,0x01,0x00,0x05,0xEB,0x21,0x3C,0x13,0xFE,0xA4,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,0x61,0xEA,0x4B,0x3C,0x03,0xFE,0xA8,0xEA,0x88, +0x2E,0x07,0xFC,0xF0,0xD5,0x22,0x5A,0x08,0x02,0x17,0x2E,0x07,0xFF,0x62,0xEA,0x4B, +0x3C,0x03,0xFE,0xA9,0xEA,0x88,0x2E,0x07,0xFC,0xF0,0xEA,0x70,0x2E,0x07,0xFC,0xF1, +0xEA,0x93,0x2E,0x07,0xFF,0x7E,0xEA,0x73,0x2E,0x07,0xFF,0x7F,0xEA,0xBC,0x2E,0x00, +0x00,0x9E,0xD5,0x16,0x5A,0x08,0x03,0x18,0x2E,0x07,0xFF,0x63,0xEA,0x4B,0x3C,0x03, +0xFE,0xA8,0xEA,0x88,0x2E,0x07,0xFC,0xE4,0xEA,0x70,0xEA,0xF7,0xEA,0x93,0x2E,0x07, +0xFF,0x7C,0xEA,0x73,0x2E,0x07,0xFF,0x7D,0xEA,0xBC,0x2E,0x00,0x00,0x9D,0xDD,0x49, +0x3C,0x0B,0xFE,0xAB,0xEB,0x01,0xC0,0x1C,0xEB,0x25,0xC8,0x1A,0x2E,0x00,0x00,0x0A, +0xEA,0x4B,0x2E,0x00,0x00,0x0C,0xEA,0x88,0x2E,0x00,0x00,0x0F,0x40,0x10,0x10,0x09, +0x3E,0x17,0xFC,0xDB,0xB9,0x1B,0x5A,0x18,0x01,0x04,0x96,0x1F,0xD5,0x02,0xEA,0xF7, +0xEA,0x93,0x2E,0x07,0xFF,0x7C,0xEA,0x73,0x2E,0x00,0x00,0x0E,0xEA,0xBC,0xB8,0x00, +0x5A,0x08,0x07,0x05,0x2E,0x07,0xFF,0x65,0xEA,0x4B,0xEB,0x26,0xC0,0x04,0x2E,0x07, +0xFF,0x71,0xEA,0x4B,0xEA,0x44,0xC0,0x07,0x2E,0x07,0xFC,0xE4,0xEA,0x70,0xEA,0xF7, +0x8C,0x02,0xEA,0x93,0xB8,0x1C,0xC0,0x03,0x84,0x00,0xEA,0x70,0xFC,0x80,0xFC,0x40, +0x2E,0x50,0x00,0x10,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,0x4C,0xEB,0x1B, +0x4E,0x02,0x01,0x2C,0xEA,0x82,0x3C,0x0D,0xFF,0x78,0x4E,0x13,0x01,0x0E,0xE6,0x02, +0x4E,0xF2,0x01,0x0B,0x2E,0x37,0xFD,0x1D,0x4E,0x33,0x01,0x07,0x2E,0x20,0x00,0x14, +0x2E,0x70,0x00,0xE1,0x54,0x01,0x00,0x0F,0x8C,0xE1,0x9C,0x41,0x8A,0xE0,0xEA,0x31, +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,0x7F,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,0x3B,0x2E,0x10,0x00,0x3C,0xE2,0x04, +0x40,0x10,0x80,0x06,0x41,0x07,0x84,0x02,0x3F,0x07,0xFD,0x0D,0x2E,0x10,0x00,0x12, +0xE2,0x20,0xE8,0x0D,0x2E,0x10,0x00,0x11,0xE2,0x01,0xE8,0x09,0x3C,0x43,0xFE,0xA0, +0x2E,0x70,0x00,0x13,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,0x15,0xE2,0x20,0xE8,0x03,0x4F,0x02,0x00,0x0E, +0x2E,0x10,0x00,0x3E,0xE2,0x20,0x4E,0xF2,0x00,0x84,0x2E,0x10,0x00,0x3D,0xE2,0x01, +0x4E,0xF2,0x00,0x7F,0x4F,0x02,0x00,0x7D,0xEA,0x8F,0x5A,0x08,0xFF,0x04,0x48,0x00, +0x00,0x7D,0xC8,0x08,0x3E,0x27,0xFC,0xF6,0x3E,0x37,0xFC,0xDD,0x3E,0x07,0xFC,0xEB, +0xD5,0x4F,0x2E,0x07,0xFC,0xF6,0xE2,0x40,0xE8,0x03,0x9A,0x82,0xD5,0x02,0x8A,0x40, +0x2E,0x07,0xFC,0xDD,0x96,0x90,0xE2,0x60,0xE8,0x03,0x9A,0xC3,0xD5,0x02,0x8A,0x60, +0xDD,0x5A,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,0x16,0x5A,0x68,0x01,0x0F, +0x96,0x1F,0xE0,0x02,0xE9,0x03,0xE0,0x03,0xE8,0x03,0x84,0x1F,0xEA,0xB9,0x2E,0x57, +0xFC,0xD6,0xD9,0x26,0x84,0x01,0xEB,0x0D,0xD5,0x23,0x92,0x04,0xE2,0x02,0xE9,0x03, +0xE2,0x03,0xE8,0x04,0x84,0x1F,0xEA,0xB9,0xD5,0x1B,0x98,0x1A,0x2E,0x47,0xFC,0xEB, +0x96,0x00,0xE2,0x04,0xE8,0x07,0x8A,0x80,0xE4,0x83,0xE9,0x04,0x84,0x1F,0xEA,0xB9, +0xD5,0x03,0x3E,0x07,0xFC,0xEB,0xFE,0x94,0x42,0x21,0x8C,0x73,0xFE,0x4C,0x96,0x90, +0xE0,0x22,0xE8,0x06,0xEA,0x8F,0x90,0xA1,0xE0,0xA0,0xE9,0xDD,0xD5,0xE4,0xEA,0x8F, +0x5C,0xF0,0x00,0xF0,0xE8,0x1D,0x8C,0x01,0xEA,0xB9,0xD5,0x1A,0x5A,0x60,0x03,0x19, +0x3F,0x07,0xFC,0xD6,0xD5,0x15,0x84,0x20,0x3E,0x17,0xFC,0xD6,0xC8,0x0E,0x2E,0x20, +0x00,0x17,0x3C,0x13,0xFE,0xA7,0x94,0x91,0xE0,0x22,0xE8,0x05,0x8C,0x21,0x3C,0x1B, +0xFE,0xA7,0xD5,0x06,0xEB,0x0D,0xD5,0x02,0x84,0x00,0x3C,0x0B,0xFE,0xA7,0xEA,0x8F, +0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBA,0xFC,0xC0,0xFC,0x20,0x3F,0xCF,0xFD,0xD4, +0x2E,0x50,0x01,0x85,0x2E,0x40,0x01,0x84,0x84,0x22,0x9A,0xAC,0x8C,0x41,0x40,0x21, +0x04,0x56,0x2F,0x00,0x01,0x86,0x88,0x44,0x2E,0x70,0x01,0x87,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,0xFC,0xE1,0xCB,0x21,0xB8,0x00,0xC0,0x57,0x46,0x01, +0x00,0x01,0x00,0x10,0x0B,0xA0,0xC9,0x52,0x2E,0x00,0x00,0x18,0xE0,0x02,0xE8,0x13, +0x2E,0x07,0xFD,0x24,0x8C,0x01,0x96,0x00,0x3E,0x07,0xFD,0x24,0x2E,0x07,0xFD,0x24, +0x2E,0x27,0xFC,0xEA,0xE2,0x40,0xE8,0x42,0x84,0x01,0x3E,0x07,0xFC,0xE1,0x3E,0x17, +0xFD,0x20,0xD5,0x3C,0x3E,0x17,0xFD,0x24,0xD5,0x39,0xBA,0x03,0xCA,0x07,0xBA,0x00, +0xCA,0x05,0x3E,0x27,0xFD,0x24,0x3E,0x27,0xFC,0xE1,0x2E,0x30,0x00,0x1C,0x46,0x21, +0x00,0x01,0x04,0x21,0x03,0xFD,0xE2,0x62,0xE8,0x29,0xFA,0x76,0x80,0x40,0x42,0x23, +0x8C,0x73,0xEB,0x1C,0xEB,0x27,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,0x24,0x3E,0x07,0xFC,0xE1,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,0x53,0x46,0x33,0x00,0x00,0x88,0x67,0x4E,0x92,0x00,0x04,0xB6,0xC3, +0xD5,0x03,0x97,0xB0,0xAF,0x98,0xDD,0x56,0x04,0x00,0x00,0x3A,0x92,0x0C,0x96,0x0F, +0x5A,0x08,0x03,0x06,0x84,0x20,0x46,0x03,0x00,0xB9,0xB6,0x20,0x84,0x20,0xEA,0x5E, +0x10,0x10,0x00,0xA8,0xFC,0xC0,0xFC,0x00,0xF8,0x32,0x80,0x43,0xDD,0x4B,0xFC,0x80, +0xFC,0x20,0x80,0xE0,0x80,0xC1,0xDD,0x53,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,0xE9,0x40,0x00,0x0B,0x04,0xFE,0x0F,0x40,0x00,0x11,0x04, +0xD5,0x04,0x88,0x46,0xA6,0x10,0x96,0x00,0xEA,0x3C,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,0x5F,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,0x5B,0xEB,0x33,0x44,0x00,0x04,0x00, +0xF2,0x01,0xDD,0x48,0xEA,0x8B,0x81,0x60,0x4E,0x03,0x00,0x9C,0x46,0xEF,0xF0,0x0F, +0x81,0x80,0x50,0x07,0x0F,0xFF,0x84,0xC1,0x85,0xA4,0xF0,0x84,0xEB,0x82,0x58,0x00, +0x00,0x04,0x38,0x70,0x34,0x00,0x8C,0x01,0x38,0xA6,0x80,0x00,0x4E,0x72,0x00,0x8A, +0x54,0x05,0x00,0xFB,0x85,0x00,0xF0,0x83,0xE3,0x07,0x4E,0xF2,0x00,0x7C,0x40,0x04, +0x34,0x00,0xEB,0x5B,0x58,0x10,0x80,0x00,0x88,0x01,0x00,0x90,0x00,0x06,0x5A,0xA0, +0xBD,0x6C,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, +0xFC,0xD3,0x81,0xC6,0x5A,0x08,0x01,0x06,0xD5,0x59,0x5A,0xA0,0xB6,0x0A,0x81,0xC6, +0x88,0xC8,0x96,0x30,0xF0,0x81,0xEA,0xD7,0x84,0xC3,0xF0,0x82,0xD5,0x07,0x2E,0x07, +0xFC,0xBC,0x5A,0x00,0xFF,0xF6,0x81,0xC6,0xD5,0x49,0x80,0x0A,0x80,0x2C,0xF2,0x02, +0x80,0x69,0x49,0xFF,0xFF,0x32,0x5A,0xA0,0xB9,0x42,0xF0,0x03,0x5A,0x00,0xB2,0x3F, +0x5A,0xA0,0xE9,0x3D,0x80,0x0A,0x80,0x2C,0xF2,0x02,0xEA,0x3B,0xF0,0x85,0x4C,0x90, +0x00,0x36,0x44,0x00,0x00,0x32,0xDD,0x50,0x9E,0x31,0x97,0x80,0xF3,0x05,0xCE,0xE6, +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,0x85,0x8C,0xE2,0x40,0xD6,0x9C,0x00,0x5C,0xF6,0x84,0x00,0x4E,0xF3,0xFF,0x70, +0x80,0x0B,0xFC,0xE3,0x46,0x09,0x00,0x08,0x02,0x50,0x00,0x08,0xEA,0xEA,0xD1,0x03, +0x12,0x10,0x00,0x08,0xDD,0x9E,0xFC,0x00,0xEA,0xB5,0x46,0x10,0x30,0x00,0xEA,0xB7, +0x8C,0x21,0xEB,0x2E,0xB4,0x02,0x96,0x04,0xC0,0x04,0x8E,0x21,0xC9,0xFC,0xFA,0x14, +0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x11,0x00,0x00,0x80,0x40,0xDD,0x4B, +0xEA,0x48,0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x11,0x10,0x00,0x80,0x40, +0xDD,0x4B,0xEA,0x48,0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x12,0x90,0x00, +0x80,0x40,0xDD,0x4B,0xEA,0x48,0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x12, +0x80,0x00,0x80,0x40,0xDD,0x4B,0xEA,0x48,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,0x42,0xEB,0x3F,0xEA,0x5D,0xFC,0x81,0x9E,0x41,0xE6,0x23,0xE8,0x1B, +0xEA,0x27,0x84,0x40,0x10,0x20,0x80,0x94,0x84,0x41,0x10,0x20,0x80,0x94,0xEA,0x3C, +0x5A,0x00,0x02,0x08,0x5A,0x00,0x03,0x0A,0xEA,0xD5,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,0x2E,0x3C,0x1D,0xFF,0xD1,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,0x2E,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,0x5A,0x42,0x11,0x00,0x24,0x2E,0x27, +0xFD,0xA2,0x84,0x01,0x40,0x20,0x88,0x57,0x80,0x27,0x88,0x40,0x49,0x00,0x0A,0x6F, +0x84,0x01,0x80,0x40,0x80,0x27,0x49,0x00,0x0A,0x75,0x80,0x06,0xD5,0x04,0xFA,0x02, +0xDD,0x9E,0xFA,0x14,0xFC,0xC0,0x46,0x18,0x00,0x60,0x00,0x00,0x80,0x14,0xEB,0x02, +0x10,0x00,0x80,0x14,0xDD,0x9E,0x46,0x08,0x00,0x60,0x00,0x10,0x00,0x10,0x84,0x01, +0x40,0x00,0x04,0x12,0xDD,0x9E,0x00,0x00,0xFC,0x01,0x10,0x0F,0x80,0x07,0x00,0x0F, +0x80,0x07,0x96,0x00,0xE6,0x06,0xE8,0x47,0x3E,0xFF,0xD5,0x88,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,0xFD,0x83,0xFF,0x2E,0x07,0xFC,0xBA,0xC0,0x02,0xEB,0x0B,0xEA,0x57,0xEA,0xA5, +0xC8,0x11,0xEA,0x7D,0xC8,0x0F,0x49,0xFF,0xE6,0x40,0xC8,0x0C,0xEA,0x3C,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,0x56,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, +0x00,0xE1,0xE0,0x83,0xE8,0x18,0x82,0x11,0x43,0x02,0x48,0x73,0x84,0x60,0x2E,0x60, +0x00,0xE0,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,0x8C,0xF0,0x81,0xDD,0x47, +0x80,0xE1,0x80,0xC2,0xDD,0x40,0xC0,0x02,0x84,0xC4,0xEA,0x2B,0xC0,0x1A,0xDD,0x43, +0x02,0x30,0x00,0x9C,0x02,0x00,0x00,0x0A,0x8A,0x60,0x40,0x31,0xA4,0x08,0xBB,0x80, +0x3C,0x3D,0xFF,0x63,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,0xD6,0xC8,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,0xB7,0x10,0x31,0x00,0x28,0x3C,0x3D,0xFF,0x64,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,0x5B,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,0xC7,0xF2,0x49,0xFF,0xC4,0x06,0x46,0x00, +0x00,0x0D,0x00,0x00,0x04,0xF9,0x8E,0x01,0x96,0x00,0x3E,0x07,0xFC,0xC6,0x46,0x00, +0x00,0x0D,0x00,0x00,0x06,0xA5,0x8E,0x01,0x96,0x00,0x3E,0x07,0xFC,0xCD,0xEA,0x8B, +0x80,0xC0,0xC8,0x0E,0xDD,0x5A,0xDD,0x50,0xDD,0x4D,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,0x2E,0x80,0x26, +0x8C,0xC1,0x84,0x00,0x97,0xB0,0xEA,0x2E,0x5A,0x68,0x04,0xF8,0x84,0xE0,0x3E,0x77, +0xFC,0xD1,0x46,0x68,0x00,0x20,0x85,0x21,0x3E,0x97,0xFC,0xB9,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,0x5A,0x10,0x73,0x00,0x94, +0xEA,0x6D,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,0x4D, +0x8E,0x07,0xE6,0x02,0xE8,0x0B,0x46,0x01,0x00,0x07,0xEA,0x62,0xEA,0x21,0xEA,0x20, +0xD0,0x04,0xDD,0x4C,0xEA,0xF3,0xC0,0x02,0xEA,0x5A,0x84,0x20,0xEA,0x76,0xAE,0x40, +0xDD,0x4F,0x46,0x01,0x00,0x00,0x58,0x00,0x0B,0x14,0x84,0x20,0xDD,0x42,0xFC,0xC0, +0xFC,0x00,0x3F,0xCF,0xFD,0x90,0x46,0x10,0x00,0xE7,0x84,0x00,0x50,0x10,0x8C,0x15, +0x44,0x20,0x00,0x68,0xDD,0x4B,0xDD,0x43,0x84,0x21,0x46,0x20,0xFF,0xFF,0xEA,0x46, +0x50,0x21,0x0F,0xFF,0x10,0x10,0x00,0x1C,0x10,0x10,0x00,0x84,0x10,0x10,0x00,0x80, +0xEB,0x4D,0xB4,0xA0,0xEA,0x27,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,0x5A,0xEA,0x5E,0xEA,0xFE,0xEA,0x43,0xB4,0x01,0xEA,0xF6,0xB6,0x01,0x84,0x01, +0xEA,0x54,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,0x56, +0xF8,0x07,0xC1,0x31,0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFE,0xEA,0xE1,0x04,0x10, +0x00,0x15,0x92,0x30,0x96,0x48,0x83,0xFF,0x5A,0x18,0x33,0x26,0xEB,0x4A,0x8E,0x27, +0xE6,0x22,0xE8,0x21,0x04,0x10,0x00,0x15,0x92,0x38,0x5A,0x18,0x11,0x05,0x3E,0x17, +0xFC,0xBE,0xD5,0x08,0x04,0x00,0x00,0x15,0x92,0x18,0x5A,0x08,0x22,0x04,0x3E,0x07, +0xFC,0xBE,0x2E,0x07,0xFC,0xBE,0x5A,0x08,0x22,0x09,0xEA,0x47,0xEA,0x3F,0x83,0xFF, +0x46,0x11,0x00,0x07,0xEA,0x6F,0xD5,0x07,0x2E,0x07,0xFC,0xBE,0x5A,0x08,0x11,0x04, +0x84,0x01,0xEB,0x0A,0xDD,0x56,0x04,0x10,0x00,0x16,0x4E,0x00,0xFF,0xD4,0xC1,0x06, +0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFD,0xEA,0xE1,0x04,0x00,0x00,0x17,0x5A,0x08, +0xA5,0x11,0xFC,0x00,0x44,0x10,0x00,0x87,0xDD,0x56,0x14,0x10,0x00,0x17,0xF9,0x9A, +0x84,0x00,0xEB,0x42,0xEB,0x3F,0xEA,0x5D,0xEA,0xB5,0xEA,0xD3,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,0x56,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,0x35,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,0x2B, +0x96,0x00,0xDD,0x58,0x49,0xFF,0xC9,0x8B,0x84,0x40,0x84,0x21,0xB4,0x06,0x42,0x00, +0x58,0x0B,0xC0,0x18,0x3C,0x0D,0xFF,0x65,0x5A,0x08,0x01,0x13,0xDD,0x4D,0x5A,0x08, +0x06,0x10,0x84,0x25,0x84,0x02,0xEA,0xAB,0x2E,0x17,0xFC,0xCB,0x8C,0x21,0x96,0x48, +0x3E,0x17,0xFC,0xCB,0x8C,0x21,0x94,0x09,0x54,0x00,0x00,0xFE,0xEA,0xDC,0x84,0x40, +0x84,0x22,0xB4,0x06,0x84,0xC1,0x42,0x00,0x5C,0x0B,0xC0,0x07,0xDD,0x4C,0xFE,0x36, +0xC0,0x19,0x80,0x06,0xEA,0xD0,0xD5,0x16,0xC2,0x10,0x5A,0x18,0x02,0x0B,0xF1,0x81, +0xEA,0xB5,0xF1,0x01,0x80,0x01,0x44,0x10,0x07,0xD0,0x49,0xFF,0xFC,0x0E,0xD5,0x0C, +0x80,0x06,0xEA,0x2E,0xEB,0x2D,0xD5,0x08,0x5A,0x10,0x02,0x07,0x84,0x00,0xEA,0x2E, +0xD5,0x03,0x84,0x23,0xD5,0xFC,0xFC,0x81,0xFC,0x20,0x46,0x60,0x00,0xCB,0x50,0x73, +0x08,0x02,0xDD,0x53,0x80,0x27,0x84,0x00,0xEA,0x5F,0x54,0x20,0x00,0x7F,0x80,0x27, +0x84,0x00,0xDD,0x4B,0x50,0x13,0x08,0x05,0x84,0x00,0xEA,0x5F,0x96,0x00,0x92,0x03, +0xFC,0xA0,0xFC,0x40,0x46,0x60,0x00,0xCB,0x50,0xA3,0x08,0x05,0x80,0x2A,0x80,0xE0, +0x84,0x00,0xEA,0x5F,0x50,0x63,0x08,0x02,0x81,0x20,0xDD,0x53,0x80,0x26,0x84,0x00, +0xEA,0x5F,0x54,0x20,0x00,0x7F,0x80,0x26,0x84,0x00,0xDD,0x4B,0x54,0x24,0x80,0x07, +0x40,0x21,0x1C,0x64,0x84,0x00,0x80,0x2A,0x96,0x90,0xDD,0x4B,0xFC,0xC0,0x2E,0x07, +0xFF,0x40,0xC0,0x34,0xFC,0x00,0xEA,0x76,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,0xD4,0xE2,0x46,0xE8,0x04,0xC0,0x12,0x8E,0x01,0xD5,0x08,0x3C,0x2D,0xFF,0xD5, +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,0x2B,0x58,0x10,0x80,0x04,0xEB,0x06,0x84,0x20,0x10,0x10,0x00,0x68,0xEB,0x4C, +0x54,0x10,0x80,0xFB,0xEA,0x60,0xDD,0x9E,0xC3,0x20,0xFC,0x00,0x3E,0x07,0xFF,0x40, +0x3C,0x1F,0xFF,0xD1,0x46,0x50,0x00,0xF4,0x3C,0x2F,0xFF,0xD2,0x99,0x8A,0x3C,0x3F, +0xFF,0xD3,0x8A,0x22,0x50,0x42,0x82,0x40,0x42,0x53,0x10,0x24,0xFF,0x0C,0x40,0x52, +0x8C,0xB7,0x40,0x32,0x0C,0x77,0x3C,0x5F,0xFF,0xD4,0x3C,0x3F,0xFF,0xD5,0xC0,0x07, +0x49,0xFF,0xFF,0xD6,0x84,0x00,0xD5,0x03,0xFA,0x00,0xDD,0x9E,0xFC,0x80,0x46,0x09, +0x00,0x90,0xEB,0x2B,0xEA,0xB2,0xEB,0x06,0x84,0x20,0x10,0x10,0x00,0x64,0xEB,0x4C, +0x54,0x10,0x80,0xFD,0xEA,0x60,0xDD,0x9E,0x46,0x09,0x00,0x90,0xEB,0x2B,0x58,0x10, +0x80,0x01,0xEB,0x06,0x84,0x2F,0xEA,0x2F,0xEB,0x4C,0x54,0x10,0x80,0xFE,0xEA,0x60, +0xDD,0x9E,0x3E,0x07,0xFD,0xA0,0x84,0x60,0x3E,0x37,0xFD,0xA1,0x3E,0x17,0xFD,0xA2, +0x3E,0x17,0xFD,0xA3,0x3E,0x27,0xFD,0xA4,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,0x8B,0xC8,0x2F,0x3E,0x77,0xFF,0x40,0x44,0x10,0x01,0xF4,0x3C,0x1F, +0xFF,0xD1,0x84,0x2A,0x3C,0x1F,0xFF,0xD2,0x44,0x10,0x02,0x58,0x3C,0x1F,0xFF,0xD3, +0x46,0x10,0x00,0xCF,0x50,0x10,0x88,0x50,0x3C,0x1F,0xFF,0xD4,0x46,0x10,0x00,0xC7, +0x50,0x10,0x86,0x1A,0x3C,0x1F,0xFF,0xD5,0x44,0x10,0x00,0x80,0x84,0x45,0x49,0xFF, +0xFF,0xC2,0x49,0xFF,0xFD,0x79,0x49,0x00,0x05,0x44,0x84,0x09,0xEB,0x42,0xEB,0x3F, +0xEA,0x5D,0xEA,0x48,0xC8,0x07,0x44,0x10,0x00,0xDA,0x12,0x13,0x00,0x1A,0x12,0x13, +0x00,0x1E,0xFC,0xA0,0x2E,0x07,0xFD,0xA0,0xC0,0x09,0x46,0x19,0x00,0x90,0xA6,0x08, +0xEA,0x37,0xAE,0x08,0x84,0x01,0x3E,0x07,0xFD,0xA1,0xDD,0x9E,0x2E,0x07,0xFD,0xA0, +0xC0,0x10,0xEB,0x4A,0xEA,0x76,0x5A,0x18,0x08,0x09,0xA0,0x41,0x84,0x20,0x3E,0x17, +0xFD,0xA1,0x00,0x00,0x00,0x60,0xD5,0x05,0xA0,0x02,0x84,0x00,0x3E,0x07,0xFD,0xA1, +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,0xEF,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,0x90,0xF1,0x81,0xBA,0x00,0xBA,0x82,0xB8,0x80,0xB6,0x1F,0x2E,0x27,0xFF,0x5A, +0x92,0x47,0x3E,0x27,0xFF,0x40,0x84,0x41,0x3E,0x27,0xFC,0xC5,0x3E,0x27,0xFC,0xC3, +0x49,0xFF,0xFD,0x02,0xF1,0x01,0xB4,0x1F,0xC1,0x03,0x49,0xFF,0xF3,0x33,0xB8,0x00, +0x9E,0x42,0xE6,0x27,0xE8,0x20,0x3E,0xFF,0xDF,0xE4,0x38,0x17,0x84,0x00,0x40,0xF0, +0xBC,0x00,0xDD,0x0F,0x08,0x08,0x08,0x08,0x16,0x1E,0x26,0x00,0xEB,0x3E,0xEA,0x90, +0x2E,0x27,0xFD,0x31,0x84,0x20,0xE2,0x22,0xD5,0x0C,0x84,0x26,0xEA,0x90,0x85,0xE2, +0xD5,0x08,0xEB,0x3E,0xEA,0x90,0x85,0xE0,0xD5,0x04,0x84,0x26,0xEA,0x90,0x85,0xE1, +0x3C,0xFF,0xFF,0x6A,0xEA,0xCB,0xEA,0x8E,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,0x5B,0xEB,0x38,0xC9,0x18,0x46,0x01,0x00,0x07,0xEA,0x62,0xEA,0x47, +0xEA,0x3F,0xD8,0x06,0x44,0x11,0xFF,0x00,0xDD,0x56,0x14,0x10,0x00,0x30,0x84,0x05, +0xEA,0x54,0xEA,0xB5,0x84,0x20,0xDD,0x43,0xEA,0xF4,0x44,0x10,0x07,0xD0,0x84,0x02, +0x49,0xFF,0xFA,0x3B,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,0x4A,0x5A,0x18, +0x07,0x0C,0x46,0x10,0x00,0x0D,0x02,0x10,0x82,0x6C,0xEA,0xF4,0x46,0x10,0x00,0x0D, +0x02,0x10,0x82,0x6D,0xD5,0x0C,0x5A,0x18,0x08,0x0D,0x46,0x10,0x00,0x0D,0x02,0x10, +0x83,0x42,0xEA,0xF4,0x46,0x10,0x00,0x0D,0x02,0x10,0x83,0x43,0x12,0x10,0x00,0xB6, +0xEA,0x27,0x02,0x00,0x82,0xB8,0x02,0x10,0x80,0xB6,0x49,0xFF,0xC5,0x10,0xEA,0x8B, +0xFC,0x80,0x46,0x08,0x00,0x20,0x00,0x10,0x00,0xF8,0xEB,0x4D,0xEA,0xB2,0x10,0x10, +0x7D,0xBC,0xEA,0xC1,0xEA,0x81,0xB4,0xA0,0xD9,0xFF,0xDD,0x9E,0xC0,0x04,0xFC,0x00, +0xEA,0x5A,0xFC,0x80,0xEA,0x3C,0x04,0x00,0x80,0x30,0x66,0x00,0x00,0x01,0x14,0x00, +0x80,0x30,0xDD,0x9E,0xFC,0x21,0x3F,0xCF,0xFD,0x90,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,0x14,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,0x5E,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,0xEB,0x13,0x5A,0x08,0x01,0x06, +0x84,0x06,0xB8,0x80,0x84,0x04,0xD5,0x0A,0xEB,0x13,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,0xFC,0xBB,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,0xF3,0xD5,0x07,0xF0,0x01,0x42,0x00,0x3C,0x0B, +0xC0,0x03,0x49,0xFF,0xF8,0xF6,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,0xAB, +0x3E,0x67,0xFC,0xCB,0x84,0x04,0xEA,0xDC,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,0xBA,0x49,0xFF, +0xF9,0x5C,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xC3,0xFB,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,0x3F,0xD5,0x24,0xF0,0x01,0xEA,0xA5,0xC0,0x21,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x55,0x00,0xDD,0x45,0x3E,0x67,0xFC,0xC7, +0x80,0x26,0x3E,0x67,0xFC,0xCC,0x80,0x06,0xEA,0xBA,0x49,0xFF,0xF9,0x1E,0x80,0x27, +0x2E,0x07,0xFF,0x5E,0x49,0xFF,0xFE,0x44,0xDD,0x53,0x46,0x10,0x00,0xBC,0x80,0x06, +0x8C,0x21,0x84,0x46,0xDD,0x4B,0x3E,0x77,0xFF,0x3F,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,0x2B, +0xC0,0x16,0x2E,0x07,0xFD,0x27,0x3E,0x07,0xFD,0x29,0x8C,0x01,0x96,0x04,0x3E,0x07, +0xFD,0x27,0xD5,0x0D,0x8E,0x05,0x96,0x40,0xE6,0x23,0xE8,0x09,0x84,0x23,0x40,0x10, +0x04,0x16,0x84,0x44,0x96,0x00,0xEB,0x5B,0xEA,0x7B,0xEA,0xAC,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,0x11,0x44,0x10,0xFE,0xFF,0x83,0xFF,0xF8,0x03,0x44,0x10, +0xFD,0xFF,0xFE,0x56,0xEA,0x34,0xEB,0x11,0x83,0xFF,0x44,0x10,0xFB,0xFF,0x4E,0x00, +0xFF,0xFA,0x44,0x10,0xF7,0xFF,0xFE,0x56,0xEA,0x34,0x83,0xFF,0xFA,0x20,0xEA,0x60, +0x10,0x10,0x00,0x48,0xEB,0x31,0x2E,0x17,0xFD,0x27,0xC1,0x22,0x5A,0x10,0x01,0x03, +0xF8,0x51,0xEB,0x6E,0x02,0x51,0x06,0x8E,0xEB,0x6E,0x02,0x41,0x06,0x8F,0xEB,0x6E, +0x02,0x31,0x06,0x8D,0xEB,0x6E,0x02,0x21,0x06,0x8B,0xF8,0x1E,0xEB,0x6E,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,0x6E, +0x02,0x51,0x05,0xB8,0xEB,0x6E,0x02,0x41,0x05,0xB9,0xEB,0x6E,0x02,0x31,0x05,0xB7, +0xEB,0x6E,0x02,0x21,0x05,0xB5,0x12,0x50,0x00,0x9C,0x12,0x40,0x00,0x0A,0x12,0x30, +0x00,0x9A,0x12,0x20,0x00,0x8A,0x83,0xFF,0xEB,0x6E,0x04,0x21,0x02,0xCC,0x83,0x80, +0xBA,0x8E,0xEA,0x79,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,0x81,0x83,0xFF,0xB4,0xA2,0xDD,0x43,0xD9,0xFE,0x83,0x80,0xB9,0x0E,0x42,0x10, +0xD4,0x09,0xB9,0x8E,0xEB,0x08,0xC9,0x24,0xEB,0x5E,0x00,0x30,0x8B,0x8D,0xEB,0x5E, +0x00,0x20,0x8B,0x8E,0xEB,0x5E,0x00,0x10,0x8B,0x8F,0xF8,0x23,0xEB,0x5E,0x02,0x40, +0x85,0xB8,0xEB,0x5E,0x02,0x30,0x85,0xB9,0xEB,0x5E,0x02,0x20,0x85,0xB7,0xEB,0x5E, +0x02,0x10,0x85,0xB5,0xF8,0x28,0xEB,0x5E,0x04,0x10,0x82,0xCC,0xEB,0x1D,0xEB,0x5E, +0x02,0x10,0x85,0xB6,0xEA,0x34,0xEB,0x5E,0x00,0x10,0x8B,0x8B,0xD5,0x30,0xEB,0x5E, +0x00,0x30,0x8D,0x39,0xEB,0x5E,0x00,0x20,0x8D,0x3A,0xEB,0x5E,0x00,0x10,0x8D,0x3B, +0x10,0x30,0x00,0x44,0x10,0x20,0x00,0x48,0xEB,0x31,0x83,0xFF,0xEB,0x5E,0x02,0x40, +0x86,0x8E,0xEB,0x5E,0x02,0x30,0x86,0x8F,0xEB,0x5E,0x02,0x20,0x86,0x8D,0xEB,0x5E, +0x02,0x10,0x86,0x8B,0x12,0x40,0x00,0x9C,0x12,0x30,0x00,0x0A,0x12,0x20,0x00,0x9A, +0x12,0x10,0x00,0x8A,0x83,0xFF,0xEB,0x5E,0x04,0x10,0x83,0x37,0xEB,0x1D,0xEB,0x5E, +0x02,0x10,0x86,0x8C,0xEA,0x34,0xEB,0x5E,0x00,0x10,0x8D,0x37,0xEA,0x79,0x84,0x21, +0x10,0x10,0x01,0x9C,0x49,0xFF,0xFC,0xF0,0xFC,0x80,0x00,0x00,0xFC,0x20,0x3F,0xCF, +0xFD,0x90,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,0x57,0x97,0xB0,0xEB,0x1B,0xC0,0x0B,0xB8,0x00,0x5A,0x08,0x06,0x09,0x84,0x22, +0x84,0x00,0xEA,0x2E,0x84,0x02,0xEA,0xDC,0x84,0x00,0xB8,0x81,0xDD,0x4D,0x8E,0x02, +0xE6,0x07,0x4E,0xF2,0x01,0xA2,0x3E,0xFF,0xE5,0xB4,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,0x56,0x04,0x10,0x00,0x3A,0x9F,0xF1,0xEA,0xDA,0x84,0x01,0xC1,0x09, +0x46,0x11,0x00,0x07,0xEA,0xD8,0x40,0x00,0x1C,0x0C,0x40,0x00,0x80,0x12,0xD5,0x08, +0x46,0x11,0x00,0x07,0xEA,0xD8,0x40,0x00,0x1C,0x0C,0xFE,0x0F,0x96,0x01,0x46,0x11, +0x00,0x07,0xEA,0x99,0x46,0x01,0x00,0x07,0x02,0x10,0x07,0xF4,0x44,0x00,0xDF,0xFF, +0xFE,0x0E,0x46,0x11,0x00,0x07,0xEA,0x99,0xEA,0xD8,0x44,0x00,0xBF,0xFF,0xFE,0x0E, +0x46,0x11,0x00,0x07,0xEA,0x99,0x02,0x00,0x87,0xF4,0x54,0x00,0x7F,0xFF,0xEA,0x99, +0x84,0x00,0x3E,0x07,0xFF,0x3E,0x84,0x0E,0xDD,0x40,0xC0,0x05,0x80,0x06,0x49,0xFF, +0xBF,0x93,0xEA,0x63,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,0x46,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,0x63,0xD5,0x0F,0x80,0x06,0x49,0xFF,0xFE,0x8A,0x5A,0x60, +0x04,0x05,0x5A,0x60,0x08,0x03,0xEA,0x63,0xB8,0x00,0x49,0xFF,0xF1,0x4B,0x5A,0x60, +0x04,0x13,0xD5,0xEF,0x84,0x01,0x44,0x10,0x04,0xA6,0xEA,0xAB,0x2E,0x07,0xFC,0xC7, +0xC8,0x1A,0xEA,0x76,0xA6,0x40,0xEA,0xB2,0xAE,0x40,0xA6,0x40,0x58,0x10,0x80,0x04, +0xAE,0x40,0xD5,0x11,0xEA,0x2B,0x96,0x00,0xDD,0x58,0x49,0xFF,0xC4,0x60,0xEB,0x13, +0x5A,0x00,0x01,0x04,0x48,0x00,0x00,0x4A,0xEA,0x43,0xB4,0x01,0x58,0x00,0x04,0x00, +0xB6,0x01,0xD5,0x43,0x2E,0x07,0xFC,0xC7,0x8C,0x01,0x96,0x00,0xE6,0x04,0xE8,0x03, +0xEA,0xF1,0xD5,0x3B,0x84,0x00,0xEA,0xF1,0xDD,0x43,0x00,0x10,0x03,0x20,0x5A,0x10, +0x10,0x06,0x00,0x10,0x03,0x20,0x5A,0x18,0x06,0x31,0xEA,0xC1,0xEB,0x4D,0xEA,0x81, +0xB4,0xA0,0xD9,0xFF,0x46,0x19,0x00,0x90,0xA6,0x08,0xC8,0xFF,0x49,0xFF,0xFB,0x21, +0xEA,0x57,0xEB,0x1B,0xC0,0x09,0x2E,0x0F,0xFF,0x5A,0x4E,0x04,0x00,0x06,0x49,0xFF, +0xFA,0xE5,0x3E,0x07,0xFC,0xBB,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,0x46,0xEA,0x42,0xE6,0x01,0xEA,0x66,0x84,0x44,0x84,0x00,0xEB,0x5B,0xEA,0x7B, +0xEA,0xAC,0xEA,0x2B,0x96,0x00,0xDD,0x58,0x49,0xFF,0xB5,0xEE,0xEA,0x63,0x5A,0x68, +0x01,0x0A,0xDD,0x43,0x84,0x22,0xEA,0x58,0x84,0x23,0xEA,0x46,0xEA,0x42,0xE6,0x01, +0xEA,0x66,0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x00,0x00,0xBC,0xA6,0x40, +0xC9,0xFF,0xEA,0x64,0xE6,0x03,0xEA,0x64,0xE9,0x0C,0x8E,0x02,0xE0,0xC0,0xE9,0x11, +0xEA,0x64,0xE2,0x06,0xE9,0x0E,0x2E,0x17,0xFC,0xC6,0x9C,0x32,0x8A,0x01,0xD5,0x04, +0xE2,0x06,0xE9,0x07,0x9E,0x31,0x96,0x00,0xEB,0x5B,0xEA,0x7B,0x84,0x44,0xEA,0xAC, +0xEA,0x64,0x4C,0x60,0x40,0x35,0x84,0xC1,0xDD,0x43,0x12,0x60,0x02,0xE0,0xEA,0x2B, +0x96,0x00,0xDD,0x58,0xEA,0x5A,0xEA,0x5E,0xEA,0xFE,0xEA,0x43,0xB4,0x01,0xEA,0xF6, +0xB6,0x01,0x2E,0x07,0xFF,0x3E,0xE6,0x09,0xE9,0x04,0x84,0x04,0xEA,0x54,0xD5,0x02, +0xEB,0x2D,0x46,0x60,0x00,0xD8,0x50,0x63,0x0C,0x0D,0x80,0x26,0x44,0x20,0x00,0xAA, +0x84,0x00,0xDD,0x4B,0x44,0x00,0x02,0xBC,0xDD,0x50,0x84,0x00,0x80,0x26,0x44,0x20, +0x00,0xBA,0xDD,0x4B,0x2E,0x07,0xFF,0x3E,0xE6,0x14,0xE8,0x04,0x8C,0x01,0x3E,0x07, +0xFF,0x3E,0xEA,0x7D,0x4E,0x02,0x00,0x5E,0x84,0x01,0xD5,0x02,0x84,0x02,0xEA,0x54, +0xEA,0x63,0xEA,0x9D,0x4C,0x60,0x40,0x56,0x49,0xFF,0xFB,0x66,0x2E,0x17,0xFC,0xCD, +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,0x46,0xEA,0x5A,0xEA,0x5E,0xEA,0xFE, +0xEA,0x43,0xB4,0x01,0xEA,0xF6,0xB6,0x01,0xEA,0x9D,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,0x4B,0x44,0x00,0x02,0xBC,0xDD,0x50, +0x84,0x00,0x80,0x26,0x44,0x20,0x00,0xBA,0xDD,0x4B,0xEA,0x42,0xE6,0x01,0xEA,0x66, +0x84,0x44,0x84,0x00,0xEB,0x5B,0xEA,0x7B,0xEA,0xAC,0xEA,0x9D,0x5A,0x00,0x01,0x0E, +0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x10,0x00,0xBC,0xA6,0x08,0x96,0x00, +0xC8,0xFE,0xEA,0x27,0x10,0x00,0x80,0xB4,0xDD,0x43,0x84,0xC1,0x12,0x60,0x02,0xE0, +0xEA,0x2B,0x96,0x00,0xDD,0x58,0x84,0x04,0xEA,0x54,0xEA,0x7D,0xC0,0x02,0xEB,0x2D, +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,0xEA,0xD0,0x2E,0x27, +0xFF,0xA8,0x84,0x2A,0xFE,0x54,0x84,0x03,0xEA,0xAB,0xFC,0x80,0x2E,0x07,0xFF,0x3F, +0xDD,0x9E,0x8E,0x01,0xC0,0x03,0xEA,0x6D,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,0xFD, +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,0x37,0xD5,0x03,0x46,0x09,0x00,0x10,0x88,0x20,0xB6,0x41,0xDD,0x9E, +0xE6,0x24,0xE8,0x0C,0x94,0x4D,0x96,0x90,0xC0,0x04,0xEB,0x37,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,0x37,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,0x03, +0xD0,0x16,0x46,0x01,0x00,0x00,0xEA,0x4D,0x44,0x00,0xA3,0x3A,0xD0,0x10,0x46,0x01, +0x00,0x00,0xEA,0x4D,0xEB,0x05,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,0x05,0xD0,0x07,0x46,0x01,0x00,0x00,0xEA,0x4D, +0x44,0x00,0x3A,0xA3,0xD8,0x3F,0xEA,0x9E,0xC0,0x3D,0xFC,0x20,0x49,0xFF,0xBB,0x0B, +0xEA,0x7A,0xEA,0x31,0x84,0xA0,0x98,0x50,0x42,0x11,0x00,0x73,0x2E,0x07,0xFF,0xBA, +0x46,0x31,0x00,0x00,0x58,0x31,0x80,0x04,0x88,0x20,0x3C,0x23,0xFE,0x9D,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,0x5B,0x12,0x00,0x80,0x01, +0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x05,0xD8,0x04,0x44,0x0F,0xA5,0x5A,0xD5,0x03, +0x44,0x0F,0xA3,0x3A,0xEB,0x5B,0x12,0x00,0x80,0x00,0x8C,0x41,0x3C,0x2B,0xFE,0x9D, +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,0x4C,0x96,0x04, +0xC0,0x08,0x46,0x09,0x00,0x28,0x84,0x21,0x10,0x10,0x00,0x68,0x84,0x22,0xEA,0x2F, +0xDD,0x56,0x02,0x10,0x00,0x72,0x83,0xFF,0xEA,0xDA,0xC1,0x06,0x46,0x0E,0xBE,0xBE, +0x50,0x00,0x0B,0xEB,0xD5,0x14,0x02,0x10,0x00,0x72,0xEB,0x38,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,0xB2,0x82, +0xDD,0x4C,0x96,0x04,0xC0,0x05,0xEA,0x7D,0xC0,0x03,0x49,0xFF,0xFE,0x8F,0x44,0x00, +0x13,0x88,0x49,0xFF,0xB2,0x6C,0xFC,0x80,0xFC,0x00,0xEA,0x48,0xDD,0x53,0xEA,0xCE, +0x84,0x20,0x84,0x41,0xEA,0x3B,0x5A,0x08,0xEE,0x04,0x84,0x00,0xD5,0x20,0xEA,0xCE, +0x84,0x20,0x84,0x41,0xEA,0x3B,0x5A,0x08,0xDE,0x04,0x84,0x01,0xD5,0x18,0xEA,0xCE, +0x84,0x20,0x84,0x41,0xEA,0x3B,0x5A,0x08,0xCE,0x17,0x44,0x00,0x00,0xE8,0x84,0x20, +0x84,0x46,0xEA,0x3B,0x5A,0x08,0x03,0x04,0x84,0x02,0xD5,0x09,0x44,0x00,0x00,0xE8, +0x84,0x20,0x84,0x46,0xEA,0x3B,0x5A,0x08,0x04,0x07,0x84,0x03,0x46,0x11,0x00,0x07, +0x12,0x00,0x80,0x40,0xEA,0x3C,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,0xCA, +0x14,0x10,0x01,0x60,0xD5,0x14,0xDD,0x43,0x84,0x20,0xEB,0x34,0xEB,0x36,0x83,0xFF, +0xEB,0x34,0xEB,0x36,0x84,0x3A,0x14,0x10,0x00,0xAD,0x84,0x27,0x10,0x10,0x02,0xAC, +0x83,0xFF,0x46,0x10,0x03,0x10,0x50,0x10,0x80,0x31,0xEA,0xCA,0x84,0x21,0xDD,0x43, +0x10,0x10,0x01,0xCC,0xDD,0x9E,0xFC,0x40,0xDD,0x53,0xF8,0x04,0xFA,0x72,0x49,0xFF, +0xF2,0x4C,0xDD,0x52,0x84,0x20,0x84,0x4D,0x83,0xFF,0xFA,0x73,0x49,0xFF,0xF2,0x45, +0xEA,0xD3,0x49,0xFF,0xFE,0x20,0x84,0xE0,0x46,0x91,0x00,0x07,0x58,0x94,0x82,0x98, +0xDD,0x52,0x84,0x20,0x84,0x41,0x83,0xFF,0x84,0x65,0x49,0xFF,0xF2,0x36,0x50,0x33, +0xFF,0xF3,0xDD,0x52,0x84,0x20,0x84,0x42,0x83,0xFF,0x96,0xD8,0x49,0xFF,0xF2,0x2D, +0xDD,0x52,0x84,0x20,0x84,0x44,0x44,0x30,0x00,0x80,0x49,0xFF,0xF2,0x26,0x44,0x60, +0x00,0x64,0xEA,0x6D,0x8E,0xC1,0x97,0xB1,0xCE,0xFD,0xDD,0x52,0x80,0x26,0x84,0x44, +0x80,0x66,0x49,0xFF,0xF2,0x1A,0xDD,0x52,0x80,0x26,0x84,0x45,0xEA,0x3B,0x38,0x04, +0x9C,0x08,0x8C,0xE1,0x5A,0x78,0x0D,0xD6,0x44,0x00,0x72,0xC4,0x46,0x11,0x00,0x07, +0x14,0x00,0x80,0xB1,0x84,0x41,0x80,0x26,0xDD,0x52,0x44,0x30,0x00,0x40,0x49,0xFF, +0xF2,0x04,0xDD,0x52,0x80,0x26,0x80,0x47,0xFA,0x70,0x49,0xFF,0xF1,0xFE,0xFC,0xC0, +0xFC,0x00,0x84,0x22,0x80,0xC0,0x80,0x41,0xEA,0xD5,0x84,0x61,0x49,0xFF,0xF1,0xF5, +0x84,0x67,0x40,0x31,0x98,0x64,0xEA,0xD5,0x84,0x22,0x84,0x45,0x96,0xD8,0x49,0xFF, +0xF1,0xEC,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,0x5C,0x49,0x00,0x2A,0xEA,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,0x4F,0x00, +0x49,0x00,0x42,0x45,0x2E,0x07,0xFF,0x5B,0x3C,0x0D,0xFF,0x64,0x49,0x00,0x42,0x63, +0x44,0x20,0x05,0x10,0x49,0x00,0x4E,0x41,0x3E,0x17,0xFE,0x1C,0x44,0x00,0x00,0xBB, +0x49,0x00,0x42,0x2D,0x49,0x00,0x4E,0x3E,0x49,0x00,0x1B,0x91,0x46,0x09,0x00,0x00, +0x66,0x00,0x00,0xFF,0x3E,0x07,0xFC,0xD1,0x3C,0x00,0x01,0xA2,0x44,0x00,0x00,0x64, +0x3E,0x07,0xFE,0x3E,0x58,0x00,0x06,0x58,0x04,0x00,0x03,0xC1,0x2E,0x17,0xFE,0x1C, +0x5E,0xF7,0x80,0x97,0x50,0x00,0x05,0x5A,0x46,0x0A,0x55,0xAA,0x02,0x3F,0x80,0x07, +0x2E,0x00,0x00,0xE3,0x49,0x00,0x32,0xEA,0x02,0x0F,0x80,0x07,0x04,0x50,0x03,0xF1, +0x46,0x18,0x00,0x20,0x44,0x00,0xFF,0xFF,0x2E,0x07,0xFD,0x31,0x44,0x10,0x00,0x64, +0x2E,0x07,0xFC,0xB9,0x49,0x00,0x32,0x2E,0x3A,0x05,0x04,0x00,0x49,0x00,0x4E,0xD6, +0x10,0x10,0x00,0x60,0x2E,0x00,0x00,0x97,0x2E,0x00,0x00,0xE0,0x14,0x00,0x83,0xC1, +0x40,0x11,0x05,0x04,0x12,0x10,0x00,0x1E,0x3C,0x0B,0xFE,0xAC,0x49,0x00,0x44,0x63, +0x58,0x00,0x00,0x01,0x3A,0x0F,0x84,0x20,0x50,0x0F,0x80,0x0F,0x3C,0x03,0xFF,0x9D, +0x49,0x00,0x42,0x95,0x46,0x19,0x00,0x00,0x49,0x00,0x49,0x86,0x3E,0x07,0xFE,0x1D, +0x50,0x00,0x03,0x3A,0x2E,0x07,0xFD,0x00,0x49,0x00,0x1B,0x9C,0x2E,0x07,0xFC,0xD1, +0x46,0x19,0x00,0x20,0x2E,0x07,0xFD,0x26,0x2E,0x17,0xFE,0x18,0x10,0x10,0x00,0x8C, +0x46,0x0A,0x33,0xAA,0x49,0x00,0x43,0x8B,0x2E,0x07,0xFE,0x19,0x3C,0x3D,0xFF,0x83, +0x3E,0x07,0xFC,0xE2,0x3E,0x1F,0xFF,0x58,0x02,0x50,0x00,0x00,0x2E,0x07,0xFC,0xE1, +0x2E,0x07,0xFD,0x09,0x49,0x00,0x09,0x7D,0x3C,0x0B,0xFE,0xA3,0x58,0x00,0x06,0x44, +0x3C,0x0B,0xFE,0xA6,0x3E,0x07,0xFC,0xC5,0x54,0xC6,0x00,0xFF,0x2E,0x07,0xFF,0x5A, +0x2E,0x07,0xFF,0x5C,0x10,0x10,0x01,0x68,0x49,0x00,0x0F,0x28,0x49,0x00,0x42,0x16, +0x44,0x00,0x01,0xB0,0x42,0x10,0x84,0x0B,0x64,0x00,0x00,0x08,0x46,0x09,0x00,0x88, +0x49,0x00,0x42,0x68,0x10,0x10,0x00,0x44,0x58,0x00,0x00,0x98,0x04,0x50,0x03,0xC4, +0x48,0x00,0x4E,0x20,0x2E,0x07,0xFC,0xC6,0x3C,0x03,0xFF,0x9E,0x3E,0xF7,0xFC,0xB9, +0x49,0x00,0x50,0x7A,0x58,0x21,0x0B,0x14,0x2E,0x07,0xFC,0xBF,0x3B,0x00,0xC4,0x00, +0x49,0x00,0x4E,0xB2,0x2E,0x07,0xFC,0xB8,0x40,0x00,0x00,0x09,0x66,0x10,0x80,0xFF, +0x14,0x00,0x83,0xC4,0x3E,0x07,0xFC,0xDB,0x3C,0x30,0x01,0xA2,0x58,0x10,0x8D,0x68, +0x3E,0x07,0xFC,0xDE,0x58,0x00,0x00,0x78,0x3E,0x07,0xFD,0x04,0x46,0x09,0x00,0x90, +0x2E,0x00,0x00,0xE1,0x3C,0x33,0xFE,0xA6,0x10,0x10,0x02,0x38,0x2E,0x27,0xFF,0xC9, +0x58,0x10,0x8B,0x14,0x40,0x11,0x05,0x00,0x49,0x00,0x44,0x63,0x12,0x10,0x07,0xA0, +0x40,0xF7,0x80,0x11,0x3E,0x2F,0xFB,0xB4,0x50,0x10,0x8F,0xFF,0x2E,0x17,0xFD,0x20, +0x3E,0x27,0xFE,0x1D,0x3C,0x23,0xFE,0xAC,0x2E,0x27,0xFE,0x1D,0x02,0x0F,0x80,0x04, +0x2E,0x17,0xFC,0xCF,0x3C,0x0B,0xFE,0xAE,0x46,0xF1,0x00,0x01,0x40,0x00,0x07,0x00, +0x49,0x00,0x42,0xA0,0x44,0x40,0xFF,0xFF,0x42,0x00,0x04,0x0B,0x42,0x10,0x94,0x0B, +0x2E,0x07,0xFC,0xD6,0x3E,0x10,0x00,0xE1,0x58,0x10,0x86,0x04,0x44,0x00,0x00,0xFF, +0x3E,0x07,0xFD,0x1F,0x10,0x04,0x80,0x00,0x49,0x00,0x10,0x9E,0x3C,0x2D,0xFF,0x83, +0x2E,0x07,0xFD,0x1D,0x2E,0x17,0xFD,0x26,0x12,0x00,0x87,0xF4,0x49,0x00,0x42,0x95, +0x49,0x00,0x18,0xAC,0x02,0xF7,0x80,0x12,0x2E,0x07,0xFC,0xCD,0x2E,0x07,0xFC,0xCF, +0x3C,0x43,0xFE,0xAC,0x38,0x11,0x0D,0x01,0x2E,0x07,0xFF,0x8A,0x3B,0x01,0x44,0x20, +0x38,0x11,0x0D,0x09,0x3C,0x0C,0x00,0x37,0x42,0x00,0x08,0x0B,0x3C,0x13,0xFF,0x93, +0x3C,0x13,0xFF,0x94,0x02,0x00,0x02,0xD4,0x49,0x00,0x01,0xDE,0x3E,0x17,0xFE,0x1D, +0x49,0x00,0x44,0x0C,0x49,0x00,0x44,0xE3,0x58,0x00,0x0A,0x98,0x3C,0x13,0xFF,0x9A, +0x40,0xF0,0x3C,0x00,0x40,0x00,0x20,0x08,0x44,0x00,0x05,0x10,0x58,0x10,0x80,0x02, +0x44,0x60,0xFF,0xFF,0x58,0x00,0x01,0x48,0x49,0x00,0x43,0x82,0x3C,0x00,0x00,0xBF, +0x46,0x29,0x00,0x00,0x02,0x10,0x07,0xA0,0x3E,0x07,0xFC,0xD6,0x49,0x00,0x12,0xA9, +0x3E,0x07,0xFC,0xEC,0x3E,0x07,0xFC,0xEE,0x38,0x30,0x89,0x09,0x38,0x13,0x08,0x00, +0x10,0x05,0x80,0x00,0x3C,0x1C,0x00,0x36,0x46,0x10,0xFF,0xFF,0x49,0x00,0x03,0x3F, +0x3C,0x0D,0xFF,0x75,0x44,0x40,0x00,0x30,0x2E,0x17,0xFF,0xCC,0x44,0x20,0xFF,0xFF, +0x3E,0x07,0xFD,0x00,0x49,0x00,0x18,0xD8,0x38,0x07,0x1C,0x00,0x14,0x10,0x01,0x5F, +0x2E,0x17,0xFF,0x5C,0x2E,0x17,0xFF,0x5A,0x3C,0x0B,0xFE,0xA0,0x44,0x00,0x00,0xC6, +0x3E,0x07,0xFC,0xD8,0x49,0x00,0x4E,0xAD,0x3C,0x30,0x01,0x9E,0x3C,0x30,0x01,0x9F, +0x44,0x00,0x03,0xE8,0x2E,0x07,0xFC,0xE8,0x44,0x00,0x00,0xCB,0x02,0x0F,0x80,0x01, +0x02,0x0F,0x80,0x02,0x02,0x10,0x87,0xF4,0x3E,0x07,0xFC,0xC0,0x42,0x10,0xA8,0x0B, +0x58,0x00,0x00,0x4C,0x49,0x00,0x50,0x68,0x40,0x01,0x00,0x40,0x3E,0x2F,0xFE,0xB8, +0x40,0x00,0x04,0x16,0x2E,0x07,0xFD,0x10,0x10,0x10,0x00,0x50,0x38,0x00,0x80,0x01, +0x12,0x00,0x87,0x92,0x3C,0x13,0xFF,0x9B,0x2E,0x17,0xFD,0x1D,0x02,0x00,0x07,0x92, +0x44,0x70,0x00,0xFF,0x02,0x0F,0x80,0x05,0x40,0x00,0x40,0x08,0x44,0x10,0x35,0xCA, +0x2E,0x07,0xFF,0xC8,0x3B,0x00,0xC4,0x20,0x54,0xA0,0x00,0xFF,0x10,0x00,0x82,0xC0, +0x44,0x20,0x00,0x30,0x00,0x03,0x00,0x92,0x3E,0x07,0xFC,0xC7,0x42,0x31,0xC0,0x24, +0x42,0x00,0x10,0x0B,0x12,0x10,0x02,0xB8,0x49,0x00,0x32,0x8C,0x58,0x00,0x08,0x00, +0x2E,0x07,0xFC,0xD9,0x2E,0x07,0xFF,0xCC,0x3E,0x07,0xFD,0x1C,0x3E,0x07,0xFD,0x1D, +0x48,0x00,0x12,0xA8,0x58,0x00,0x02,0xC4,0x10,0x00,0x80,0x08,0x10,0x60,0x00,0xA0, +0x49,0x00,0x35,0xE6,0x42,0x01,0x04,0x73,0x2E,0x07,0xFD,0x20,0x58,0x00,0x00,0x02, +0x44,0x00,0xA5,0x5A,0x58,0x00,0x00,0x04,0x44,0x00,0x5A,0xA5,0x10,0x10,0x00,0x40, +0x49,0x00,0x34,0xFC,0x2E,0x17,0xFD,0x31,0x3C,0x03,0xFE,0xA6,0x3E,0x07,0xFC,0xBA, +0x44,0x60,0x00,0x55,0x2E,0x07,0xFC,0xCE,0x3E,0x07,0xFD,0x20,0x42,0x13,0x00,0x73, +0x00,0x20,0x00,0x08,0x3E,0x07,0xFC,0xF5,0x02,0x20,0x00,0x1E,0x50,0x1F,0x81,0x90, +0x49,0x00,0x3A,0xD2,0x66,0x00,0x00,0x02,0x2E,0x17,0xFE,0x1D,0x49,0x00,0x15,0x62, +0x42,0x10,0x80,0x03,0x3C,0x0B,0xFE,0xC1,0x58,0x10,0x81,0x44,0x3C,0x03,0xFE,0xAC, +0x42,0x00,0x14,0x0B,0x46,0x61,0x00,0x02,0x14,0x10,0x00,0x0E,0x3C,0x0C,0x00,0x36, +0x49,0x00,0x1B,0xBE,0x58,0x21,0x0D,0x08,0x02,0x00,0x02,0xD6,0x3C,0x03,0xFF,0x1C, +0x3C,0x03,0xFF,0x1D,0x46,0x11,0x00,0x03,0x2E,0x07,0xFC,0xF3,0x2E,0x07,0xFC,0xF5, +0x58,0x63,0x01,0x44,0x00,0x00,0x02,0x7C,0x3E,0x0F,0xFE,0x7C,0x3C,0x03,0xFF,0x9C, +0x00,0x10,0x00,0x40,0x3E,0x07,0xFC,0xE9,0x3E,0x67,0xFC,0xC5,0x50,0x21,0x00,0xE8, +0x2E,0x07,0xFC,0xBD,0x44,0x20,0x00,0x48,0x10,0x10,0x00,0x4C,0x58,0x10,0x80,0x78, +0x58,0x10,0x80,0x04,0x14,0x10,0x01,0x6D,0x49,0x00,0x3E,0x3A,0x14,0x10,0x01,0x6E, +0x46,0x09,0x00,0x80,0x42,0x10,0x90,0x0B,0x2E,0x20,0x00,0xE3,0x38,0xF1,0x06,0x02, +0x58,0x21,0x0F,0xF4,0x38,0x06,0x82,0x02,0x49,0x00,0x0A,0xB0,0x2E,0x17,0xFF,0xC9, +0x64,0x12,0x00,0x43,0x3C,0x0D,0xFF,0x88,0x2E,0x07,0xFC,0xF7,0x64,0x03,0x00,0x03, +0x49,0x00,0x1B,0x95,0x3C,0x00,0x00,0xBE,0x40,0x03,0x98,0x60,0x2E,0x07,0xFC,0xE3, +0x3C,0x0B,0xFF,0x9E,0x58,0x00,0x0B,0x68,0x49,0x00,0x0F,0x1C,0x3C,0x1D,0xFF,0x64, +0x40,0x00,0x82,0x00,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, +0xA5,0x5A,0x08,0x04,0x06,0x02,0x09,0x52,0x63,0x75,0x73,0x74,0x6F,0x6D,0x65,0x72, +0x00,0x00,0x00,0x00,0x70,0x72,0x6F,0x6A,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x37,0x31,0x30,0x32,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, +0x15,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,0xED,0x03,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,0x80,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,0x14,0x28,0xA0, +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,0x48,0x69, +0x00,0x00,0x00,0x00,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,0x67,0x11,0xF7,0x97 diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_common.c b/drivers/input/touchscreen/hxchipset83112b/himax_common.c index 24dd7a2b8e56..d62fd6416fd7 100644 --- a/drivers/input/touchscreen/hxchipset83112b/himax_common.c +++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.c @@ -23,6 +23,7 @@ #ifdef HX_RST_PIN_FUNC extern void himax_ic_reset(uint8_t loadconfig,uint8_t int_off); #endif +/*[Arima_8901][jinjia] Upgrade himax fw CID0804_D02_C15 for Ghost touch 20201209 begin*/ /*[Arima_8901][jinjia] Upgrade himax fw CID0804_D02_C14 for 0.9mm CG performance 20190903 begin*/ /*[Arima_8901][TracyChui]Add usb plug detect function and updated FW CID0804_D02_C13 20190816 start */ /*[Arima_8901][jinjia] Upgrade himax fw CID0804_D02_C12 for 0.9mm CG performance 20190812 begin*/ @@ -41,7 +42,7 @@ unsigned char i_CTPM_FW_HX83112A[]= }; unsigned char i_CTPM_FW_HX83112B[]= { -#include "FP_DJN_Arima_CID0804_D02_C14_20190903.i" +#include "FP_DJN_Arima_CID0804_D02_C15_20201209.i" }; #endif @@ -54,6 +55,7 @@ unsigned char i_CTPM_FW_HX83112B[]= /*[Arima_8901][jinjia] 20190812 end*/ /*[Arima_8901][TracyChui] 20190816 end */ /*[Arima_8901][jinjia] 20190812 end*/ +/*[Arima_8901][jinjia] 20201209 end*/ /*[Arima_8710][allen_yu] Solve the report point issue 20180619 begin*/ static void himax_release_all_finger(void); -- GitLab From 46b0260c246869c5be3deac3c6c7c6607c2d7f78 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 13 Aug 2019 12:53:17 +0100 Subject: [PATCH 34/78] tcp: Clear sk_send_head after purging the write queue Denis Andzakovic discovered a potential use-after-free in older kernel versions, using syzkaller. tcp_write_queue_purge() frees all skbs in the TCP write queue and can leave sk->sk_send_head pointing to freed memory. tcp_disconnect() clears that pointer after calling tcp_write_queue_purge(), but tcp_connect() does not. It is (surprisingly) possible to add to the write queue between disconnection and reconnection, so this needs to be done in both places. This bug was introduced by backports of commit 7f582b248d0a ("tcp: purge write queue in tcp_connect_init()") and does not exist upstream because of earlier changes in commit 75c119afe14f ("tcp: implement rb-tree based retransmit queue"). The latter is a major change that's not suitable for stable. Reported-by: Denis Andzakovic Bisected-by: Salvatore Bonaccorso Fixes: 7f582b248d0a ("tcp: purge write queue in tcp_connect_init()") Cc: # before 4.15 Cc: Eric Dumazet Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman Bug: 143009752 (cherry picked from commit e99e7745d03fc50ba7c5b7c91c17294fee2d5991) Signed-off-by: Matthias Maennich Change-Id: Ie325f18e7fe1c327a45e149034b90d2e74922263 (cherry picked from commit 3ed1460d6b17326093eb657afa89a7274e444a32) --- include/net/tcp.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/net/tcp.h b/include/net/tcp.h index 92a5e8396401..92e3c3aadd91 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1551,6 +1551,8 @@ struct tcp_fastopen_context { struct rcu_head rcu; }; +static inline void tcp_init_send_head(struct sock *sk); + /* write queue abstraction */ static inline void tcp_write_queue_purge(struct sock *sk) { @@ -1558,6 +1560,7 @@ static inline void tcp_write_queue_purge(struct sock *sk) while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) sk_wmem_free_skb(sk, skb); + tcp_init_send_head(sk); sk_mem_reclaim(sk); tcp_clear_all_retrans_hints(tcp_sk(sk)); tcp_init_send_head(sk); -- GitLab From c2df86a1e574873e23b55147c2463ef6de776aa0 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Tue, 28 Apr 2020 09:59:02 -0400 Subject: [PATCH 35/78] selinux: properly handle multiple messages in selinux_netlink_send() commit fb73974172ffaaf57a7c42f35424d9aece1a5af6 upstream. Fix the SELinux netlink_send hook to properly handle multiple netlink messages in a single sk_buff; each message is parsed and subject to SELinux access control. Prior to this patch, SELinux only inspected the first message in the sk_buff. Cc: stable@vger.kernel.org Reported-by: Dmitry Vyukov Reviewed-by: Stephen Smalley Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 6affa87d168d91af6c8f303dc1fc7a7f59869818) (cherry picked from commit 0e4d54ed47d9862440c880878b7706dc94d37a25) --- security/selinux/hooks.c | 68 ++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5adb50f835e8..6581b288e2af 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5021,39 +5021,59 @@ static int selinux_tun_dev_open(void *security) static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) { - int err = 0; - u32 perm; + int rc = 0; + unsigned int msg_len; + unsigned int data_len = skb->len; + unsigned char *data = skb->data; struct nlmsghdr *nlh; struct sk_security_struct *sksec = sk->sk_security; + u16 sclass = sksec->sclass; + u32 perm; - if (skb->len < NLMSG_HDRLEN) { - err = -EINVAL; - goto out; - } - nlh = nlmsg_hdr(skb); + while (data_len >= nlmsg_total_size(0)) { + nlh = (struct nlmsghdr *)data; - err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); - if (err) { - if (err == -EINVAL) { + /* NOTE: the nlmsg_len field isn't reliably set by some netlink + * users which means we can't reject skb's with bogus + * length fields; our solution is to follow what + * netlink_rcv_skb() does and simply skip processing at + * messages with length fields that are clearly junk + */ + if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len) + return 0; + + rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm); + if (rc == 0) { + rc = sock_has_perm(current, sk, perm); + if (rc) + return rc; + } else if (rc == -EINVAL) { + /* -EINVAL is a missing msg/perm mapping */ pr_warn_ratelimited("SELinux: unrecognized netlink" - " message: protocol=%hu nlmsg_type=%hu sclass=%s" - " pig=%d comm=%s\n", - sk->sk_protocol, nlh->nlmsg_type, - secclass_map[sksec->sclass - 1].name, - task_pid_nr(current), current->comm); - if (!selinux_enforcing || security_get_allow_unknown()) - err = 0; + " message: protocol=%hu nlmsg_type=%hu sclass=%s" + " pid=%d comm=%s\n", + sk->sk_protocol, nlh->nlmsg_type, + secclass_map[sclass - 1].name, + task_pid_nr(current), current->comm); + if (selinux_enforcing && !security_get_allow_unknown()) + return rc; + rc = 0; + } else if (rc == -ENOENT) { + /* -ENOENT is a missing socket/class mapping, ignore */ + rc = 0; + } else { + return rc; } - /* Ignore */ - if (err == -ENOENT) - err = 0; - goto out; + /* move to the next message after applying netlink padding */ + msg_len = NLMSG_ALIGN(nlh->nlmsg_len); + if (msg_len >= data_len) + return 0; + data_len -= msg_len; + data += msg_len; } - err = sock_has_perm(current, sk, perm); -out: - return err; + return rc; } #ifdef CONFIG_NETFILTER -- GitLab From 007258f99b02f924f04f13929f840af4c521f983 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 28 Mar 2020 16:18:11 -0400 Subject: [PATCH 36/78] USB: core: Fix free-while-in-use bug in the USB S-Glibrary commit 056ad39ee9253873522f6469c3364964a322912b upstream. FuzzUSB (a variant of syzkaller) found a free-while-still-in-use bug in the USB scatter-gather library: BUG: KASAN: use-after-free in atomic_read include/asm-generic/atomic-instrumented.h:26 [inline] BUG: KASAN: use-after-free in usb_hcd_unlink_urb+0x5f/0x170 drivers/usb/core/hcd.c:1607 Read of size 4 at addr ffff888065379610 by task kworker/u4:1/27 CPU: 1 PID: 27 Comm: kworker/u4:1 Not tainted 5.5.11 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 Workqueue: scsi_tmf_2 scmd_eh_abort_handler Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xce/0x128 lib/dump_stack.c:118 print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374 __kasan_report+0x153/0x1cb mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:639 check_memory_region_inline mm/kasan/generic.c:185 [inline] check_memory_region+0x152/0x1b0 mm/kasan/generic.c:192 __kasan_check_read+0x11/0x20 mm/kasan/common.c:95 atomic_read include/asm-generic/atomic-instrumented.h:26 [inline] usb_hcd_unlink_urb+0x5f/0x170 drivers/usb/core/hcd.c:1607 usb_unlink_urb+0x72/0xb0 drivers/usb/core/urb.c:657 usb_sg_cancel+0x14e/0x290 drivers/usb/core/message.c:602 usb_stor_stop_transport+0x5e/0xa0 drivers/usb/storage/transport.c:937 This bug occurs when cancellation of the S-G transfer races with transfer completion. When that happens, usb_sg_cancel() may continue to access the transfer's URBs after usb_sg_wait() has freed them. The bug is caused by the fact that usb_sg_cancel() does not take any sort of reference to the transfer, and so there is nothing to prevent the URBs from being deallocated while the routine is trying to use them. The fix is to take such a reference by incrementing the transfer's io->count field while the cancellation is in progres and decrementing it afterward. The transfer's URBs are not deallocated until io->complete is triggered, which happens when io->count reaches zero. Signed-off-by: Alan Stern Reported-and-tested-by: Kyungtae Kim CC: Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2003281615140.14837-100000@netrider.rowland.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit ab20e851e49e75a9e653463853995076899a4e48) (cherry picked from commit 114755b20cbdc9a98565e2b349594e39ee26ff4c) --- drivers/usb/core/message.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index cb1003183d30..25e83ddd5aa7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -585,12 +585,13 @@ void usb_sg_cancel(struct usb_sg_request *io) int i, retval; spin_lock_irqsave(&io->lock, flags); - if (io->status) { + if (io->status || io->count == 0) { spin_unlock_irqrestore(&io->lock, flags); return; } /* shut everything down */ io->status = -ECONNRESET; + io->count++; /* Keep the request alive until we're done */ spin_unlock_irqrestore(&io->lock, flags); for (i = io->entries - 1; i >= 0; --i) { @@ -604,6 +605,12 @@ void usb_sg_cancel(struct usb_sg_request *io) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } + + spin_lock_irqsave(&io->lock, flags); + io->count--; + if (!io->count) + complete(&io->complete); + spin_unlock_irqrestore(&io->lock, flags); } EXPORT_SYMBOL_GPL(usb_sg_cancel); -- GitLab From a18908edd5d012e5bba60da58de3d94691a4ca4d Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Mon, 20 Jul 2020 21:14:33 -0700 Subject: [PATCH 37/78] binder: fix UAF when releasing todo list When releasing a thread todo list when tearing down a binder_proc, the following race was possible which could result in a use-after-free: 1. Thread 1: enter binder_release_work from binder_thread_release 2. Thread 2: binder_update_ref_for_handle() calls binder_dec_node_ilocked() 3. Thread 2: dec nodeA --> 0 (will free node) 4. Thread 1: ACQ inner_proc_lock 5. Thread 2: block on inner_proc_lock 6. Thread 1: dequeue work (BINDER_WORK_NODE, part of nodeA) 7. Thread 1: REL inner_proc_lock 8. Thread 2: ACQ inner_proc_lock 9. Thread 2: todo list cleanup, but work was already dequeued 10. Thread 2: free node 11. Thread 2: REL inner_proc_lock 12. Thread 1: deref w->type (UAF) The problem was that for a BINDER_WORK_NODE, the binder_work element must not be accessed after releasing the inner_proc_lock while processing the todo list elements since another thread might be handling a deref on the node containing the binder_work element leading to the node being freed. Bug: 161151868 Signed-off-by: Todd Kjos Change-Id: I4ae752abfe1aa38872be6f266ddd271802952625 --- drivers/android/binder.c | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index f7f9a20d5d98..51bef2482149 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -281,7 +281,7 @@ struct binder_device { struct binder_work { struct list_head entry; - enum { + enum binder_work_type { BINDER_WORK_TRANSACTION = 1, BINDER_WORK_TRANSACTION_COMPLETE, BINDER_WORK_RETURN_ERROR, @@ -938,27 +938,6 @@ static struct binder_work *binder_dequeue_work_head_ilocked( return w; } -/** - * binder_dequeue_work_head() - Dequeues the item at head of list - * @proc: binder_proc associated with list - * @list: list to dequeue head - * - * Removes the head of the list if there are items on the list - * - * Return: pointer dequeued binder_work, NULL if list was empty - */ -static struct binder_work *binder_dequeue_work_head( - struct binder_proc *proc, - struct list_head *list) -{ - struct binder_work *w; - - binder_inner_proc_lock(proc); - w = binder_dequeue_work_head_ilocked(list); - binder_inner_proc_unlock(proc); - return w; -} - static void binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); static void binder_free_thread(struct binder_thread *thread); @@ -4584,13 +4563,17 @@ static void binder_release_work(struct binder_proc *proc, struct list_head *list) { struct binder_work *w; + enum binder_work_type wtype; while (1) { - w = binder_dequeue_work_head(proc, list); + binder_inner_proc_lock(proc); + w = binder_dequeue_work_head_ilocked(list); + wtype = w ? w->type : 0; + binder_inner_proc_unlock(proc); if (!w) return; - switch (w->type) { + switch (wtype) { case BINDER_WORK_TRANSACTION: { struct binder_transaction *t; @@ -4624,9 +4607,11 @@ static void binder_release_work(struct binder_proc *proc, kfree(death); binder_stats_deleted(BINDER_STAT_DEATH); } break; + case BINDER_WORK_NODE: + break; default: pr_err("unexpected work type, %d, not freed\n", - w->type); + wtype); break; } } -- GitLab From f81a265f76264a8f7303f164dffed7331a84081e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 29 Aug 2020 12:26:01 +0100 Subject: [PATCH 38/78] HID: core: Correctly handle ReportSize being zero commit bce1305c0ece3dc549663605e567655dd701752c upstream. It appears that a ReportSize value of zero is legal, even if a bit non-sensical. Most of the HID code seems to handle that gracefully, except when computing the total size in bytes. When fed as input to memset, this leads to some funky outcomes. Detect the corner case and correctly compute the size. Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier Signed-off-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman (cherry picked from commit cf7797ea60e3e721e3ae5090edbc2ec72d715436) --- drivers/hid/hid-core.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 4f3706e44905..b49211cbdb1c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1406,6 +1406,17 @@ static void hid_output_field(const struct hid_device *hid, } } +/* + * Compute the size of a report. + */ +static size_t hid_compute_report_size(struct hid_report *report) +{ + if (report->size) + return ((report->size - 1) >> 3) + 1; + + return 0; +} + /* * Create a report. 'data' has to be allocated using * hid_alloc_report_buf() so that it has proper size. @@ -1418,7 +1429,7 @@ void hid_output_report(struct hid_report *report, __u8 *data) if (report->id > 0) *data++ = report->id; - memset(data, 0, ((report->size - 1) >> 3) + 1); + memset(data, 0, hid_compute_report_size(report)); for (n = 0; n < report->maxfield; n++) hid_output_field(report->device, report->field[n], data); } @@ -1545,7 +1556,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, csize--; } - rsize = ((report->size - 1) >> 3) + 1; + rsize = hid_compute_report_size(report); if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) rsize = HID_MAX_BUFFER_SIZE - 1; -- GitLab From 17ced0ab7d9966627aeef19ae8e74fb109b788ab Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 1 Sep 2020 10:52:33 +0100 Subject: [PATCH 39/78] HID: core: Sanitize event code and type when mapping input commit 35556bed836f8dc07ac55f69c8d17dce3e7f0e25 upstream. When calling into hid_map_usage(), the passed event code is blindly stored as is, even if it doesn't fit in the associated bitmap. This event code can come from a variety of sources, including devices masquerading as input devices, only a bit more "programmable". Instead of taking the event code at face value, check that it actually fits the corresponding bitmap, and if it doesn't: - spit out a warning so that we know which device is acting up - NULLify the bitmap pointer so that we catch unexpected uses Code paths that can make use of untrusted inputs can now check that the mapping was indeed correct and bail out if not. Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier Signed-off-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman (cherry picked from commit ac48d8300edd1aa4ce0fbef0ff5136d363f44cdf) --- drivers/hid/hid-input.c | 4 ++++ drivers/hid/hid-multitouch.c | 2 ++ include/linux/hid.h | 42 +++++++++++++++++++++++++----------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 5dbb05961cb5..d45820271510 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1084,6 +1084,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } mapped: + /* Mapping failed, bail out */ + if (!bit) + return; + if (device->driver->input_mapped && device->driver->input_mapped(device, hidinput, field, usage, &bit, &max) < 0) { diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index fba655d639af..8c3d1de1da15 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -567,6 +567,8 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_UP_BUTTON: code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE); hid_map_usage(hi, usage, bit, max, EV_KEY, code); + if (!*bit) + return -1; input_set_capability(hi->input, EV_KEY, code); return 1; diff --git a/include/linux/hid.h b/include/linux/hid.h index 877bb9aaca18..17c8bea4f884 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -877,34 +877,49 @@ static inline void hid_device_io_stop(struct hid_device *hid) { * @max: maximal valid usage->code to consider later (out parameter) * @type: input event type (EV_KEY, EV_REL, ...) * @c: code which corresponds to this usage and type + * + * The value pointed to by @bit will be set to NULL if either @type is + * an unhandled event type, or if @c is out of range for @type. This + * can be used as an error condition. */ static inline void hid_map_usage(struct hid_input *hidinput, struct hid_usage *usage, unsigned long **bit, int *max, - __u8 type, __u16 c) + __u8 type, unsigned int c) { struct input_dev *input = hidinput->input; - - usage->type = type; - usage->code = c; + unsigned long *bmap = NULL; + unsigned int limit = 0; switch (type) { case EV_ABS: - *bit = input->absbit; - *max = ABS_MAX; + bmap = input->absbit; + limit = ABS_MAX; break; case EV_REL: - *bit = input->relbit; - *max = REL_MAX; + bmap = input->relbit; + limit = REL_MAX; break; case EV_KEY: - *bit = input->keybit; - *max = KEY_MAX; + bmap = input->keybit; + limit = KEY_MAX; break; case EV_LED: - *bit = input->ledbit; - *max = LED_MAX; + bmap = input->ledbit; + limit = LED_MAX; break; } + + if (unlikely(c > limit || !bmap)) { + pr_warn_ratelimited("%s: Invalid code %d type %d\n", + input->name, c, type); + *bit = NULL; + return; + } + + usage->type = type; + usage->code = c; + *max = limit; + *bit = bmap; } /** @@ -918,7 +933,8 @@ static inline void hid_map_usage_clear(struct hid_input *hidinput, __u8 type, __u16 c) { hid_map_usage(hidinput, usage, bit, max, type, c); - clear_bit(c, *bit); + if (*bit) + clear_bit(usage->code, *bit); } /** -- GitLab From 1fc74bd78d4754adcaf08bf4d66aa7695d4b2255 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 19 Aug 2020 17:12:17 +0100 Subject: [PATCH 40/78] epoll: Keep a reference on files added to the check list commit a9ed4a6560b8562b7e2e2bed9527e88001f7b682 upstream. When adding a new fd to an epoll, and that this new fd is an epoll fd itself, we recursively scan the fds attached to it to detect cycles, and add non-epool files to a "check list" that gets subsequently parsed. However, this check list isn't completely safe when deletions can happen concurrently. To sidestep the issue, make sure that a struct file placed on the check list sees its f_count increased, ensuring that a concurrent deletion won't result in the file disapearing from under our feet. Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier Signed-off-by: Al Viro Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 9bbd20326fefd709dc6e7cbf7442ea640bb5f601) --- fs/eventpoll.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index e76d0c3fa2c7..eaae76416a55 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1749,9 +1749,11 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests) * not already there, and calling reverse_path_check() * during ep_insert(). */ - if (list_empty(&epi->ffd.file->f_tfile_llink)) + if (list_empty(&epi->ffd.file->f_tfile_llink)) { + get_file(epi->ffd.file); list_add(&epi->ffd.file->f_tfile_llink, &tfile_check_list); + } } } mutex_unlock(&ep->mtx); @@ -1795,6 +1797,7 @@ static void clear_tfile_check_list(void) 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); } @@ -1949,9 +1952,11 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, clear_tfile_check_list(); 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; -- GitLab From 42af61b9e043039ec392e10e10b4a969375aa792 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 22 Aug 2020 18:25:52 -0400 Subject: [PATCH 41/78] do_epoll_ctl(): clean the failure exits up a bit commit 52c479697c9b73f628140dcdfcd39ea302d05482 upstream. Signed-off-by: Al Viro Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman (cherry picked from commit b3ce6ca929dc677f7e443eb3012dfc7a433b1161) --- fs/eventpoll.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index eaae76416a55..5b839ce77e02 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1948,10 +1948,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, 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 { get_file(tf.file); list_add(&tf.file->f_tfile_llink, @@ -1980,8 +1978,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, 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) @@ -2004,8 +2000,10 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, mutex_unlock(&ep->mtx); error_tgt_fput: - if (full_check) + if (full_check) { + clear_tfile_check_list(); mutex_unlock(&epmutex); + } fdput(tf); error_fput: -- GitLab From 704ba01175bfaa46e3c4a62f2431d1fed749f7ba Mon Sep 17 00:00:00 2001 From: Anthony Steinhauser Date: Tue, 19 May 2020 06:40:42 -0700 Subject: [PATCH 42/78] x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced IBRS. [ Upstream commit 21998a351512eba4ed5969006f0c55882d995ada ] When STIBP is unavailable or enhanced IBRS is available, Linux force-disables the IBPB mitigation of Spectre-BTB even when simultaneous multithreading is disabled. While attempts to enable IBPB using prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, ...) fail with EPERM, the seccomp syscall (or its prctl(PR_SET_SECCOMP, ...) equivalent) which are used e.g. by Chromium or OpenSSH succeed with no errors but the application remains silently vulnerable to cross-process Spectre v2 attacks (classical BTB poisoning). At the same time the SYSFS reporting (/sys/devices/system/cpu/vulnerabilities/spectre_v2) displays that IBPB is conditionally enabled when in fact it is unconditionally disabled. STIBP is useful only when SMT is enabled. When SMT is disabled and STIBP is unavailable, it makes no sense to force-disable also IBPB, because IBPB protects against cross-process Spectre-BTB attacks regardless of the SMT state. At the same time since missing STIBP was only observed on AMD CPUs, AMD does not recommend using STIBP, but recommends using IBPB, so disabling IBPB because of missing STIBP goes directly against AMD's advice: https://developer.amd.com/wp-content/resources/Architecture_Guidelines_Update_Indirect_Branch_Control.pdf Similarly, enhanced IBRS is designed to protect cross-core BTB poisoning and BTB-poisoning attacks from user space against kernel (and BTB-poisoning attacks from guest against hypervisor), it is not designed to prevent cross-process (or cross-VM) BTB poisoning between processes (or VMs) running on the same core. Therefore, even with enhanced IBRS it is necessary to flush the BTB during context-switches, so there is no reason to force disable IBPB when enhanced IBRS is available. Enable the prctl control of IBPB even when STIBP is unavailable or enhanced IBRS is available. Fixes: 7cc765a67d8e ("x86/speculation: Enable prctl mode for spectre_v2_user") Signed-off-by: Anthony Steinhauser Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin (cherry picked from commit 38be87f5e7a7a7378d4ef4528c13bd1d666ab867) Change-Id: Ibf6503df2aed0612cf4d9e3f3bbd52bd41c68fe1 --- arch/x86/kernel/cpu/bugs.c | 75 +++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 24307d5bb4b8..31c1d4499a2f 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -487,7 +487,9 @@ early_param("nospectre_v1", nospectre_v1_cmdline); static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = SPECTRE_V2_NONE; -static enum spectre_v2_user_mitigation spectre_v2_user __ro_after_init = +static enum spectre_v2_user_mitigation spectre_v2_user_stibp __ro_after_init = + SPECTRE_V2_USER_NONE; +static enum spectre_v2_user_mitigation spectre_v2_user_ibpb __ro_after_init = SPECTRE_V2_USER_NONE; #ifdef RETPOLINE @@ -654,23 +656,36 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n", static_key_enabled(&switch_mm_always_ibpb) ? "always-on" : "conditional"); + + spectre_v2_user_ibpb = mode; } - /* If enhanced IBRS is enabled no STIPB required */ - if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) + /* + * If enhanced IBRS is enabled or SMT impossible, STIBP is not + * required. + */ + if (!smt_possible || spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) return; /* - * If SMT is not possible or STIBP is not available clear the STIPB - * mode. + * At this point, an STIBP mode other than "off" has been set. + * If STIBP support is not being forced, check if STIBP always-on + * is preferred. */ - if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP)) + if (mode != SPECTRE_V2_USER_STRICT && + boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) + mode = SPECTRE_V2_USER_STRICT_PREFERRED; + + /* + * If STIBP is not available, clear the STIBP mode. + */ + if (!boot_cpu_has(X86_FEATURE_STIBP)) mode = SPECTRE_V2_USER_NONE; + + spectre_v2_user_stibp = mode; + set_mode: - spectre_v2_user = mode; - /* Only print the STIBP mode when SMT possible */ - if (smt_possible) - pr_info("%s\n", spectre_v2_user_strings[mode]); + pr_info("%s\n", spectre_v2_user_strings[mode]); } static const char * const spectre_v2_strings[] = { @@ -910,7 +925,7 @@ void arch_smt_update(void) { mutex_lock(&spec_ctrl_mutex); - switch (spectre_v2_user) { + switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: break; case SPECTRE_V2_USER_STRICT: @@ -1142,13 +1157,16 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) { switch (ctrl) { case PR_SPEC_ENABLE: - if (spectre_v2_user == SPECTRE_V2_USER_NONE) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return 0; /* * Indirect branch speculation is always disabled in strict * mode. */ - if (spectre_v2_user == SPECTRE_V2_USER_STRICT) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) return -EPERM; task_clear_spec_ib_disable(task); task_update_spec_tif(task); @@ -1159,9 +1177,12 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) * Indirect branch speculation is always allowed when * mitigation is force disabled. */ - if (spectre_v2_user == SPECTRE_V2_USER_NONE) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return -EPERM; - if (spectre_v2_user == SPECTRE_V2_USER_STRICT) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) return 0; task_set_spec_ib_disable(task); if (ctrl == PR_SPEC_FORCE_DISABLE) @@ -1192,7 +1213,8 @@ void arch_seccomp_spec_mitigate(struct task_struct *task) { if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP) ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE); - if (spectre_v2_user == SPECTRE_V2_USER_SECCOMP) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || + spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) ib_prctl_set(task, PR_SPEC_FORCE_DISABLE); } #endif @@ -1221,21 +1243,24 @@ static int ib_prctl_get(struct task_struct *task) if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) return PR_SPEC_NOT_AFFECTED; - switch (spectre_v2_user) { - case SPECTRE_V2_USER_NONE: + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return PR_SPEC_ENABLE; - case SPECTRE_V2_USER_PRCTL: - case SPECTRE_V2_USER_SECCOMP: + else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) + return PR_SPEC_DISABLE; + else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL || + spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || + spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL || + spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) { if (task_spec_ib_force_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; if (task_spec_ib_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_DISABLE; return PR_SPEC_PRCTL | PR_SPEC_ENABLE; - case SPECTRE_V2_USER_STRICT: - return PR_SPEC_DISABLE; - default: + } else return PR_SPEC_NOT_AFFECTED; - } } int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) @@ -1476,7 +1501,7 @@ static char *stibp_state(void) if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) return ""; - switch (spectre_v2_user) { + switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: return ", STIBP: disabled"; case SPECTRE_V2_USER_STRICT: -- GitLab From 31e92f2f336c773208e04bcf052fd807ed559c54 Mon Sep 17 00:00:00 2001 From: Anthony Steinhauser Date: Sun, 5 Jan 2020 12:19:43 -0800 Subject: [PATCH 43/78] x86/speculation: Prevent rogue cross-process SSBD shutdown commit dbbe2ad02e9df26e372f38cc3e70dab9222c832e upstream. On context switch the change of TIF_SSBD and TIF_SPEC_IB are evaluated to adjust the mitigations accordingly. This is optimized to avoid the expensive MSR write if not needed. This optimization is buggy and allows an attacker to shutdown the SSBD protection of a victim process. The update logic reads the cached base value for the speculation control MSR which has neither the SSBD nor the STIBP bit set. It then OR's the SSBD bit only when TIF_SSBD is different and requests the MSR update. That means if TIF_SSBD of the previous and next task are the same, then the base value is not updated, even if TIF_SSBD is set. The MSR write is not requested. Subsequently if the TIF_STIBP bit differs then the STIBP bit is updated in the base value and the MSR is written with a wrong SSBD value. This was introduced when the per task/process conditional STIPB switching was added on top of the existing SSBD switching. It is exploitable if the attacker creates a process which enforces SSBD and has the contrary value of STIBP than the victim process (i.e. if the victim process enforces STIBP, the attacker process must not enforce it; if the victim process does not enforce STIBP, the attacker process must enforce it) and schedule it on the same core as the victim process. If the victim runs after the attacker the victim becomes vulnerable to Spectre V4. To fix this, update the MSR value independent of the TIF_SSBD difference and dependent on the SSBD mitigation method available. This ensures that a subsequent STIPB initiated MSR write has the correct state of SSBD. [ tglx: Handle X86_FEATURE_VIRT_SSBD & X86_FEATURE_VIRT_SSBD correctly and massaged changelog ] Fixes: 5bfbe3ad5840 ("x86/speculation: Prepare for per task indirect branch speculation control") Signed-off-by: Anthony Steinhauser Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit fc0abf5a64ea5d028af0cf5d37d5898afe6748c5) --- arch/x86/kernel/process.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f1f3c471438f..fcc5dfb2cbd4 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -324,28 +324,20 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp, u64 msr = x86_spec_ctrl_base; bool updmsr = false; - /* - * If TIF_SSBD is different, select the proper mitigation - * method. Note that if SSBD mitigation is disabled or permanentely - * enabled this branch can't be taken because nothing can set - * TIF_SSBD. - */ - if (tif_diff & _TIF_SSBD) { - if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) { + /* Handle change of TIF_SSBD depending on the mitigation method. */ + if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) { + if (tif_diff & _TIF_SSBD) amd_set_ssb_virt_state(tifn); - } else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) { + } else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) { + if (tif_diff & _TIF_SSBD) amd_set_core_ssb_state(tifn); - } else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || - static_cpu_has(X86_FEATURE_AMD_SSBD)) { - msr |= ssbd_tif_to_spec_ctrl(tifn); - updmsr = true; - } + } else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || + static_cpu_has(X86_FEATURE_AMD_SSBD)) { + updmsr |= !!(tif_diff & _TIF_SSBD); + msr |= ssbd_tif_to_spec_ctrl(tifn); } - /* - * Only evaluate TIF_SPEC_IB if conditional STIBP is enabled, - * otherwise avoid the MSR write. - */ + /* Only evaluate TIF_SPEC_IB if conditional STIBP is enabled. */ if (IS_ENABLED(CONFIG_SMP) && static_branch_unlikely(&switch_to_cond_stibp)) { updmsr |= !!(tif_diff & _TIF_SPEC_IB); -- GitLab From 9fc1e624cbb56975fc89686daf23c2ee851ae8bd Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Wed, 27 May 2020 22:20:52 -0700 Subject: [PATCH 44/78] fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info() [ Upstream commit 1d605416fb7175e1adf094251466caa52093b413 ] KMSAN reported uninitialized data being written to disk when dumping core. As a result, several kilobytes of kmalloc memory may be written to the core file and then read by a non-privileged user. Reported-by: sam Signed-off-by: Alexander Potapenko Signed-off-by: Andrew Morton Acked-by: Kees Cook Cc: Al Viro Cc: Alexey Dobriyan Cc: Link: http://lkml.kernel.org/r/20200419100848.63472-1-glider@google.com Link: https://github.com/google/kmsan/issues/76 Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin (cherry picked from commit d228bc4b19e0b1c35f3eb404acbf1d607c01e64c) --- fs/binfmt_elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index e7e25a86bbff..241749c766b8 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1709,7 +1709,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, (!regset->active || regset->active(t->task, regset) > 0)) { int ret; size_t size = regset->n * regset->size; - void *data = kmalloc(size, GFP_KERNEL); + void *data = kzalloc(size, GFP_KERNEL); if (unlikely(!data)) return 0; ret = regset->get(t->task, regset, -- GitLab From da07264714ea5574c9fa0224e2f66b9c6697b2cd Mon Sep 17 00:00:00 2001 From: Rohan Sethi Date: Thu, 20 Aug 2020 17:09:16 +0530 Subject: [PATCH 45/78] msm: kgsl: skip if requested address doesn't fall in the svm range User should not be provided address out of SVM region. Return error for any such requests from user. Change-Id: If149044039b156f8192f405714f5c1a0571004e7 Signed-off-by: gkiranku Signed-off-by: Rohan Sethi --- drivers/gpu/msm/kgsl_iommu.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index d023170a5de4..87e4cb3cfd3c 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -2427,6 +2427,22 @@ static uint64_t kgsl_iommu_find_svm_region(struct kgsl_pagetable *pagetable, return addr; } +static bool iommu_addr_in_svm_ranges(struct kgsl_iommu_pt *pt, + u64 gpuaddr, u64 size) +{ + if ((gpuaddr >= pt->compat_va_start && gpuaddr < pt->compat_va_end) && + ((gpuaddr + size) > pt->compat_va_start && + (gpuaddr + size) <= pt->compat_va_end)) + return true; + + if ((gpuaddr >= pt->svm_start && gpuaddr < pt->svm_end) && + ((gpuaddr + size) > pt->svm_start && + (gpuaddr + size) <= pt->svm_end)) + return true; + + return false; +} + static int kgsl_iommu_set_svm_region(struct kgsl_pagetable *pagetable, uint64_t gpuaddr, uint64_t size) { @@ -2434,9 +2450,8 @@ static int kgsl_iommu_set_svm_region(struct kgsl_pagetable *pagetable, struct kgsl_iommu_pt *pt = pagetable->priv; struct rb_node *node; - /* Make sure the requested address doesn't fall in the global range */ - if (ADDR_IN_GLOBAL(pagetable->mmu, gpuaddr) || - ADDR_IN_GLOBAL(pagetable->mmu, gpuaddr + size)) + /* Make sure the requested address doesn't fall out of SVM range */ + if (!iommu_addr_in_svm_ranges(pt, gpuaddr, size)) return -ENOMEM; spin_lock(&pagetable->lock); -- GitLab From 8f0fb820d3f1883ca2218a159ce167251e474c8a Mon Sep 17 00:00:00 2001 From: Kamal Agrawal Date: Wed, 19 Aug 2020 10:25:15 +0530 Subject: [PATCH 46/78] msm: kgsl: Correctly clean up dma buffer attachment in case of error In kgsl_ioctl_gpuobj_import(), user memory of type KGSL_USER_MEM_TYPE_ADDR can also lead to setting up a dma buffer. When attaching mem entry to process fails, dma buffer attachment is cleaned up only in case of KGSL_USER_MEM_TYPE_DMABUF. Similar situation can arise in case of kgsl_ioctl_map_user_mem(). Fix this by obtaining user memory type from the memdesc flags. Change-Id: I502bd0ae19241802e8f835f20391b2ce67999418 Signed-off-by: Puranam V G Tejaswi Signed-off-by: Kamal Agrawal --- drivers/gpu/msm/kgsl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 66102af23356..b47f095a2dd1 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2020, 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 @@ -2487,7 +2487,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv, return 0; unmap: - if (param->type == KGSL_USER_MEM_TYPE_DMABUF) { + if (kgsl_memdesc_usermem_type(&entry->memdesc) == KGSL_MEM_ENTRY_ION) { kgsl_destroy_ion(entry->priv_data); entry->memdesc.sgt = NULL; } @@ -2793,7 +2793,7 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, return result; error_attach: - switch (memtype) { + switch (kgsl_memdesc_usermem_type(&entry->memdesc)) { case KGSL_MEM_ENTRY_ION: kgsl_destroy_ion(entry->priv_data); entry->memdesc.sgt = NULL; -- GitLab From 6aaa0d0793fc88d89454f5ea37d93bd9c6d83c98 Mon Sep 17 00:00:00 2001 From: Puranam V G Tejaswi Date: Fri, 24 Jul 2020 08:54:54 +0530 Subject: [PATCH 47/78] msm: kgsl: Fix possible use-after-free while adding context to active list Consider a scenario where a context is valid when the check is made in adreno_dispatcher_queue_cmds(), but by the time we reach _track_context(), context has been detached. We would try to delete the entry from the active context list as part of detaching the context though the entry is not added yet. Now in _track_context() the context is actually added. When the context is finally destroyed, we would be left with invalid entry in the list. Next time when a context is added, an attempt would be made to use a freed entry. Fix this by moving the entry deletion part under drawctxt lock. Change-Id: Idab7cbf10987598b3e6395b2d50c20d1990d1f02 Signed-off-by: Puranam V G Tejaswi --- drivers/gpu/msm/adreno_drawctxt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c index a7699156a2b8..ebcf0dd6e4bc 100644 --- a/drivers/gpu/msm/adreno_drawctxt.c +++ b/drivers/gpu/msm/adreno_drawctxt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2020, 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 @@ -487,11 +487,12 @@ void adreno_drawctxt_detach(struct kgsl_context *context) drawctxt = ADRENO_CONTEXT(context); rb = drawctxt->rb; + spin_lock(&drawctxt->lock); + spin_lock(&adreno_dev->active_list_lock); list_del_init(&drawctxt->active_node); spin_unlock(&adreno_dev->active_list_lock); - spin_lock(&drawctxt->lock); count = drawctxt_detach_drawobjs(drawctxt, list); spin_unlock(&drawctxt->lock); -- GitLab From 08a82c8020a153e5d61242d3079cabddef09ab77 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Wed, 5 Aug 2020 14:05:26 +0530 Subject: [PATCH 48/78] msm: camera: cci: Fix incorrect use of cci config ioctl The cci configuration will be transitioned to a new API that does not require routing through the v4l layer. This is work-in-progrss so in the mean time prevent the device from being exposed as configurable from userspace. The ioctl will still be exposed to kernel users so fix the arg size as well. We want size of struct not pointer. CRs-Fixed: 2702760 Change-Id: I9c7bd8f76980603dbf27e1c5bc9b19f8a3b8a39a Signed-off-by: Fernando Pacheco Signed-off-by: VijayaKumar T M --- .../msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c | 5 ++--- .../msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h | 4 ++-- .../msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c | 5 ++--- .../msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c index 958737f1a879..5f7668a9579a 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, 2020 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 @@ -329,8 +329,7 @@ static int cam_cci_platform_probe(struct platform_device *pdev) sizeof(new_cci_dev->device_name)); new_cci_dev->v4l2_dev_str.name = new_cci_dev->device_name; - new_cci_dev->v4l2_dev_str.sd_flags = - (V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS); + new_cci_dev->v4l2_dev_str.sd_flags = V4L2_SUBDEV_FL_HAS_EVENTS; new_cci_dev->v4l2_dev_str.ent_function = CAM_CCI_DEVICE_TYPE; new_cci_dev->v4l2_dev_str.token = diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h index ef2463dde4d0..506c53acd530 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 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 @@ -308,6 +308,6 @@ static inline struct v4l2_subdev *cam_cci_get_subdev(void) #endif #define VIDIOC_MSM_CCI_CFG \ - _IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct cam_cci_ctrl *) + _IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct cam_cci_ctrl) #endif /* _CAM_CCI_DEV_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c index 69b5af002610..56bd000ca042 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 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 @@ -403,8 +403,7 @@ static int cam_cci_platform_probe(struct platform_device *pdev) sizeof(new_cci_dev->device_name)); new_cci_dev->v4l2_dev_str.name = new_cci_dev->device_name; - new_cci_dev->v4l2_dev_str.sd_flags = - (V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS); + new_cci_dev->v4l2_dev_str.sd_flags = V4L2_SUBDEV_FL_HAS_EVENTS; new_cci_dev->v4l2_dev_str.ent_function = CAM_CCI_DEVICE_TYPE; new_cci_dev->v4l2_dev_str.token = diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h index 54eed834be07..3d0382ff5cf7 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, 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 @@ -316,6 +316,6 @@ static inline struct v4l2_subdev *cam_cci_get_subdev(int cci_dev_index) #endif #define VIDIOC_MSM_CCI_CFG \ - _IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct cam_cci_ctrl *) + _IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct cam_cci_ctrl) #endif /* _CAM_CCI_DEV_H_ */ -- GitLab From 1e6b63e847946cbc9caf7e0389b3a09a6b403124 Mon Sep 17 00:00:00 2001 From: Indira Biruduraju Date: Tue, 11 Aug 2020 15:24:16 +0530 Subject: [PATCH 49/78] msm: kgsl: Remove VM_MAYWRITE flag to restrict mprotect When VM_MAYWRITE flag is used during mmap(), mprotect() can be used later to change the protection of memstore to allow write. Make sure this does not happen by removing VM_MAYWRITE from the vm_flags of vma. Change-Id: I6f69f05858ea40611d512cfa796caabeaa88cdb5 Signed-off-by: Indira Biruduraju --- drivers/gpu/msm/kgsl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index b47f095a2dd1..2ddf48a519cf 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -4139,6 +4139,8 @@ kgsl_mmap_memstore(struct kgsl_device *device, struct vm_area_struct *vma) if (vma->vm_flags & VM_WRITE) return -EPERM; + vma->vm_flags &= ~VM_MAYWRITE; + if (memdesc->size != vma_size) { KGSL_MEM_ERR(device, "memstore bad size: %d should be %llu\n", vma_size, memdesc->size); -- GitLab From a97f294aa6b61aefee4a651248ff2156c7e78d15 Mon Sep 17 00:00:00 2001 From: Venkata Prahlad Valluru Date: Mon, 14 Sep 2020 14:41:13 +0530 Subject: [PATCH 50/78] gpu: drm: msm: add event to event_list after register is successful Add event to event_list after msm_register_event is successful to avoid use-after-free vulnerability. Change-Id: I34fb39c99051978cbab64a852851964691a5ea9e Signed-off-by: Ping Li Signed-off-by: Venkata Prahlad Valluru --- drivers/gpu/drm/msm/msm_drv.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 1c058db125f9..ff8c1cd9aba8 100755 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -1295,24 +1295,27 @@ static int msm_ioctl_register_event(struct drm_device *dev, void *data, * calls add to client list and return. */ count = msm_event_client_count(dev, req_event, false); - /* Add current client to list */ - spin_lock_irqsave(&dev->event_lock, flag); - list_add_tail(&client->base.link, &priv->client_event_list); - spin_unlock_irqrestore(&dev->event_lock, flag); - - if (count) + if (count) { + /* Add current client to list */ + spin_lock_irqsave(&dev->event_lock, flag); + list_add_tail(&client->base.link, &priv->client_event_list); + spin_unlock_irqrestore(&dev->event_lock, flag); return 0; + } ret = msm_register_event(dev, req_event, file, true); if (ret) { DRM_ERROR("failed to enable event %x object %x object id %d\n", req_event->event, req_event->object_type, req_event->object_id); + kfree(client); + } else { + /* Add current client to list */ spin_lock_irqsave(&dev->event_lock, flag); - list_del(&client->base.link); + list_add_tail(&client->base.link, &priv->client_event_list); spin_unlock_irqrestore(&dev->event_lock, flag); - kfree(client); } + return ret; } -- GitLab From 9ea6cad35f8790597769381c1415b60293c9eb02 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 24 Sep 2020 09:05:53 -0600 Subject: [PATCH 51/78] msm: kgsl: Don't allow re-importing memory owned by KGSL Don't allow IOCTL_KGSL_MAP_USER_MEM to import user memory that was already allocated and mapped by KGSL in the first place. Remapping memory never makes sense and it messes up reference counting in the pools. Change-Id: Ic0dedbade96ac6b30dcbbb794bf57a597f1bb351 Signed-off-by: Jordan Crouse Signed-off-by: Archana Sriram --- drivers/gpu/msm/kgsl.c | 57 +++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 2ddf48a519cf..fa4e6052ed49 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2090,14 +2090,6 @@ long kgsl_ioctl_cmdstream_freememontimestamp_ctxtid( return ret; } -static inline int _check_region(unsigned long start, unsigned long size, - uint64_t len) -{ - uint64_t end = ((uint64_t) start) + size; - - return (end > len); -} - static int check_vma_flags(struct vm_area_struct *vma, unsigned int flags) { @@ -2112,23 +2104,27 @@ static int check_vma_flags(struct vm_area_struct *vma, return -EFAULT; } -static int check_vma(struct vm_area_struct *vma, struct file *vmfile, - struct kgsl_memdesc *memdesc) +static int check_vma(unsigned long hostptr, u64 size) { - if (vma == NULL || vma->vm_file != vmfile) - return -EINVAL; + struct vm_area_struct *vma; + unsigned long cur = hostptr; - /* userspace may not know the size, in which case use the whole vma */ - if (memdesc->size == 0) - memdesc->size = vma->vm_end - vma->vm_start; - /* range checking */ - if (vma->vm_start != memdesc->useraddr || - (memdesc->useraddr + memdesc->size) != vma->vm_end) - return -EINVAL; - return check_vma_flags(vma, memdesc->flags); + while (cur < (hostptr + size)) { + vma = find_vma(current->mm, cur); + if (!vma) + return false; + + /* Don't remap memory that we already own */ + if (vma->vm_file && vma->vm_file->f_op == &kgsl_fops) + return false; + + cur = vma->vm_end; + } + + return true; } -static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, struct file *vmfile) +static int memdesc_sg_virt(struct kgsl_memdesc *memdesc) { int ret = 0; long npages = 0, i; @@ -2151,18 +2147,17 @@ static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, struct file *vmfile) } down_read(¤t->mm->mmap_sem); - /* If we have vmfile, make sure we map the correct vma and map it all */ - if (vmfile != NULL) - ret = check_vma(find_vma(current->mm, memdesc->useraddr), - vmfile, memdesc); - - if (ret == 0) { - npages = get_user_pages(memdesc->useraddr, - sglen, write, pages, NULL); - ret = (npages < 0) ? (int)npages : 0; + if (!check_vma(memdesc->useraddr, memdesc->size)) { + up_read(¤t->mm->mmap_sem); + ret = -EFAULT; + goto out; } + + npages = get_user_pages(memdesc->useraddr, + sglen, write, pages, NULL); up_read(¤t->mm->mmap_sem); + ret = (npages < 0) ? (int)npages : 0; if (ret) goto out; @@ -2213,7 +2208,7 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr; } - return memdesc_sg_virt(&entry->memdesc, NULL); + return memdesc_sg_virt(&entry->memdesc); } #ifdef CONFIG_DMA_SHARED_BUFFER -- GitLab From e372004b2528c1535e0f51144d68461250d4caaf Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Tue, 16 Jun 2020 20:16:55 +0800 Subject: [PATCH 52/78] block: Fix use-after-free in blkdev_get() [ Upstream commit 2d3a8e2deddea6c89961c422ec0c5b851e648c14 ] In blkdev_get() we call __blkdev_get() to do some internal jobs and if there is some errors in __blkdev_get(), the bdput() is called which means we have released the refcount of the bdev (actually the refcount of the bdev inode). This means we cannot access bdev after that point. But acctually bdev is still accessed in blkdev_get() after calling __blkdev_get(). This results in use-after-free if the refcount is the last one we released in __blkdev_get(). Let's take a look at the following scenerio: CPU0 CPU1 CPU2 blkdev_open blkdev_open Remove disk bd_acquire blkdev_get __blkdev_get del_gendisk bdev_unhash_inode bd_acquire bdev_get_gendisk bd_forget failed because of unhashed bdput bdput (the last one) bdev_evict_inode access bdev => use after free [ 459.350216] BUG: KASAN: use-after-free in __lock_acquire+0x24c1/0x31b0 [ 459.351190] Read of size 8 at addr ffff88806c815a80 by task syz-executor.0/20132 [ 459.352347] [ 459.352594] CPU: 0 PID: 20132 Comm: syz-executor.0 Not tainted 4.19.90 #2 [ 459.353628] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 [ 459.354947] Call Trace: [ 459.355337] dump_stack+0x111/0x19e [ 459.355879] ? __lock_acquire+0x24c1/0x31b0 [ 459.356523] print_address_description+0x60/0x223 [ 459.357248] ? __lock_acquire+0x24c1/0x31b0 [ 459.357887] kasan_report.cold+0xae/0x2d8 [ 459.358503] __lock_acquire+0x24c1/0x31b0 [ 459.359120] ? _raw_spin_unlock_irq+0x24/0x40 [ 459.359784] ? lockdep_hardirqs_on+0x37b/0x580 [ 459.360465] ? _raw_spin_unlock_irq+0x24/0x40 [ 459.361123] ? finish_task_switch+0x125/0x600 [ 459.361812] ? finish_task_switch+0xee/0x600 [ 459.362471] ? mark_held_locks+0xf0/0xf0 [ 459.363108] ? __schedule+0x96f/0x21d0 [ 459.363716] lock_acquire+0x111/0x320 [ 459.364285] ? blkdev_get+0xce/0xbe0 [ 459.364846] ? blkdev_get+0xce/0xbe0 [ 459.365390] __mutex_lock+0xf9/0x12a0 [ 459.365948] ? blkdev_get+0xce/0xbe0 [ 459.366493] ? bdev_evict_inode+0x1f0/0x1f0 [ 459.367130] ? blkdev_get+0xce/0xbe0 [ 459.367678] ? destroy_inode+0xbc/0x110 [ 459.368261] ? mutex_trylock+0x1a0/0x1a0 [ 459.368867] ? __blkdev_get+0x3e6/0x1280 [ 459.369463] ? bdev_disk_changed+0x1d0/0x1d0 [ 459.370114] ? blkdev_get+0xce/0xbe0 [ 459.370656] blkdev_get+0xce/0xbe0 [ 459.371178] ? find_held_lock+0x2c/0x110 [ 459.371774] ? __blkdev_get+0x1280/0x1280 [ 459.372383] ? lock_downgrade+0x680/0x680 [ 459.373002] ? lock_acquire+0x111/0x320 [ 459.373587] ? bd_acquire+0x21/0x2c0 [ 459.374134] ? do_raw_spin_unlock+0x4f/0x250 [ 459.374780] blkdev_open+0x202/0x290 [ 459.375325] do_dentry_open+0x49e/0x1050 [ 459.375924] ? blkdev_get_by_dev+0x70/0x70 [ 459.376543] ? __x64_sys_fchdir+0x1f0/0x1f0 [ 459.377192] ? inode_permission+0xbe/0x3a0 [ 459.377818] path_openat+0x148c/0x3f50 [ 459.378392] ? kmem_cache_alloc+0xd5/0x280 [ 459.379016] ? entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 459.379802] ? path_lookupat.isra.0+0x900/0x900 [ 459.380489] ? __lock_is_held+0xad/0x140 [ 459.381093] do_filp_open+0x1a1/0x280 [ 459.381654] ? may_open_dev+0xf0/0xf0 [ 459.382214] ? find_held_lock+0x2c/0x110 [ 459.382816] ? lock_downgrade+0x680/0x680 [ 459.383425] ? __lock_is_held+0xad/0x140 [ 459.384024] ? do_raw_spin_unlock+0x4f/0x250 [ 459.384668] ? _raw_spin_unlock+0x1f/0x30 [ 459.385280] ? __alloc_fd+0x448/0x560 [ 459.385841] do_sys_open+0x3c3/0x500 [ 459.386386] ? filp_open+0x70/0x70 [ 459.386911] ? trace_hardirqs_on_thunk+0x1a/0x1c [ 459.387610] ? trace_hardirqs_off_caller+0x55/0x1c0 [ 459.388342] ? do_syscall_64+0x1a/0x520 [ 459.388930] do_syscall_64+0xc3/0x520 [ 459.389490] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 459.390248] RIP: 0033:0x416211 [ 459.390720] Code: 75 14 b8 02 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 04 19 00 00 c3 48 83 ec 08 e8 0a fa ff ff 48 89 04 24 b8 02 00 00 00 0f 05 <48> 8b 3c 24 48 89 c2 e8 53 fa ff ff 48 89 d0 48 83 c4 08 48 3d 01 [ 459.393483] RSP: 002b:00007fe45dfe9a60 EFLAGS: 00000293 ORIG_RAX: 0000000000000002 [ 459.394610] RAX: ffffffffffffffda RBX: 00007fe45dfea6d4 RCX: 0000000000416211 [ 459.395678] RDX: 00007fe45dfe9b0a RSI: 0000000000000002 RDI: 00007fe45dfe9b00 [ 459.396758] RBP: 000000000076bf20 R08: 0000000000000000 R09: 000000000000000a [ 459.397930] R10: 0000000000000075 R11: 0000000000000293 R12: 00000000ffffffff [ 459.399022] R13: 0000000000000bd9 R14: 00000000004cdb80 R15: 000000000076bf2c [ 459.400168] [ 459.400430] Allocated by task 20132: [ 459.401038] kasan_kmalloc+0xbf/0xe0 [ 459.401652] kmem_cache_alloc+0xd5/0x280 [ 459.402330] bdev_alloc_inode+0x18/0x40 [ 459.402970] alloc_inode+0x5f/0x180 [ 459.403510] iget5_locked+0x57/0xd0 [ 459.404095] bdget+0x94/0x4e0 [ 459.404607] bd_acquire+0xfa/0x2c0 [ 459.405113] blkdev_open+0x110/0x290 [ 459.405702] do_dentry_open+0x49e/0x1050 [ 459.406340] path_openat+0x148c/0x3f50 [ 459.406926] do_filp_open+0x1a1/0x280 [ 459.407471] do_sys_open+0x3c3/0x500 [ 459.408010] do_syscall_64+0xc3/0x520 [ 459.408572] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 459.409415] [ 459.409679] Freed by task 1262: [ 459.410212] __kasan_slab_free+0x129/0x170 [ 459.410919] kmem_cache_free+0xb2/0x2a0 [ 459.411564] rcu_process_callbacks+0xbb2/0x2320 [ 459.412318] __do_softirq+0x225/0x8ac Fix this by delaying bdput() to the end of blkdev_get() which means we have finished accessing bdev. Fixes: 77ea887e433a ("implement in-kernel gendisk events handling") Reported-by: Hulk Robot Signed-off-by: Jason Yan Tested-by: Sedat Dilek Reviewed-by: Jan Kara Reviewed-by: Christoph Hellwig Reviewed-by: Dan Carpenter Cc: Christoph Hellwig Cc: Jens Axboe Cc: Ming Lei Cc: Jan Kara Cc: Dan Carpenter Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin (cherry picked from commit a54b15af2b495ed97660a6276710ef36e06ac6c9) --- fs/block_dev.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 11c061b17e6e..af27a71ec344 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1286,10 +1286,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) */ 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 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) 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 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) put_disk(disk); module_put(owner); out: - bdput(bdev); return ret; } @@ -1502,6 +1501,9 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) bdput(whole); } + if (res) + bdput(bdev); + return res; } EXPORT_SYMBOL(blkdev_get); -- GitLab From 807a600f7f34ff7fc2157d081e9556e188ec8273 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 15 Oct 2020 11:42:00 -0700 Subject: [PATCH 53/78] icmp: randomize the global rate limiter [ Upstream commit b38e7819cae946e2edf869e604af1e65a5d241c5 ] Keyu Man reported that the ICMP rate limiter could be used by attackers to get useful signal. Details will be provided in an upcoming academic publication. Our solution is to add some noise, so that the attackers no longer can get help from the predictable token bucket limiter. Fixes: 4cdf507d5452 ("icmp: add a global rate limitation") Signed-off-by: Eric Dumazet Reported-by: Keyu Man Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman (cherry picked from commit df838165a187b7c699ec372a2a136f9873112776) --- Documentation/networking/ip-sysctl.txt | 4 +++- net/ipv4/icmp.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 12d9a6878fe2..54de8ff14627 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -912,12 +912,14 @@ icmp_ratelimit - INTEGER 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/net/ipv4/icmp.c b/net/ipv4/icmp.c index 5dab15856ccd..6b66f059a15b 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -246,7 +246,7 @@ static struct { /** * 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 @@ bool icmp_global_allow(void) } 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); -- GitLab From 87f04358c2fe1bbf8b25790748db095c5f72906e Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Wed, 27 May 2020 19:06:24 -0400 Subject: [PATCH 54/78] mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked() commit c444eb564fb16645c172d550359cb3d75fe8a040 upstream. Write protect anon page faults require an accurate mapcount to decide if to break the COW or not. This is implemented in the THP path with reuse_swap_page() -> page_trans_huge_map_swapcount()/page_trans_huge_mapcount(). If the COW triggers while the other processes sharing the page are under a huge pmd split, to do an accurate reading, we must ensure the mapcount isn't computed while it's being transferred from the head page to the tail pages. reuse_swap_cache() already runs serialized by the page lock, so it's enough to add the page lock around __split_huge_pmd_locked too, in order to add the missing serialization. Note: the commit in "Fixes" is just to facilitate the backporting, because the code before such commit didn't try to do an accurate THP mapcount calculation and it instead used the page_count() to decide if to COW or not. Both the page_count and the pin_count are THP-wide refcounts, so they're inaccurate if used in reuse_swap_page(). Reverting such commit (besides the unrelated fix to the local anon_vma assignment) would have also opened the window for memory corruption side effects to certain workloads as documented in such commit header. Signed-off-by: Andrea Arcangeli Suggested-by: Jann Horn Reported-by: Jann Horn Acked-by: Kirill A. Shutemov Fixes: 6d0a07edd17c ("mm: thp: calculate the mapcount correctly for THP pages during WP faults") Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman (cherry picked from commit d93d7bd61072a03dde173d36ae5815488a585fc0) --- mm/huge_memory.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index fad4a0ca903c..00329e03e570 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1755,6 +1755,8 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, spinlock_t *ptl; struct mm_struct *mm = vma->vm_mm; unsigned long haddr = address & HPAGE_PMD_MASK; + bool was_locked = false; + pmd_t _pmd; mmu_notifier_invalidate_range_start(mm, haddr, haddr + HPAGE_PMD_SIZE); ptl = pmd_lock(mm, pmd); @@ -1764,11 +1766,32 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, * pmd against. Otherwise we can end up replacing wrong page. */ VM_BUG_ON(freeze && !page); - if (page && page != pmd_page(*pmd)) - goto out; + if (page) { + VM_WARN_ON_ONCE(!PageLocked(page)); + was_locked = true; + if (page != pmd_page(*pmd)) + goto out; + } +repeat: if (pmd_trans_huge(*pmd)) { - page = pmd_page(*pmd); + if (!page) { + page = pmd_page(*pmd); + if (unlikely(!trylock_page(page))) { + get_page(page); + _pmd = *pmd; + spin_unlock(ptl); + lock_page(page); + spin_lock(ptl); + if (unlikely(!pmd_same(*pmd, _pmd))) { + unlock_page(page); + put_page(page); + page = NULL; + goto repeat; + } + put_page(page); + } + } if (PageMlocked(page)) clear_page_mlock(page); } else if (!pmd_devmap(*pmd)) @@ -1776,6 +1799,8 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, __split_huge_pmd_locked(vma, pmd, haddr, freeze); out: spin_unlock(ptl); + if (!was_locked && page) + unlock_page(page); mmu_notifier_invalidate_range_end(mm, haddr, haddr + HPAGE_PMD_SIZE); } -- GitLab From 89f64ca3f60ba5ffe6458c08140213f7d87f4cdc Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 3 Dec 2020 02:25:04 +0100 Subject: [PATCH 55/78] tty: Fix ->pgrp locking in tiocspgrp() commit 54ffccbf053b5b6ca4f6e45094b942fab92a25fc upstream. tiocspgrp() takes two tty_struct pointers: One to the tty that userspace passed to ioctl() (`tty`) and one to the TTY being changed (`real_tty`). These pointers are different when ioctl() is called with a master fd. To properly lock real_tty->pgrp, we must take real_tty->ctrl_lock. This bug makes it possible for racing ioctl(TIOCSPGRP, ...) calls on both sides of a PTY pair to corrupt the refcount of `struct pid`, leading to use-after-free errors. Fixes: 47f86834bbd4 ("redo locking of tty->pgrp") CC: stable@kernel.org Signed-off-by: Jann Horn Reviewed-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 742f3062298ac1ae1d28de31b1f946f93db1eba1) --- drivers/tty/tty_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 08e47dec0901..6267efa99bed 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2649,10 +2649,10 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t if (session_of_pgrp(pgrp) != task_session(current)) goto out_unlock; retval = 0; - spin_lock_irq(&tty->ctrl_lock); + spin_lock_irq(&real_tty->ctrl_lock); put_pid(real_tty->pgrp); real_tty->pgrp = get_pid(pgrp); - spin_unlock_irq(&tty->ctrl_lock); + spin_unlock_irq(&real_tty->ctrl_lock); out_unlock: rcu_read_unlock(); return retval; -- GitLab From 6bce65cd7d447bc6992065e19f6b344ea23b44c6 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 28 Dec 2020 16:06:42 +0530 Subject: [PATCH 56/78] msm: kgsl: Stop using memdesc->usermem It shouldn't be illegal for memory descriptors to have multiple virtual memory mappings under certain circumstances. If that is the case tracking a single usermem address for each memdesc no longer makes much sense. Get rid of the memdesc->usermem member and use an atomic counter to track mappings instead. Change-Id: Ic0dedbad31bafcd1019ccc8e68657cb7e3c72727 Signed-off-by: Jordan Crouse Signed-off-by: Harshitha Sai Neelati --- drivers/gpu/msm/kgsl.c | 62 ++++++++++++++++++-------------- drivers/gpu/msm/kgsl.h | 9 ++--- drivers/gpu/msm/kgsl_debugfs.c | 20 +++++++---- drivers/gpu/msm/kgsl_sharedmem.c | 4 --- drivers/gpu/msm/kgsl_trace.h | 6 ++-- 5 files changed, 57 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index fa4e6052ed49..632c1bb7521d 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -265,6 +265,7 @@ kgsl_mem_entry_create(void) kref_get(&entry->refcount); } + atomic_set(&entry->map_count, 0); return entry; } #ifdef CONFIG_DMA_SHARED_BUFFER @@ -459,9 +460,6 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry) type = kgsl_memdesc_usermem_type(&entry->memdesc); entry->priv->stats[type].cur -= entry->memdesc.size; - if (type != KGSL_MEM_ENTRY_ION) - entry->priv->gpumem_mapped -= entry->memdesc.mapsize; - spin_unlock(&entry->priv->mem_lock); kgsl_mmu_put_gpuaddr(&entry->memdesc); @@ -2124,7 +2122,7 @@ static int check_vma(unsigned long hostptr, u64 size) return true; } -static int memdesc_sg_virt(struct kgsl_memdesc *memdesc) +static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, unsigned long useraddr) { int ret = 0; long npages = 0, i; @@ -2147,13 +2145,13 @@ static int memdesc_sg_virt(struct kgsl_memdesc *memdesc) } down_read(¤t->mm->mmap_sem); - if (!check_vma(memdesc->useraddr, memdesc->size)) { + if (!check_vma(useraddr, memdesc->size)) { up_read(¤t->mm->mmap_sem); ret = -EFAULT; goto out; } - npages = get_user_pages(memdesc->useraddr, + npages = get_user_pages(useraddr, sglen, write, pages, NULL); up_read(¤t->mm->mmap_sem); @@ -2192,7 +2190,6 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, entry->memdesc.pagetable = pagetable; entry->memdesc.size = (uint64_t) size; - entry->memdesc.useraddr = hostptr; entry->memdesc.flags |= (uint64_t)KGSL_MEMFLAGS_USERMEM_ADDR; if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) { @@ -2200,15 +2197,15 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, /* Register the address in the database */ ret = kgsl_mmu_set_svm_region(pagetable, - (uint64_t) entry->memdesc.useraddr, (uint64_t) size); + (uint64_t) hostptr, (uint64_t) size); if (ret) return ret; - entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr; + entry->memdesc.gpuaddr = (uint64_t) hostptr; } - return memdesc_sg_virt(&entry->memdesc); + return memdesc_sg_virt(&entry->memdesc, hostptr); } #ifdef CONFIG_DMA_SHARED_BUFFER @@ -2293,8 +2290,7 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device, return ret; } - /* Setup the user addr/cache mode for cache operations */ - entry->memdesc.useraddr = hostptr; + /* Setup the cache mode for cache operations */ _setup_cache_mode(entry, vma); up_read(¤t->mm->mmap_sem); return 0; @@ -3307,7 +3303,12 @@ long kgsl_ioctl_gpumem_get_info(struct kgsl_device_private *dev_priv, param->flags = (unsigned int) entry->memdesc.flags; param->size = (size_t) entry->memdesc.size; param->mmapsize = (size_t) kgsl_memdesc_footprint(&entry->memdesc); - param->useraddr = entry->memdesc.useraddr; + /* + * Entries can have multiple user mappings so thre isn't any one address + * we can report. Plus, the user should already know their mappings, so + * there isn't any value in reporting it back to them. + */ + param->useraddr = 0; kgsl_mem_entry_put(entry); return result; @@ -3776,9 +3777,6 @@ static int _sparse_bind(struct kgsl_process_private *process, if (memdesc->gpuaddr) return -EINVAL; - if (memdesc->useraddr != 0) - return -EINVAL; - pagetable = memdesc->pagetable; /* Clear out any mappings */ @@ -4058,7 +4056,12 @@ long kgsl_ioctl_gpuobj_info(struct kgsl_device_private *dev_priv, param->flags = entry->memdesc.flags; param->size = entry->memdesc.size; param->va_len = kgsl_memdesc_footprint(&entry->memdesc); - param->va_addr = (uint64_t) entry->memdesc.useraddr; + /* + * Entries can have multiple user mappings so thre isn't any one address + * we can report. Plus, the user should already know their mappings, so + * there isn't any value in reporting it back to them. + */ + param->va_addr = 0; kgsl_mem_entry_put(entry); return 0; @@ -4165,24 +4168,21 @@ static void kgsl_gpumem_vm_open(struct vm_area_struct *vma) if (kgsl_mem_entry_get(entry) == 0) vma->vm_private_data = NULL; + + atomic_inc(&entry->map_count); } static int kgsl_gpumem_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct kgsl_mem_entry *entry = vma->vm_private_data; - int ret; if (!entry) return VM_FAULT_SIGBUS; if (!entry->memdesc.ops || !entry->memdesc.ops->vmfault) return VM_FAULT_SIGBUS; - ret = entry->memdesc.ops->vmfault(&entry->memdesc, vma, vmf); - if ((ret == 0) || (ret == VM_FAULT_NOPAGE)) - entry->priv->gpumem_mapped += PAGE_SIZE; - - return ret; + return entry->memdesc.ops->vmfault(&entry->memdesc, vma, vmf); } static void @@ -4193,7 +4193,13 @@ kgsl_gpumem_vm_close(struct vm_area_struct *vma) if (!entry) return; - entry->memdesc.useraddr = 0; + /* + * Remove the memdesc from the mapped stat once all the mappings have + * gone away + */ + if (!atomic_dec_return(&entry->map_count)) + entry->priv->gpumem_mapped -= entry->memdesc.size; + kgsl_mem_entry_put(entry); } @@ -4232,7 +4238,8 @@ get_mmap_entry(struct kgsl_process_private *private, } } - if (entry->memdesc.useraddr != 0) { + /* Don't allow ourselves to remap user memory */ + if (entry->memdesc.flags & KGSL_MEMFLAGS_USERMEM_ADDR) { ret = -EBUSY; goto err_put; } @@ -4557,9 +4564,10 @@ static int kgsl_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_file = file; - entry->memdesc.useraddr = vma->vm_start; + if (atomic_inc_return(&entry->map_count) == 1) + entry->priv->gpumem_mapped += entry->memdesc.size; - trace_kgsl_mem_mmap(entry); + trace_kgsl_mem_mmap(entry, vma->vm_start); return 0; } diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 8456be78e78a..75d2c406cad3 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -205,11 +205,9 @@ struct kgsl_memdesc_ops { * @pagetable: Pointer to the pagetable that the object is mapped in * @hostptr: Kernel virtual address * @hostptr_count: Number of threads using hostptr - * @useraddr: User virtual address (if applicable) * @gpuaddr: GPU virtual address * @physaddr: Physical address of the memory object * @size: Size of the memory object - * @mapsize: Size of memory mapped in userspace * @priv: Internal flags and settings * @sgt: Scatter gather table for allocated pages * @ops: Function hooks for the memdesc memory type @@ -224,11 +222,9 @@ struct kgsl_memdesc { struct kgsl_pagetable *pagetable; void *hostptr; unsigned int hostptr_count; - unsigned long useraddr; uint64_t gpuaddr; phys_addr_t physaddr; uint64_t size; - uint64_t mapsize; unsigned int priv; struct sg_table *sgt; struct kgsl_memdesc_ops *ops; @@ -286,6 +282,11 @@ struct kgsl_mem_entry { struct work_struct work; spinlock_t bind_lock; struct rb_root bind_tree; + /* + * @map_count: Count how many vmas this object is mapped in - used for + * debugfs accounting + */ + atomic_t map_count; }; struct kgsl_device_private; diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c index 834706a973d2..00f60bb29c00 100644 --- a/drivers/gpu/msm/kgsl_debugfs.c +++ b/drivers/gpu/msm/kgsl_debugfs.c @@ -152,7 +152,11 @@ static int print_mem_entry(void *data, void *ptr) flags[3] = get_alignflag(m); flags[4] = get_cacheflag(m); flags[5] = kgsl_memdesc_use_cpu_map(m) ? 'p' : '-'; - flags[6] = (m->useraddr) ? 'Y' : 'N'; + /* + * Show Y if at least one vma has this entry + * mapped (could be multiple) + */ + flags[6] = atomic_read(&entry->map_count) ? 'Y' : 'N'; flags[7] = kgsl_memdesc_is_secured(m) ? 's' : '-'; flags[8] = m->flags & KGSL_MEMFLAGS_SPARSE_PHYS ? 'P' : '-'; flags[9] = '\0'; @@ -163,12 +167,16 @@ static int print_mem_entry(void *data, void *ptr) kgsl_get_egl_counts(entry, &egl_surface_count, &egl_image_count); - seq_printf(s, "%pK %pK %16llu %5d %9s %10s %16s %5d %16llu %6d %6d", + seq_printf(s, "%pK %d %16llu %5d %9s %10s %16s %5d %16d %6d %6d", (uint64_t *)(uintptr_t) m->gpuaddr, - (unsigned long *) m->useraddr, - m->size, entry->id, flags, + /* + * Show zero for the useraddr - we can't reliably track + * that value for multiple vmas anyway + */ + 0, m->size, entry->id, flags, memtype_str(usermem_type), - usage, (m->sgt ? m->sgt->nents : 0), m->mapsize, + usage, (m->sgt ? m->sgt->nents : 0), + atomic_read(&entry->map_count), egl_surface_count, egl_image_count); if (entry->metadata[0] != 0) @@ -239,7 +247,7 @@ static int process_mem_seq_show(struct seq_file *s, void *ptr) if (ptr == SEQ_START_TOKEN) { seq_printf(s, "%16s %16s %16s %5s %9s %10s %16s %5s %16s %6s %6s\n", "gpuaddr", "useraddr", "size", "id", "flags", "type", - "usage", "sglen", "mapsize", "eglsrf", "eglimg"); + "usage", "sglen", "mapcount", "eglsrf", "eglimg"); return 0; } else return print_mem_entry(s, ptr); diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 2313236a6368..599fe9e53f88 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -445,8 +445,6 @@ static int kgsl_page_alloc_vmfault(struct kgsl_memdesc *memdesc, get_page(page); vmf->page = page; - memdesc->mapsize += PAGE_SIZE; - return 0; } @@ -577,8 +575,6 @@ static int kgsl_contiguous_vmfault(struct kgsl_memdesc *memdesc, else if (ret == -EFAULT) return VM_FAULT_SIGBUS; - memdesc->mapsize += PAGE_SIZE; - return VM_FAULT_NOPAGE; } diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h index c7690a14abcd..82fc5f8cd78c 100644 --- a/drivers/gpu/msm/kgsl_trace.h +++ b/drivers/gpu/msm/kgsl_trace.h @@ -432,9 +432,9 @@ TRACE_EVENT(kgsl_mem_alloc, TRACE_EVENT(kgsl_mem_mmap, - TP_PROTO(struct kgsl_mem_entry *mem_entry), + TP_PROTO(struct kgsl_mem_entry *mem_entry, unsigned long useraddr), - TP_ARGS(mem_entry), + TP_ARGS(mem_entry, useraddr), TP_STRUCT__entry( __field(unsigned long, useraddr) @@ -446,7 +446,7 @@ TRACE_EVENT(kgsl_mem_mmap, ), TP_fast_assign( - __entry->useraddr = mem_entry->memdesc.useraddr; + __entry->useraddr = useraddr; __entry->gpuaddr = mem_entry->memdesc.gpuaddr; __entry->size = mem_entry->memdesc.size; kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), -- GitLab From b835067880b2635dcff6ec2c39daf1ae09ac5972 Mon Sep 17 00:00:00 2001 From: Neeraja P Date: Thu, 7 Jan 2021 20:48:09 +0530 Subject: [PATCH 57/78] msm: kgsl: Deregister gpu address on memdesc_sg_virt failure When memdesc_sg_virt returns error in kgsl_setup_anon_useraddr function, the gpu address registered in SVM region will not be deregistered. This change deregisters the gpu address on memdesc_sg_virt failure. Change-Id: Ic99167e283a0c6331bb9f5f0b608b6cdb3c918e4 Signed-off-by: Neeraja P --- drivers/gpu/msm/kgsl.c | 10 ++++++++-- drivers/gpu/msm/kgsl_mmu.c | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 632c1bb7521d..bfae8270d7ad 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2184,6 +2184,8 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, { /* Map an anonymous memory chunk */ + int ret; + if (size == 0 || offset != 0 || !IS_ALIGNED(size, PAGE_SIZE)) return -EINVAL; @@ -2193,7 +2195,6 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, entry->memdesc.flags |= (uint64_t)KGSL_MEMFLAGS_USERMEM_ADDR; if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) { - int ret; /* Register the address in the database */ ret = kgsl_mmu_set_svm_region(pagetable, @@ -2205,7 +2206,12 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, entry->memdesc.gpuaddr = (uint64_t) hostptr; } - return memdesc_sg_virt(&entry->memdesc, hostptr); + ret = memdesc_sg_virt(&entry->memdesc, hostptr); + + if (ret && kgsl_memdesc_use_cpu_map(&entry->memdesc)) + kgsl_mmu_put_gpuaddr(&entry->memdesc); + + return ret; } #ifdef CONFIG_DMA_SHARED_BUFFER diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index a0fd3ece4e78..e12b70b03d5f 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-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 @@ -439,7 +439,8 @@ void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc) if (memdesc->size == 0 || memdesc->gpuaddr == 0) return; - if (!kgsl_memdesc_is_global(memdesc)) + if (!kgsl_memdesc_is_global(memdesc) && + (KGSL_MEMDESC_MAPPED & memdesc->priv)) unmap_fail = kgsl_mmu_unmap(pagetable, memdesc); /* -- GitLab From 3fed6e393d5c040e75f818687fb8b2850dc40da4 Mon Sep 17 00:00:00 2001 From: Vamsi krishna Gattupalli Date: Wed, 2 Dec 2020 12:59:03 +0530 Subject: [PATCH 58/78] msm:ADSPRPC :Fix to avoid Use after free in fastrpc_internal_munmap Added a check to validate map before freeing it to avoid Use after free scenario. Change-Id: Ic723a4fe964a4909119663500018f2a07976105b Signed-off-by: Vamsi krishna Gattupalli --- drivers/char/adsprpc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 03ccd6c949ce..4069e2e56af2 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2728,13 +2728,15 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl, mutex_unlock(&fl->fl_map_mutex); if (err) goto bail; - VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr, - map->phys, map->size, map->flags)); - if (err) - goto bail; - mutex_lock(&fl->fl_map_mutex); - fastrpc_mmap_free(map, 0); - mutex_unlock(&fl->fl_map_mutex); + if (map) { + VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr, + map->phys, map->size, map->flags)); + if (err) + goto bail; + mutex_lock(&fl->fl_map_mutex); + fastrpc_mmap_free(map, 0); + mutex_unlock(&fl->fl_map_mutex); + } bail: if (err && map) { mutex_lock(&fl->fl_map_mutex); -- GitLab From 7ee539a94e44e10568826f6db22f21897b2d898a Mon Sep 17 00:00:00 2001 From: Tanwee Kausar Date: Mon, 10 Aug 2020 16:10:50 -0700 Subject: [PATCH 59/78] crypto: Fix possible stack out of bound error Adding fix to check the upper limit on the length of the destination array while copying elements from source address to avoid stack out of bound error. Change-Id: Ieb24e8f9b4a2b53fbc9442b25d790b12f737d471 Signed-off-by: Tanwee Kausar --- drivers/crypto/msm/qce50.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c index e80523b61441..cf539f1107dc 100644 --- a/drivers/crypto/msm/qce50.c +++ b/drivers/crypto/msm/qce50.c @@ -850,6 +850,11 @@ static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq, switch (creq->alg) { case CIPHER_ALG_DES: 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]; -- GitLab From 1b573631d1a5b541fb1ef4b9c6443d7cd6f1e1ad Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 3 Feb 2021 13:45:39 +0000 Subject: [PATCH 60/78] futex: Handle faults correctly for PI futexes fixup_pi_state_owner() tries to ensure that the state of the rtmutex, pi_state and the user space value related to the PI futex are consistent before returning to user space. In case that the user space value update faults and the fault cannot be resolved by faulting the page in via fault_in_user_writeable() the function returns with -EFAULT and leaves the rtmutex and pi_state owner state inconsistent. A subsequent futex_unlock_pi() operates on the inconsistent pi_state and releases the rtmutex despite not owning it which can corrupt the RB tree of the rtmutex and cause a subsequent kernel stack use after free. It was suggested to loop forever in fixup_pi_state_owner() if the fault cannot be resolved, but that results in runaway tasks which is especially undesired when the problem happens due to a programming error and not due to malice. As the user space value cannot be fixed up, the proper solution is to make the rtmutex and the pi_state consistent so both have the same owner. This leaves the user space value out of sync. Any subsequent operation on the futex will fail because the 10th rule of PI futexes (pi_state owner and user space value are consistent) has been violated. As a consequence this removes the inept attempts of 'fixing' the situation in case that the current task owns the rtmutex when returning with an unresolvable fault by unlocking the rtmutex which left pi_state::owner and rtmutex::owner out of sync in a different and only slightly less dangerous way. Fixes: 1b7558e457ed ("futexes: fix fault handling in futex_lock_pi") Reported-by: gzobqq@gmail.com Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman (cherry picked from commit b960d9ae7f76f98537f251af0363b89d09b8fb11) Change-Id: If1764bdde4eff115558ca318050ce273ff5d90ac --- kernel/futex.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 7123d9cab456..f00a693bb5f1 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -988,7 +988,8 @@ void exit_pi_state_list(struct task_struct *curr) * FUTEX_OWNER_DIED bit. See [4] * * [10] There is no transient state which leaves owner and user space - * TID out of sync. + * TID out of sync. Except one error case where the kernel is denied + * write access to the user address, see fixup_pi_state_owner(). */ /* @@ -2653,13 +2654,6 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; - /* - * If fixup_owner() faulted and was unable to handle the fault, unlock - * it and return the fault to userspace. - */ - if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) - rt_mutex_unlock(&q.pi_state->pi_mutex); - /* Unqueue and drop the lock */ unqueue_me_pi(&q); @@ -2964,8 +2958,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (q.pi_state && (q.pi_state->owner != current)) { spin_lock(q.lock_ptr); ret = fixup_pi_state_owner(uaddr2, &q, current); - if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) - rt_mutex_unlock(&q.pi_state->pi_mutex); /* * Drop the reference to the pi state which * the requeue_pi() code acquired for us. @@ -3002,14 +2994,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; - /* - * If fixup_pi_state_owner() faulted and was unable to handle - * the fault, unlock the rt_mutex and return the fault to - * userspace. - */ - if (ret && rt_mutex_owner(pi_mutex) == current) - rt_mutex_unlock(pi_mutex); - /* Unqueue and drop the lock. */ unqueue_me_pi(&q); } -- GitLab From 5c938b911f2fe214ce8e77ff4b7c05bfc12b0034 Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Sat, 5 Dec 2020 00:48:48 +0000 Subject: [PATCH 61/78] HID: make arrays usage and value to be the same commit ed9be64eefe26d7d8b0b5b9fa3ffdf425d87a01f upstream. The HID subsystem allows an "HID report field" to have a different number of "values" and "usages" when it is allocated. When a field struct is created, the size of the usage array is guaranteed to be at least as large as the values array, but it may be larger. This leads to a potential out-of-bounds write in __hidinput_change_resolution_multipliers() and an out-of-bounds read in hidinput_count_leds(). To fix this, let's make sure that both the usage and value arrays are the same size. Cc: stable@vger.kernel.org Signed-off-by: Will McVicker Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman (cherry picked from commit b12d39309ecf08cdcab716a5063f9ec23cb9f001) --- drivers/hid/hid-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b49211cbdb1c..bf1e85b96a89 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -91,7 +91,7 @@ EXPORT_SYMBOL_GPL(hid_register_report); * 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 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned 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 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign 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; -- GitLab From 77476612a794311966bc78ba3e2cf4ddd94cdd0f Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Tue, 9 Jun 2020 10:53:22 +0300 Subject: [PATCH 62/78] netfilter: nf_conntrack_h323: lost .data_len definition for Q.931/ipv6 Could you please push this patch into stable@? it fixes memory corruption in kernels v3.5 .. v4.10 Lost .data_len definition leads to write beyond end of struct nf_ct_h323_master. Usually it corrupts following struct nf_conn_nat, however if nat is not loaded it corrupts following slab object. In mainline this problem went away in v4.11, after commit 9f0f3ebeda47 ("netfilter: helpers: remove data_len usage for inkernel helpers") however many stable kernels are still affected. Fixes: 1afc56794e03 ("netfilter: nf_ct_helper: implement variable length helper private data") # v3.5 cc: stable@vger.kernel.org Reviewed-by: Florian Westphal Signed-off-by: Vasily Averin Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 396ba2fc4f27ef6c44bbc0098bfddf4da76dc4c9) --- net/netfilter/nf_conntrack_h323_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index f65d93639d12..29fe1e7eac88 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -1225,6 +1225,7 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = { { .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, -- GitLab From 183aca7590a1fefe6c0c83730b8b1adc6781aeac Mon Sep 17 00:00:00 2001 From: shaohanlin Date: Tue, 1 Jun 2021 09:19:54 +0800 Subject: [PATCH 63/78] Revert "futex: Handle faults correctly for PI futexes" Security patch 2021-06 has removed this patch from v1.3 This reverts commit 7b909dce2e7c78dd1ea4ffc1dd4afdbfba1de890. --- kernel/futex.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index f00a693bb5f1..7123d9cab456 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -988,8 +988,7 @@ void exit_pi_state_list(struct task_struct *curr) * FUTEX_OWNER_DIED bit. See [4] * * [10] There is no transient state which leaves owner and user space - * TID out of sync. Except one error case where the kernel is denied - * write access to the user address, see fixup_pi_state_owner(). + * TID out of sync. */ /* @@ -2654,6 +2653,13 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; + /* + * If fixup_owner() faulted and was unable to handle the fault, unlock + * it and return the fault to userspace. + */ + if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) + rt_mutex_unlock(&q.pi_state->pi_mutex); + /* Unqueue and drop the lock */ unqueue_me_pi(&q); @@ -2958,6 +2964,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (q.pi_state && (q.pi_state->owner != current)) { spin_lock(q.lock_ptr); ret = fixup_pi_state_owner(uaddr2, &q, current); + if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) + rt_mutex_unlock(&q.pi_state->pi_mutex); /* * Drop the reference to the pi state which * the requeue_pi() code acquired for us. @@ -2994,6 +3002,14 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; + /* + * If fixup_pi_state_owner() faulted and was unable to handle + * the fault, unlock the rt_mutex and return the fault to + * userspace. + */ + if (ret && rt_mutex_owner(pi_mutex) == current) + rt_mutex_unlock(pi_mutex); + /* Unqueue and drop the lock. */ unqueue_me_pi(&q); } -- GitLab From d9470f5c490572615c5ad06de4d68b92b9477f96 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 3 Feb 2021 13:45:39 +0000 Subject: [PATCH 64/78] futex: Handle faults correctly for PI futexes fixup_pi_state_owner() tries to ensure that the state of the rtmutex, pi_state and the user space value related to the PI futex are consistent before returning to user space. In case that the user space value update faults and the fault cannot be resolved by faulting the page in via fault_in_user_writeable() the function returns with -EFAULT and leaves the rtmutex and pi_state owner state inconsistent. A subsequent futex_unlock_pi() operates on the inconsistent pi_state and releases the rtmutex despite not owning it which can corrupt the RB tree of the rtmutex and cause a subsequent kernel stack use after free. It was suggested to loop forever in fixup_pi_state_owner() if the fault cannot be resolved, but that results in runaway tasks which is especially undesired when the problem happens due to a programming error and not due to malice. As the user space value cannot be fixed up, the proper solution is to make the rtmutex and the pi_state consistent so both have the same owner. This leaves the user space value out of sync. Any subsequent operation on the futex will fail because the 10th rule of PI futexes (pi_state owner and user space value are consistent) has been violated. As a consequence this removes the inept attempts of 'fixing' the situation in case that the current task owns the rtmutex when returning with an unresolvable fault by unlocking the rtmutex which left pi_state::owner and rtmutex::owner out of sync in a different and only slightly less dangerous way. Fixes: 1b7558e457ed ("futexes: fix fault handling in futex_lock_pi") Reported-by: gzobqq@gmail.com Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman (cherry picked from commit b960d9ae7f76f98537f251af0363b89d09b8fb11) Change-Id: I64d0c5fc20ba1aa64254d6d3b83eacd8862369d9 --- kernel/futex.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 7123d9cab456..f00a693bb5f1 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -988,7 +988,8 @@ void exit_pi_state_list(struct task_struct *curr) * FUTEX_OWNER_DIED bit. See [4] * * [10] There is no transient state which leaves owner and user space - * TID out of sync. + * TID out of sync. Except one error case where the kernel is denied + * write access to the user address, see fixup_pi_state_owner(). */ /* @@ -2653,13 +2654,6 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; - /* - * If fixup_owner() faulted and was unable to handle the fault, unlock - * it and return the fault to userspace. - */ - if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) - rt_mutex_unlock(&q.pi_state->pi_mutex); - /* Unqueue and drop the lock */ unqueue_me_pi(&q); @@ -2964,8 +2958,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (q.pi_state && (q.pi_state->owner != current)) { spin_lock(q.lock_ptr); ret = fixup_pi_state_owner(uaddr2, &q, current); - if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) - rt_mutex_unlock(&q.pi_state->pi_mutex); /* * Drop the reference to the pi state which * the requeue_pi() code acquired for us. @@ -3002,14 +2994,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, if (res) ret = (res < 0) ? res : 0; - /* - * If fixup_pi_state_owner() faulted and was unable to handle - * the fault, unlock the rt_mutex and return the fault to - * userspace. - */ - if (ret && rt_mutex_owner(pi_mutex) == current) - rt_mutex_unlock(pi_mutex); - /* Unqueue and drop the lock. */ unqueue_me_pi(&q); } -- GitLab From 75cbf3037585ecef27ca5659a5d1f97cbd408c76 Mon Sep 17 00:00:00 2001 From: Puranam V G Tejaswi Date: Mon, 30 Nov 2020 21:01:16 +0530 Subject: [PATCH 65/78] msm: kgsl: Allocate user_ctxt_record based on preemption feature flag Allocation of memory to user_ctxt_record is done based on adreno_device flag. If a context is created when preemption is disabled, the memory to user_ctxt_record is not allocated. Now if we enable preemption, through the sysfs knob, the device flag is again set. We may try to access user_ctxt_record in preemption_pre_ibsubmit(). So allocate memory to user_ctxt_record based on the preemption feature flag instead of preemption device flag. Change-Id: I947ef5a1bfbd8bff471427fae60d7fcd507b85a2 Signed-off-by: Puranam V G Tejaswi Signed-off-by: Harshitha Sai Neelati --- drivers/gpu/msm/adreno_a6xx_preempt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx_preempt.c b/drivers/gpu/msm/adreno_a6xx_preempt.c index 89965f2c9b06..9b227d55fc08 100644 --- a/drivers/gpu/msm/adreno_a6xx_preempt.c +++ b/drivers/gpu/msm/adreno_a6xx_preempt.c @@ -782,7 +782,7 @@ void a6xx_preemption_context_destroy(struct kgsl_context *context) struct kgsl_device *device = context->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); - if (!adreno_is_preemption_enabled(adreno_dev)) + if (!ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) return; gpumem_free_entry(context->user_ctxt_record); @@ -797,7 +797,7 @@ int a6xx_preemption_context_init(struct kgsl_context *context) struct adreno_device *adreno_dev = ADRENO_DEVICE(device); uint64_t flags = 0; - if (!adreno_is_preemption_enabled(adreno_dev)) + if (!ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) return 0; if (context->flags & KGSL_CONTEXT_SECURE) -- GitLab From d66ae7b23eec44fe51ea53f02422973f366317f3 Mon Sep 17 00:00:00 2001 From: Archana Sriram Date: Sun, 18 Oct 2020 23:34:04 +0530 Subject: [PATCH 66/78] msm: kgsl: Compare pid pointer instead of TGID for a new process There is a possibility of sharing process_private between two unrelated processes due to PID wrapping. In kgsl_process_private_new(), instead of checking numeric TGID, compare the unique pid pointer of the current process with that of the existing processes in kgsl process list to allow sharing of process_private data judiciously. Also, in all required functions get TGID/PID of a process from its struct pid. Change-Id: I0e3d5d79275cdb3f3c304fb36322ad56b0d0b227 Signed-off-by: Archana Sriram --- drivers/gpu/msm/adreno_debugfs.c | 4 ++-- drivers/gpu/msm/adreno_dispatch.c | 2 +- drivers/gpu/msm/adreno_profile.c | 4 ++-- drivers/gpu/msm/kgsl.c | 31 +++++++++++++++++++------------ drivers/gpu/msm/kgsl_debugfs.c | 9 +++++---- drivers/gpu/msm/kgsl_device.h | 8 ++++---- drivers/gpu/msm/kgsl_iommu.c | 4 ++-- drivers/gpu/msm/kgsl_sharedmem.c | 2 +- drivers/gpu/msm/kgsl_trace.h | 10 +++++----- 9 files changed, 41 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index aef802cbf491..6b4877c4321f 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2008-2020, 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 @@ -281,7 +281,7 @@ static int ctx_print(struct seq_file *s, void *unused) ctx_type_str(drawctxt->type), drawctxt->base.priority, drawctxt->base.proc_priv->comm, - drawctxt->base.proc_priv->pid, + pid_nr(drawctxt->base.proc_priv->pid), drawctxt->base.tid); seq_puts(s, "flags: "); diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 7b3bc51e1280..5f8048f57dcd 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -1701,7 +1701,7 @@ static inline const char *_kgsl_context_comm(struct kgsl_context *context) #define pr_fault(_d, _c, fmt, args...) \ dev_err((_d)->dev, "%s[%d]: " fmt, \ _kgsl_context_comm((_c)->context), \ - (_c)->context->proc_priv->pid, ##args) + pid_nr((_c)->context->proc_priv->pid), ##args) static void adreno_fault_header(struct kgsl_device *device, diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c index 3b8512909e48..c1dc3293972f 100644 --- a/drivers/gpu/msm/adreno_profile.c +++ b/drivers/gpu/msm/adreno_profile.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018,2020, 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 @@ -167,7 +167,7 @@ static int _build_pre_ib_cmds(struct adreno_device *adreno_dev, ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, drawctxt->base.id, &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, - drawctxt->base.proc_priv->pid, &data_offset); + pid_nr(drawctxt->base.proc_priv->pid), &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, drawctxt->base.tid, &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index bfae8270d7ad..562e09dd89c9 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -541,7 +541,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) { KGSL_DRV_ERR_RATELIMIT(device, "Per process context limit reached for pid %u", - dev_priv->process_priv->pid); + pid_nr(dev_priv->process_priv->pid)); spin_unlock(&proc_priv->ctxt_count_lock); return -ENOSPC; } @@ -864,6 +864,7 @@ static void kgsl_destroy_process_private(struct kref *kref) struct kgsl_process_private *private = container_of(kref, struct kgsl_process_private, refcount); + put_pid(private->pid); idr_destroy(&private->mem_idr); idr_destroy(&private->syncsource_idr); @@ -893,7 +894,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid) mutex_lock(&kgsl_driver.process_mutex); list_for_each_entry(p, &kgsl_driver.process_list, list) { - if (p->pid == pid) { + if (pid_nr(p->pid) == pid) { if (kgsl_process_private_get(p)) private = p; break; @@ -907,13 +908,15 @@ static struct kgsl_process_private *kgsl_process_private_new( struct kgsl_device *device) { struct kgsl_process_private *private; - pid_t tgid = task_tgid_nr(current); + struct pid *cur_pid = get_task_pid(current->group_leader, PIDTYPE_PID); /* Search in the process list */ list_for_each_entry(private, &kgsl_driver.process_list, list) { - if (private->pid == tgid) { - if (!kgsl_process_private_get(private)) + if (private->pid == cur_pid) { + if (!kgsl_process_private_get(private)) { + put_pid(cur_pid); private = ERR_PTR(-EINVAL); + } return private; } } @@ -925,7 +928,7 @@ static struct kgsl_process_private *kgsl_process_private_new( kref_init(&private->refcount); - private->pid = tgid; + private->pid = cur_pid; get_task_comm(private->comm, current->group_leader); spin_lock_init(&private->mem_lock); @@ -936,12 +939,14 @@ static struct kgsl_process_private *kgsl_process_private_new( idr_init(&private->syncsource_idr); /* Allocate a pagetable for the new process object */ - private->pagetable = kgsl_mmu_getpagetable(&device->mmu, tgid); + private->pagetable = kgsl_mmu_getpagetable(&device->mmu, + pid_nr(cur_pid)); if (IS_ERR(private->pagetable)) { int err = PTR_ERR(private->pagetable); idr_destroy(&private->mem_idr); idr_destroy(&private->syncsource_idr); + put_pid(private->pid); kfree(private); private = ERR_PTR(err); @@ -1857,7 +1862,7 @@ long gpumem_free_entry(struct kgsl_mem_entry *entry) return -EBUSY; trace_kgsl_mem_free(entry); - kgsl_memfree_add(entry->priv->pid, + kgsl_memfree_add(pid_nr(entry->priv->pid), entry->memdesc.pagetable ? entry->memdesc.pagetable->name : 0, entry->memdesc.gpuaddr, entry->memdesc.size, @@ -1880,7 +1885,7 @@ static void gpumem_free_func(struct kgsl_device *device, /* Free the memory for all event types */ trace_kgsl_mem_timestamp_free(device, entry, KGSL_CONTEXT_ID(context), timestamp, 0); - kgsl_memfree_add(entry->priv->pid, + kgsl_memfree_add(pid_nr(entry->priv->pid), entry->memdesc.pagetable ? entry->memdesc.pagetable->name : 0, entry->memdesc.gpuaddr, entry->memdesc.size, @@ -1980,7 +1985,7 @@ static bool gpuobj_free_fence_func(void *priv) struct kgsl_mem_entry *entry = priv; trace_kgsl_mem_free(entry); - kgsl_memfree_add(entry->priv->pid, + kgsl_memfree_add(pid_nr(entry->priv->pid), entry->memdesc.pagetable ? entry->memdesc.pagetable->name : 0, entry->memdesc.gpuaddr, entry->memdesc.size, @@ -4487,13 +4492,15 @@ kgsl_get_unmapped_area(struct file *file, unsigned long addr, if (IS_ERR_VALUE(val)) KGSL_DRV_ERR_RATELIMIT(device, "get_unmapped_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n", - private->pid, addr, pgoff, len, (int) val); + pid_nr(private->pid), addr, + pgoff, len, (int) val); } else { val = _get_svm_area(private, entry, addr, len, flags); if (IS_ERR_VALUE(val)) KGSL_DRV_ERR_RATELIMIT(device, "_get_svm_area: pid %d mmap_base %lx addr %lx pgoff %lx len %ld failed error %d\n", - private->pid, current->mm->mmap_base, addr, + pid_nr(private->pid), + current->mm->mmap_base, addr, pgoff, len, (int) val); } diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c index 00f60bb29c00..7a69b57cab16 100644 --- a/drivers/gpu/msm/kgsl_debugfs.c +++ b/drivers/gpu/msm/kgsl_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2008-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2008-2017, 2019-2020 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 @@ -405,7 +405,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private) unsigned char name[16]; struct dentry *dentry; - snprintf(name, sizeof(name), "%d", private->pid); + snprintf(name, sizeof(name), "%d", pid_nr(private->pid)); private->debug_root = debugfs_create_dir(name, proc_d_debugfs); @@ -425,14 +425,15 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private) } dentry = debugfs_create_file("mem", 0444, private->debug_root, - (void *) ((unsigned long) private->pid), &process_mem_fops); + (void *) ((unsigned long) pid_nr(private->pid)), + &process_mem_fops); if (IS_ERR_OR_NULL(dentry)) WARN((dentry == NULL), "Unable to create 'mem' file for %s\n", name); dentry = debugfs_create_file("sparse_mem", 0444, private->debug_root, - (void *) ((unsigned long) private->pid), + (void *) ((unsigned long) pid_nr(private->pid)), &process_sparse_mem_fops); if (IS_ERR_OR_NULL(dentry)) diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 229e206727ab..cc9401e95d82 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2020, 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 @@ -433,13 +433,13 @@ struct kgsl_context { #define pr_context(_d, _c, fmt, args...) \ dev_err((_d)->dev, "%s[%d]: " fmt, \ _context_comm((_c)), \ - (_c)->proc_priv->pid, ##args) + pid_nr((_c)->proc_priv->pid), ##args) /** * struct kgsl_process_private - Private structure for a KGSL process (across * all devices) * @priv: Internal flags, use KGSL_PROCESS_* values - * @pid: ID for the task owner of the process + * @pid: Identification structure for the task owner of the process * @comm: task name of the process * @mem_lock: Spinlock to protect the process memory lists * @refcount: kref object for reference counting the process @@ -457,7 +457,7 @@ struct kgsl_context { */ struct kgsl_process_private { unsigned long priv; - pid_t pid; + struct pid *pid; char comm[TASK_COMM_LEN]; spinlock_t mem_lock; struct kref refcount; diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 87e4cb3cfd3c..6c5bcb9dff74 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -648,7 +648,7 @@ static void _get_entries(struct kgsl_process_private *private, prev->flags = p->memdesc.flags; prev->priv = p->memdesc.priv; prev->pending_free = p->pending_free; - prev->pid = private->pid; + prev->pid = pid_nr(private->pid); __kgsl_get_memory_usage(prev); } @@ -658,7 +658,7 @@ static void _get_entries(struct kgsl_process_private *private, next->flags = n->memdesc.flags; next->priv = n->memdesc.priv; next->pending_free = n->pending_free; - next->pid = private->pid; + next->pid = pid_nr(private->pid); __kgsl_get_memory_usage(next); } } diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 599fe9e53f88..2453d1269470 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -268,7 +268,7 @@ void kgsl_process_init_sysfs(struct kgsl_device *device, /* Keep private valid until the sysfs enries are removed. */ kgsl_process_private_get(private); - snprintf(name, sizeof(name), "%d", private->pid); + snprintf(name, sizeof(name), "%d", pid_nr(private->pid)); if (kobject_init_and_add(&private->kobj, &ktype_mem_entry, kgsl_driver.prockobj, name)) { diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h index 82fc5f8cd78c..afaaf56fc6f0 100644 --- a/drivers/gpu/msm/kgsl_trace.h +++ b/drivers/gpu/msm/kgsl_trace.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2020, 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 @@ -416,7 +416,7 @@ TRACE_EVENT(kgsl_mem_alloc, TP_fast_assign( __entry->gpuaddr = mem_entry->memdesc.gpuaddr; __entry->size = mem_entry->memdesc.size; - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -509,7 +509,7 @@ TRACE_EVENT(kgsl_mem_map, __entry->size = mem_entry->memdesc.size; __entry->fd = fd; __entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -544,7 +544,7 @@ TRACE_EVENT(kgsl_mem_free, __entry->gpuaddr = mem_entry->memdesc.gpuaddr; __entry->size = mem_entry->memdesc.size; __entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -579,7 +579,7 @@ TRACE_EVENT(kgsl_mem_sync_cache, __entry->gpuaddr = mem_entry->memdesc.gpuaddr; kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); __entry->id = mem_entry->id; __entry->op = op; __entry->offset = offset; -- GitLab From 81699bd3335ca6d1d19b1f6213fc04be97bfb986 Mon Sep 17 00:00:00 2001 From: Archana Sriram Date: Mon, 14 Dec 2020 16:55:35 +0530 Subject: [PATCH 67/78] msm: kgsl: Correct the refcount on current process PID In kgsl_process_private_new() function there is inconsistency in the refcount of current process PID. Fix this to avoid overflowing of reference counter leading to use after free of this struct. Change-Id: I6291b9a05e139337e7f8471d0f9409fc839969a3 Signed-off-by: Archana Sriram --- drivers/gpu/msm/kgsl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 562e09dd89c9..dec3e3ce07d5 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -914,17 +914,24 @@ static struct kgsl_process_private *kgsl_process_private_new( list_for_each_entry(private, &kgsl_driver.process_list, list) { if (private->pid == cur_pid) { if (!kgsl_process_private_get(private)) { - put_pid(cur_pid); private = ERR_PTR(-EINVAL); } + /* + * We need to hold only one reference to the PID for + * each process struct to avoid overflowing the + * reference counter which can lead to use-after-free. + */ + put_pid(cur_pid); return private; } } /* Create a new object */ private = kzalloc(sizeof(struct kgsl_process_private), GFP_KERNEL); - if (private == NULL) + if (private == NULL) { + put_pid(cur_pid); return ERR_PTR(-ENOMEM); + } kref_init(&private->refcount); -- GitLab From 869e44fea97909724b2502777279cb399691fa3c Mon Sep 17 00:00:00 2001 From: shaohanlin Date: Thu, 1 Jul 2021 08:44:30 +0800 Subject: [PATCH 68/78] Fix build error of CVE-2021-0904 Change-Id: I6615d79fae19bf480492505e6d4aeccb448aa68f --- drivers/gpu/msm/kgsl_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 6c5bcb9dff74..0bb24d66cdbc 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -828,7 +828,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, if (context != NULL) { /* save pagefault timestamp for GFT */ set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv); - pid = context->proc_priv->pid; + pid = pid_nr(context->proc_priv->pid); } ctx->fault = 1; -- GitLab From ebdf429b8debb418ca5c5fcdd097bdbc3c9f5926 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 3 Dec 2020 02:25:05 +0100 Subject: [PATCH 69/78] tty: Fix ->session locking commit c8bcd9c5be24fb9e6132e97da5a35e55a83e36b9 upstream. Currently, locking of ->session is very inconsistent; most places protect it using the legacy tty mutex, but disassociate_ctty(), __do_SAK(), tiocspgrp() and tiocgsid() don't. Two of the writers hold the ctrl_lock (because they already need it for ->pgrp), but __proc_set_tty() doesn't do that yet. On a PREEMPT=y system, an unprivileged user can theoretically abuse this broken locking to read 4 bytes of freed memory via TIOCGSID if tiocgsid() is preempted long enough at the right point. (Other things might also go wrong, especially if root-only ioctls are involved; I'm not sure about that.) Change the locking on ->session such that: - tty_lock() is held by all writers: By making disassociate_ctty() hold it. This should be fine because the same lock can already be taken through the call to tty_vhangup_session(). The tricky part is that we need to shorten the area covered by siglock to be able to take tty_lock() without ugly retry logic; as far as I can tell, this should be fine, since nothing in the signal_struct is touched in the `if (tty)` branch. - ctrl_lock is held by all writers: By changing __proc_set_tty() to hold the lock a little longer. - All readers that aren't holding tty_lock() hold ctrl_lock: By adding locking to tiocgsid() and __do_SAK(), and expanding the area covered by ctrl_lock in tiocspgrp(). Cc: stable@kernel.org Signed-off-by: Jann Horn Reviewed-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 5d64f8bacf47f7f46abf0d2a6fd8238859d8fdee) Issue: FP3SEC-45 Change-Id: I0c3c49edf32a9c3a8b0a92adc32f482faba206e0 --- drivers/tty/tty_io.c | 51 ++++++++++++++++++++++++++++++++------------ include/linux/tty.h | 4 ++++ 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6267efa99bed..d78334283819 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -544,8 +544,8 @@ static void __proc_set_tty(struct tty_struct *tty) 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 @@ void disassociate_ctty(int on_exit) 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 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t 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 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t if (session_of_pgrp(pgrp) != task_session(current)) goto out_unlock; retval = 0; - spin_lock_irq(&real_tty->ctrl_lock); put_pid(real_tty->pgrp); real_tty->pgrp = get_pid(pgrp); - spin_unlock_irq(&real_tty->ctrl_lock); out_unlock: rcu_read_unlock(); +out_unlock_ctrl: + spin_unlock_irq(&real_tty->ctrl_lock); return retval; } @@ -2666,21 +2674,31 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t * * 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 @@ void __do_SAK(struct tty_struct *tty) 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 @@ void __do_SAK(struct tty_struct *tty) task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); + put_pid(session); #endif } diff --git a/include/linux/tty.h b/include/linux/tty.h index 6f841149c3f4..03f6c8051420 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -293,6 +293,10 @@ struct tty_struct { 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; -- GitLab From 14643f6a98d726ec3bca6ffec1bf8def5673c090 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 12 Mar 2021 08:59:48 -0800 Subject: [PATCH 70/78] net: qrtr: fix a kernel-infoleak in qrtr_recvmsg() commit 50535249f624d0072cd885bcdce4e4b6fb770160 upstream. struct sockaddr_qrtr has a 2-byte hole, and qrtr_recvmsg() currently does not clear it before copying kernel data to user space. It might be too late to name the hole since sockaddr_qrtr structure is uapi. BUG: KMSAN: kernel-infoleak in kmsan_copy_to_user+0x9c/0xb0 mm/kmsan/kmsan_hooks.c:249 CPU: 0 PID: 29705 Comm: syz-executor.3 Not tainted 5.11.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x21c/0x280 lib/dump_stack.c:120 kmsan_report+0xfb/0x1e0 mm/kmsan/kmsan_report.c:118 kmsan_internal_check_memory+0x202/0x520 mm/kmsan/kmsan.c:402 kmsan_copy_to_user+0x9c/0xb0 mm/kmsan/kmsan_hooks.c:249 instrument_copy_to_user include/linux/instrumented.h:121 [inline] _copy_to_user+0x1ac/0x270 lib/usercopy.c:33 copy_to_user include/linux/uaccess.h:209 [inline] move_addr_to_user+0x3a2/0x640 net/socket.c:237 ____sys_recvmsg+0x696/0xd50 net/socket.c:2575 ___sys_recvmsg net/socket.c:2610 [inline] do_recvmmsg+0xa97/0x22d0 net/socket.c:2710 __sys_recvmmsg net/socket.c:2789 [inline] __do_sys_recvmmsg net/socket.c:2812 [inline] __se_sys_recvmmsg+0x24a/0x410 net/socket.c:2805 __x64_sys_recvmmsg+0x62/0x80 net/socket.c:2805 do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x465f69 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f43659d6188 EFLAGS: 00000246 ORIG_RAX: 000000000000012b RAX: ffffffffffffffda RBX: 000000000056bf60 RCX: 0000000000465f69 RDX: 0000000000000008 RSI: 0000000020003e40 RDI: 0000000000000003 RBP: 00000000004bfa8f R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000010060 R11: 0000000000000246 R12: 000000000056bf60 R13: 0000000000a9fb1f R14: 00007f43659d6300 R15: 0000000000022000 Local variable ----addr@____sys_recvmsg created at: ____sys_recvmsg+0x168/0xd50 net/socket.c:2550 ____sys_recvmsg+0x168/0xd50 net/socket.c:2550 Bytes 2-3 of 12 are uninitialized Memory access of size 12 starts at ffff88817c627b40 Data copied to user address 0000000020000140 Fixes: bdabad3e363d ("net: Add Qualcomm IPC router") Signed-off-by: Eric Dumazet Cc: Courtney Cavin Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman (cherry picked from commit ab29b020bc29aecaa05e29063cddea83df393023) Issue: FP3SEC-66 Change-Id: I264291af8e2ad302a07a2fdb93fbc7cc985f41a3 --- net/qrtr/qrtr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index a419201a5cf4..349a832e72c8 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -713,6 +713,11 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, 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); -- GitLab From 26177c91a8470cdcb9e4cb077c46314625dd3490 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Fri, 9 Apr 2021 13:22:31 +0530 Subject: [PATCH 71/78] msm: adsprpc: Allocate buffer taking NULL byte into consideration When attaching to audiopd on ADSP, allocate one extra byte for the process name so that it is null terminated when data is copied from file pointer in the userspace. Change-Id: Iffb9ef5cb0198ff7cbf44d0f3be03a1c9f29a90f Acked-by: Vishnu Karthik D Signed-off-by: Jeya R (cherry picked from commit 4d5a6020f9fc49c83e7808a63a2a8088225cde81) Issue: FP3SEC-88 --- drivers/char/adsprpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 4069e2e56af2..64e6e2fa1e5d 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2283,7 +2283,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (!init->filelen) goto bail; - proc_name = kzalloc(init->filelen, GFP_KERNEL); + proc_name = kzalloc(init->filelen + 1, GFP_KERNEL); VERIFY(err, !IS_ERR_OR_NULL(proc_name)); if (err) goto bail; -- GitLab From 4673c6b76ea9008e2219415a10af2b9b0764e00f Mon Sep 17 00:00:00 2001 From: Hridya Valsaraju Date: Sun, 25 Jul 2021 20:49:06 -0700 Subject: [PATCH 72/78] ANDROID: staging: ion: move buffer kmap from begin/end_cpu_access() Since dma_buf_begin/end_cpu_access() calls always used to bracket dma_buf_kmap/kunmap calls, ION performed kmap/kunmap invocations for the buffer during dma_buf_begin/end_cpu_access() calls and cached the results with a kmap counter. However, dma_buf_begin/end_cpu_access() invocations can be triggered from the userspace using the DMA_BUF_IOC_SYNC ioctl as well. This means that a mapping that was created by a device driver using by a dma_buf_kmap() call or an ion_map_kernel() call could be unmapped from userspace if a client accidentally(or maliciously) invoked DMA_BUF_IOCTL_SYNC IOCTL with 'DMA_BUF_SYNC_END' argument since this would inturn invoke dma_buf_end_cpu_access() which would then decrement the kmap counter and invoke kunmap() when the counter gets to 0. This patch moves the kmap/kunmap operations from the begin/end_cpu_access() DMA-BUF ops to the map/unmap DMA-BUF ops to prevent the issue. Bug: 187527909 Change-Id: I00dc8eefefb1f3aab99e770f90d624011f7740f0 [hridya: minor conflicts during cherry-picking] Signed-off-by: Hridya Valsaraju Issue: FP3SEC-110 (cherry picked from commit 41a097c0ed6658bf451c5cf993ab0469eb1ce4a5) --- drivers/staging/android/ion/ion.c | 43 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index a34829caef03..452ec06ae27f 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1349,42 +1349,45 @@ static void ion_dma_buf_release(struct dma_buf *dmabuf) static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) { 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 ERR_PTR(-ENOTTY); + } + mutex_lock(&buffer->lock); + vaddr = ion_buffer_kmap_get(buffer); + mutex_unlock(&buffer->lock); - return buffer->vaddr + offset * PAGE_SIZE; + 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) { - 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; - } - - mutex_lock(&buffer->lock); - vaddr = ion_buffer_kmap_get(buffer); - mutex_unlock(&buffer->lock); - return PTR_ERR_OR_ZERO(vaddr); + 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; } -- GitLab From a12e9436663b4689e5c35c144b384c97428ca1bc Mon Sep 17 00:00:00 2001 From: Qian Cai Date: Tue, 4 Feb 2020 13:40:29 -0500 Subject: [PATCH 73/78] skbuff: fix a data race in skb_queue_len() [ Upstream commit 86b18aaa2b5b5bb48e609cd591b3d2d0fdbe0442 ] sk_buff.qlen can be accessed concurrently as noticed by KCSAN, BUG: KCSAN: data-race in __skb_try_recv_from_queue / unix_dgram_sendmsg read to 0xffff8a1b1d8a81c0 of 4 bytes by task 5371 on cpu 96: unix_dgram_sendmsg+0x9a9/0xb70 include/linux/skbuff.h:1821 net/unix/af_unix.c:1761 ____sys_sendmsg+0x33e/0x370 ___sys_sendmsg+0xa6/0xf0 __sys_sendmsg+0x69/0xf0 __x64_sys_sendmsg+0x51/0x70 do_syscall_64+0x91/0xb47 entry_SYSCALL_64_after_hwframe+0x49/0xbe write to 0xffff8a1b1d8a81c0 of 4 bytes by task 1 on cpu 99: __skb_try_recv_from_queue+0x327/0x410 include/linux/skbuff.h:2029 __skb_try_recv_datagram+0xbe/0x220 unix_dgram_recvmsg+0xee/0x850 ____sys_recvmsg+0x1fb/0x210 ___sys_recvmsg+0xa2/0xf0 __sys_recvmsg+0x66/0xf0 __x64_sys_recvmsg+0x51/0x70 do_syscall_64+0x91/0xb47 entry_SYSCALL_64_after_hwframe+0x49/0xbe Since only the read is operating as lockless, it could introduce a logic bug in unix_recvq_full() due to the load tearing. Fix it by adding a lockless variant of skb_queue_len() and unix_recvq_full() where READ_ONCE() is on the read while WRITE_ONCE() is on the write similar to the commit d7d16a89350a ("net: add skb_queue_empty_lockless()"). Signed-off-by: Qian Cai Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (cherry picked from commit ce5d34a31676bb33b578577d64dcf4111a03eceb) Change-Id: Ia72d1e605cb54a5d1f8ecf359b590120c3607cc4 --- include/linux/skbuff.h | 14 +++++++++++++- net/unix/af_unix.c | 11 +++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index fdde51a16c87..55466725d352 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1553,6 +1553,18 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_) return list_->qlen; } +/** + * 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 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) { 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/net/unix/af_unix.c b/net/unix/af_unix.c index e7012a509035..3aaf209cf7a1 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -191,11 +191,17 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk) 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; @@ -1793,7 +1799,8 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, * - 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); -- GitLab From 0c36db775727849c12f788043fa20f2abae30cb2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 16 Jun 2021 07:47:15 -0700 Subject: [PATCH 74/78] net/af_unix: fix a data-race in unix_dgram_sendmsg / unix_release_sock [ Upstream commit a494bd642d9120648b06bb7d28ce6d05f55a7819 ] While unix_may_send(sk, osk) is called while osk is locked, it appears unix_release_sock() can overwrite unix_peer() after this lock has been released, making KCSAN unhappy. Changing unix_release_sock() to access/change unix_peer() before lock is released should fix this issue. BUG: KCSAN: data-race in unix_dgram_sendmsg / unix_release_sock write to 0xffff88810465a338 of 8 bytes by task 20852 on cpu 1: unix_release_sock+0x4ed/0x6e0 net/unix/af_unix.c:558 unix_release+0x2f/0x50 net/unix/af_unix.c:859 __sock_release net/socket.c:599 [inline] sock_close+0x6c/0x150 net/socket.c:1258 __fput+0x25b/0x4e0 fs/file_table.c:280 ____fput+0x11/0x20 fs/file_table.c:313 task_work_run+0xae/0x130 kernel/task_work.c:164 tracehook_notify_resume include/linux/tracehook.h:189 [inline] exit_to_user_mode_loop kernel/entry/common.c:175 [inline] exit_to_user_mode_prepare+0x156/0x190 kernel/entry/common.c:209 __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline] syscall_exit_to_user_mode+0x20/0x40 kernel/entry/common.c:302 do_syscall_64+0x56/0x90 arch/x86/entry/common.c:57 entry_SYSCALL_64_after_hwframe+0x44/0xae read to 0xffff88810465a338 of 8 bytes by task 20888 on cpu 0: unix_may_send net/unix/af_unix.c:189 [inline] unix_dgram_sendmsg+0x923/0x1610 net/unix/af_unix.c:1712 sock_sendmsg_nosec net/socket.c:654 [inline] sock_sendmsg net/socket.c:674 [inline] ____sys_sendmsg+0x360/0x4d0 net/socket.c:2350 ___sys_sendmsg net/socket.c:2404 [inline] __sys_sendmmsg+0x315/0x4b0 net/socket.c:2490 __do_sys_sendmmsg net/socket.c:2519 [inline] __se_sys_sendmmsg net/socket.c:2516 [inline] __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2516 do_syscall_64+0x4a/0x90 arch/x86/entry/common.c:47 entry_SYSCALL_64_after_hwframe+0x44/0xae value changed: 0xffff888167905400 -> 0x0000000000000000 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 20888 Comm: syz-executor.0 Not tainted 5.13.0-rc5-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (cherry picked from commit a1461c0d7c155c969395d2757e17795bd7e7f5e0) Change-Id: I2c599ba822c2fe7790929255da45e8c72fdb21d3 --- net/unix/af_unix.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3aaf209cf7a1..43a17fb9f290 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -534,12 +534,14 @@ static void unix_release_sock(struct sock *sk, int embrion) 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); @@ -554,7 +556,6 @@ static void unix_release_sock(struct sock *sk, int embrion) 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 */ -- GitLab From e32d008da8e2cc1941ec0252a9662b1257cf20d6 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 8 Feb 2019 09:01:44 -0700 Subject: [PATCH 75/78] net: split out functions related to registering inflight socket files commit f4e65870e5cede5ca1ec0006b6c9803994e5f7b8 upstream. We need this functionality for the io_uring file registration, but we cannot rely on it since CONFIG_UNIX can be modular. Move the helpers to a separate file, that's always builtin to the kernel if CONFIG_UNIX is m/y. No functional changes in this patch, just moving code around. Reviewed-by: Hannes Reinecke Acked-by: David S. Miller Signed-off-by: Jens Axboe [ backported to older kernels to get access to unix_gc_lock - gregkh ] Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 1f02ba8b5b42fe25cab3d8e6f400e10c4c688700) Change-Id: I40583ea11ea321bde97ee49545a10936ade3260d --- include/net/af_unix.h | 1 + net/Makefile | 2 +- net/unix/Kconfig | 5 ++ net/unix/Makefile | 2 + net/unix/af_unix.c | 76 +------------------- net/unix/garbage.c | 68 +----------------- net/unix/scm.c | 161 ++++++++++++++++++++++++++++++++++++++++++ net/unix/scm.h | 10 +++ 8 files changed, 184 insertions(+), 141 deletions(-) create mode 100644 net/unix/scm.c create mode 100644 net/unix/scm.h diff --git a/include/net/af_unix.h b/include/net/af_unix.h index fd60eccb59a6..79f2e1ccfcfb 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/net/Makefile b/net/Makefile index c84a3470ad8d..83e91dcafec0 100644 --- a/net/Makefile +++ b/net/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/ 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/unix/Kconfig b/net/unix/Kconfig index 8b31ab85d050..3b9e450656a4 100644 --- a/net/unix/Kconfig +++ b/net/unix/Kconfig @@ -19,6 +19,11 @@ config UNIX 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 b663c607b1c6..dc686c6757fb 100644 --- a/net/unix/Makefile +++ b/net/unix/Makefile @@ -9,3 +9,5 @@ unix-$(CONFIG_SYSCTL) += sysctl_net_unix.o 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 43a17fb9f290..f280a70c41d7 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -118,6 +118,8 @@ #include #include +#include "scm.h" + struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE]; EXPORT_SYMBOL_GPL(unix_socket_table); DEFINE_SPINLOCK(unix_table_lock); @@ -1505,80 +1507,6 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ return err; } -static 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]); -} - -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; - - /* - * 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; -} - static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) { int err = 0; diff --git a/net/unix/garbage.c b/net/unix/garbage.c index c36757e72844..8bbe1b8e4ff7 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -86,77 +86,13 @@ #include #include +#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 000000000000..df8f636ab1d8 --- /dev/null +++ b/net/unix/scm.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 000000000000..5a255a477f16 --- /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 -- GitLab From 97106c23a056b030778b59b5231fcf56e3634f42 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 28 Jul 2021 14:47:20 +0200 Subject: [PATCH 76/78] af_unix: fix garbage collect vs MSG_PEEK commit cbcf01128d0a92e131bd09f1688fe032480b65ca upstream. unix_gc() assumes that candidate sockets can never gain an external reference (i.e. be installed into an fd) while the unix_gc_lock is held. Except for MSG_PEEK this is guaranteed by modifying inflight count under the unix_gc_lock. MSG_PEEK does not touch any variable protected by unix_gc_lock (file count is not), yet it needs to be serialized with garbage collection. Do this by locking/unlocking unix_gc_lock: 1) increment file count 2) lock/unlock barrier to make sure incremented file count is visible to garbage collection 3) install file into fd This is a lock barrier (unlike smp_mb()) that ensures that garbage collection is run completely before or completely after the barrier. Cc: Signed-off-by: Miklos Szeredi Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Issue: FP3SEC-122 (cherry picked from commit a805a7bd94644207d762d9c287078fecfcf52b3e) Change-Id: I905b16f8d08324541f3281427d3f633bc5373769 --- net/unix/af_unix.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f280a70c41d7..fa4f39e8ee0c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1507,6 +1507,53 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ return err; } +static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) +{ + scm->fp = scm_fp_dup(UNIXCB(skb).fp); + + /* + * 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. + */ + 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) { int err = 0; @@ -2140,7 +2187,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, 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; @@ -2385,7 +2432,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, /* 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); -- GitLab From 497c3cb980a628d5100e10278822a0730d8a2732 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 30 Dec 2020 16:30:50 +0530 Subject: [PATCH 77/78] msm: kgsl: Protect the memdesc->gpuaddr in SVM use cases When SVM is being used there can only be one GPU address assigned to the memory descriptor. Don't allow the GPU address to be changed after it has been negotiated the first time by a process. Change-Id: Ic0dedbad2a1b3ccdc2c1598a6c501b2be288d64e Signed-off-by: Jordan Crouse Signed-off-by: Harshitha Sai Neelati Signed-off-by: Pranav Patel Issue: FP3SEC-127 (cherry picked from commit 286b115bad6c40288f69fb765f63013dde9e4a93) --- drivers/gpu/msm/kgsl.c | 29 ++++++++++++++++++++++++++--- drivers/gpu/msm/kgsl.h | 5 +++++ drivers/gpu/msm/kgsl_iommu.c | 7 ++++++- drivers/gpu/msm/kgsl_mmu.c | 8 +++++++- drivers/gpu/msm/kgsl_sharedmem.c | 1 + 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index dec3e3ce07d5..9fc0cbbac1ea 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -4290,19 +4290,34 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private, { int ret; + /* + * Protect access to the gpuaddr here to prevent multiple vmas from + * trying to map a SVM region at the same time + */ + spin_lock(&entry->memdesc.lock); + + if (entry->memdesc.gpuaddr) { + spin_unlock(&entry->memdesc.lock); + return (unsigned long) -EBUSY; + } + ret = kgsl_mmu_set_svm_region(private->pagetable, (uint64_t) addr, (uint64_t) size); - if (ret != 0) - return ret; + if (ret != 0) { + spin_unlock(&entry->memdesc.lock); + return (unsigned long) ret; + } entry->memdesc.gpuaddr = (uint64_t) addr; + spin_unlock(&entry->memdesc.lock); + entry->memdesc.pagetable = private->pagetable; ret = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (ret) { kgsl_mmu_put_gpuaddr(&entry->memdesc); - return ret; + return (unsigned long) ret; } kgsl_memfree_purge(private->pagetable, entry->memdesc.gpuaddr, @@ -4365,6 +4380,14 @@ static unsigned long _search_range(struct kgsl_process_private *private, result = _gpu_set_svm_region(private, entry, cpu, len); if (!IS_ERR_VALUE(result)) break; + /* + * _gpu_set_svm_region will return -EBUSY if we tried to set up + * SVM on an object that already has a GPU address. If + * that happens don't bother walking the rest of the + * region + */ + if ((long) result == -EBUSY) + return -EBUSY; trace_kgsl_mem_unmapped_area_collision(entry, cpu, len); diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 75d2c406cad3..8e4f0eaa6837 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -234,6 +234,11 @@ struct kgsl_memdesc { struct page **pages; unsigned int page_count; unsigned int cur_bindings; + /* + * @lock: Spinlock to protect the gpuaddr from being accessed by + * multiple entities trying to map the same SVM region at once + */ + spinlock_t lock; }; /* diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 0bb24d66cdbc..82536f444ef8 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-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 @@ -2523,6 +2523,11 @@ static int kgsl_iommu_get_gpuaddr(struct kgsl_pagetable *pagetable, goto out; } + /* + * This path is only called in a non-SVM path with locks so we can be + * sure we aren't racing with anybody so we don't need to worry about + * taking the lock + */ ret = _insert_gpuaddr(pagetable, addr, size); if (ret == 0) { memdesc->gpuaddr = addr; diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index e12b70b03d5f..b2558a79d375 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -451,10 +451,16 @@ void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc) if (PT_OP_VALID(pagetable, put_gpuaddr) && (unmap_fail == 0)) pagetable->pt_ops->put_gpuaddr(memdesc); + memdesc->pagetable = NULL; + + /* + * If SVM tries to take a GPU address it will lose the race until the + * gpuaddr returns to zero so we shouldn't need to worry about taking a + * lock here + */ if (!kgsl_memdesc_is_global(memdesc)) memdesc->gpuaddr = 0; - memdesc->pagetable = NULL; } EXPORT_SYMBOL(kgsl_mmu_put_gpuaddr); diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 2453d1269470..374051e5058c 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -797,6 +797,7 @@ void kgsl_memdesc_init(struct kgsl_device *device, (memdesc->flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT, ilog2(PAGE_SIZE)); kgsl_memdesc_set_align(memdesc, align); + spin_lock_init(&memdesc->lock); } int -- GitLab From 4237d09c04a13ac0f43453619819875ed7d210a5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 Sep 2020 11:30:48 -0400 Subject: [PATCH 78/78] fix regression in "epoll: Keep a reference on files added to the check list" [ Upstream commit 77f4689de17c0887775bb77896f4cc11a39bf848 ] epoll_loop_check_proc() can run into a file already committed to destruction; we can't grab a reference on those and don't need to add them to the set for reverse path check anyway. Tested-by: Marc Zyngier Fixes: a9ed4a6560b8 ("epoll: Keep a reference on files added to the check list") Signed-off-by: Al Viro Signed-off-by: Sasha Levin Issue: FP3SEC-128 (cherry picked from commit 8238ee93a30a5ff6fc75751e122a28e0d92f3e12) Change-Id: I48d8321f802dc1634a8a9fc9d79a6a975e7de969 --- fs/eventpoll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 5b839ce77e02..4bcbab679afb 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1750,9 +1750,9 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests) * during ep_insert(). */ if (list_empty(&epi->ffd.file->f_tfile_llink)) { - get_file(epi->ffd.file); - list_add(&epi->ffd.file->f_tfile_llink, - &tfile_check_list); + if (get_file_rcu(epi->ffd.file)) + list_add(&epi->ffd.file->f_tfile_llink, + &tfile_check_list); } } } -- GitLab