From b6a43551ab392640cdf47ebe3e5f09dce801dfab Mon Sep 17 00:00:00 2001 From: amd64 Date: Wed, 23 Mar 2022 22:58:45 +0200 Subject: [PATCH] treewide: update kernel source code to BUJ3 firmware --- .../kona-sec-gts7xl-eur-overlay-r00.dts | 2 +- .../kona-sec-gts7xl-eur-overlay-r01.dts | 2 +- .../kona-sec-gts7xl-eur-overlay-r02.dts | 2 +- .../kona-sec-gts7xl-eur-overlay-r03.dts | 2 +- .../kona-sec-gts7xl-eur-overlay-r04.dts | 2 +- .../kona-sec-gts7xl-eur-overlay-r05.dts | 2 +- .../kona-sec-gts7xl-eur-overlay-r06.dts | 2 +- .../bindings/bluetooth/bluetooth_power.txt | 2 + .../boot/dts/vendor/qcom/kona-mtp-ws.dtsi | 1 + arch/arm64/boot/dts/vendor/qcom/kona.dtsi | 9 - .../configs/vendor/gts7xl_eur_open_defconfig | 15 +- .../vendor/gts7xl_eur_open_stock_defconfig | 20 +- arch/arm64/kernel/process.c | 4 +- block/blk-mq.c | 2 +- block/blk-sysfs.c | 3 +- block/cfq-iosched.c | 5 +- block/genhd.c | 7 +- block/mq-deadline.c | 70 +- build_kernel.sh | 1 - crypto/drbg.c | 16 +- drivers/adsp_factory/Kconfig | 7 + drivers/adsp_factory/adsp.h | 3 + drivers/adsp_factory/adsp_factory.c | 6 + drivers/adsp_factory/ssc_core.c | 38 +- drivers/adsp_factory/stk31610_light.c | 49 +- drivers/adsp_factory/tmd4907_stk31610_light.c | 3 + drivers/adsp_factory/tmd490x_light.c | 1 + .../battery_v2/include/charger/mfc_charger.h | 2 + .../include/charger/mfc_s2miw04_charger.h | 2 + .../include/charger/pca9468_charger.h | 8 +- .../include/charger/s2asl01_switching.h | 6 + .../include/fuelgauge/max77705_fuelgauge.h | 2 - drivers/battery_v2/include/sec_battery.h | 11 + .../battery_v2/include/sec_charging_common.h | 18 +- drivers/battery_v2/max77705_fuelgauge.c | 26 +- drivers/battery_v2/mfc_charger.c | 144 +- drivers/battery_v2/mfc_s2miw04_charger.c | 132 +- drivers/battery_v2/pca9468_charger.c | 375 +- drivers/battery_v2/s2asl01_switching.c | 72 +- drivers/battery_v2/sec_battery.c | 263 +- drivers/battery_v2/sec_battery_dt.c | 61 +- drivers/battery_v2/sec_battery_sysfs.c | 17 +- drivers/battery_v2/sec_dual_battery.c | 46 - drivers/battery_v2/sec_step_charging.c | 55 +- drivers/block/loop.c | 374 +- drivers/block/zram/zram_drv.c | 21 +- drivers/bluetooth/bluetooth-power.c | 100 +- drivers/bus/mhi/core/mhi_main.c | 36 +- drivers/bus/mhi/devices/mhi_netdev.c | 4 +- drivers/ccic/max77705_pd.c | 2 +- drivers/char/adsprpc.c | 13 +- drivers/char/diag/diag_dci.c | 16 +- drivers/char/diag/diag_masks.c | 14 +- drivers/cpufreq/cpufreq_limit.c | 254 +- drivers/fingerprint/qbt2000_common.c | 7 +- drivers/gpu/msm/kgsl.c | 2 +- drivers/input/misc/qpnp-power-on.c | 9 +- drivers/input/touchscreen/Kconfig | 1 + drivers/input/touchscreen/Makefile | 1 + .../input/touchscreen/sec_ts/y79a_c/sec_ts.c | 7 + .../touchscreen/sec_ts/y79a_c/sec_ts_fn.c | 5 + .../input/touchscreen/stm/fts5cu56a/Kconfig | 12 + .../input/touchscreen/stm/fts5cu56a/Makefile | 3 + .../input/touchscreen/stm/fts5cu56a/fts_fwu.c | 1042 ++ .../input/touchscreen/stm/fts5cu56a/fts_sec.c | 7612 ++++++++++ .../input/touchscreen/stm/fts5cu56a/fts_ts.c | 4425 ++++++ .../input/touchscreen/stm/fts5cu56a/fts_ts.h | 1092 ++ .../touchscreen/stm/fts9cu80f_b/fts_sec.c | 16 + .../touchscreen/zinitix/zt7650/zinitix_ts.c | 38 +- drivers/input/wacom/wacom_i2c.c | 24 +- drivers/input/wacom/wacom_reg.h | 2 + drivers/kunit/strerror-test.c | 6 +- drivers/kunit/strerror.c | 9 +- drivers/leds/leds-rt8547.c | 8 - drivers/md/alta_bigdata.c | 13 +- drivers/misc/qseecom.c | 126 +- drivers/mmc/core/block.c | 5 + drivers/mmc/core/queue.c | 6 +- drivers/mmc/host/cqhci.c | 10 +- drivers/motor/cs40l2x-private.h | 6 + drivers/motor/cs40l2x.c | 285 +- .../ethernet/qualcomm/rmnet/shs/rmnet_shs.h | 5 +- .../qualcomm/rmnet/shs/rmnet_shs_main.c | 50 +- .../wireless/broadcom/bcmdhd_101_16/Kconfig | 16 +- .../wireless/broadcom/bcmdhd_101_16/Makefile | 79 +- .../wireless/broadcom/bcmdhd_101_16/aiutils.c | 2 +- .../broadcom/bcmdhd_101_16/bcm_app_utils.c | 2 +- .../broadcom/bcmdhd_101_16/bcm_l2_filter.c | 2 +- .../broadcom/bcmdhd_101_16/bcmbloom.c | 2 +- .../broadcom/bcmdhd_101_16/bcmevent.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/bcmsdh.c | 2 +- .../broadcom/bcmdhd_101_16/bcmsdh_linux.c | 2 +- .../broadcom/bcmdhd_101_16/bcmsdh_sdmmc.c | 2 +- .../bcmdhd_101_16/bcmsdh_sdmmc_linux.c | 2 +- .../broadcom/bcmdhd_101_16/bcmsdstd.h | 2 +- .../broadcom/bcmdhd_101_16/bcmstdlib_s.c | 2 +- .../broadcom/bcmdhd_101_16/bcmutils.c | 2 +- .../broadcom/bcmdhd_101_16/bcmwifi_channels.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/bcmxtlv.c | 2 +- .../net/wireless/broadcom/bcmdhd_101_16/dhd.h | 29 +- .../broadcom/bcmdhd_101_16/dhd_bitpack.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_bitpack.h | 2 +- .../wireless/broadcom/bcmdhd_101_16/dhd_bus.h | 2 +- .../wireless/broadcom/bcmdhd_101_16/dhd_cdc.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_cfg80211.c | 10 +- .../broadcom/bcmdhd_101_16/dhd_cfg80211.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_common.c | 47 +- .../broadcom/bcmdhd_101_16/dhd_custom_cis.c | 2 +- .../bcmdhd_101_16/dhd_custom_exynos.c | 44 +- .../broadcom/bcmdhd_101_16/dhd_custom_gpio.c | 2 +- .../bcmdhd_101_16/dhd_custom_memprealloc.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_custom_msm.c | 10 +- .../broadcom/bcmdhd_101_16/dhd_custom_sec.c | 5 +- .../wireless/broadcom/bcmdhd_101_16/dhd_dbg.h | 5 +- .../broadcom/bcmdhd_101_16/dhd_dbg_ring.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_dbg_ring.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_debug.c | 42 +- .../broadcom/bcmdhd_101_16/dhd_debug.h | 8 +- .../broadcom/bcmdhd_101_16/dhd_debug_linux.c | 2 +- .../bcmdhd_101_16/dhd_event_log_filter.c | 2 +- .../bcmdhd_101_16/dhd_event_log_filter.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_flowring.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_flowring.h | 2 +- .../wireless/broadcom/bcmdhd_101_16/dhd_ip.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/dhd_ip.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_linux.c | 593 +- .../broadcom/bcmdhd_101_16/dhd_linux.h | 2 +- .../bcmdhd_101_16/dhd_linux_exportfs.c | 6 +- .../broadcom/bcmdhd_101_16/dhd_linux_lb.c | 27 +- .../bcmdhd_101_16/dhd_linux_pktdump.c | 26 +- .../bcmdhd_101_16/dhd_linux_pktdump.h | 2 +- .../bcmdhd_101_16/dhd_linux_platdev.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_linux_priv.h | 5 +- .../broadcom/bcmdhd_101_16/dhd_linux_sched.c | 2 +- .../bcmdhd_101_16/dhd_linux_sock_qos.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_linux_tx.c | 17 +- .../broadcom/bcmdhd_101_16/dhd_linux_tx.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_linux_wq.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_linux_wq.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_mschdbg.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_mschdbg.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_msgbuf.c | 194 +- .../broadcom/bcmdhd_101_16/dhd_pcie.c | 58 +- .../broadcom/bcmdhd_101_16/dhd_pcie.h | 8 +- .../broadcom/bcmdhd_101_16/dhd_pcie_linux.c | 45 +- .../broadcom/bcmdhd_101_16/dhd_pktlog.c | 15 +- .../broadcom/bcmdhd_101_16/dhd_pktlog.h | 2 +- .../wireless/broadcom/bcmdhd_101_16/dhd_pno.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/dhd_pno.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_proto.h | 4 +- .../broadcom/bcmdhd_101_16/dhd_qos_algo.h | 2 +- .../wireless/broadcom/bcmdhd_101_16/dhd_rtt.c | 16 +- .../wireless/broadcom/bcmdhd_101_16/dhd_rtt.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_sdio.c | 169 +- .../broadcom/bcmdhd_101_16/dhd_sec_feature.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_statlog.c | 2 +- .../broadcom/bcmdhd_101_16/dhd_statlog.h | 2 +- .../broadcom/bcmdhd_101_16/dhd_wlfc.c | 52 +- .../broadcom/bcmdhd_101_16/dhd_wlfc.h | 4 +- .../wireless/broadcom/bcmdhd_101_16/frag.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/frag.h | 2 +- .../broadcom/bcmdhd_101_16/hnd_pktpool.c | 2 +- .../broadcom/bcmdhd_101_16/hnd_pktq.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/hndpmu.c | 2 +- .../broadcom/bcmdhd_101_16/include/802.11.h | 2 +- .../broadcom/bcmdhd_101_16/include/802.11ax.h | 2 +- .../broadcom/bcmdhd_101_16/include/802.11s.h | 2 +- .../broadcom/bcmdhd_101_16/include/802.1d.h | 2 +- .../broadcom/bcmdhd_101_16/include/802.3.h | 2 +- .../broadcom/bcmdhd_101_16/include/aidmp.h | 2 +- .../bcmdhd_101_16/include/bcm_l2_filter.h | 2 +- .../bcmdhd_101_16/include/bcm_mpool_pub.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcm_ring.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmarp.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmbloom.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmcdc.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmdefs.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmdevs.h | 2 +- .../bcmdhd_101_16/include/bcmdevs_legacy.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmdhcp.h | 2 +- .../bcmdhd_101_16/include/bcmendian.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmerror.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmeth.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmevent.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmicmp.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmiov.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmip.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmipv6.h | 2 +- .../bcmdhd_101_16/include/bcmmsgbuf.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmpcie.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmproto.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmrand.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmsdbus.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmsdh.h | 2 +- .../bcmdhd_101_16/include/bcmsdh_sdmmc.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmsdpcm.h | 2 +- .../bcmdhd_101_16/include/bcmstdlib_s.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmtcp.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmtlv.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmudp.h | 2 +- .../broadcom/bcmdhd_101_16/include/bcmutils.h | 2 +- .../bcmdhd_101_16/include/bcmwifi_channels.h | 2 +- .../bcmdhd_101_16/include/bcmwifi_rates.h | 2 +- .../bcmdhd_101_16/include/bcmwifi_rspec.h | 2 +- .../bcmdhd_101_16/include/brcm_nl80211.h | 2 +- .../bcmdhd_101_16/include/dhd_daemon.h | 2 +- .../broadcom/bcmdhd_101_16/include/dhdioctl.h | 2 +- .../bcmdhd_101_16/include/dngl_stats.h | 2 +- .../bcmdhd_101_16/include/dnglevent.h | 2 +- .../bcmdhd_101_16/include/dnglioctl.h | 2 +- .../broadcom/bcmdhd_101_16/include/eap.h | 2 +- .../broadcom/bcmdhd_101_16/include/eapol.h | 2 +- .../broadcom/bcmdhd_101_16/include/epivers.h | 18 +- .../broadcom/bcmdhd_101_16/include/etd.h | 2 +- .../broadcom/bcmdhd_101_16/include/ethernet.h | 2 +- .../bcmdhd_101_16/include/event_log.h | 2 +- .../bcmdhd_101_16/include/event_log_payload.h | 2 +- .../bcmdhd_101_16/include/event_log_set.h | 2 +- .../bcmdhd_101_16/include/event_log_tag.h | 2 +- .../bcmdhd_101_16/include/event_trace.h | 2 +- .../broadcom/bcmdhd_101_16/include/fils.h | 2 +- .../bcmdhd_101_16/include/hnd_armtrap.h | 2 +- .../broadcom/bcmdhd_101_16/include/hnd_cons.h | 2 +- .../bcmdhd_101_16/include/hnd_debug.h | 2 +- .../bcmdhd_101_16/include/hnd_pktpool.h | 2 +- .../broadcom/bcmdhd_101_16/include/hnd_pktq.h | 2 +- .../broadcom/bcmdhd_101_16/include/hnd_trap.h | 2 +- .../broadcom/bcmdhd_101_16/include/hndchipc.h | 2 +- .../broadcom/bcmdhd_101_16/include/hndlhl.h | 2 +- .../broadcom/bcmdhd_101_16/include/hndoobr.h | 2 +- .../broadcom/bcmdhd_101_16/include/hndpmu.h | 2 +- .../broadcom/bcmdhd_101_16/include/hndsoc.h | 2 +- .../bcmdhd_101_16/include/linux_osl.h | 2 +- .../bcmdhd_101_16/include/linux_pkt.h | 2 +- .../broadcom/bcmdhd_101_16/include/linuxver.h | 2 +- .../broadcom/bcmdhd_101_16/include/lpflags.h | 2 +- .../broadcom/bcmdhd_101_16/include/mbo.h | 2 +- .../broadcom/bcmdhd_101_16/include/msgtrace.h | 2 +- .../broadcom/bcmdhd_101_16/include/nan.h | 2 +- .../broadcom/bcmdhd_101_16/include/osl.h | 2 +- .../broadcom/bcmdhd_101_16/include/osl_decl.h | 2 +- .../broadcom/bcmdhd_101_16/include/osl_ext.h | 2 +- .../broadcom/bcmdhd_101_16/include/p2p.h | 2 +- .../include/packed_section_end.h | 2 +- .../include/packed_section_start.h | 2 +- .../broadcom/bcmdhd_101_16/include/pcicfg.h | 2 +- .../bcmdhd_101_16/include/pcie_core.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbchipc.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbconfig.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbgci.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbhndarm.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbhnddma.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbpcmcia.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbsdio.h | 2 +- .../bcmdhd_101_16/include/sbsdpcmdev.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbsocram.h | 2 +- .../broadcom/bcmdhd_101_16/include/sbsysmem.h | 2 +- .../broadcom/bcmdhd_101_16/include/sdio.h | 2 +- .../broadcom/bcmdhd_101_16/include/sdioh.h | 2 +- .../broadcom/bcmdhd_101_16/include/sdiovar.h | 2 +- .../broadcom/bcmdhd_101_16/include/siutils.h | 2 +- .../broadcom/bcmdhd_101_16/include/typedefs.h | 2 +- .../broadcom/bcmdhd_101_16/include/vlan.h | 2 +- .../broadcom/bcmdhd_101_16/include/wl_bam.h | 2 +- .../bcmdhd_101_16/include/wl_bigdata.h | 2 +- .../bcmdhd_101_16/include/wldev_common.h | 2 +- .../bcmdhd_101_16/include/wlfc_proto.h | 2 +- .../broadcom/bcmdhd_101_16/include/wlioctl.h | 2 +- .../bcmdhd_101_16/include/wlioctl_defs.h | 2 +- .../bcmdhd_101_16/include/wlioctl_utils.h | 2 +- .../broadcom/bcmdhd_101_16/include/wpa.h | 2 +- .../broadcom/bcmdhd_101_16/linux_osl.c | 2 +- .../broadcom/bcmdhd_101_16/linux_osl_priv.h | 2 +- .../broadcom/bcmdhd_101_16/linux_pkt.c | 2 +- .../broadcom/bcmdhd_101_16/pcie_core.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/sbutils.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/siutils.c | 2 +- .../broadcom/bcmdhd_101_16/siutils_priv.h | 2 +- .../bcmdhd_101_16/wb_regon_coordinator.c | 2 +- .../broadcom/bcmdhd_101_16/wifi_stats.h | 2 +- .../broadcom/bcmdhd_101_16/wl_android.c | 41 +- .../broadcom/bcmdhd_101_16/wl_android.h | 2 +- .../wireless/broadcom/bcmdhd_101_16/wl_bam.c | 2 +- .../broadcom/bcmdhd_101_16/wl_bigdata.c | 2 +- .../broadcom/bcmdhd_101_16/wl_cfg80211.c | 102 +- .../broadcom/bcmdhd_101_16/wl_cfg80211.h | 15 +- .../broadcom/bcmdhd_101_16/wl_cfg_btcoex.c | 2 +- .../broadcom/bcmdhd_101_16/wl_cfgdbg.c | 2 +- .../broadcom/bcmdhd_101_16/wl_cfgnan.c | 14 +- .../broadcom/bcmdhd_101_16/wl_cfgnan.h | 2 +- .../broadcom/bcmdhd_101_16/wl_cfgp2p.c | 57 +- .../broadcom/bcmdhd_101_16/wl_cfgp2p.h | 2 +- .../broadcom/bcmdhd_101_16/wl_cfgscan.c | 22 +- .../broadcom/bcmdhd_101_16/wl_cfgscan.h | 2 +- .../broadcom/bcmdhd_101_16/wl_cfgvendor.c | 91 +- .../broadcom/bcmdhd_101_16/wl_cfgvendor.h | 9 +- .../broadcom/bcmdhd_101_16/wl_cfgvif.c | 67 +- .../broadcom/bcmdhd_101_16/wl_cfgvif.h | 2 +- .../broadcom/bcmdhd_101_16/wl_linux_mon.c | 2 +- .../wireless/broadcom/bcmdhd_101_16/wl_roam.c | 2 +- .../broadcom/bcmdhd_101_16/wlc_types.h | 2 +- .../broadcom/bcmdhd_101_16/wldev_common.c | 2 +- drivers/net/wireless/cnss2/pci.c | 6 + .../qcacld-3.0/core/dp/txrx/ol_rx_defrag.c | 2 +- .../qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c | 2 + .../qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c | 8 +- .../core/hdd/src/wlan_hdd_cfg80211.c | 5 +- .../qcacld-3.0/core/hdd/src/wlan_hdd_main.c | 26 + drivers/nfc/pn547.c | 83 +- drivers/optics/tcs3407.c | 7 + drivers/perf_mgr/perf_mgr.c | 13 +- drivers/power/reset/Makefile | 2 + drivers/power/reset/msm-poweroff.c | 5 + drivers/samsung/Kconfig | 4 +- drivers/samsung/debug/Kconfig | 23 +- drivers/samsung/debug/sec_debug.c | 30 +- drivers/samsung/debug/sec_debug_internal.h | 4 + drivers/samsung/debug/sec_debug_partition.c | 18 + drivers/samsung/debug/sec_debug_sched_log.c | 219 +- drivers/samsung/debug/sec_debug_summary.c | 87 +- drivers/samsung/debug/sec_hw_param.c | 129 +- drivers/samsung/debug/sec_log_buf.c | 81 +- drivers/samsung/quest/Kconfig | 11 +- drivers/samsung/quest/Makefile | 10 +- drivers/samsung/quest/sec_quest.c | 169 +- drivers/samsung/quest/sec_quest_param.c | 33 +- drivers/scsi/sd.c | 8 +- drivers/scsi/ufs/ufs.h | 9 +- drivers/scsi/ufs/ufshcd.c | 57 +- .../security/samsung/five_tee_driver/Kconfig | 2 +- .../security/samsung/five_tee_driver/Makefile | 27 +- .../samsung/five_tee_driver/five_ta_uuid.h | 9 + .../samsung/five_tee_driver/five_tee_driver.c | 207 +- .../five_tee_driver/five_tee_interface.h | 47 + .../source/gp-api/client/teec_common_qsee.c | 44 +- drivers/security/samsung/icdrv/Makefile | 7 +- drivers/security/samsung/icdrv/oemflag.c | 15 +- drivers/security/samsung/icdrv/oemflag.h | 3 + drivers/security/samsung/tzic/Kconfig | 6 +- drivers/security/samsung/tzic/Makefile | 32 +- drivers/security/samsung/tzic/tzic64.c | 4 +- drivers/security/samsung/tzic/tzic_qsee.c | 15 + drivers/sensors/Kconfig | 6 + drivers/sensors/a96t3x6.c | 16 +- drivers/sensors/a96t3x6.h | 4 + .../vl53l5/src/vl53l5_k_ioctl_controls.c | 2 +- drivers/sensors/vl53l5/src/vl53l5_k_module.c | 81 +- drivers/soc/qcom/socinfo.c | 2 +- drivers/staging/android/ion/ion.c | 93 +- drivers/usb/gadget/function/f_cdev.c | 56 +- drivers/usb/gadget/function/f_conn_gadget.c | 17 +- drivers/usb/notify/usb_notify.c | 4 +- drivers/uwb/sr100.c | 24 +- firmware/Makefile | 1 + firmware/epen/w9021_gts7l.bin | Bin 262164 -> 262164 bytes firmware/epen/w9021_gts7xl.bin | Bin 262164 -> 262164 bytes firmware/tsp_sec/y79a_c2_4layer.bin | Bin 209440 -> 209480 bytes firmware/tsp_stm/fts1ba90a_gts7xl.bin | Bin 118032 -> 118032 bytes firmware/tsp_stm/fts9cu80f_bloom.fw | Bin 122300 -> 122300 bytes firmware/tsp_zinitix/zt7650_r8.bin | Bin 131072 -> 131072 bytes fs/ext4/dir.c | 1 + fs/ext4/ext4_jbd2.c | 2 + fs/ext4/extents.c | 1 + fs/ext4/namei.c | 1 + fs/ext4/super.c | 2 + fs/ext4/xattr.c | 5 +- fs/f2fs/checkpoint.c | 10 +- fs/f2fs/f2fs.h | 33 +- fs/f2fs/file.c | 52 + fs/f2fs/sysfs.c | 177 +- fs/fs-writeback.c | 1 + fs/fuse/dev.c | 2 + fs/fuse/dir.c | 1 + fs/fuse/inode.c | 1 + include/crypto/drbg.h | 7 - include/kunit/strerror.h | 6 +- include/kunit/test.h | 34 +- include/linux/adsp/adsp_ft_common.h | 14 +- include/linux/bluetooth-power.h | 2 + include/linux/ccic/max77705C_pass2_PID03.h | 12612 ++++++++-------- include/linux/cpufreq.h | 10 +- include/linux/cpufreq_limit.h | 34 +- include/linux/cred.h | 5 + include/linux/input/qpnp-power-on.h | 1 + include/linux/leds-rt8547.h | 4 - include/linux/mm.h | 1 + include/linux/olog.pb.h | 10 +- include/linux/samsung/debug/sec_debug.h | 16 +- .../samsung/debug/sec_debug_partition_type.h | 21 + .../linux/samsung/debug/sec_debug_sched_log.h | 7 +- .../samsung/debug/sec_debug_sched_log_type.h | 27 +- .../linux/samsung/debug/sec_debug_summary.h | 4 - .../samsung/debug/sec_debug_summary_type.h | 20 + .../samsung/debug/sec_debug_user_reset_type.h | 169 +- include/linux/samsung/sec_quest.h | 74 +- include/linux/task_integrity.h | 26 + include/trace/events/ext4.h | 19 +- include/uapi/linux/loop.h | 31 +- init/Kconfig | 7 + kernel/cred.c | 14 +- kernel/power/main.c | 177 +- kernel/sched/fair.c | 12 +- mm/Kconfig | 3 +- mm/backing-dev.c | 7 + mm/oom_kill.c | 1 + mm/page-writeback.c | 5 +- net/netfilter/xt_qtaguid.c | 19 +- security/mstdrv/Kconfig | 7 +- security/mstdrv/mstdrv.c | 4 +- security/samsung/defex_lsm/Makefile | 54 +- .../defex_lsm/catch_engine/defex_catch_list.c | 8 +- .../samsung/defex_lsm/catch_engine/defex_ht.c | 4 +- security/samsung/defex_lsm/cert/defex_sign.c | 42 - .../samsung/defex_lsm/core/defex_common.c | 25 +- .../samsung/defex_lsm/core/defex_get_mode.c | 13 +- security/samsung/defex_lsm/core/defex_lsm.c | 6 +- security/samsung/defex_lsm/core/defex_main.c | 18 +- .../samsung/defex_lsm/core/defex_rules_proc.c | 448 + security/samsung/defex_lsm/core/defex_sysfs.c | 549 +- .../samsung/defex_lsm/debug/defex_debug.c | 53 +- .../samsung/defex_lsm/defex_packed_rules.bin | Bin 10757 -> 10804 bytes security/samsung/defex_lsm/defex_rules.c | 15 +- .../feature_immutable/defex_immutable.c | 117 +- .../defex_priv.c | 116 +- .../feature_safeplace/defex_safeplace.c | 116 +- .../samsung/defex_lsm/include/defex_debug.h | 7 + .../defex_lsm/include/defex_internal.h | 72 +- .../samsung/defex_lsm/include/defex_rules.h | 3 - .../samsung/defex_lsm/include/defex_sign.h | 6 +- .../samsung/defex_lsm/include/defex_test.h | 87 + security/samsung/five/Kconfig | 14 + security/samsung/five/Makefile | 18 +- security/samsung/five/five.h | 2 +- security/samsung/five/five_appraise.c | 12 +- security/samsung/five/five_audit.c | 3 +- security/samsung/five/five_hooks.c | 13 +- security/samsung/five/five_init.c | 11 +- security/samsung/five/five_keyring.c | 27 +- security/samsung/five/five_main.c | 103 +- security/samsung/five/five_pa.c | 26 +- security/samsung/five/five_tee_api.h | 33 - security/samsung/five/five_tee_interface.c | 27 - security/samsung/five/five_tee_interface.h | 7 - security/samsung/five/gki/five.h | 110 + security/samsung/five/gki/five_appraise.c | 852 ++ security/samsung/five/gki/five_audit.c | 216 + security/samsung/five/gki/five_audit.h | 40 + security/samsung/five/gki/five_cache.c | 44 + security/samsung/five/gki/five_cache.h | 30 + security/samsung/five/gki/five_crypto.c | 537 + security/samsung/five/gki/five_hooks.c | 313 + security/samsung/five/gki/five_hooks.h | 111 + security/samsung/five/gki/five_iint.c | 258 + security/samsung/five/gki/five_iint.h | 286 + security/samsung/five/gki/five_init.c | 45 + security/samsung/five/gki/five_main.c | 1139 ++ security/samsung/five/gki/five_pa.c | 144 + security/samsung/five/gki/five_state.c | 387 + .../samsung/five/gki/five_tee_interface.c | 116 + .../samsung/five/gki/five_tee_interface.h | 47 + security/samsung/five/gki/five_tint_dev.c | 419 + security/samsung/five/gki/five_tint_dev.h | 24 + security/samsung/five/gki/five_vfs.c | 130 + security/samsung/five/gki/five_vfs.h | 24 + security/samsung/five/gki/task_integrity.c | 196 + security/samsung/five/gki/task_integrity.h | 426 + techpack/audio/asoc/kona.c | 2 +- .../cam_sensor_module/cam_cci/cam_cci_core.c | 24 +- .../cam_sensor_module/cam_cci/cam_cci_dev.c | 53 - .../cam_sensor_module/cam_cci/cam_cci_dev.h | 6 - .../cam_ois/cam_ois_rumba_s4.c | 2 +- techpack/display/msm/dp/dp_display.c | 116 +- techpack/display/msm/dp/secdp.h | 13 +- techpack/display/msm/dp/secdp_sysfs.c | 60 +- techpack/display/msm/dsi/dsi_defs.h | 3 +- techpack/display/msm/dsi/dsi_panel.c | 3 +- .../ss_dsi_mdnie_EA8079B_AMS646YB01.h | 204 +- .../ss_dsi_panel_EA8079B_AMS646YB01.c | 2 +- techpack/display/msm/samsung/Kconfig | 7 + .../msm/samsung/MAFPC/ss_dsi_mafpc_XA1.c | 8 +- techpack/display/msm/samsung/Makefile | 3 + ...dsi_panel_S6E36W3_AMB114EU09_octa_cmd.dtsi | 8 +- .../ss_dsi_mdnie_S6E36W3_AMB114EU09.h | 184 +- .../ss_dsi_panel_S6E36W3_AMB114EU09.c | 2 +- .../ss_dsi_mdnie_S6E3FA7_AMB623VH01.h | 182 + .../ss_dsi_panel_S6E3FA7_AMB623VH01.c | 2 +- .../ss_dsi_mdnie_S6E3FA9_AMB667UM01.h | 182 + .../ss_dsi_panel_S6E3FA9_AMB667UM01.c | 2 +- .../msm/samsung/S6E3FC3_AMS646YD01/Makefile | 12 + ...panel_S6E3FC3_AMS646YD01_fhd_octa_cmd.dtsi | 1568 ++ .../ss_dsi_mdnie_S6E3FC3_AMS646YD01.h | 5068 +++++++ .../ss_dsi_panel_S6E3FC3_AMS646YD01.c | 1335 ++ .../ss_dsi_panel_S6E3FC3_AMS646YD01.h | 2207 +++ ...panel_S6E3HA9_AMF670UH01_fhd_octa_cmd.dtsi | 8 + .../ss_dsi_mdnie_S6E3HA9_AMF670UH01.h | 184 +- .../ss_dsi_panel_S6E3HA9_AMF670UH01.c | 2 +- ...anel_S6E3HAB_AMB623TS01_wqhd_octa_cmd.dtsi | 8 + .../ss_dsi_mdnie_S6E3HAB_AMB623TS01.h | 182 + .../ss_dsi_panel_S6E3HAB_AMB623TS01.c | 2 +- ...anel_S6E3HAB_AMB677TY01_wqhd_octa_cmd.dtsi | 8 + .../ss_dsi_mdnie_S6E3HAB_AMB677TY01.h | 182 + .../ss_dsi_panel_S6E3HAB_AMB677TY01.c | 2 +- .../ss_dsi_mdnie_S6E3HAB_AMB687TZ01.h | 184 +- .../ss_dsi_panel_S6E3HAB_AMB687TZ01.c | 2 +- .../ss_dsi_mdnie_S6E3HAC_AMB687VX01.h | 182 + .../ss_dsi_panel_S6E3HAC_AMB687VX01.c | 2 +- .../ss_dsi_mdnie_S6E3XA0_AMB729WA01.h | 184 +- .../ss_dsi_panel_S6E3XA0_AMB729WA01.c | 2 +- ...anel_S6E3XA1_AMF759VG01_qxga_octa_cmd.dtsi | 6 +- .../ss_dsi_mdnie_S6E3XA1_AMF759VG01.h | 184 +- .../ss_dsi_panel_S6E3XA1_AMF759VG01.c | 2 +- .../ss_dsi_panel_S6TUUM3_AMSA24VU01.c | 19 +- .../msm/samsung/ss_dsi_mdnie_lite_common.c | 4 +- .../display/msm/samsung/ss_dsi_panel_common.c | 27 + .../display/msm/samsung/ss_dsi_panel_common.h | 3 + .../msm/samsung/ss_flash_table_data_common.c | 22 + .../msm/samsung/ss_interpolation_common.c | 5 +- .../display/msm/samsung/ss_panel_notify.h | 1 + techpack/display/msm/sde/sde_encoder.c | 21 - 519 files changed, 45202 insertions(+), 10418 deletions(-) create mode 100644 drivers/input/touchscreen/stm/fts5cu56a/Kconfig create mode 100644 drivers/input/touchscreen/stm/fts5cu56a/Makefile create mode 100644 drivers/input/touchscreen/stm/fts5cu56a/fts_fwu.c create mode 100644 drivers/input/touchscreen/stm/fts5cu56a/fts_sec.c create mode 100644 drivers/input/touchscreen/stm/fts5cu56a/fts_ts.c create mode 100644 drivers/input/touchscreen/stm/fts5cu56a/fts_ts.h create mode 100644 drivers/security/samsung/five_tee_driver/five_tee_interface.h create mode 100644 security/samsung/defex_lsm/core/defex_rules_proc.c create mode 100644 security/samsung/defex_lsm/include/defex_test.h create mode 100644 security/samsung/five/gki/five.h create mode 100644 security/samsung/five/gki/five_appraise.c create mode 100644 security/samsung/five/gki/five_audit.c create mode 100644 security/samsung/five/gki/five_audit.h create mode 100644 security/samsung/five/gki/five_cache.c create mode 100644 security/samsung/five/gki/five_cache.h create mode 100644 security/samsung/five/gki/five_crypto.c create mode 100644 security/samsung/five/gki/five_hooks.c create mode 100644 security/samsung/five/gki/five_hooks.h create mode 100644 security/samsung/five/gki/five_iint.c create mode 100644 security/samsung/five/gki/five_iint.h create mode 100644 security/samsung/five/gki/five_init.c create mode 100644 security/samsung/five/gki/five_main.c create mode 100644 security/samsung/five/gki/five_pa.c create mode 100644 security/samsung/five/gki/five_state.c create mode 100644 security/samsung/five/gki/five_tee_interface.c create mode 100644 security/samsung/five/gki/five_tee_interface.h create mode 100644 security/samsung/five/gki/five_tint_dev.c create mode 100644 security/samsung/five/gki/five_tint_dev.h create mode 100644 security/samsung/five/gki/five_vfs.c create mode 100644 security/samsung/five/gki/five_vfs.h create mode 100644 security/samsung/five/gki/task_integrity.c create mode 100644 security/samsung/five/gki/task_integrity.h create mode 100644 techpack/display/msm/samsung/S6E3FC3_AMS646YD01/Makefile create mode 100644 techpack/display/msm/samsung/S6E3FC3_AMS646YD01/dsi_panel_S6E3FC3_AMS646YD01_fhd_octa_cmd.dtsi create mode 100644 techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_mdnie_S6E3FC3_AMS646YD01.h create mode 100644 techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.c create mode 100644 techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.h diff --git a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r00.dts b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r00.dts index 3cd8e02a4..e3634c779 100644 --- a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r00.dts +++ b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r00.dts @@ -8283,7 +8283,7 @@ target = <0xffffffff>; __overlay__ { - reg = <0x0 0x90400000 0x0 0x4600000>; + reg = <0x0 0x90400000 0x0 0x600000>; }; }; diff --git a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r01.dts b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r01.dts index e4a65e7b7..05c05159a 100644 --- a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r01.dts +++ b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r01.dts @@ -8283,7 +8283,7 @@ target = <0xffffffff>; __overlay__ { - reg = <0x0 0x90400000 0x0 0x4600000>; + reg = <0x0 0x90400000 0x0 0x600000>; }; }; diff --git a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r02.dts b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r02.dts index 284061275..55be5e563 100644 --- a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r02.dts +++ b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r02.dts @@ -8283,7 +8283,7 @@ target = <0xffffffff>; __overlay__ { - reg = <0x0 0x90400000 0x0 0x4600000>; + reg = <0x0 0x90400000 0x0 0x600000>; }; }; diff --git a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r03.dts b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r03.dts index 06c62c49b..a7c5c562a 100644 --- a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r03.dts +++ b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r03.dts @@ -8293,7 +8293,7 @@ target = <0xffffffff>; __overlay__ { - reg = <0x0 0x90400000 0x0 0x4600000>; + reg = <0x0 0x90400000 0x0 0x600000>; }; }; diff --git a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r04.dts b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r04.dts index 3d55b3bcf..37452c1d7 100644 --- a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r04.dts +++ b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r04.dts @@ -8293,7 +8293,7 @@ target = <0xffffffff>; __overlay__ { - reg = <0x0 0x90400000 0x0 0x4600000>; + reg = <0x0 0x90400000 0x0 0x600000>; }; }; diff --git a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r05.dts b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r05.dts index 02724b4b7..c87bd1168 100644 --- a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r05.dts +++ b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r05.dts @@ -8293,7 +8293,7 @@ target = <0xffffffff>; __overlay__ { - reg = <0x0 0x90400000 0x0 0x4600000>; + reg = <0x0 0x90400000 0x0 0x600000>; }; }; diff --git a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r06.dts b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r06.dts index 514b8e2f4..9f9c23305 100644 --- a/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r06.dts +++ b/arch/arm64/boot/dts/samsung/gts7xl/kona-sec-gts7xl-eur-overlay-r06.dts @@ -8293,7 +8293,7 @@ target = <0xffffffff>; __overlay__ { - reg = <0x0 0x90400000 0x0 0x4600000>; + reg = <0x0 0x90400000 0x0 0x600000>; }; }; diff --git a/arch/arm64/boot/dts/vendor/bindings/bluetooth/bluetooth_power.txt b/arch/arm64/boot/dts/vendor/bindings/bluetooth/bluetooth_power.txt index f18ce5946..4d5ed957c 100644 --- a/arch/arm64/boot/dts/vendor/bindings/bluetooth/bluetooth_power.txt +++ b/arch/arm64/boot/dts/vendor/bindings/bluetooth/bluetooth_power.txt @@ -11,6 +11,7 @@ Required properties: qca,qca6390 qca,wcn6750 - qca,bt-reset-gpio: GPIO pin to bring BT Controller out of reset + - qca,wl-reset-gpio: GPIO pin for WLAN EN, used here to check status only Optional properties: - qca,bt-vdd-pa-supply: Bluetooth VDD PA regulator handle @@ -50,6 +51,7 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&bt_en_sleep>; qca,bt-reset-gpio = <&tlmm 21 0>; /* BT_EN */ + qca,wl-reset-gpio = <&tlmm 90 0>; /* WL_EN */ qca,bt-vdd-aon-supply = <&pm8150_s6>; qca,bt-vdd-dig-supply = <&pm8009_s2>; qca,bt-vdd-rfa1-supply = <&pm8150_s5>; diff --git a/arch/arm64/boot/dts/vendor/qcom/kona-mtp-ws.dtsi b/arch/arm64/boot/dts/vendor/qcom/kona-mtp-ws.dtsi index 362c9fd2e..917b0900b 100644 --- a/arch/arm64/boot/dts/vendor/qcom/kona-mtp-ws.dtsi +++ b/arch/arm64/boot/dts/vendor/qcom/kona-mtp-ws.dtsi @@ -11,6 +11,7 @@ pinctrl-names = "default"; pinctrl-0 = <&bt_en_sleep>; qca,bt-reset-gpio = <&tlmm 21 0>; /* BT_EN */ + qca,wl-reset-gpio = <&tlmm 90 0>; /* WL_EN */ qca,bt-sw-ctrl-gpio = <&tlmm 124 0>; /* SW_CTRL */ qca,bt-vdd-aon-supply = <&pm8150_s6>; qca,bt-vdd-dig-supply = <&pm8150_s6>; diff --git a/arch/arm64/boot/dts/vendor/qcom/kona.dtsi b/arch/arm64/boot/dts/vendor/qcom/kona.dtsi index 25bef3472..d21557d7e 100644 --- a/arch/arm64/boot/dts/vendor/qcom/kona.dtsi +++ b/arch/arm64/boot/dts/vendor/qcom/kona.dtsi @@ -398,15 +398,6 @@ reg = <0x0 0x80900000 0x0 0x200000>; }; - ramoops: ramoops@80880000 { - compatible = "removed-dma-pool", "ramoops"; - reg = <0 0x80880000 0 0x00080000>; - record-size = <0x10000>; - console-size = <0x60000>; - pmsg-size = <0x10000>; - no-map; - }; - removed_mem: removed_region@80b00000 { no-map; reg = <0x0 0x80b00000 0x0 0x5300000>; diff --git a/arch/arm64/configs/vendor/gts7xl_eur_open_defconfig b/arch/arm64/configs/vendor/gts7xl_eur_open_defconfig index bce1e308b..c7338c1c2 100644 --- a/arch/arm64/configs/vendor/gts7xl_eur_open_defconfig +++ b/arch/arm64/configs/vendor/gts7xl_eur_open_defconfig @@ -78,6 +78,7 @@ CONFIG_TICK_CPU_ACCOUNTING=y # CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_SCHED_WALT=y +# CONFIG_WALT_POWER_FEATURE is not set CONFIG_SCHED_SEC_TASK_BOOST=y CONFIG_HAVE_SCHED_AVG_IRQ=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -2413,6 +2414,7 @@ CONFIG_TOUCHSCREEN_FTS1BA90A=y # CONFIG_TOUCHSCREEN_NOVATEK_NT36523 is not set # CONFIG_TOUCHSCREEN_MELFAS_MSS100 is not set # CONFIG_TOUCHSCREEN_ZINITIX_ZT7650 is not set +# CONFIG_TOUCHSCREEN_STM_FTS5CU56A is not set CONFIG_TOUCHSCREEN_SYNAPTICS_TCM=y CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_I2C=y # CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_SPI is not set @@ -3611,6 +3613,7 @@ CONFIG_PANEL_S6TUUM3_AMSA24VU01_WQXGA=y # CONFIG_PANEL_S6E3FA7_AMB623VH01_HD is not set # CONFIG_PANEL_EA8076A_AMS646UJ10_FHD is not set # CONFIG_PANEL_EA8079B_AMS646YB01_FHD is not set +# CONFIG_PANEL_S6E3FC3_AMS646YD01_FHD is not set CONFIG_SEC_DISPLAYPORT=y # CONFIG_SEC_DISPLAYPORT_MST is not set CONFIG_SEC_DISPLAYPORT_BIGDATA=y @@ -5839,6 +5842,7 @@ CONFIG_SENSORS_A96T3X6_UNSUPPORT_OTG=y # CONFIG_SENSORS_VL53L5_SUPPORT_UAPI is not set # CONFIG_SENSORS_VL53L5_SUPPORT_KERNEL_INTERFACE is not set # CONFIG_SEC_SLPI_SLEEP_DEBUG is not set +# CONFIG_SEC_SENSORS_ENG_DEBUG is not set # CONFIG_SENSORS_HRMSENSOR is not set # CONFIG_SENSORS_MAX86915 is not set # CONFIG_SENSORS_TCS3407 is not set @@ -5874,7 +5878,10 @@ CONFIG_SEC_LOG_BUF_NO_CONSOLE=y CONFIG_SEC_LOG_LAST_KMSG=y CONFIG_SEC_LOG_STORE_LAST_KMSG=y # CONFIG_SEC_LOG_STORE_LPM_KMSG is not set +# CONFIG_SEC_STORE_POWER_ONOFF_HISTORY is not set CONFIG_SEC_DEBUG_SCHED_LOG=y +# CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU is not set +# CONFIG_SEC_DEBUG_SCHED_LOG_IRQ_V2 is not set # CONFIG_SEC_DEBUG_MSG_LOG is not set # CONFIG_SEC_DEBUG_DCVS_LOG is not set # CONFIG_SEC_DEBUG_POWER_LOG is not set @@ -5894,6 +5901,7 @@ CONFIG_SEC_DEBUG_MDM_FILE_INFO=y # CONFIG_SEC_FILE_LEAK_DEBUG is not set CONFIG_KERNEL_MODE_NEON_DEBUG=y CONFIG_SEC_CP_SEPARATE_DEBUG=y +CONFIG_SEC_DEBUG_MODULE_INFO=y CONFIG_SEC_BOOTSTAT=y CONFIG_SEC_NOEYEINFO=y CONFIG_SEC_QPNP_PON_SPARE_BITS=7 @@ -5907,9 +5915,9 @@ CONFIG_SEC_DEBUG_APPS_CLK_LOGGING=y # Samsung Vbus Notifier drivers # # CONFIG_VBUS_NOTIFIER_MODULE is not set -# CONFIG_SEC_QUEST_AUTO_TRIGGER_KWORKER is not set -# CONFIG_SEC_QUEST_AUTO_TRIGGER_INIT_WRITE is not set -# CONFIG_SEC_QUEST_UEFI_ACT_TRIGGER is not set +CONFIG_SEC_QUEST=y +CONFIG_SEC_QUEST_UEFI=y +CONFIG_SEC_QUEST_UEFI_ENHANCEMENT=y # CONFIG_SEC_QUEST_UEFI_USER is not set # CONFIG_SEC_QUEST_DDR_SCAN_USER is not set CONFIG_ADSP_FACTORY=y @@ -5944,6 +5952,7 @@ CONFIG_VEML3328_SUB_FACTORY=y # CONFIG_VEML3235_SUB_FACTORY is not set # CONFIG_SUPPORT_TMD4907_STK33610_FACTORY is not set # CONFIG_SUPPORT_SSC_AOD_RECT is not set +# CONFIG_SUPPORT_LIGHT_DUALIZATION is not set # # NOTIFIER configs diff --git a/arch/arm64/configs/vendor/gts7xl_eur_open_stock_defconfig b/arch/arm64/configs/vendor/gts7xl_eur_open_stock_defconfig index 762f21574..2f8d177b1 100644 --- a/arch/arm64/configs/vendor/gts7xl_eur_open_stock_defconfig +++ b/arch/arm64/configs/vendor/gts7xl_eur_open_stock_defconfig @@ -80,6 +80,7 @@ CONFIG_TICK_CPU_ACCOUNTING=y # CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_SCHED_WALT=y +# CONFIG_WALT_POWER_FEATURE is not set CONFIG_SCHED_SEC_TASK_BOOST=y CONFIG_HAVE_SCHED_AVG_IRQ=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -2459,6 +2460,7 @@ CONFIG_TOUCHSCREEN_FTS1BA90A=y # CONFIG_TOUCHSCREEN_NOVATEK_NT36523 is not set # CONFIG_TOUCHSCREEN_MELFAS_MSS100 is not set # CONFIG_TOUCHSCREEN_ZINITIX_ZT7650 is not set +# CONFIG_TOUCHSCREEN_STM_FTS5CU56A is not set CONFIG_TOUCHSCREEN_SYNAPTICS_TCM=y CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_I2C=y # CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_SPI is not set @@ -3657,6 +3659,7 @@ CONFIG_PANEL_S6TUUM3_AMSA24VU01_WQXGA=y # CONFIG_PANEL_S6E3FA7_AMB623VH01_HD is not set # CONFIG_PANEL_EA8076A_AMS646UJ10_FHD is not set # CONFIG_PANEL_EA8079B_AMS646YB01_FHD is not set +# CONFIG_PANEL_S6E3FC3_AMS646YD01_FHD is not set CONFIG_SEC_DISPLAYPORT=y # CONFIG_SEC_DISPLAYPORT_MST is not set CONFIG_SEC_DISPLAYPORT_BIGDATA=y @@ -5898,6 +5901,7 @@ CONFIG_SENSORS_A96T3X6_UNSUPPORT_OTG=y # CONFIG_SENSORS_VL53L5_SUPPORT_UAPI is not set # CONFIG_SENSORS_VL53L5_SUPPORT_KERNEL_INTERFACE is not set # CONFIG_SEC_SLPI_SLEEP_DEBUG is not set +# CONFIG_SEC_SENSORS_ENG_DEBUG is not set # CONFIG_SENSORS_HRMSENSOR is not set # CONFIG_SENSORS_MAX86915 is not set # CONFIG_SENSORS_TCS3407 is not set @@ -5933,7 +5937,10 @@ CONFIG_SEC_LOG_BUF_NO_CONSOLE=y CONFIG_SEC_LOG_LAST_KMSG=y CONFIG_SEC_LOG_STORE_LAST_KMSG=y # CONFIG_SEC_LOG_STORE_LPM_KMSG is not set +# CONFIG_SEC_STORE_POWER_ONOFF_HISTORY is not set CONFIG_SEC_DEBUG_SCHED_LOG=y +# CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU is not set +# CONFIG_SEC_DEBUG_SCHED_LOG_IRQ_V2 is not set # CONFIG_SEC_DEBUG_MSG_LOG is not set # CONFIG_SEC_DEBUG_DCVS_LOG is not set # CONFIG_SEC_DEBUG_POWER_LOG is not set @@ -5959,7 +5966,7 @@ CONFIG_SEC_NOEYEINFO=y CONFIG_SEC_QPNP_PON_SPARE_BITS=7 CONFIG_ARGOS=y CONFIG_SEC_MISC=y -CONFIG_SEC_SMEM=yCONFIG_FIVE_SIGN +CONFIG_SEC_SMEM=y CONFIG_SEC_SMEM_VENDOR1_VERSION=5 CONFIG_SEC_DEBUG_APPS_CLK_LOGGING=y @@ -5967,9 +5974,9 @@ CONFIG_SEC_DEBUG_APPS_CLK_LOGGING=y # Samsung Vbus Notifier drivers # # CONFIG_VBUS_NOTIFIER_MODULE is not set -# CONFIG_SEC_QUEST_AUTO_TRIGGER_KWORKER is not set -# CONFIG_SEC_QUEST_AUTO_TRIGGER_INIT_WRITE is not set -# CONFIG_SEC_QUEST_UEFI_ACT_TRIGGER is not set +CONFIG_SEC_QUEST=y +CONFIG_SEC_QUEST_UEFI=y +CONFIG_SEC_QUEST_UEFI_ENHANCEMENT=y # CONFIG_SEC_QUEST_UEFI_USER is not set # CONFIG_SEC_QUEST_DDR_SCAN_USER is not set CONFIG_ADSP_FACTORY=y @@ -6004,6 +6011,7 @@ CONFIG_VEML3328_SUB_FACTORY=y # CONFIG_VEML3235_SUB_FACTORY is not set # CONFIG_SUPPORT_TMD4907_STK33610_FACTORY is not set # CONFIG_SUPPORT_SSC_AOD_RECT is not set +# CONFIG_SUPPORT_LIGHT_DUALIZATION is not set # # NOTIFIER configs @@ -6052,7 +6060,7 @@ CONFIG_CC_ATTACH_LOG=y # CONFIG_REDRIVER=y # CONFIG_COMBO_REDRIVER_PTN36502 is not set -CONFIG_COMBO_REDRIVER_PS5169=yCONFIG_FIVE_SIGN +CONFIG_COMBO_REDRIVER_PS5169=y # CONFIG_SUPPORT_PS5169_ADBTUNE is not set # @@ -6397,6 +6405,8 @@ CONFIG_SECURITY_DEFEX=y # CONFIG_DEFEX_KERNEL_ONLY is not set CONFIG_SECURITY_DSMS=y CONFIG_FIVE=n +# CONFIG_FIVE_GKI_10 is not set +# CONFIG_FIVE_GKI_20 is not set # CONFIG_FIVE_DEBUG is not set CONFIG_FIVE_CERT_USER="x509_five_user.der" CONFIG_FIVE_DEFAULT_HASH_SHA1=y diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 816908f85..9ea685e9e 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -288,6 +288,8 @@ static void show_extra_register_data(struct pt_regs *regs, int nbytes) fs = get_fs(); set_fs(KERNEL_DS); + show_data(regs->pc - nbytes, nbytes * 2, "PC"); + show_data(regs->regs[30] - nbytes, nbytes * 2, "LR"); show_data(regs->sp - nbytes, nbytes * 2, "SP"); for (i = 0; i < 30; i++) { char name[4]; @@ -340,7 +342,7 @@ void __show_regs(struct pt_regs *regs) pr_cont("\n"); } - if (!user_mode(regs)) + if (!user_mode(regs) && (oops_in_progress == 1 || oops_in_progress == 2)) show_extra_register_data(regs, 128); } diff --git a/block/blk-mq.c b/block/blk-mq.c index b783fa4f8..095f44505 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -155,7 +155,7 @@ static void blk_mq_check_disk_inflight_rw(struct blk_mq_hw_ctx *hctx, { struct mq_inflight *mi = priv; - /* This function sholud be called only when mi->part is a whole disk */ + /* This function should be called only when mi->part is a whole disk */ mi->inflight[rq_data_dir(rq)]++; } diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index e2ccb9048..3b3654994 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -103,7 +103,8 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count) unsigned long ra_kb; ssize_t ret; static const char temp[] = "temporary "; - + + /* IOPP-ra-v2.1.4.14 */ if (strncmp(page, temp, sizeof(temp) - 1) != 0) return count; diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index a1133cf21..19d233590 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -36,9 +36,11 @@ static u64 cfq_slice_async = NSEC_PER_SEC / 25; static const int cfq_slice_async_rq = 2; static u64 cfq_slice_idle = NSEC_PER_SEC / 125; static u64 cfq_group_idle = NSEC_PER_SEC / 125; +/* IOPP-cfq_rt_idle_only-v1.0.k4.19 */ static int cfq_rt_idle_only = 1; static const u64 cfq_target_latency = (u64)NSEC_PER_SEC * 3/10; /* 300 ms */ static const int cfq_hist_divisor = 4; +/* IOPP-cfq_max_async_dispatch-v1.0.4.4 */ static int cfq_max_async_dispatch = 4; /* @@ -3821,7 +3823,8 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfq_mark_cfqq_prio_changed(cfqq); if (is_sync) { - if (!cfq_class_idle(cfqq) && (!cfqd->cfq_rt_idle_only || cfq_class_rt(cfqq))) + if (!cfq_class_idle(cfqq) && + (!cfqd->cfq_rt_idle_only || cfq_class_rt(cfqq))) cfq_mark_cfqq_idle_window(cfqq); cfq_mark_cfqq_sync(cfqq); } diff --git a/block/genhd.c b/block/genhd.c index d73a975df..17e443598 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1093,7 +1093,7 @@ static int show_iodevs(struct seq_file *seqf, void *v) struct hd_struct *part; char buf[BDEVNAME_SIZE]; - /* Don't show non-partitionable removeable devices or empty devices */ + /* Don't show non-partitionable removable devices or empty devices */ if (!get_capacity(sgp) || (!disk_max_parts(sgp) && (sgp->flags & GENHD_FL_REMOVABLE))) return 0; @@ -1694,7 +1694,7 @@ static const struct seq_operations diskstats_op = { .show = diskstats_show }; -/* IOPP-iod-v1.1.4.19 - change inflight count */ +/* IOPP-iod-v1.1.k4.19 */ #define PG2KB(x) ((unsigned long)((x) << (PAGE_SHIFT - 10))) static int iostats_show(struct seq_file *seqf, void *v) { @@ -1740,14 +1740,13 @@ static int iostats_show(struct seq_file *seqf, void *v) inflight[0] + inflight[1], jiffies_to_msecs(part_stat_read(hd, io_ticks)), jiffies_to_msecs(part_stat_read(hd, time_in_queue)), - /* followings are added */ + /* following are added */ part_stat_read(hd, ios[STAT_DISCARD]), part_stat_read(hd, sectors[STAT_DISCARD]), part_stat_read(hd, flush_ios), gp->queue->flush_ios, inflight[0], /* read request count */ - /* hd->io_time_us / USEC_PER_MSEC, */ gp->queue->in_flight_time / USEC_PER_MSEC, PG2KB(thresh), PG2KB(bdi->last_thresh), diff --git a/block/mq-deadline.c b/block/mq-deadline.c index 69094d641..7bd9176c0 100644 --- a/block/mq-deadline.c +++ b/block/mq-deadline.c @@ -29,8 +29,11 @@ static const int read_expire = HZ / 2; /* max time before a read is submitted. */ static const int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */ static const int writes_starved = 2; /* max times reads can starve a write */ -static const int fifo_batch = 16; /* # of sequential requests treated as one +/* IOPP-mq_dd_max_async_dispatch-v1.0.k5.4 */ +static const int fifo_batch; /* # of sequential requests treated as one by the above parameters. For throughput. */ +static const int async_percent = 25; /* reserve 75% of requests for sync. */ +static const unsigned int max_async_depth = 8; /* maximun value of async request. */ struct deadline_data { /* @@ -57,6 +60,7 @@ struct deadline_data { int fifo_batch; int writes_starved; int front_merges; + int async_word_depth; spinlock_t lock; spinlock_t zone_lock; @@ -389,6 +393,60 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) return rq; } +static unsigned int dd_sched_tags_map_nr(struct request_queue *q) +{ + return q->queue_hw_ctx[0]->sched_tags->bitmap_tags.sb.map_nr; +} + +static unsigned int dd_sched_tags_depth(struct request_queue *q) +{ + return q->queue_hw_ctx[0]->sched_tags->bitmap_tags.sb.depth; +} + +static unsigned int dd_set_async_word_depth(struct request_queue *q) +{ + unsigned int map_nr; + unsigned int depth; + unsigned int async_depth; + + /* depth = map_nr * word_depth */ + + depth = dd_sched_tags_depth(q); + map_nr = dd_sched_tags_map_nr(q); + + async_depth = depth * async_percent / 100U; + async_depth = min(async_depth, max_async_depth); + + return (async_depth/map_nr) ? (async_depth/map_nr):1; +} + +static void dd_depth_updated(struct blk_mq_hw_ctx *hctx) +{ + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + struct request_queue *q = hctx->queue; + + dd->async_word_depth = dd_set_async_word_depth(q); + sbitmap_queue_min_shallow_depth(&hctx->sched_tags->bitmap_tags, dd->async_word_depth); +} + +static void dd_limit_depth(unsigned int op, struct blk_mq_alloc_data *data) +{ + if (!op_is_sync(op)) { + struct deadline_data *dd = data->q->elevator->elevator_data; + + data->shallow_depth = dd->async_word_depth; + } +} + +static int dd_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) +{ + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + + sbitmap_queue_min_shallow_depth(&hctx->sched_tags->bitmap_tags, + dd->async_word_depth); + return 0; +} + static void dd_exit_queue(struct elevator_queue *e) { struct deadline_data *dd = e->elevator_data; @@ -431,6 +489,8 @@ static int dd_init_queue(struct request_queue *q, struct elevator_type *e) spin_lock_init(&dd->zone_lock); INIT_LIST_HEAD(&dd->dispatch); + dd->async_word_depth = dd_set_async_word_depth(q); + q->elevator = eq; return 0; } @@ -617,6 +677,7 @@ SHOW_FUNCTION(deadline_write_expire_show, dd->fifo_expire[WRITE], 1); SHOW_FUNCTION(deadline_writes_starved_show, dd->writes_starved, 0); SHOW_FUNCTION(deadline_front_merges_show, dd->front_merges, 0); SHOW_FUNCTION(deadline_fifo_batch_show, dd->fifo_batch, 0); +SHOW_FUNCTION(deadline_async_word_depth_show, dd->async_word_depth, 0); #undef SHOW_FUNCTION #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ @@ -645,12 +706,16 @@ STORE_FUNCTION(deadline_fifo_batch_store, &dd->fifo_batch, 0, INT_MAX, 0); #define DD_ATTR(name) \ __ATTR(name, 0644, deadline_##name##_show, deadline_##name##_store) +#define DD_ATTR_RO(name) \ + __ATTR(name, 0444, deadline_##name##_show, NULL) + static struct elv_fs_entry deadline_attrs[] = { DD_ATTR(read_expire), DD_ATTR(write_expire), DD_ATTR(writes_starved), DD_ATTR(front_merges), DD_ATTR(fifo_batch), + DD_ATTR_RO(async_word_depth), __ATTR_NULL }; @@ -786,6 +851,9 @@ static struct elevator_type mq_deadline = { .requests_merged = dd_merged_requests, .request_merged = dd_request_merged, .has_work = dd_has_work, + .limit_depth = dd_limit_depth, + .depth_updated = dd_depth_updated, + .init_hctx = dd_init_hctx, .init_sched = dd_init_queue, .exit_sched = dd_exit_queue, }, diff --git a/build_kernel.sh b/build_kernel.sh index ba72b5020..031d7778f 100755 --- a/build_kernel.sh +++ b/build_kernel.sh @@ -76,4 +76,3 @@ if [ -f out/arch/arm64/boot/Image ]; then zip -r9 "dragkernel-gts7xl-$HASH.zip" * -x *.DS_Store .git* README.md *placeholder LICENSE cd ../ fi - diff --git a/crypto/drbg.c b/crypto/drbg.c index ed5786f3a..bc48bc1f3 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -118,7 +118,7 @@ * the SHA256 / AES 256 over other ciphers. Thus, the favored * DRBGs are the latest entries in this array. */ -const struct drbg_core drbg_cores[] = { +static const struct drbg_core drbg_cores[] = { #ifdef CONFIG_CRYPTO_DRBG_CTR { .flags = DRBG_CTR | DRBG_STRENGTH128, @@ -211,7 +211,6 @@ const struct drbg_core drbg_cores[] = { }, #endif /* CONFIG_CRYPTO_DRBG_HMAC */ }; -EXPORT_SYMBOL(drbg_cores); static int drbg_uninstantiate(struct drbg_state *drbg); @@ -227,7 +226,7 @@ static int drbg_uninstantiate(struct drbg_state *drbg); * Return: normalized strength in *bytes* value or 32 as default * to counter programming errors */ -unsigned short drbg_sec_strength(drbg_flag_t flags) +static inline unsigned short drbg_sec_strength(drbg_flag_t flags) { switch (flags & DRBG_STRENGTH_MASK) { case DRBG_STRENGTH128: @@ -240,7 +239,6 @@ unsigned short drbg_sec_strength(drbg_flag_t flags) return 32; } } -EXPORT_SYMBOL(drbg_sec_strength); /* * Convert an integer into a byte representation of this integer. @@ -1267,7 +1265,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, } /* Free all substructures in a DRBG state without the DRBG state structure */ -void drbg_dealloc_state(struct drbg_state *drbg) +static inline void drbg_dealloc_state(struct drbg_state *drbg) { if (!drbg) return; @@ -1283,13 +1281,12 @@ void drbg_dealloc_state(struct drbg_state *drbg) drbg->d_ops = NULL; drbg->core = NULL; } -EXPORT_SYMBOL(drbg_dealloc_state); /* * Allocate all sub-structures for a DRBG state. * The DRBG state structure must already be allocated. */ -int drbg_alloc_state(struct drbg_state *drbg) +static inline int drbg_alloc_state(struct drbg_state *drbg) { int ret = -ENOMEM; unsigned int sb_size = 0; @@ -1360,7 +1357,6 @@ int drbg_alloc_state(struct drbg_state *drbg) drbg_dealloc_state(drbg); return ret; } -EXPORT_SYMBOL(drbg_alloc_state); /************************************************************************* * DRBG interface functions @@ -1932,7 +1928,8 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, * * return: flags */ -void drbg_convert_tfm_core(const char *cra_driver_name, int *coreref, bool *pr) +static inline void drbg_convert_tfm_core(const char *cra_driver_name, + int *coreref, bool *pr) { int i = 0; size_t start = 0; @@ -1959,7 +1956,6 @@ void drbg_convert_tfm_core(const char *cra_driver_name, int *coreref, bool *pr) } } } -EXPORT_SYMBOL(drbg_convert_tfm_core); static int drbg_kcapi_init(struct crypto_tfm *tfm) { diff --git a/drivers/adsp_factory/Kconfig b/drivers/adsp_factory/Kconfig index 64a908501..5830469df 100644 --- a/drivers/adsp_factory/Kconfig +++ b/drivers/adsp_factory/Kconfig @@ -360,3 +360,10 @@ config SUPPORT_SSC_AOD_RECT default n help Support getting AOD rec. + +config SUPPORT_LIGHT_DUALIZATION + tristate "Support dual light sensors" + default n + help + Select y to support light sensor dualization. + Select n not to support light sensor dualization diff --git a/drivers/adsp_factory/adsp.h b/drivers/adsp_factory/adsp.h index 1f76c8b21..5c9af1fac 100644 --- a/drivers/adsp_factory/adsp.h +++ b/drivers/adsp_factory/adsp.h @@ -226,4 +226,7 @@ int get_light_sidx(struct adsp_data *data); struct adsp_data* adsp_get_struct_data(void); void light_brightness_work_func(struct work_struct *work); #endif +#ifdef CONFIG_SUPPORT_LIGHT_DUALIZATION +void light_set_name_vendor(int32_t buf); +#endif #endif /* __ADSP_SENSOR_H__ */ diff --git a/drivers/adsp_factory/adsp_factory.c b/drivers/adsp_factory/adsp_factory.c index c2c2f2e06..b9154e575 100644 --- a/drivers/adsp_factory/adsp_factory.c +++ b/drivers/adsp_factory/adsp_factory.c @@ -500,6 +500,12 @@ static int process_received_msg(struct sk_buff *skb, struct nlmsghdr *nlh) memcpy(data->msg_buf[sensor_type], (int32_t *)NLMSG_DATA(nlh), nlh->nlmsg_len - (int32_t)sizeof(struct nlmsghdr)); +#ifdef CONFIG_SUPPORT_LIGHT_DUALIZATION + if (sensor_type == MSG_LIGHT && msg_type == MSG_TYPE_ST_SHOW_DATA) + { + light_set_name_vendor(data->msg_buf[MSG_LIGHT][0]); + } +#endif data->ready_flag[msg_type] |= 1 << sensor_type; return 0; diff --git a/drivers/adsp_factory/ssc_core.c b/drivers/adsp_factory/ssc_core.c index acf39d90b..70484221b 100644 --- a/drivers/adsp_factory/ssc_core.c +++ b/drivers/adsp_factory/ssc_core.c @@ -1026,22 +1026,34 @@ static ssize_t lcd_onoff_store(struct device *dev, return size; } #endif -static ssize_t abs_lcd_onoff_store(struct device *dev, +static ssize_t algo_lcd_onoff_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { - int32_t msg_buf[2]; - int new_value; + int32_t msg_buf[2] = {0, }; + int cmd_type; - if (sysfs_streq(buf, "0")) - new_value = 0; - else if (sysfs_streq(buf, "1")) - new_value = 1; - else + if (kstrtoint(buf, 10, &cmd_type)) { + pr_err("[FACTORY] %s: kstrtoint fail\n", __func__); return size; + } - pr_info("[FACTORY] %s: new_value %d\n", __func__, new_value); - msg_buf[0] = OPTION_TYPE_SSC_ABS_LCD_TYPE; - msg_buf[1] = new_value; + switch (cmd_type) { + case COMMON_DATA_SET_ABS_ON: + case COMMON_DATA_SET_ABS_OFF: + msg_buf[0] = OPTION_TYPE_SSC_ABS_LCD_TYPE; + msg_buf[1] = (cmd_type == COMMON_DATA_SET_ABS_ON) ? 1 : 0; + break; + case COMMON_DATA_SET_LCD_INTENT_ON: + case COMMON_DATA_SET_LCD_INTENT_OFF: + msg_buf[0] = OPTION_TYPE_SSC_LCD_INTENT_TYPE; + msg_buf[1] = (cmd_type == COMMON_DATA_SET_LCD_INTENT_ON) ? 1 : 0; + break; + default: + pr_info("[FACTORY] %s: Not support:%d \n", __func__, cmd_type); + return size; + } + + pr_info("[FACTORY] %s: lcd:%d,%d\n", __func__, msg_buf[0], msg_buf[1]); adsp_unicast(msg_buf, sizeof(msg_buf), MSG_SSC_CORE, 0, MSG_TYPE_OPTION_DEFINE); @@ -1347,7 +1359,7 @@ static DEVICE_ATTR(fac_fstate, 0220, NULL, fac_fstate_store); static DEVICE_ATTR(update_ssc_flip, 0220, NULL, update_ssc_flip_store); #endif static DEVICE_ATTR(support_dual_sensor, 0440, support_dual_sensor_show, NULL); -static DEVICE_ATTR(abs_lcd_onoff, 0220, NULL, abs_lcd_onoff_store); +static DEVICE_ATTR(algo_lcd_onoff, 0220, NULL, algo_lcd_onoff_store); static DEVICE_ATTR(sensor_dump, 0444, sensor_dump_show, NULL); #ifdef CONFIG_SUPPORT_SSC_SPU static DEVICE_ATTR(ssc_firmware_info, 0440, ssc_firmware_info_show, NULL); @@ -1377,7 +1389,7 @@ static struct device_attribute *core_attrs[] = { &dev_attr_update_ssc_flip, #endif &dev_attr_support_dual_sensor, - &dev_attr_abs_lcd_onoff, + &dev_attr_algo_lcd_onoff, &dev_attr_sensor_dump, #ifdef CONFIG_SUPPORT_SSC_SPU &dev_attr_ssc_firmware_info, diff --git a/drivers/adsp_factory/stk31610_light.c b/drivers/adsp_factory/stk31610_light.c index a82dd81a6..9eba4a46b 100755 --- a/drivers/adsp_factory/stk31610_light.c +++ b/drivers/adsp_factory/stk31610_light.c @@ -17,12 +17,19 @@ #include #include "adsp.h" -#define VENDOR "Sensortek" -#define CHIP_ID "STK31610" +#define STK31610 's' +#define TCS3407 'T' + +#define VENDOR_STK31610 "Sensortek" +#define CHIP_ID_STK31610 "STK31610" +#define VENDOR_TCS3407 "AMS" +#define CHIP_ID_TCS3407 "TCS3407" + #define ASCII_TO_DEC(x) (x - 48) int brightness; +int chip_id = 0;// 0 : STK31610, 1 : TCS3407 enum { OPTION_TYPE_COPR_ENABLE, @@ -43,13 +50,38 @@ enum { static ssize_t light_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s\n", VENDOR); + char temp[10] = {0,}; + + if (chip_id == 1) + strcpy(temp, VENDOR_TCS3407); + else + strcpy(temp, VENDOR_STK31610); + + return snprintf(buf, PAGE_SIZE, "%s\n", temp); } static ssize_t light_name_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s\n", CHIP_ID); + char temp[10] = {0,}; + + if (chip_id == 1) + strcpy(temp, CHIP_ID_TCS3407); + else + strcpy(temp, CHIP_ID_STK31610); + + return snprintf(buf, PAGE_SIZE, "%s\n", temp); +} + +void light_set_name_vendor(int32_t buf) +{ + pr_info("[FACTORY] %s: name = %d\n", __func__, buf); + if (buf == STK31610) + chip_id = 0; + else if (buf == TCS3407) + chip_id = 1; + else + pr_info("[FACTORY] %s: wrong sensor name %d\n", __func__, buf); } int get_light_sidx(struct adsp_data *data) @@ -349,8 +381,9 @@ static struct device_attribute *light_attrs[] = { NULL, }; -static int __init stk33617_light_factory_init(void) +static int __init stk31610_light_factory_init(void) { + chip_id = 0; adsp_factory_register(MSG_LIGHT, light_attrs); #ifdef CONFIG_SUPPORT_BRIGHTNESS_NOTIFY_FOR_LIGHT_SENSOR ss_panel_notifier_register(&light_panel_data_notifier); @@ -362,7 +395,7 @@ static int __init stk33617_light_factory_init(void) return 0; } -static void __exit stk33617_light_factory_exit(void) +static void __exit stk31610_light_factory_exit(void) { adsp_factory_unregister(MSG_LIGHT); #ifdef CONFIG_SUPPORT_BRIGHTNESS_NOTIFY_FOR_LIGHT_SENSOR @@ -371,5 +404,5 @@ static void __exit stk33617_light_factory_exit(void) pr_info("[FACTORY] %s\n", __func__); } -module_init(stk33617_light_factory_init); -module_exit(stk33617_light_factory_exit); +module_init(stk31610_light_factory_init); +module_exit(stk31610_light_factory_exit); diff --git a/drivers/adsp_factory/tmd4907_stk31610_light.c b/drivers/adsp_factory/tmd4907_stk31610_light.c index 913aca5b1..267fb792b 100644 --- a/drivers/adsp_factory/tmd4907_stk31610_light.c +++ b/drivers/adsp_factory/tmd4907_stk31610_light.c @@ -700,6 +700,8 @@ int ams_load_ub_cell_id_from_file(char *path, char *data_str) ret = vfs_read(file_filp, (char *)data_str, sizeof(char) * AMS_UB_CELL_ID_INFO_STRING_LENGTH, &file_filp->f_pos); + data_str[AMS_UB_CELL_ID_INFO_STRING_LENGTH - 1] = '\0'; + if (ret < 0) pr_err("[FACTORY] %s: fd read fail(%s): %d\n", __func__, path, ret); @@ -967,6 +969,7 @@ void light_cal_init_work(struct adsp_data *data) ret = vfs_read(cal_filp, (char *)data->light_ub_id, sizeof(char) * AMS_UB_CELL_ID_INFO_STRING_LENGTH, &cal_filp->f_pos); + data->light_ub_id[AMS_UB_CELL_ID_INFO_STRING_LENGTH - 1] = '\0'; if (ret < 0) pr_err("[FACTORY] %s: ub read fail:%d\n", __func__, ret); diff --git a/drivers/adsp_factory/tmd490x_light.c b/drivers/adsp_factory/tmd490x_light.c index c84ede75c..5e9f21535 100644 --- a/drivers/adsp_factory/tmd490x_light.c +++ b/drivers/adsp_factory/tmd490x_light.c @@ -663,6 +663,7 @@ void light_lcd_version_dualization(struct adsp_data *data) pr_err("[FACTORY] %s: fd read fail(%s): %d\n", __func__, ret); } else { + ver_str[LIGHT_LCD_TYPE_STRING_LENGTH - 1] = '\0'; pr_info("[FACTORY] %s: data: %s\n", __func__, ver_str); lcd_ver = ver_str[LIGHT_LCD_VERSION_CHAR_NUM] - '0'; } diff --git a/drivers/battery_v2/include/charger/mfc_charger.h b/drivers/battery_v2/include/charger/mfc_charger.h index e077b28e3..766c3e188 100644 --- a/drivers/battery_v2/include/charger/mfc_charger.h +++ b/drivers/battery_v2/include/charger/mfc_charger.h @@ -1228,6 +1228,8 @@ struct mfc_charger_data { bool req_tx_id; bool is_abnormal_pad; + bool afc_tx_done; + #if defined(CONFIG_CHECK_UNAUTH_PAD) u8 ping_freq; bool req_afc_tx; diff --git a/drivers/battery_v2/include/charger/mfc_s2miw04_charger.h b/drivers/battery_v2/include/charger/mfc_s2miw04_charger.h index 828175529..86bea5944 100644 --- a/drivers/battery_v2/include/charger/mfc_s2miw04_charger.h +++ b/drivers/battery_v2/include/charger/mfc_s2miw04_charger.h @@ -996,6 +996,8 @@ struct mfc_charger_data { bool req_tx_id; bool is_abnormal_pad; + bool afc_tx_done; + #if defined(CONFIG_CHECK_UNAUTH_PAD) u8 ping_freq; bool req_afc_tx; diff --git a/drivers/battery_v2/include/charger/pca9468_charger.h b/drivers/battery_v2/include/charger/pca9468_charger.h index 5abe3bd4c..a05ca808d 100644 --- a/drivers/battery_v2/include/charger/pca9468_charger.h +++ b/drivers/battery_v2/include/charger/pca9468_charger.h @@ -334,6 +334,8 @@ static int adc_gain[16] = { 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, /* Maximum TA voltage threshold */ #define PCA9468_TA_MAX_VOL 9800000 // 9800000uV +/* Minimum TA voltage threshold */ +#define PCA9468_TA_MIN_VOL 7000000 // 7000000uV /* Maximum TA current threshold */ #define PCA9468_TA_MAX_CUR 2450000 // 2450000uA /* Mimimum TA current threshold */ @@ -375,6 +377,8 @@ static int adc_gain[16] = { 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, #define PCA9468_TA_IIN_OFFSET 100000 // 100mA /* IIN_CC upper protection offset in Power Limit Mode TA */ #define PCA9468_IIN_CC_UPPER_OFFSET 150000 // 150mA +/* TA current low offset for reducing input current */ +#define PCA9468_TA_CUR_LOW_OFFSET 200000 // 200mA /* PD Message Voltage and Current Step */ #define PD_MSG_TA_VOL_STEP 20000 // 20mV @@ -590,7 +594,7 @@ struct pca9468_charger { unsigned int ret_state; unsigned int iin_cc; - + unsigned int ta_cur; unsigned int ta_vol; unsigned int ta_objpos; @@ -608,7 +612,7 @@ struct pca9468_charger { bool req_new_vfloat; unsigned int new_iin; unsigned int new_vfloat; - + int adc_comp_gain; int retry_cnt; diff --git a/drivers/battery_v2/include/charger/s2asl01_switching.h b/drivers/battery_v2/include/charger/s2asl01_switching.h index 13ea954db..261dcce13 100644 --- a/drivers/battery_v2/include/charger/s2asl01_switching.h +++ b/drivers/battery_v2/include/charger/s2asl01_switching.h @@ -163,6 +163,11 @@ struct s2asl01_platform_data { bool tsd_en; }; +enum s2asl01_ver { + VER_6030 = 0, + VER_6130, +}; + struct s2asl01_switching_data { struct device *dev; struct i2c_client *client; @@ -173,6 +178,7 @@ struct s2asl01_switching_data { struct delayed_work limiter_isr_work; int rev_id; int es_num; + int ic_ver; int irq_bat_int; bool in_ok; bool supllement_mode; diff --git a/drivers/battery_v2/include/fuelgauge/max77705_fuelgauge.h b/drivers/battery_v2/include/fuelgauge/max77705_fuelgauge.h index 4a16fa250..a363e917b 100644 --- a/drivers/battery_v2/include/fuelgauge/max77705_fuelgauge.h +++ b/drivers/battery_v2/include/fuelgauge/max77705_fuelgauge.h @@ -68,8 +68,6 @@ struct sec_fg_info { int pr_cnt; /* full charge comp */ struct delayed_work full_comp_work; - u32 previous_fullcap; - u32 previous_vffullcap; /* battery info */ u32 soc; diff --git a/drivers/battery_v2/include/sec_battery.h b/drivers/battery_v2/include/sec_battery.h index 71b3ef4c4..a0940a477 100644 --- a/drivers/battery_v2/include/sec_battery.h +++ b/drivers/battery_v2/include/sec_battery.h @@ -251,6 +251,12 @@ struct adc_sample_info { int index; }; +enum slate_mode_info { + SB_SLATE_NONE = 0, + SB_SLATE_NORMAL, + SB_SLATE_SMART, +}; + #if defined(CONFIG_BATTERY_SAMSUNG_MHS) struct cable_info { int cable_type; @@ -555,6 +561,7 @@ struct sec_battery_info { int wpc_vout_level; int wpc_max_vout_level; unsigned int current_event; + bool refresh_current; /* wireless charging enable */ struct mutex wclock; @@ -676,9 +683,11 @@ struct sec_battery_info { unsigned int tx_ocp_cnt; struct delayed_work ext_event_work; struct delayed_work misc_event_work; + struct delayed_work wpc_tx_en_work; struct wakeup_source *ext_event_wake_lock; struct wakeup_source *misc_event_wake_lock; struct wakeup_source *tx_event_wake_lock; + struct wakeup_source *wpc_tx_en_wake_lock; struct mutex batt_handlelock; struct mutex current_eventlock; struct mutex typec_notylock; @@ -706,6 +715,7 @@ struct sec_battery_info { int raw_bat_temp; bool support_unknown_wpcthm; + unsigned int slate_mode; }; /* event check */ @@ -770,6 +780,7 @@ extern void sec_bat_set_temp_control_test(struct sec_battery_info *battery, bool extern void sec_bat_get_battery_info(struct sec_battery_info *battery); extern int sec_bat_set_charge(struct sec_battery_info *battery, int chg_mode); extern int sec_bat_set_charging_current(struct sec_battery_info *battery); +extern void sec_bat_refresh_charging_current(struct sec_battery_info *battery); extern void sec_bat_aging_check(struct sec_battery_info *battery); extern void sec_wireless_set_tx_enable(struct sec_battery_info *battery, bool wc_tx_enable); diff --git a/drivers/battery_v2/include/sec_charging_common.h b/drivers/battery_v2/include/sec_charging_common.h index b2d44e134..019d47908 100644 --- a/drivers/battery_v2/include/sec_charging_common.h +++ b/drivers/battery_v2/include/sec_charging_common.h @@ -72,6 +72,7 @@ enum power_supply_ext_property { POWER_SUPPLY_EXT_PROP_WIRELESS_INITIAL_WC_CHECK, POWER_SUPPLY_EXT_PROP_WIRELESS_PARAM_INFO, POWER_SUPPLY_EXT_PROP_WIRELESS_CHECK_FW_VER, + POWER_SUPPLY_EXT_PROP_WIRELESS_SGF, POWER_SUPPLY_EXT_PROP_AICL_CURRENT, POWER_SUPPLY_EXT_PROP_CHECK_MULTI_CHARGE, POWER_SUPPLY_EXT_PROP_CHIP_ID, @@ -158,6 +159,7 @@ enum power_supply_ext_property { POWER_SUPPLY_EXT_PROP_WPC_EN, POWER_SUPPLY_EXT_PROP_WPC_EN_MST, POWER_SUPPLY_EXT_PROP_INBAT_VOLTAGE, + POWER_SUPPLY_EXT_PROP_INFO, }; enum rx_device_type { @@ -1295,6 +1297,7 @@ struct sec_battery_platform_data { int siop_apdo_input_limit_current; int siop_apdo_charging_limit_current; #endif + int input_current_by_siop_20; int siop_wireless_input_limit_current; int siop_wireless_charging_limit_current; @@ -1347,11 +1350,16 @@ struct sec_battery_platform_data { #endif #if defined(CONFIG_DUAL_BATTERY) - /* main + sub value should be over 110% */ - unsigned int main_charging_rate; - unsigned int sub_charging_rate; - unsigned int dc_main_charging_rate; - unsigned int dc_sub_charging_rate; + /* zone 1 : 0C ~ 0.4C */ + unsigned int main_zone1_current_rate; + unsigned int sub_zone1_current_rate; + /* zone 2 : 0.4C ~ 1.1C */ + unsigned int main_zone2_current_rate; + unsigned int sub_zone2_current_rate; + /* zone 3 : 1.1C ~ MAX */ + unsigned int main_zone3_current_rate; + unsigned int sub_zone3_current_rate; + unsigned int force_recharge_margin; unsigned int max_main_charging_current; unsigned int min_main_charging_current; diff --git a/drivers/battery_v2/max77705_fuelgauge.c b/drivers/battery_v2/max77705_fuelgauge.c index a27d9be91..74e85d9d9 100644 --- a/drivers/battery_v2/max77705_fuelgauge.c +++ b/drivers/battery_v2/max77705_fuelgauge.c @@ -224,9 +224,6 @@ static int max77705_fg_read_vfocv(struct max77705_fuelgauge_data *fuelgauge) temp2 = temp / 1000000; vfocv += (temp2 << 4); -#if !defined(CONFIG_SEC_FACTORY) - max77705_fg_periodic_read(fuelgauge); -#endif max77705_fg_periodic_read_power(fuelgauge); return vfocv; @@ -1267,14 +1264,15 @@ bool max77705_fg_init(struct max77705_fuelgauge_data *fuelgauge) #endif fuelgauge->info.fullcap_check_interval = ts.tv_sec; - fuelgauge->info.is_first_check = true; - /* Init parameters to prevent wrong compensation. */ - fuelgauge->info.previous_fullcap = - max77705_read_word(fuelgauge->i2c, FULLCAP_REG); - fuelgauge->info.previous_vffullcap = - max77705_read_word(fuelgauge->i2c, FULLCAP_NOM_REG); + if (max77705_bulk_read(fuelgauge->i2c, CONFIG2_REG, 2, data) < 0) { + pr_err("%s: Failed to read CONFIG2_REG\n", __func__); + } else if ((data[0] & 0x0F) != 0x05) { + data[0] &= ~0x2F; + data[0] |= (0x5 & 0xF); /* ISysNCurr: 11.25 */ + max77705_bulk_write(fuelgauge->i2c, CONFIG2_REG, 2, data); + } if (fuelgauge->pdata->jig_gpio) { int ret; @@ -2107,9 +2105,6 @@ static int max77705_fg_get_property(struct power_supply *psy, (fuelgauge->battery_data->Capacity * fuelgauge->fg_resistor / 2); pr_info("%s: asoc(%d), fullcap(%d)\n", __func__, val->intval, fullcap); -#if !defined(CONFIG_SEC_FACTORY) - max77705_fg_periodic_read(fuelgauge); -#endif } break; case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: @@ -2218,6 +2213,11 @@ static int max77705_fg_get_property(struct power_supply *psy, val->intval = ocv / 6; } break; + case POWER_SUPPLY_EXT_PROP_INFO: +#if !defined(CONFIG_SEC_FACTORY) + max77705_fg_periodic_read(fuelgauge); +#endif + break; default: return -EINVAL; } @@ -2374,6 +2374,8 @@ static int max77705_fg_set_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_MAX ... POWER_SUPPLY_EXT_PROP_MAX: switch (ext_psp) { + case POWER_SUPPLY_EXT_PROP_INFO: + break; default: return -EINVAL; } diff --git a/drivers/battery_v2/mfc_charger.c b/drivers/battery_v2/mfc_charger.c index 865144ed7..5cd2dd62b 100644 --- a/drivers/battery_v2/mfc_charger.c +++ b/drivers/battery_v2/mfc_charger.c @@ -64,6 +64,12 @@ extern unsigned int mfc_chip_id_now; #define EXTERN_MFC_FUNC #endif +struct sgf_data { + unsigned int size; + unsigned int type; + char *data; +}; + extern bool sleep_mode; extern unsigned int lpcharge; extern bool mfc_fw_update; @@ -1964,8 +1970,8 @@ static int VerifyMTPwRAM_IDT(struct mfc_charger_data *charger, unsigned short st msleep(10); // Clear MTP program status byte if (mfc_reg_write(charger->client, 0x0400, 0x00) < 0) { - pr_err("%s %s: clear MTP verifier status byte error\n", MFC_FW_MSG, __func__); - return MFC_VERIFY_ERR_CLR_MTP_STATUS_BYTE; + pr_err("%s %s: clear MTP verifier status byte error\n", MFC_FW_MSG, __func__); + return MFC_VERIFY_ERR_CLR_MTP_STATUS_BYTE; } msleep(10); @@ -2220,8 +2226,8 @@ static int PgmOTPwRAM_IDT(struct mfc_charger_data *charger, unsigned short OtpAd // Clear MTP program status byte if (mfc_reg_write(charger->client, 0x0400, 0x00) < 0) { - pr_err("%s: clear MTP programming status byte error\n", __func__); - return MFC_FWUP_ERR_CLR_MTP_STATUS_BYTE; + pr_err("%s: clear MTP programming status byte error\n", __func__); + return MFC_FWUP_ERR_CLR_MTP_STATUS_BYTE; } if (mfc_reg_write(charger->client, 0x3048, 0xD0) < 0) { @@ -2512,6 +2518,12 @@ static void mfc_wpc_afc_vout_work(struct work_struct *work) __pm_stay_awake(charger->wpc_vout_mode_lock); queue_delayed_work(charger->wqueue, &charger->wpc_vout_mode_work, 0); + + if ((charger->pdata->cable_type == SEC_WIRELESS_PAD_WPC_HV_20) && + (charger->tx_id == 0xEF)) { + pr_info("%s: set power = %d\n", __func__, charger->current_rx_power); + mfc_reset_rx_power(charger, charger->current_rx_power); + } } skip_set_afc_vout: @@ -3299,6 +3311,72 @@ static void mfc_cs100_work(struct work_struct *work) __pm_relax(charger->wpc_cs100_lock); } +static void mfc_set_tx_data(struct mfc_charger_data *charger, int idx) +{ + if (idx < 0) + idx = 0; + else if (idx >= charger->pdata->len_wc20_list) + idx = charger->pdata->len_wc20_list - 1; + + charger->vout_by_txid = charger->pdata->wireless20_vout_list[idx]; + charger->vrect_by_txid = charger->pdata->wireless20_vrect_list[idx]; + charger->max_power_by_txid = charger->pdata->wireless20_max_power_list[idx]; +} + +static int mfc_set_sgf_data(struct mfc_charger_data *charger, struct sgf_data *pdata) +{ + pr_info("%s: size = %d, type = %d\n", __func__, pdata->size, pdata->type); + + switch (pdata->type) { + case WPC_TX_COM_RX_POWER: + { + union power_supply_propval value = {0, }; + int tx_power = *(int *)pdata->data; + + switch (tx_power) { + case TX_RX_POWER_7_5W: + pr_info("%s : TX Power is 7.5W\n", __func__); + charger->current_rx_power = TX_RX_POWER_7_5W; + mfc_set_tx_data(charger, 0); + break; + case TX_RX_POWER_12W: + pr_info("%s : TX Power is 12W\n", __func__); + charger->current_rx_power = TX_RX_POWER_12W; + mfc_set_tx_data(charger, 1); + break; + case TX_RX_POWER_15W: + pr_info("%s : TX Power is 15W\n", __func__); + charger->current_rx_power = TX_RX_POWER_15W; + mfc_set_tx_data(charger, 2); + break; + case TX_RX_POWER_17_5W: + pr_info("%s : TX Power is 17.5W\n", __func__); + charger->current_rx_power = TX_RX_POWER_17_5W; + mfc_set_tx_data(charger, 3); + break; + case TX_RX_POWER_20W: + pr_info("%s : TX Power is 20W\n", __func__); + charger->current_rx_power = TX_RX_POWER_20W; + mfc_set_tx_data(charger, 4); + break; + default: + pr_info("%s : Undefined TX Power(%d)\n", __func__, tx_power); + return -EINVAL; + } + charger->adt_transfer_status = WIRELESS_AUTH_PASS; + charger->pdata->cable_type = value.intval = SEC_WIRELESS_PAD_WPC_HV_20; + pr_info("%s: change cable type to WPC HV 2.0\n", __func__); + + __pm_stay_awake(charger->wpc_afc_vout_lock); + queue_delayed_work(charger->wqueue, &charger->wpc_afc_vout_work, msecs_to_jiffies(0)); + } + break; + default: + return -EINVAL; + } + return 0; +} + #if defined(CONFIG_UPDATE_BATTERY_DATA) static int mfc_chg_parse_dt(struct device *dev, mfc_charger_platform_data_t *pdata); #endif @@ -3911,6 +3989,16 @@ static int mfc_chg_set_property(struct power_supply *psy, mfc_set_wpc_en(charger, WPC_EN_MST, false); break; #endif + case POWER_SUPPLY_EXT_PROP_WIRELESS_SGF: + { + struct sgf_data data; + + data.size = *(int *)val->strval; + data.type = *(int *)(val->strval + 4); + data.data = (char *)(val->strval + 8); + mfc_set_sgf_data(charger, &data); + } + break; default: return -ENODATA; } @@ -4210,6 +4298,7 @@ static void mfc_wpc_det_work(struct work_struct *work) charger->wc_ldo_status = MFC_LDO_ON; charger->tx_id_done = false; charger->req_tx_id = false; + charger->afc_tx_done = false; charger->is_abnormal_pad = false; #if defined(CONFIG_CHECK_UNAUTH_PAD) charger->req_afc_tx = false; @@ -4323,8 +4412,18 @@ static void mfc_wpc_isr_work(struct work_struct *work) value.intval = charger->is_abnormal_pad; psy_do_property("wireless", set, POWER_SUPPLY_PROP_WIRELESS_ABNORMAL_PAD, value); - if (charger->req_tx_id && charger->tx_id_cnt < TX_ID_CHECK_CNT) - mfc_send_command(charger, MFC_AFC_CONF_5V_TX); + if (charger->req_tx_id && charger->afc_tx_done) { + if (delayed_work_pending(&charger->wpc_afc_vout_work)) { + __pm_relax(charger->wpc_afc_vout_lock); + cancel_delayed_work(&charger->wpc_afc_vout_work); + } + mfc_send_command(charger, MFC_AFC_CONF_5V); + charger->pdata->cable_type = value.intval = SEC_WIRELESS_PAD_WPC; + psy_do_property("wireless", set, + POWER_SUPPLY_PROP_ONLINE, value); + charger->pad_vout = PAD_VOUT_5V; + charger->afc_tx_done = false; + } __pm_relax(charger->wpc_rx_wake_lock); return; } @@ -4336,8 +4435,18 @@ static void mfc_wpc_isr_work(struct work_struct *work) value.intval = charger->is_abnormal_pad; psy_do_property("wireless", set, POWER_SUPPLY_PROP_WIRELESS_ABNORMAL_PAD, value); - if (charger->tx_id_cnt < TX_ID_CHECK_CNT) - mfc_send_command(charger, MFC_AFC_CONF_5V_TX); + if (charger->afc_tx_done) { + if (delayed_work_pending(&charger->wpc_afc_vout_work)) { + __pm_relax(charger->wpc_afc_vout_lock); + cancel_delayed_work(&charger->wpc_afc_vout_work); + } + mfc_send_command(charger, MFC_AFC_CONF_5V); + charger->pdata->cable_type = value.intval = SEC_WIRELESS_PAD_WPC; + psy_do_property("wireless", set, + POWER_SUPPLY_PROP_ONLINE, value); + charger->pad_vout = PAD_VOUT_5V; + charger->afc_tx_done = false; + } __pm_relax(charger->wpc_rx_wake_lock); return; } @@ -4349,6 +4458,7 @@ static void mfc_wpc_isr_work(struct work_struct *work) break; case TX_AFC_SET_10V: pr_info("%s data = 0x%x, might be 10V irq\n", __func__, val_data); + charger->afc_tx_done = true; if (!gpio_get_value(charger->pdata->wpc_det)) { pr_err("%s Wireless charging is paused during set high voltage.\n", __func__); __pm_relax(charger->wpc_rx_wake_lock); @@ -4419,6 +4529,9 @@ static void mfc_wpc_isr_work(struct work_struct *work) POWER_SUPPLY_PROP_ONLINE, value); charger->pad_vout = PAD_VOUT_10V; } + value.intval = charger->is_abnormal_pad; + psy_do_property("wireless", set, + POWER_SUPPLY_PROP_WIRELESS_ABNORMAL_PAD, value); #endif mfc_fod_set(charger, (charger->pdata->capacity > 85) ? FOD_STATE_CV : FOD_STATE_CC); @@ -4683,8 +4796,11 @@ static void mfc_wpc_tx_id_work(struct work_struct *work) container_of(work, struct mfc_charger_data, wpc_tx_id_work.work); pr_info("%s\n", __func__); - +#if defined(CONFIG_CHECK_UNAUTH_PAD) if (!charger->tx_id && (!charger->is_abnormal_pad || charger->tx_id_cnt < TX_ID_CHECK_CNT)) { +#else + if (!charger->tx_id && !charger->is_abnormal_pad) { +#endif if (charger->tx_id_cnt < 10) { mfc_send_command(charger, MFC_REQUEST_TX_ID); charger->req_tx_id = true; @@ -4712,8 +4828,15 @@ static void mfc_wpc_tx_id_work(struct work_struct *work) } else { pr_info("%s: TX ID (0x%x)\n", __func__, charger->tx_id); #if defined(CONFIG_CHECK_UNAUTH_PAD) - if (charger->is_abnormal_pad) + if (charger->is_abnormal_pad) { + union power_supply_propval value = {0, }; + mfc_send_command(charger, MFC_AFC_CONF_5V_TX); + + value.intval = charger->is_abnormal_pad; + psy_do_property("wireless", set, + POWER_SUPPLY_PROP_WIRELESS_ABNORMAL_PAD, value); + } #endif } @@ -5736,6 +5859,7 @@ static int mfc_charger_probe( charger->wpc_en_flag = (WPC_EN_SYSFS | WPC_EN_CHARGING | WPC_EN_CCIC); charger->req_tx_id = false; charger->is_abnormal_pad = false; + charger->afc_tx_done = false; #if defined(CONFIG_CHECK_UNAUTH_PAD) charger->req_afc_tx = false; charger->ping_freq = 0; diff --git a/drivers/battery_v2/mfc_s2miw04_charger.c b/drivers/battery_v2/mfc_s2miw04_charger.c index 24d7b84d5..0e707d325 100644 --- a/drivers/battery_v2/mfc_s2miw04_charger.c +++ b/drivers/battery_v2/mfc_s2miw04_charger.c @@ -58,6 +58,12 @@ extern unsigned int mfc_chip_id_now; #define EXTERN_MFC_FUNC #endif +struct sgf_data { + unsigned int size; + unsigned int type; + char *data; +}; + extern bool sleep_mode; extern unsigned int lpcharge; extern bool mfc_fw_update; @@ -1997,6 +2003,12 @@ static void mfc_wpc_afc_vout_work(struct work_struct *work) __pm_stay_awake(charger->wpc_vout_mode_lock); queue_delayed_work(charger->wqueue, &charger->wpc_vout_mode_work, 0); + + if ((charger->pdata->cable_type == SEC_WIRELESS_PAD_WPC_HV_20) && + (charger->tx_id == 0xEF)) { + pr_info("%s: set power = %d\n", __func__, charger->current_rx_power); + mfc_reset_rx_power(charger, charger->current_rx_power); + } } skip_set_afc_vout: @@ -2086,10 +2098,6 @@ static void mfc_wpc_fw_update_work(struct work_struct *work) charger->pdata->otp_firmware_result = MFC_FWUP_ERR_RUNNING; is_changed = true; - disable_irq(charger->pdata->irq_wpc_int); - disable_irq(charger->pdata->irq_wpc_det); - if (charger->pdata->irq_wpc_pdrc) - disable_irq(charger->pdata->irq_wpc_pdrc); dev_err(&charger->client->dev, "%s, request_firmware\n", __func__); ret = request_firmware(&charger->firm_data_bin, MFC_FLASH_FW_HEX_LSI_PATH, @@ -2099,6 +2107,11 @@ static void mfc_wpc_fw_update_work(struct work_struct *work) charger->pdata->otp_firmware_result = MFC_FWUP_ERR_REQUEST_FW_BIN; goto fw_err; } + disable_irq(charger->pdata->irq_wpc_int); + disable_irq(charger->pdata->irq_wpc_det); + if (charger->pdata->irq_wpc_pdrc) + disable_irq(charger->pdata->irq_wpc_pdrc); + __pm_stay_awake(charger->wpc_update_lock); #if defined(CONFIG_WIRELESS_IC_PARAM) mfc_set_wireless_param(MFC_CHIP_ID_S2MIW04, 0); @@ -2643,6 +2656,72 @@ static void mfc_tx_phm_work(struct work_struct *work) __pm_relax(charger->wpc_tx_phm_lock); } +static void mfc_set_tx_data(struct mfc_charger_data *charger, int idx) +{ + if (idx < 0) + idx = 0; + else if (idx >= charger->pdata->len_wc20_list) + idx = charger->pdata->len_wc20_list - 1; + + charger->vout_by_txid = charger->pdata->wireless20_vout_list[idx]; + charger->vrect_by_txid = charger->pdata->wireless20_vrect_list[idx]; + charger->max_power_by_txid = charger->pdata->wireless20_max_power_list[idx]; +} + +static int mfc_set_sgf_data(struct mfc_charger_data *charger, struct sgf_data *pdata) +{ + pr_info("%s: size = %d, type = %d\n", __func__, pdata->size, pdata->type); + + switch (pdata->type) { + case WPC_TX_COM_RX_POWER: + { + union power_supply_propval value = {0, }; + int tx_power = *(int *)pdata->data; + + switch (tx_power) { + case TX_RX_POWER_7_5W: + pr_info("%s : TX Power is 7.5W\n", __func__); + charger->current_rx_power = TX_RX_POWER_7_5W; + mfc_set_tx_data(charger, 0); + break; + case TX_RX_POWER_12W: + pr_info("%s : TX Power is 12W\n", __func__); + charger->current_rx_power = TX_RX_POWER_12W; + mfc_set_tx_data(charger, 1); + break; + case TX_RX_POWER_15W: + pr_info("%s : TX Power is 15W\n", __func__); + charger->current_rx_power = TX_RX_POWER_15W; + mfc_set_tx_data(charger, 2); + break; + case TX_RX_POWER_17_5W: + pr_info("%s : TX Power is 17.5W\n", __func__); + charger->current_rx_power = TX_RX_POWER_17_5W; + mfc_set_tx_data(charger, 3); + break; + case TX_RX_POWER_20W: + pr_info("%s : TX Power is 20W\n", __func__); + charger->current_rx_power = TX_RX_POWER_20W; + mfc_set_tx_data(charger, 4); + break; + default: + pr_info("%s : Undefined TX Power(%d)\n", __func__, tx_power); + return -EINVAL; + } + charger->adt_transfer_status = WIRELESS_AUTH_PASS; + charger->pdata->cable_type = value.intval = SEC_WIRELESS_PAD_WPC_HV_20; + pr_info("%s: change cable type to WPC HV 2.0\n", __func__); + + __pm_stay_awake(charger->wpc_afc_vout_lock); + queue_delayed_work(charger->wqueue, &charger->wpc_afc_vout_work, msecs_to_jiffies(0)); + } + break; + default: + return -EINVAL; + } + return 0; +} + #if defined(CONFIG_UPDATE_BATTERY_DATA) static int mfc_chg_parse_dt(struct device *dev, mfc_charger_platform_data_t *pdata); #endif @@ -3216,6 +3295,16 @@ static int mfc_s2miw04_chg_set_property(struct power_supply *psy, mfc_set_wireless_ic_param(charger, charger->chip_id_now, charger->pdata->otp_firmware_ver); break; #endif + case POWER_SUPPLY_EXT_PROP_WIRELESS_SGF: + { + struct sgf_data data; + + data.size = *(int *)val->strval; + data.type = *(int *)(val->strval + 4); + data.data = (char *)(val->strval + 8); + mfc_set_sgf_data(charger, &data); + } + break; default: return -ENODATA; } @@ -3489,6 +3578,7 @@ static void mfc_wpc_det_work(struct work_struct *work) charger->wc_ldo_status = MFC_LDO_ON; charger->tx_id_done = false; charger->req_tx_id = false; + charger->afc_tx_done = false; charger->is_abnormal_pad = false; #if defined(CONFIG_CHECK_UNAUTH_PAD) charger->req_afc_tx = false; @@ -3694,9 +3784,19 @@ static void mfc_wpc_isr_work(struct work_struct *work) value.intval = charger->is_abnormal_pad; psy_do_property("wireless", set, POWER_SUPPLY_PROP_WIRELESS_ABNORMAL_PAD, value); - if (charger->req_tx_id && charger->tx_id_cnt < TX_ID_CHECK_CNT) - mfc_send_command(charger, MFC_AFC_CONF_5V_TX); - __pm_relax(&charger->wpc_rx_wake_lock); + if (charger->req_tx_id && charger->afc_tx_done) { + if (delayed_work_pending(&charger->wpc_afc_vout_work)) { + __pm_relax(charger->wpc_afc_vout_lock); + cancel_delayed_work(&charger->wpc_afc_vout_work); + } + mfc_send_command(charger, MFC_AFC_CONF_5V); + charger->pdata->cable_type = value.intval = SEC_WIRELESS_PAD_WPC; + psy_do_property("wireless", set, + POWER_SUPPLY_PROP_ONLINE, value); + charger->pad_vout = PAD_VOUT_5V; + charger->afc_tx_done = false; + } + __pm_relax(charger->wpc_rx_wake_lock); return; } #else @@ -3707,8 +3807,18 @@ static void mfc_wpc_isr_work(struct work_struct *work) value.intval = charger->is_abnormal_pad; psy_do_property("wireless", set, POWER_SUPPLY_PROP_WIRELESS_ABNORMAL_PAD, value); - if (charger->tx_id_cnt < TX_ID_CHECK_CNT) - mfc_send_command(charger, MFC_AFC_CONF_5V_TX); + if (charger->afc_tx_done) { + if (delayed_work_pending(&charger->wpc_afc_vout_work)) { + __pm_relax(charger->wpc_afc_vout_lock); + cancel_delayed_work(&charger->wpc_afc_vout_work); + } + mfc_send_command(charger, MFC_AFC_CONF_5V); + charger->pdata->cable_type = value.intval = SEC_WIRELESS_PAD_WPC; + psy_do_property("wireless", set, + POWER_SUPPLY_PROP_ONLINE, value); + charger->pad_vout = PAD_VOUT_5V; + charger->afc_tx_done = false; + } __pm_relax(charger->wpc_rx_wake_lock); return; } @@ -3720,6 +3830,7 @@ static void mfc_wpc_isr_work(struct work_struct *work) break; case TX_AFC_SET_10V: pr_info("%s data = 0x%x, might be 10V irq\n", __func__, val_data); + charger->afc_tx_done = true; if (!gpio_get_value(charger->pdata->wpc_det)) { pr_err("%s Wireless charging is paused during set high voltage.\n", __func__); __pm_relax(charger->wpc_rx_wake_lock); @@ -4030,7 +4141,7 @@ static void mfc_wpc_tx_id_work(struct work_struct *work) pr_info("%s\n", __func__); - if (!charger->tx_id && (!charger->is_abnormal_pad || charger->tx_id_cnt < TX_ID_CHECK_CNT)) { + if (!charger->tx_id && !charger->is_abnormal_pad) { if (charger->tx_id_cnt < 10) { mfc_send_command(charger, MFC_REQUEST_TX_ID); charger->req_tx_id = true; @@ -4842,6 +4953,7 @@ static int mfc_s2miw04_charger_probe( charger->wpc_en_flag = (WPC_EN_SYSFS | WPC_EN_CHARGING | WPC_EN_CCIC); charger->req_tx_id = false; charger->is_abnormal_pad = false; + charger->afc_tx_done = false; #if defined(CONFIG_CHECK_UNAUTH_PAD) charger->req_afc_tx = false; charger->ping_freq = 0; diff --git a/drivers/battery_v2/pca9468_charger.c b/drivers/battery_v2/pca9468_charger.c index 0ed97417b..5d2eb8d4e 100644 --- a/drivers/battery_v2/pca9468_charger.c +++ b/drivers/battery_v2/pca9468_charger.c @@ -216,7 +216,7 @@ static void pca9468_monitor_work(struct pca9468_charger *pca9468) pca9468->adc_val[ADCCH_VBAT], pca9468->adc_val[ADCCH_VIN], pca9468->adc_val[ADCCH_IIN], pca9468->adc_val[ADCCH_DIETEMP], get_system_current(pca9468), pca9468->ta_objpos, - ta_vol, ta_cur); + ta_vol, ta_cur); } #endif @@ -270,7 +270,7 @@ static void pca9468_wdt_control_work(struct work_struct *work) struct device *dev = pca9468->dev; struct i2c_client *client = container_of(dev, struct i2c_client, dev); int vin, iin; - + pca9468_set_wdt_timer(pca9468, WDT_4SEC); /* this is for kick watchdog */ @@ -281,8 +281,8 @@ static void pca9468_wdt_control_work(struct work_struct *work) client->addr = 0xff; - pr_info("## %s: disable slave addr (vin:%dmV, iin:%dmA)\n", - __func__, vin/PCA9468_SEC_DENOM_U_M, iin/PCA9468_SEC_DENOM_U_M); + pr_info("## %s: disable client addr (vin:%dmV, iin:%dmA)\n", + __func__, vin / PCA9468_SEC_DENOM_U_M, iin / PCA9468_SEC_DENOM_U_M); } static void pca9468_set_done(struct pca9468_charger *pca9468, bool enable) @@ -311,18 +311,18 @@ static void pca9468_set_switching_charger(struct pca9468_charger *pca9468, bool pr_info("%s: error switching_charger, ret=%d\n", __func__, ret); } #else -static int pca9468_set_switching_charger( bool enable, - unsigned int input_current, - unsigned int charging_current, +static int pca9468_set_switching_charger(bool enable, + unsigned int input_current, + unsigned int charging_current, unsigned int vfloat) { int ret; struct power_supply *psy_swcharger; union power_supply_propval val; - pr_info("%s: enable=%d, iin=%d, ichg=%d, vfloat=%d\n", + pr_info("%s: enable=%d, iin=%d, ichg=%d, vfloat=%d\n", __func__, enable, input_current, charging_current, vfloat); - + /* Insert Code */ /* Get power supply name */ @@ -434,7 +434,7 @@ static int pca9468_send_pd_message(struct pca9468_charger *pca9468, unsigned int /* Vbus reset happened in the previous PD communication */ goto out; } - + #ifdef CONFIG_USBPD_PHY_QCOM /* check the phandle */ if (pca9468->pd == NULL) { @@ -448,19 +448,28 @@ static int pca9468_send_pd_message(struct pca9468_charger *pca9468, unsigned int } #endif - pr_info("%s: msg_type=%d, ta_cur=%d, ta_vol=%d, ta_objpos=%d\n", + /* Check whether requested TA voltage is in valid range or not */ + if (pca9468->ta_vol < PCA9468_TA_MIN_VOL) { + /* request TA voltage is less than minimum threshold */ + /* This is abnormal case, too low input voltage */ + /* Normally VIN_UVLO already happened */ + pr_err("%s: Abnormal low VIN, ta_vol=%d\n", __func__, pca9468->ta_vol); + goto out; + } + + pr_info("%s: msg_type=%d, ta_cur=%d, ta_vol=%d, ta_objpos=%d\n", __func__, msg_type, pca9468->ta_cur, pca9468->ta_vol, pca9468->ta_objpos); #if defined(CONFIG_BATTERY_SAMSUNG) pdo_idx = pca9468->ta_objpos; pps_vol = pca9468->ta_vol / PCA9468_SEC_DENOM_U_M; pps_cur = pca9468->ta_cur / PCA9468_SEC_DENOM_U_M; - pr_info("## %s: msg_type=%d, pdo_idx=%d, pps_vol=%dmV(max_vol=%dmV), pps_cur=%dmA(max_cur=%dmA)\n", + pr_info("## %s: msg_type=%d, pdo_idx=%d, pps_vol=%dmV(max_vol=%dmV), pps_cur=%dmA(max_cur=%dmA)\n", __func__, msg_type, pdo_idx, pps_vol, pca9468->pdo_max_voltage, pps_cur, pca9468->pdo_max_current); #endif - + switch (msg_type) { case PD_MSG_REQUEST_APDO: #ifdef CONFIG_USBPD_PHY_QCOM @@ -494,7 +503,7 @@ static int pca9468_send_pd_message(struct pca9468_charger *pca9468, unsigned int schedule_delayed_work(&pca9468->pps_work, msecs_to_jiffies(PCA9468_PPS_PERIODIC_T)); } break; - + case PD_MSG_REQUEST_FIXED_PDO: #ifdef CONFIG_USBPD_PHY_QCOM ret = usbpd_request_pdo(pca9468->pd, pca9468->ta_objpos, pca9468->ta_vol, pca9468->ta_cur); @@ -534,7 +543,7 @@ static int pca9468_send_pd_message(struct pca9468_charger *pca9468, unsigned int So, check the charging state again */ ret = -EINVAL; } - + pr_info("%s: ret=%d\n", __func__, ret); mutex_unlock(&pca9468->lock); return ret; @@ -576,7 +585,7 @@ static int pca9468_get_apdo_max_power(struct pca9468_charger *pca9468) pca9468->ta_max_cur = ta_max_cur_ma * PCA9468_SEC_DENOM_U_M; pca9468->ta_max_pwr = ta_max_pwr_mw; - pr_info("%s: ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d\n", + pr_info("%s: ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d\n", __func__, pca9468->ta_max_vol, pca9468->ta_max_cur, pca9468->ta_max_pwr); pca9468->pdo_index = pca9468->ta_objpos; @@ -669,7 +678,7 @@ static int pca9468_read_adc(struct pca9468_charger *pca9468, u8 adc_ch) conv_adc = 0; // If ADC raw value is 0, convert value will be minus value because of compensation gain, so in this case conv_adc is 0 break; - + case ADCCH_DIETEMP: // Read ADC value ret = pca9468_bulk_read_reg(pca9468, PCA9468_REG_STS_ADC_7, reg_data, 2); @@ -799,8 +808,8 @@ static int pca9468_softreset(struct pca9468_charger *pca9468) /* Do softreset */ - /* Set softreset regsiter */ - + /* Set softreset register */ + /* [0x30] = 0x5B */ val = 0x5B; ret = pca9468_write_reg(pca9468, PCA9468_REG_ADC_ACCESS, val); @@ -811,7 +820,7 @@ static int pca9468_softreset(struct pca9468_charger *pca9468) ret = pca9468_write_reg(pca9468, 0x4F, val); if (ret < 0) goto error; - /* [0x4B] = 0x40 */ + /* [0x4B] = 0x40 */ val = 0x40; ret = pca9468_write_reg(pca9468, 0x4B, val); if (ret < 0) @@ -820,7 +829,7 @@ static int pca9468_softreset(struct pca9468_charger *pca9468) /* Wait 5ms */ usleep_range(5000, 6000); - /* Reset PCA9468 and all regsiters values go to POR values */ + /* Reset PCA9468 and all registers values go to POR values */ // Check the current register after softreset */ /* Read all control registers for debugging */ pr_info("%s: After softreset\n", __func__); @@ -838,9 +847,9 @@ static int pca9468_softreset(struct pca9468_charger *pca9468) pr_info("%s: control reg[0x21]=0x%x,[0x22]=0x%x,[0x23]=0x%x,[0x24]=0x%x,[0x25]=0x%x\n", __func__, reg_val[0], reg_val[1], reg_val[2], reg_val[3], reg_val[4]); pr_info("%s: control reg[0x26]=0x%x,[0x27]=0x%x,[0x28]=0x%x,[0x29]=0x%x,[0x2A]=0x%x\n", - __func__, reg_val[5], reg_val[6], reg_val[7], reg_val[8], reg_val[9]); + __func__, reg_val[5], reg_val[6], reg_val[7], reg_val[8], reg_val[9]); - /* Set the initial regsiter value */ + /* Set the initial register value */ /* Set OV_DELTA to 30% */ #ifdef CONFIG_PCA9468_FACTORY_MODE val = OV_DELTA_40P << MASK2SHIFT(PCA9468_BIT_OV_DELTA); @@ -851,22 +860,22 @@ static int pca9468_softreset(struct pca9468_charger *pca9468) PCA9468_BIT_OV_DELTA, val); if (ret < 0) goto error; - + /* Set Reverse Current Detection and standby mode*/ val = PCA9468_BIT_REV_IIN_DET | PCA9468_EN_ACTIVE_L | PCA9468_STANDBY_FORCED; ret = pca9468_update_reg(pca9468, PCA9468_REG_START_CTRL, - (PCA9468_BIT_REV_IIN_DET | PCA9468_BIT_EN_CFG | PCA9468_BIT_STANDBY_EN), + (PCA9468_BIT_REV_IIN_DET | PCA9468_BIT_EN_CFG | PCA9468_BIT_STANDBY_EN), val); if (ret < 0) goto error; - + /* clear LIMIT_INCREMENT_EN */ val = 0; ret = pca9468_update_reg(pca9468, PCA9468_REG_IIN_CTRL, PCA9468_BIT_LIMIT_INCREMENT_EN, val); if (ret < 0) goto error; - + /* Set the ADC channel */ val = (PCA9468_BIT_CH7_EN | /* NTC voltage ADC */ PCA9468_BIT_CH6_EN | /* DIETEMP ADC */ @@ -874,7 +883,7 @@ static int pca9468_softreset(struct pca9468_charger *pca9468) PCA9468_BIT_CH3_EN | /* VBAT ADC */ PCA9468_BIT_CH2_EN | /* VIN ADC */ PCA9468_BIT_CH1_EN); /* VOUT ADC */ - + ret = pca9468_write_reg(pca9468, PCA9468_REG_ADC_CFG, val); if (ret < 0) goto error; @@ -957,10 +966,10 @@ static int pca9468_set_charging(struct pca9468_charger *pca9468, bool enable) ret = pca9468_write_reg(pca9468, PCA9468_REG_ADC_ACCESS, val); /* Enable NTC_PROTECTION_EN */ - ret = pca9468_update_reg(pca9468, PCA9468_REG_TEMP_CTRL, + ret = pca9468_update_reg(pca9468, PCA9468_REG_TEMP_CTRL, PCA9468_BIT_NTC_PROTECTION_EN, PCA9468_BIT_NTC_PROTECTION_EN); /* Enable TEMP_REG_EN */ - ret = pca9468_update_reg(pca9468, PCA9468_REG_TEMP_CTRL, + ret = pca9468_update_reg(pca9468, PCA9468_REG_TEMP_CTRL, PCA9468_BIT_TEMP_REG_EN, PCA9468_BIT_TEMP_REG_EN); } else { /* Wait 5ms to keep the shutdown sequence */ @@ -1030,9 +1039,9 @@ static int pca9468_stop_charging(struct pca9468_charger *pca9468) pca9468_set_wdt_enable(pca9468, WDT_DISABLE); #endif } - + pr_info("%s: END, ret=%d\n", __func__, ret); - + return ret; } @@ -1041,15 +1050,27 @@ static int pca9468_stop_charging(struct pca9468_charger *pca9468) static int pca9468_set_ta_current_comp(struct pca9468_charger *pca9468) { int iin; - + /* Read IIN ADC */ iin = pca9468_read_adc(pca9468, ADCCH_IIN); /* Compare IIN ADC with target input current */ if (iin > (pca9468->iin_cc + PCA9468_IIN_CC_COMP_OFFSET)) { /* TA current is higher than the target input current */ - /* Decrease TA current (50mA) */ - pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + /* Check TA current and compare it with IIN_CC */ + if (pca9468->ta_cur <= pca9468->iin_cc - PCA9468_TA_CUR_LOW_OFFSET) { + /* IIN_ADC is stiil in invalid range even though TA current is less than IIN_CC - 200mA */ + /* TA has abnormal behavior */ + /* Decrease TA voltage (20mV) */ + pca9468->ta_vol = pca9468->ta_vol - PD_MSG_TA_VOL_STEP; + pr_info("%s: Comp. Cont4: ta_vol=%d\n", __func__, pca9468->ta_vol); + } else { + /* TA current is higher than IIN_CC - 200mA */ + /* Decrease TA current first to reduce input current */ + /* Decrease TA current (50mA) */ + pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + pr_info("%s: Comp. Cont5: ta_cur=%d\n", __func__, pca9468->ta_cur); + } /* Send PD Message */ mutex_lock(&pca9468->lock); @@ -1080,7 +1101,7 @@ static int pca9468_set_ta_current_comp(struct pca9468_charger *pca9468) } /* Set TA increment flag */ pca9468->prev_inc = INC_TA_VOL; - } else { + } else { /* TA current is lower than the target input current */ /* Check the previous TA increment */ if (pca9468->prev_inc == INC_TA_VOL) { @@ -1106,12 +1127,12 @@ static int pca9468_set_ta_current_comp(struct pca9468_charger *pca9468) } /* Set TA increment flag */ pca9468->prev_inc = INC_TA_CUR; - } else { + } else { /* The previous increment is TA current, but input current does not increase */ /* Try to increase TA voltage */ /* Compare TA max voltage */ if (pca9468->ta_vol == pca9468->ta_max_vol) { - + /* TA voltage is already the maximum voltage */ /* Set timer */ mutex_lock(&pca9468->lock); @@ -1143,10 +1164,10 @@ static int pca9468_set_ta_current_comp(struct pca9468_charger *pca9468) mutex_unlock(&pca9468->lock); } } - + /* Save previous iin adc */ pca9468->prev_iin = iin; - + schedule_delayed_work(&pca9468->timer_work, msecs_to_jiffies(pca9468->timer_period)); return 0; @@ -1158,15 +1179,27 @@ static int pca9468_set_ta_current_comp2(struct pca9468_charger *pca9468) int iin; unsigned int val; unsigned int iin_apdo; - + /* Read IIN ADC */ iin = pca9468_read_adc(pca9468, ADCCH_IIN); /* Compare IIN ADC with target input current */ if (iin > (pca9468->pdata->iin_cfg + PCA9468_IIN_CC_UPPER_OFFSET)) { /* TA current is higher than the target input current */ - /* Decrease TA current (50mA) */ - pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + /* Check TA current and compare it with IIN_CC */ + if (pca9468->ta_cur <= pca9468->iin_cc - PCA9468_TA_CUR_LOW_OFFSET) { + /* IIN_ADC is stiil in invalid range even though TA current is less than IIN_CC - 200mA */ + /* TA has abnormal behavior */ + /* Decrease TA voltage (20mV) */ + pca9468->ta_vol = pca9468->ta_vol - PD_MSG_TA_VOL_STEP; + pr_info("%s: Comp. Cont4: ta_vol=%d\n", __func__, pca9468->ta_vol); + } else { + /* TA current is higher than IIN_CC - 200mA */ + /* Decrease TA current first to reduce input current */ + /* Decrease TA current (50mA) */ + pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + pr_info("%s: Comp. Cont5: ta_cur=%d\n", __func__, pca9468->ta_cur); + } /* Send PD Message */ mutex_lock(&pca9468->lock); @@ -1222,14 +1255,14 @@ static int pca9468_set_ta_current_comp2(struct pca9468_charger *pca9468) mutex_lock(&pca9468->lock); pca9468->timer_id = TIMER_CHECK_CCMODE; pca9468->timer_period = PCA9468_CCMODE_CHECK2_T; - mutex_unlock(&pca9468->lock); + mutex_unlock(&pca9468->lock); } } else { /* Increase TA voltage(40mV) */ pca9468->ta_vol = pca9468->ta_vol + PD_MSG_TA_VOL_STEP*2; if (pca9468->ta_vol > pca9468->ta_max_vol) pca9468->ta_vol = pca9468->ta_max_vol; - + pr_info("%s: Comp. Cont2: ta_vol=%d\n", __func__, pca9468->ta_vol); /* Send PD Message */ mutex_lock(&pca9468->lock); @@ -1246,10 +1279,10 @@ static int pca9468_set_ta_current_comp2(struct pca9468_charger *pca9468) pca9468->timer_period = PCA9468_CCMODE_CHECK2_T; mutex_unlock(&pca9468->lock); } - + /* Save previous iin adc */ pca9468->prev_iin = iin; - + schedule_delayed_work(&pca9468->timer_work, msecs_to_jiffies(pca9468->timer_period)); return 0; @@ -1261,15 +1294,27 @@ static int pca9468_set_ta_current_comp3(struct pca9468_charger *pca9468) int iin; unsigned int val; unsigned int iin_apdo; - + /* Read IIN ADC */ iin = pca9468_read_adc(pca9468, ADCCH_IIN); /* Compare IIN ADC with target input current */ if (iin > (pca9468->pdata->iin_cfg + PCA9468_IIN_CC_COMP3_UPPER_OFFSET)) { /* TA current is higher than the target input current */ - /* Decrease TA current (50mA) */ - pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + /* Check TA current and compare it with IIN_CC */ + if (pca9468->ta_cur <= pca9468->iin_cc - PCA9468_TA_CUR_LOW_OFFSET) { + /* IIN_ADC is stiil in invalid range even though TA current is less than IIN_CC - 200mA */ + /* TA has abnormal behavior */ + /* Decrease TA voltage (20mV) */ + pca9468->ta_vol = pca9468->ta_vol - PD_MSG_TA_VOL_STEP; + pr_info("%s: Comp. Cont4: ta_vol=%d\n", __func__, pca9468->ta_vol); + } else { + /* TA current is higher than IIN_CC - 200mA */ + /* Decrease TA current first to reduce input current */ + /* Decrease TA current (50mA) */ + pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + pr_info("%s: Comp. Cont5: ta_cur=%d\n", __func__, pca9468->ta_cur); + } /* Send PD Message */ mutex_lock(&pca9468->lock); @@ -1300,7 +1345,7 @@ static int pca9468_set_ta_current_comp3(struct pca9468_charger *pca9468) pca9468->ta_vol = pca9468->ta_vol + PD_MSG_TA_VOL_STEP*2; if (pca9468->ta_vol > pca9468->ta_max_vol) pca9468->ta_vol = pca9468->ta_max_vol; - + pr_info("%s: Comp. Cont1: ta_vol=%d\n", __func__, pca9468->ta_vol); /* Send PD Message */ mutex_lock(&pca9468->lock); @@ -1325,14 +1370,14 @@ static int pca9468_set_ta_current_comp3(struct pca9468_charger *pca9468) mutex_lock(&pca9468->lock); pca9468->timer_id = TIMER_CHECK_CCMODE; pca9468->timer_period = PCA9468_CCMODE_CHECK2_T; - mutex_unlock(&pca9468->lock); + mutex_unlock(&pca9468->lock); } } else { /* Increase TA voltage(40mV) */ pca9468->ta_vol = pca9468->ta_vol + PD_MSG_TA_VOL_STEP*2; if (pca9468->ta_vol > pca9468->ta_max_vol) pca9468->ta_vol = pca9468->ta_max_vol; - + pr_info("%s: Comp. Cont2: ta_vol=%d\n", __func__, pca9468->ta_vol); /* Send PD Message */ mutex_lock(&pca9468->lock); @@ -1349,10 +1394,10 @@ static int pca9468_set_ta_current_comp3(struct pca9468_charger *pca9468) pca9468->timer_period = PCA9468_CCMODE_CHECK2_T; mutex_unlock(&pca9468->lock); } - + /* Save previous iin adc */ pca9468->prev_iin = iin; - + schedule_delayed_work(&pca9468->timer_work, msecs_to_jiffies(pca9468->timer_period)); return 0; @@ -1456,12 +1501,12 @@ static int pca9468_adjust_ta_current (struct pca9468_charger *pca9468) /* finish sending PD message */ /* Recover IIN_CC to the original value(new_iin) */ pca9468->iin_cc = pca9468->new_iin; - + /* Clear req_new_iin */ mutex_lock(&pca9468->lock); pca9468->req_new_iin = false; mutex_unlock(&pca9468->lock); - + /* Go to return state */ #if defined(CONFIG_BATTERY_SAMSUNG) pca9468_set_charging_state(pca9468, pca9468->ret_state); @@ -1499,7 +1544,7 @@ static int pca9468_adjust_ta_current (struct pca9468_charger *pca9468) /* Check the input current compensation type */ if (pca9468->ta_max_cur*pca9468->ta_mode < pca9468->pdata->iin_cfg) { /* TA maximum current is less than the current that the battery driver required - Power Limit mode 1 */ - /* We have the upper compensation limitation when IIN_LOOP happens by IIN_CFG or + /* We have the upper compensation limitation when IIN_LOOP happens by IIN_CFG or IIN_ADC is higher than IIN_CFG + 150mA */ pca9468->comp_type = IIN_COMP2; } else { @@ -1535,7 +1580,7 @@ static int pca9468_adjust_ta_current (struct pca9468_charger *pca9468) } } pr_info("%s: New IIN, current compensation type=%d\n", __func__, pca9468->comp_type); - + /* Set TA voltage to MAX[8000mV, (2*VBAT_ADC + 500 mV)] */ pca9468->ta_vol = max(PCA9468_TA_MIN_VOL_PRESET*pca9468->ta_mode, (2*vbat*pca9468->ta_mode + PCA9468_TA_VOL_PRE_OFFSET)); val = pca9468->ta_vol/PD_MSG_TA_VOL_STEP; /* PPS voltage resolution is 20mV */ @@ -1547,7 +1592,7 @@ static int pca9468_adjust_ta_current (struct pca9468_charger *pca9468) /* Recover IIN_CC to the original value(iin_cfg) */ pca9468->iin_cc = pca9468->pdata->iin_cfg; - pr_info("%s: New IIN, ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d, iin_cc=%d, ta_mode=%d\n", + pr_info("%s: New IIN, ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d, iin_cc=%d, ta_mode=%d\n", __func__, pca9468->ta_max_vol, pca9468->ta_max_cur, pca9468->ta_max_pwr, pca9468->iin_cc, pca9468->ta_mode); /* Clear previous IIN ADC */ @@ -1618,7 +1663,7 @@ static int pca9468_adjust_ta_voltage(struct pca9468_charger *pca9468) #else pca9468->charging_state = DC_STATE_ADJUST_TAVOL; #endif - + /* Read IIN ADC */ iin = pca9468_read_adc(pca9468, ADCCH_IIN); @@ -1627,7 +1672,7 @@ static int pca9468_adjust_ta_voltage(struct pca9468_charger *pca9468) /* TA current is higher than the target input current */ /* Decrease TA voltage (20mV) */ pca9468->ta_vol = pca9468->ta_vol - PD_MSG_TA_VOL_STEP; - + /* Send PD Message */ mutex_lock(&pca9468->lock); pca9468->timer_id = TIMER_PDMSG_SEND; @@ -1658,7 +1703,7 @@ static int pca9468_adjust_ta_voltage(struct pca9468_charger *pca9468) } else { /* Increase TA voltage (20mV) */ pca9468->ta_vol = pca9468->ta_vol + PD_MSG_TA_VOL_STEP; - + /* Send PD Message */ mutex_lock(&pca9468->lock); pca9468->timer_id = TIMER_PDMSG_SEND; @@ -1749,7 +1794,7 @@ static int pca9468_set_new_iin(struct pca9468_charger *pca9468) if (ret < 0) goto error; - /* Clear req_new_iin */ + /* Clear req_new_iin */ mutex_lock(&pca9468->lock); pca9468->req_new_iin = false; mutex_unlock(&pca9468->lock); @@ -1785,7 +1830,7 @@ static int pca9468_set_new_vfloat(struct pca9468_charger *pca9468) int ret = 0; int vbat; unsigned int val; - + /* Check the charging state */ if (pca9468->charging_state == DC_STATE_NO_CHARGING) { /* Apply new vfloat when the direct charging is started */ @@ -1811,7 +1856,7 @@ static int pca9468_set_new_vfloat(struct pca9468_charger *pca9468) if (pca9468->new_vfloat > vbat) { /* cancel delayed_work */ cancel_delayed_work(&pca9468->timer_work); - + /* Set VFLOAT to new vfloat */ pca9468->pdata->v_float = pca9468->new_vfloat; ret = pca9468_set_vfloat(pca9468, pca9468->pdata->v_float); @@ -1821,14 +1866,14 @@ static int pca9468_set_new_vfloat(struct pca9468_charger *pca9468) /* Check the input current compensation type */ if (pca9468->ta_max_cur*pca9468->ta_mode < pca9468->iin_cc) { /* TA maximum current is less than the current that the battery driver required - Power Limit mode 1 */ - /* We have the upper compensation limitation when IIN_LOOP happens by IIN_CFG or + /* We have the upper compensation limitation when IIN_LOOP happens by IIN_CFG or IIN_ADC is higher than IIN_CFG + 150mA */ pca9468->comp_type = IIN_COMP2; } else { /* Check the type later after calculating TA maximum voltage */ pca9468->comp_type = IIN_NO_COMP; } - + /* Set IIN_CFG to the current IIN_CC */ pca9468->pdata->iin_cfg = pca9468->iin_cc; /* save the current iin_cc in iin_cfg */ pca9468->pdata->iin_cfg = MIN(pca9468->pdata->iin_cfg, pca9468->ta_max_cur*pca9468->ta_mode); @@ -1836,8 +1881,8 @@ static int pca9468_set_new_vfloat(struct pca9468_charger *pca9468) if (ret < 0) goto error; pca9468->iin_cc = pca9468->pdata->iin_cfg; - - /* Clear req_new_vfloat */ + + /* Clear req_new_vfloat */ mutex_lock(&pca9468->lock); pca9468->req_new_vfloat = false; mutex_unlock(&pca9468->lock); @@ -1878,7 +1923,7 @@ static int pca9468_set_new_vfloat(struct pca9468_charger *pca9468) /* Recover IIN_CC to the original value(iin_cfg) */ pca9468->iin_cc = pca9468->pdata->iin_cfg; - pr_info("%s: New VFLOAT, ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d, iin_cc=%d, ta_mode=%d\n", + pr_info("%s: New VFLOAT, ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d, iin_cc=%d, ta_mode=%d\n", __func__, pca9468->ta_max_vol, pca9468->ta_max_cur, pca9468->ta_max_pwr, pca9468->iin_cc, pca9468->ta_mode); /* Clear previous IIN ADC */ @@ -1912,14 +1957,14 @@ static int pca9468_set_new_vfloat(struct pca9468_charger *pca9468) if (pca9468->new_vfloat > vbat) { /* cancel delayed_work */ cancel_delayed_work(&pca9468->timer_work); - + /* Set VFLOAT to new vfloat */ pca9468->pdata->v_float = pca9468->new_vfloat; ret = pca9468_set_vfloat(pca9468, pca9468->pdata->v_float); if (ret < 0) goto error; - /* Clear req_new_vfloat */ + /* Clear req_new_vfloat */ mutex_lock(&pca9468->lock); pca9468->req_new_vfloat = false; mutex_unlock(&pca9468->lock); @@ -1965,7 +2010,7 @@ static int pca9468_check_error(struct pca9468_charger *pca9468) /* Read VBAT_ADC */ vbatt = pca9468_read_adc(pca9468, ADCCH_VBAT); - + /* Check Active status */ if (reg_val & PCA9468_BIT_ACTIVE_STATE_STS) { /* PCA9468 is active state */ @@ -1975,7 +2020,7 @@ static int pca9468_check_error(struct pca9468_charger *pca9468) /* Check temperature regulation loop */ /* Read INT1_STS register */ ret = pca9468_read_reg(pca9468, PCA9468_REG_INT1_STS, ®_val); - if (reg_val & PCA9468_BIT_TEMP_REG_STS) { + if (reg_val & PCA9468_BIT_TEMP_REG_STS) { /* Over temperature protection */ pr_err("%s: Device is in temperature regulation", __func__); ret = -EINVAL; @@ -2250,7 +2295,7 @@ static int pca9468_check_cvmode_status(struct pca9468_charger *pca9468) ret = iin; goto error; } - + /* Check IIN < Input Topoff current */ if (pca9468->pdata->v_float == pca9468->pdata->v_float_max && iin < pca9468->pdata->iin_topoff) { @@ -2258,7 +2303,7 @@ static int pca9468_check_cvmode_status(struct pca9468_charger *pca9468) ret = CVMODE_CHG_DONE; } else { /* It doesn't reach top-off condition yet */ - + /* Read STS_A */ ret = pca9468_read_reg(pca9468, PCA9468_REG_STS_A, &val); if (ret < 0) @@ -2278,7 +2323,7 @@ static int pca9468_check_cvmode_status(struct pca9468_charger *pca9468) } } } - + error: pr_info("%s: CVMODE Status=%d\n", __func__, ret); return ret; @@ -2310,8 +2355,8 @@ static int pca9468_charge_adjust_ccmode(struct pca9468_charger *pca9468) ret = ccmode; goto error; } - - switch(ccmode) { + + switch (ccmode) { case CCMODE_IIN_LOOP: case CCMODE_CHG_LOOP: /* Check TA current */ @@ -2345,7 +2390,7 @@ static int pca9468_charge_adjust_ccmode(struct pca9468_charger *pca9468) mutex_unlock(&pca9468->lock); schedule_delayed_work(&pca9468->timer_work, msecs_to_jiffies(pca9468->timer_period)); break; - + case CCMODE_VFLT_LOOP: /* Save TA target and voltage*/ pca9468->ta_target_vol = pca9468->ta_vol; @@ -2393,7 +2438,7 @@ static int pca9468_charge_adjust_ccmode(struct pca9468_charger *pca9468) /* Check TA voltage */ if (pca9468->ta_vol == pca9468->ta_max_vol) { /* TA voltage is already max value */ - pr_info("%s: CC adjust End: MAX value, ta_vol=%d, ta_cur=%d\n", + pr_info("%s: CC adjust End: MAX value, ta_vol=%d, ta_cur=%d\n", __func__, pca9468->ta_vol, pca9468->ta_cur); /* Clear TA increment flag */ pca9468->prev_inc = INC_NONE; @@ -2455,7 +2500,7 @@ static int pca9468_charge_adjust_ccmode(struct pca9468_charger *pca9468) mutex_unlock(&pca9468->lock); } else { /* The previous increment is TA voltage, but input current does not increase */ - /* Try to increase TA current */ + /* Try to increase TA current */ /* Check APDO max current */ if (pca9468->ta_cur == pca9468->ta_max_cur) { /* TA current is maximum current */ @@ -2515,7 +2560,7 @@ static int pca9468_charge_adjust_ccmode(struct pca9468_charger *pca9468) default: break; } - + error: pr_info("%s: End, ret=%d\n", __func__, ret); return ret; @@ -2526,7 +2571,7 @@ static int pca9468_charge_adjust_ccmode(struct pca9468_charger *pca9468) static int pca9468_charge_start_ccmode(struct pca9468_charger *pca9468) { int ret = 0; - + pr_info("%s: ======START=======\n", __func__); #if defined(CONFIG_BATTERY_SAMSUNG) @@ -2564,7 +2609,7 @@ static int pca9468_charge_ccmode(struct pca9468_charger *pca9468) int ret = 0; int ccmode; int vin_vol, iin; - + pr_info("%s: ======START=======\n", __func__); #if defined(CONFIG_BATTERY_SAMSUNG) @@ -2596,8 +2641,8 @@ static int pca9468_charge_ccmode(struct pca9468_charger *pca9468) ret = ccmode; goto error; } - - switch(ccmode) { + + switch (ccmode) { case CCMODE_LOOP_INACTIVE: /* Set input current compensation */ /* Check the current TA current with TA_MIN_CUR */ @@ -2644,9 +2689,21 @@ static int pca9468_charge_ccmode(struct pca9468_charger *pca9468) pca9468->ta_vol = pca9468->ta_vol - PD_MSG_TA_VOL_STEP; pr_info("%s: CC LOOP:iin=%d, next_ta_vol=%d\n", __func__, iin, pca9468->ta_vol); } else { - /* Decrease TA current (50mA) */ - pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; - pr_info("%s: CC LOOP:iin=%d, next_ta_cur=%d\n", __func__, iin, pca9468->ta_cur); + /* Check TA current and compare it with IIN_CC */ + if (pca9468->ta_cur <= pca9468->iin_cc - PCA9468_TA_CUR_LOW_OFFSET) { + /* IIN_LOOP still happens even though TA current is less than IIN_CC - 200mA */ + /* TA has abnormal behavior */ + /* Decrease TA voltage (20mV) */ + pca9468->ta_vol = pca9468->ta_vol - PD_MSG_TA_VOL_STEP; + pr_info("%s: CC LOOP:iin=%d, ta_cur=%d, next_ta_vol=%d\n", + __func__, iin, pca9468->ta_cur, pca9468->ta_vol); + } else { + /* TA current is higher than IIN_CC - 200mA */ + /* Decrease TA current first to reduce input current */ + /* Decrease TA current (50mA) */ + pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + pr_info("%s: CC LOOP:iin=%d, next_ta_cur=%d\n", __func__, iin, pca9468->ta_cur); + } } /* Send PD Message */ mutex_lock(&pca9468->lock); @@ -2702,8 +2759,8 @@ static int pca9468_charge_start_cvmode(struct pca9468_charger *pca9468) ret = cvmode; goto error; } - - switch(cvmode) { + + switch (cvmode) { case CVMODE_CHG_LOOP: case CVMODE_IIN_LOOP: /* Check TA current */ @@ -2744,10 +2801,10 @@ static int pca9468_charge_start_cvmode(struct pca9468_charger *pca9468) /* Set TA target voltage to TA voltage */ pca9468->ta_target_vol = pca9468->ta_vol; - + /* Need to implement notification to other driver */ /* To do here */ - + /* Go to CV mode */ mutex_lock(&pca9468->lock); pca9468->timer_id = TIMER_CHECK_CVMODE; @@ -2767,11 +2824,11 @@ static int pca9468_charge_start_cvmode(struct pca9468_charger *pca9468) mutex_unlock(&pca9468->lock); schedule_delayed_work(&pca9468->timer_work, msecs_to_jiffies(pca9468->timer_period)); break; - + default: break; } - + error: pr_info("%s: End, ret=%d\n", __func__, ret); return ret; @@ -2812,7 +2869,7 @@ static int pca9468_charge_cvmode(struct pca9468_charger *pca9468) pca9468->req_new_iin = false; mutex_unlock(&pca9468->lock); ret = pca9468_set_new_iin(pca9468); - } else { + } else { cvmode = pca9468_check_cvmode_status(pca9468); #if defined(CONFIG_BATTERY_SAMSUNG) && defined(CONFIG_DUAL_BATTERY_CELL_SENSING) psy_do_property("battery", get, @@ -2826,14 +2883,14 @@ static int pca9468_charge_cvmode(struct pca9468_charger *pca9468) ret = cvmode; goto error; } - - switch(cvmode) { + + switch (cvmode) { case CVMODE_CHG_DONE: /* Charging Done */ /* Keep CV mode until battery driver send stop charging */ - + /* Need to implement notification function */ - /* To do here */ + /* To do here */ pr_info("%s: CV Done\n", __func__); #if defined(CONFIG_BATTERY_SAMSUNG) @@ -2841,7 +2898,7 @@ static int pca9468_charge_cvmode(struct pca9468_charger *pca9468) #endif /* Check the charging status after notification function */ - if(pca9468->charging_state != DC_STATE_NO_CHARGING) { + if (pca9468->charging_state != DC_STATE_NO_CHARGING) { /* Notification function does not stop timer work yet */ /* Keep the charging done state */ /* Set timer */ @@ -2868,9 +2925,21 @@ static int pca9468_charge_cvmode(struct pca9468_charger *pca9468) /* Check TA current */ if (pca9468->ta_cur > PCA9468_TA_MIN_CUR) { /* TA current is higher than (1.0A*TA_mode) */ - /* Decrease TA current (50mA) */ - pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; - pr_info("%s: CV LOOP, Cont: ta_cur=%d\n", __func__, pca9468->ta_cur); + + /* Check TA current and compare it with IIN_CC */ + if (pca9468->ta_cur <= pca9468->iin_cc - PCA9468_TA_CUR_LOW_OFFSET) { + /* IIN_LOOP still happens even though TA current is less than IIN_CC - 200mA */ + /* TA has abnormal behavior */ + /* Decrease TA voltage (20mV) */ + pca9468->ta_vol = pca9468->ta_vol - PD_MSG_TA_VOL_STEP; + pr_info("%s: CV LOOP, Cont1: ta_vol=%d\n", __func__, pca9468->ta_vol); + } else { + /* TA current is higher than IIN_CC - 200mA */ + /* Decrease TA current first to reduce input current */ + /* Decrease TA current (50mA) */ + pca9468->ta_cur = pca9468->ta_cur - PD_MSG_TA_CUR_STEP; + pr_info("%s: CV LOOP, Cont2: ta_cur=%d\n", __func__, pca9468->ta_cur); + } } else { /* TA current is less than (1.0A*TA_mode) */ /* Decrease TA Voltage (20mV) */ @@ -2892,7 +2961,7 @@ static int pca9468_charge_cvmode(struct pca9468_charger *pca9468) /* Set TA target voltage to TA voltage */ pca9468->ta_target_vol = pca9468->ta_vol; - + /* Send PD Message */ mutex_lock(&pca9468->lock); pca9468->timer_id = TIMER_PDMSG_SEND; @@ -2967,25 +3036,25 @@ static int pca9468_charge_wc_cvmode(struct pca9468_charger *pca9468) pca9468->req_new_iin = false; mutex_unlock(&pca9468->lock); ret = pca9468_set_new_iin(pca9468); - } else { + } else { cvmode = pca9468_check_cvmode_status(pca9468); if (cvmode < 0) { ret = cvmode; goto error; } - - switch(cvmode) { + + switch (cvmode) { case CVMODE_CHG_DONE: /* Charging Done */ /* Keep WC CV mode until battery driver send stop charging */ - + /* Need to implement notification function */ - /* To do here */ + /* To do here */ pr_info("%s: WC CV Done\n", __func__); /* Check the charging status after notification function */ - if(pca9468->charging_state != DC_STATE_NO_CHARGING) { + if (pca9468->charging_state != DC_STATE_NO_CHARGING) { /* Notification function does not stop timer work yet */ /* Keep the charging done state */ /* Set timer */ @@ -3091,7 +3160,7 @@ static int pca9468_preset_dcmode(struct pca9468_charger *pca9468) ret = vbat; goto error; } - + /* Compare VBAT with VBAT ADC */ if (vbat > pca9468->pdata->v_float) { /* Invalid battery voltage to start direct charging */ @@ -3119,7 +3188,7 @@ static int pca9468_preset_dcmode(struct pca9468_charger *pca9468) goto error; } - /* Set the TA max current to input request current(iin_cfg) initially + /* Set the TA max current to input request current(iin_cfg) initially to get TA maximum current from PD IC */ pca9468->ta_max_cur = pca9468->pdata->iin_cfg; /* Set the TA max voltage to enough high value to find TA maximum voltage initially */ @@ -3156,20 +3225,20 @@ static int pca9468_preset_dcmode(struct pca9468_charger *pca9468) /* TA has the desired APDO */ pca9468->ta_mode = pca9468->pdata->ta_mode; } - + ta_mode = pca9468->ta_mode; /* Check the input current compensation type */ if (pca9468->ta_max_cur*ta_mode < pca9468->pdata->iin_cfg) { /* TA maximum current is less than the current that the battery driver required - Power Limit mode 1 */ - /* We have the upper compensation limitation when IIN_LOOP happens by IIN_CFG or + /* We have the upper compensation limitation when IIN_LOOP happens by IIN_CFG or IIN_ADC is higher than IIN_CFG + 150mA */ pca9468->comp_type = IIN_COMP2; } else { /* Check the type later after calculating TA maximum voltage */ pca9468->comp_type = IIN_NO_COMP; } - + /* Calculate new TA maximum current and voltage that used in the direct charging */ /* Set IIN_CC to MIN[IIN, (TA_MAX_CUR by APDO)*TA_mode]*/ pca9468->iin_cc = MIN(pca9468->pdata->iin_cfg, (pca9468->ta_max_cur*ta_mode)); @@ -3199,7 +3268,7 @@ static int pca9468_preset_dcmode(struct pca9468_charger *pca9468) } pr_info("%s: Preset DC, current compensation type=%d\n", __func__, pca9468->comp_type); - + /* Set TA voltage to MAX[8000mV*TA_mode, (2*VBAT_ADC*TA_mode + 500 mV)] */ pca9468->ta_vol = max(PCA9468_TA_MIN_VOL_PRESET*ta_mode, (2*vbat*ta_mode + PCA9468_TA_VOL_PRE_OFFSET)); val = pca9468->ta_vol/PD_MSG_TA_VOL_STEP; /* PPS voltage resolution is 20mV */ @@ -3211,10 +3280,10 @@ static int pca9468_preset_dcmode(struct pca9468_charger *pca9468) /* Recover IIN_CC to the original value(iin_cfg) */ pca9468->iin_cc = pca9468->pdata->iin_cfg; - pr_info("%s: Preset DC, ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d, iin_cc=%d, ta_mode=%d\n", + pr_info("%s: Preset DC, ta_max_vol=%d, ta_max_cur=%d, ta_max_pwr=%d, iin_cc=%d, ta_mode=%d\n", __func__, pca9468->ta_max_vol, pca9468->ta_max_cur, pca9468->ta_max_pwr, pca9468->iin_cc, pca9468->ta_mode); - pr_info("%s: Preset DC, ta_vol=%d, ta_cur=%d\n", + pr_info("%s: Preset DC, ta_vol=%d, ta_cur=%d\n", __func__, pca9468->ta_vol, pca9468->ta_cur); /* Send PD Message */ @@ -3234,7 +3303,7 @@ static int pca9468_preset_dcmode(struct pca9468_charger *pca9468) static int pca9468_preset_config(struct pca9468_charger *pca9468) { int ret = 0; - + pr_info("%s: ======START=======\n", __func__); #if defined(CONFIG_BATTERY_SAMSUNG) @@ -3258,7 +3327,7 @@ static int pca9468_preset_config(struct pca9468_charger *pca9468) if (ret < 0) goto error; - /* Enable PCA9468 */ + /* Enable PCA9468 */ ret = pca9468_set_charging(pca9468, true); if (ret < 0) goto error; @@ -3276,10 +3345,10 @@ static int pca9468_preset_config(struct pca9468_charger *pca9468) mutex_unlock(&pca9468->lock); schedule_delayed_work(&pca9468->timer_work, msecs_to_jiffies(pca9468->timer_period)); ret = 0; - + error: pr_info("%s: End, ret=%d\n", __func__, ret); - return ret; + return ret; } /* Check the charging status before entering the adjust cc mode */ @@ -3342,7 +3411,7 @@ static int pca9468_check_active_state(struct pca9468_charger *pca9468) /* Implement error handler function if it is needed */ /* Stop charging in timer_work */ } - + return ret; } @@ -3405,10 +3474,10 @@ static int pca9468_start_direct_charging(struct pca9468_charger *pca9468) /* Set NTC voltage threshold */ val = pca9468->pdata->ntc_th / PCA9468_NTC_TH_STEP; - ret = pca9468_write_reg(pca9468, PCA9468_REG_NTC_TH_1, (val & 0xFF)); + ret = pca9468_write_reg(pca9468, PCA9468_REG_NTC_TH_1, (val & 0xFF)); if (ret < 0) return ret; - ret = pca9468_update_reg(pca9468, PCA9468_REG_NTC_TH_2, + ret = pca9468_update_reg(pca9468, PCA9468_REG_NTC_TH_2, PCA9468_BIT_NTC_THRESHOLD9_8, (val >> 8)); if (ret < 0) return ret; @@ -3585,10 +3654,10 @@ static void pca9468_timer_work(struct work_struct *work) #ifdef CONFIG_RTC_HCTOSYS get_current_time(&pca9468->last_update_time); - pr_info("%s: timer id=%d, charging_state=%d, last_update_time=%lu\n", + pr_info("%s: timer id=%d, charging_state=%d, last_update_time=%lu\n", __func__, pca9468->timer_id, pca9468->charging_state, pca9468->last_update_time); #else - pr_info("%s: timer id=%d, charging_state=%d\n", + pr_info("%s: timer id=%d, charging_state=%d\n", __func__, pca9468->timer_id, pca9468->charging_state); #endif @@ -3604,7 +3673,7 @@ static void pca9468_timer_work(struct work_struct *work) if (ret < 0) goto error; break; - + case TIMER_PRESET_CONFIG: ret = pca9468_preset_config(pca9468); if (ret < 0) @@ -3616,12 +3685,12 @@ static void pca9468_timer_work(struct work_struct *work) if (ret < 0) goto error; break; - + case TIMER_ADJUST_CCMODE: ret = pca9468_charge_adjust_ccmode(pca9468); if (ret < 0) goto error; - break; + break; case TIMER_ENTER_CCMODE: ret = pca9468_charge_start_ccmode(pca9468); @@ -3726,7 +3795,7 @@ static void pca9468_timer_work(struct work_struct *work) cancel_delayed_work(&pca9468->pps_work); } return; - + error: #if defined(CONFIG_BATTERY_SAMSUNG) pca9468->chg_status = POWER_SUPPLY_STATUS_NOT_CHARGING; @@ -3824,7 +3893,7 @@ static int pca9468_hw_init(struct pca9468_charger *pca9468) /* Set Reverse Current Detection and standby mode*/ val = PCA9468_BIT_REV_IIN_DET | PCA9468_EN_ACTIVE_L | PCA9468_STANDBY_FORCED; ret = pca9468_update_reg(pca9468, PCA9468_REG_START_CTRL, - (PCA9468_BIT_REV_IIN_DET | PCA9468_BIT_EN_CFG | PCA9468_BIT_STANDBY_EN), + (PCA9468_BIT_REV_IIN_DET | PCA9468_BIT_EN_CFG | PCA9468_BIT_STANDBY_EN), val); if (ret < 0) return ret; @@ -3835,7 +3904,7 @@ static int pca9468_hw_init(struct pca9468_charger *pca9468) PCA9468_BIT_LIMIT_INCREMENT_EN, val); if (ret < 0) return ret; - + /* Set the ADC channel */ val = (PCA9468_BIT_CH7_EN | /* NTC voltage ADC */ PCA9468_BIT_CH6_EN | /* DIETEMP ADC */ @@ -3858,7 +3927,7 @@ static int pca9468_hw_init(struct pca9468_charger *pca9468) if (ret < 0) return ret; val = 0x00; - ret = pca9468_write_reg(pca9468, PCA9468_REG_ADC_ACCESS, val); + ret = pca9468_write_reg(pca9468, PCA9468_REG_ADC_ACCESS, val); if (ret < 0) return ret; @@ -3873,9 +3942,9 @@ static int pca9468_hw_init(struct pca9468_charger *pca9468) } else if ((val & PCA9468_BIT_OTP_VERSION) == PCA9468_REVISION_B4) { pca9468->revision = REV_B4; } - + pr_info("%s: pca9468_revision=%d\n", __func__, pca9468->revision); - + /* input current - uA*/ ret = pca9468_set_input_current(pca9468, pca9468->pdata->iin_cfg); if (ret < 0) @@ -3918,7 +3987,7 @@ static irqreturn_t pca9468_interrupt_handler(int irq, void *data) return IRQ_NONE; } - pr_info("%s: int1=0x%2x, int1_sts=0x%2x, sts_a=0x%2x\n", __func__, + pr_info("%s: int1=0x%2x, int1_sts=0x%2x, sts_a=0x%2x\n", __func__, int1[REG_INT1], int1[REG_INT1_STS], sts[REG_STS_A]); /* Check Interrupt */ @@ -3949,7 +4018,7 @@ static irqreturn_t pca9468_interrupt_handler(int irq, void *data) /* V_FLOAT loop is in regulation */ pr_info("%s: V_FLOAT loop interrupt\n", __func__); /* Disable CHG_PHASE_M */ - ret = pca9468_update_reg(pca9468, PCA9468_REG_INT1_MSK, + ret = pca9468_update_reg(pca9468, PCA9468_REG_INT1_MSK, PCA9468_BIT_CHG_PHASE_M, PCA9468_BIT_CHG_PHASE_M); if (ret < 0) { handled = false; @@ -4043,8 +4112,8 @@ static int pca9468_irq_init(struct pca9468_charger *pca9468, /* * Configure the Mask Register for interrupts: disable all interrupts by default. */ - msk = (PCA9468_BIT_V_OK_M | - PCA9468_BIT_NTC_TEMP_M | + msk = (PCA9468_BIT_V_OK_M | + PCA9468_BIT_NTC_TEMP_M | PCA9468_BIT_CHG_PHASE_M | PCA9468_BIT_RESERVED_M | PCA9468_BIT_CTRL_LIMIT_M | @@ -4054,7 +4123,7 @@ static int pca9468_irq_init(struct pca9468_charger *pca9468, ret = pca9468_write_reg(pca9468, PCA9468_REG_INT1_MSK, msk); if (ret < 0) goto fail_write; - + client->irq = irq; return 0; @@ -4089,7 +4158,7 @@ static int get_input_current_limit(struct pca9468_charger *pca9468) if (intval < 500000) intval = 500000; - + return intval; } @@ -4143,7 +4212,7 @@ static int get_charging_enabled(struct pca9468_charger *pca9468) { int ret, intval; unsigned int val; - + ret = pca9468_read_reg(pca9468, PCA9468_REG_START_CTRL, &val); if (ret < 0) return ret; @@ -4581,7 +4650,7 @@ static int pca9468_charger_parse_dt(struct device *dev, struct pca9468_platform_ struct device_node *np; #endif int ret; - if(!np_pca9468) + if (!np_pca9468) return -EINVAL; /* irq gpio */ @@ -4703,7 +4772,7 @@ static int pca9468_charger_parse_dt(struct device *dev, struct pca9468_platform_ if (ret) { pr_info("## %s: battery,chg_float_voltage is Empty\n", __func__); pdata->v_float = PCA9468_VFLOAT_DFT; - } else { + } else { pdata->v_float = pdata->v_float * PCA9468_SEC_DENOM_U_M; pr_info("## %s: battery,chg_float_voltage is %d\n", __func__, pdata->v_float); @@ -4762,7 +4831,7 @@ static int read_reg(void *data, u64 *val) int rc; unsigned int temp; - rc = regmap_read(chip->regmap, chip->debug_address, &temp); + rc = regmap_read(chip->regmap, chip->debug_address, &temp); if (rc) { pr_err("Couldn't read reg %x rc = %d\n", chip->debug_address, rc); @@ -4793,7 +4862,7 @@ static int pca9468_create_debugfs_entries(struct pca9468_charger *chip) { struct dentry *ent; int rc = 0; - + chip->debug_root = debugfs_create_dir("charger-pca9468", NULL); if (!chip->debug_root) { dev_err(chip->dev, "Couldn't create debug dir\n"); @@ -4850,7 +4919,7 @@ static int pca9468_charger_probe(struct i2c_client *client, } ret = pca9468_charger_parse_dt(&client->dev, pdata); - if (ret < 0){ + if (ret < 0) { dev_err(&client->dev, "Failed to get device of_node \n"); return -ENOMEM; } @@ -5039,7 +5108,7 @@ static void pca9468_check_and_update_charging_timer(struct pca9468_charger *pca9 unsigned long current_time = 0, next_update_time, time_left; get_current_time(¤t_time); - + if (pca9468->timer_id != TIMER_ID_NONE) { next_update_time = pca9468->last_update_time + (pca9468->timer_period / 1000); // unit is second @@ -5121,4 +5190,4 @@ module_i2c_driver(pca9468_charger_driver); MODULE_AUTHOR("Clark Kim "); MODULE_DESCRIPTION("PCA9468 charger driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION("3.4.15S"); +MODULE_VERSION("3.4.16S"); diff --git a/drivers/battery_v2/s2asl01_switching.c b/drivers/battery_v2/s2asl01_switching.c index a451d3959..47b1076d0 100644 --- a/drivers/battery_v2/s2asl01_switching.c +++ b/drivers/battery_v2/s2asl01_switching.c @@ -347,7 +347,7 @@ static void s2asl01_set_fast_charging_current_limit( u8 data = 0; int dest_current = 0; - if (switching->rev_id == 0 || switching->rev_id >= 2) { + if (switching->rev_id == 0 || switching->ic_ver == VER_6130) { if (charging_current <= 50) data = 0x00; else if (charging_current > 50 && charging_current <= 3200) @@ -393,7 +393,7 @@ static int s2asl01_get_fast_charging_current_limit( data = 0x3F; } - if (switching->rev_id == 0 || switching->rev_id >= 2) + if (switching->rev_id == 0 || switching->ic_ver == VER_6130) charging_current = (data + 1) * 50; else { if ((data >= 0x00) && (data <= 0x04)) @@ -410,22 +410,31 @@ static void s2asl01_set_trickle_charging_current_limit( { u8 data = 0; - if (switching->rev_id == 0 || switching->rev_id >= 2) { + if (switching->ic_ver == VER_6130) { if (charging_current <= 50) data = 0x00; - else if (charging_current > 50 && charging_current <= 500) + else if (charging_current > 50 && charging_current <= 550) data = (charging_current / 50) - 1; else - data = 0x09; + data = 0x0A; } else { - if (charging_current <= 50) - data = 0x00; - else if (charging_current > 50 && charging_current <= 350) - data = (charging_current - 50) / 75; - else if (charging_current > 350 && charging_current <= 550) - data = ((charging_current - 350) / 50) + 4; - else - data = 0x08; + if (switching->rev_id == 0) { + if (charging_current <= 50) + data = 0x00; + else if (charging_current > 50 && charging_current <= 500) + data = (charging_current / 50) - 1; + else + data = 0x09; + } else { + if (charging_current <= 50) + data = 0x00; + else if (charging_current > 50 && charging_current <= 350) + data = (charging_current - 50) / 75; + else if (charging_current > 350 && charging_current <= 550) + data = ((charging_current - 350) / 50) + 4; + else + data = 0x08; + } } pr_info("%s [%s]: current %d, 0x%02x\n", __func__, current_limiter_type_str[switching->pdata->bat_type], charging_current, data); @@ -444,21 +453,29 @@ static int s2asl01_get_trickle_charging_current_limit( data = data & TRICKLE_CHG_CURRENT_LIMIT_MASK; - if (switching->rev_id == 0 || switching->rev_id >= 2) { - if (data > 0x09) { + if (switching->ic_ver == VER_6130) { + if (data > 0x0A) { pr_err("%s: Invalid trickle charging current limit value\n", __func__); - data = 0x09; + data = 0x0A; } charging_current = (data + 1) * 50; } else { - if (data > 0x08) { - pr_err("%s: Invalid trickle charging current limit value\n", __func__); - data = 0x08; + if (switching->rev_id == 0) { + if (data > 0x09) { + pr_err("%s: Invalid trickle charging current limit value\n", __func__); + data = 0x09; + } + charging_current = (data + 1) * 50; + } else { + if (data > 0x08) { + pr_err("%s: Invalid trickle charging current limit value\n", __func__); + data = 0x08; + } + if ((data >= 0x00) && (data <= 0x04)) + charging_current = (data * 75) + 50; + else + charging_current = ((data - 4) * 50) + 350; } - if ((data >= 0x00) && (data <= 0x04)) - charging_current = (data * 75) + 50; - else - charging_current = ((data - 4) * 50) + 350; } return charging_current; @@ -1049,15 +1066,18 @@ static void s2asl01_get_rev_id(struct s2asl01_switching_data *switching) /* rev ID */ s2asl01_read_reg(switching->client, S2ASL01_SWITCHING_ID, &val1); + if (val1 & 0x01) + switching->ic_ver = VER_6130; + else + switching->ic_ver = VER_6030; switching->es_num = (val1 & 0xC0) >> 6; switching->rev_id = (val1 & 0x30) >> 4; - pr_info("%s [%s]: rev id : %d, es_num = %d\n", + pr_info("%s [%s]: rev id : %d, es_num = %d, ic_ver = %d\n", __func__, current_limiter_type_str[switching->pdata->bat_type], - switching->rev_id, - switching->es_num); + switching->rev_id, switching->es_num, switching->ic_ver); } static void s2asl01_init_regs(struct s2asl01_switching_data *switching) diff --git a/drivers/battery_v2/sec_battery.c b/drivers/battery_v2/sec_battery.c index 0e1d5875d..0ed1060f9 100644 --- a/drivers/battery_v2/sec_battery.c +++ b/drivers/battery_v2/sec_battery.c @@ -590,6 +590,9 @@ __visible_for_testing void sec_bat_get_charging_current_by_siop(struct sec_batte *input_current = battery->pdata->siop_store_hv_input_limit_current_2nd; else if (*input_current > battery->pdata->siop_hv_input_limit_current_2nd) *input_current = battery->pdata->siop_hv_input_limit_current_2nd; + } else if (battery->siop_level == 20 && battery->pdata->input_current_by_siop_20 > 0) { + if (*input_current > battery->pdata->input_current_by_siop_20) + *input_current = battery->pdata->input_current_by_siop_20; } } #if defined(CONFIG_CCIC_NOTIFIER) @@ -1285,49 +1288,42 @@ void sec_bat_divide_charging_current(struct sec_battery_info *battery, int charg { unsigned int main_current = 0, sub_current = 0, main_charging_rate = 0, sub_charging_rate = 0; -#if defined(CONFIG_STEP_CHARGING) - /* dc_rate should be applied when dc charging actually on going */ - if (is_pd_apdo_wire_type(battery->cable_type) && battery->step_charging_status >= 0) { -#else - if (is_pd_apdo_wire_type(battery->cable_type)) { -#endif - main_charging_rate = battery->pdata->dc_main_charging_rate; - sub_charging_rate = battery->pdata->dc_sub_charging_rate; + if (charging_current <= 1700) { + main_charging_rate = battery->pdata->main_zone1_current_rate; + sub_charging_rate = battery->pdata->sub_zone1_current_rate; + } else if (charging_current <= 3200) { + main_charging_rate = battery->pdata->main_zone2_current_rate; + sub_charging_rate = battery->pdata->sub_zone2_current_rate; } else { - main_charging_rate = battery->pdata->main_charging_rate; - sub_charging_rate = battery->pdata->sub_charging_rate; + main_charging_rate = battery->pdata->main_zone3_current_rate; + sub_charging_rate = battery->pdata->sub_zone3_current_rate; } main_current = (charging_current * main_charging_rate) / 100; sub_current = (charging_current * sub_charging_rate) / 100; + pr_info("%s: main_charging_rate(%d), sub_charging_rate(%d)\n", __func__, + main_charging_rate, sub_charging_rate); // debug + if (battery->current_event & SEC_BAT_CURRENT_EVENT_LOW_TEMP_SWELLING_2ND) { - if (battery->pdata->swelling_main_low_temp_current_2nd && - main_current > battery->pdata->swelling_main_low_temp_current_2nd) + if (battery->pdata->swelling_main_low_temp_current_2nd) main_current = battery->pdata->swelling_main_low_temp_current_2nd; - if (battery->pdata->swelling_sub_low_temp_current_2nd && - sub_current > battery->pdata->swelling_sub_low_temp_current_2nd) + if (battery->pdata->swelling_sub_low_temp_current_2nd) sub_current = battery->pdata->swelling_sub_low_temp_current_2nd; } else if (battery->current_event & SEC_BAT_CURRENT_EVENT_LOW_TEMP_SWELLING) { - if (battery->pdata->swelling_main_low_temp_current && - main_current > battery->pdata->swelling_main_low_temp_current) + if (battery->pdata->swelling_main_low_temp_current) main_current = battery->pdata->swelling_main_low_temp_current; - if (battery->pdata->swelling_sub_low_temp_current && - sub_current > battery->pdata->swelling_sub_low_temp_current) + if (battery->pdata->swelling_sub_low_temp_current) sub_current = battery->pdata->swelling_sub_low_temp_current; } else if (battery->current_event & SEC_BAT_CURRENT_EVENT_HIGH_TEMP_SWELLING) { - if (battery->pdata->swelling_main_high_temp_current && - main_current > battery->pdata->swelling_main_high_temp_current) + if (battery->pdata->swelling_main_high_temp_current) main_current = battery->pdata->swelling_main_high_temp_current; - if (battery->pdata->swelling_sub_high_temp_current && - sub_current > battery->pdata->swelling_sub_high_temp_current) + if (battery->pdata->swelling_sub_high_temp_current) sub_current = battery->pdata->swelling_sub_high_temp_current; } else if (battery->current_event & SEC_BAT_CURRENT_EVENT_LOW_TEMP_SWELLING_3RD) { - if (battery->pdata->swelling_main_low_temp_current_3rd && - main_current > battery->pdata->swelling_main_low_temp_current_3rd) + if (battery->pdata->swelling_main_low_temp_current_3rd) main_current = battery->pdata->swelling_main_low_temp_current_3rd; - if (battery->pdata->swelling_sub_low_temp_current_3rd && - sub_current > battery->pdata->swelling_sub_low_temp_current_3rd) + if (battery->pdata->swelling_sub_low_temp_current_3rd) sub_current = battery->pdata->swelling_sub_low_temp_current_3rd; } @@ -1581,7 +1577,8 @@ int sec_bat_set_charging_current(struct sec_battery_info *battery) }/* is_nocharge_type(battery->cable_type) */ /* set input current, charging current */ - if ((battery->input_current != input_current) || + if ((battery->refresh_current) || + (battery->input_current != input_current) || (battery->charging_current != charging_current)) { /* update charge power */ battery->charge_power = (battery->input_voltage * input_current) / 10; @@ -1595,10 +1592,7 @@ int sec_bat_set_charging_current(struct sec_battery_info *battery) #if defined(CONFIG_DUAL_BATTERY) sec_bat_divide_charging_current(battery, charging_current); -#endif - -#if defined(CONFIG_DUAL_BATTERY) - if (battery->charging_current < charging_current) + if (battery->charging_current <= charging_current) sec_bat_set_divide_charging_current(battery); #endif @@ -1672,7 +1666,8 @@ int sec_bat_set_charging_current(struct sec_battery_info *battery) #endif /* set topoff current */ - if (battery->topoff_current != topoff_current) { + if ((battery->refresh_current) || + (battery->topoff_current != topoff_current)) { value.intval = topoff_current; psy_do_property(battery->pdata->charger_name, set, POWER_SUPPLY_PROP_CURRENT_FULL, value); @@ -1687,10 +1682,23 @@ int sec_bat_set_charging_current(struct sec_battery_info *battery) value); #endif } + + battery->refresh_current = false; mutex_unlock(&battery->iolock); return 0; } +void sec_bat_refresh_charging_current(struct sec_battery_info *battery) +{ + mutex_lock(&battery->iolock); + battery->refresh_current = true; + mutex_unlock(&battery->iolock); + + pr_info("%s: refresh charging current (input=%d, fcc=%d, topoff=%d)\n", + __func__, battery->input_current, battery->charging_current, battery->topoff_current); + queue_delayed_work(battery->monitor_wqueue, &battery->siop_level_work, 0); +} + int sec_bat_set_charge(struct sec_battery_info *battery, int chg_mode) { @@ -3466,22 +3474,6 @@ static bool sec_bat_check_fullcharged( break; } -#if defined(CONFIG_DUAL_BATTERY) - /* This is for a case which has charging current under limiter eoc before ifpmic total current has total eoc. - * It is unusual case and there is huge gap between main battery and sub battery's charging current. - */ - if (battery->charging_mode == SEC_BATTERY_CHARGING_1ST) { - psy_do_property(battery->pdata->dual_battery_name, get, - POWER_SUPPLY_PROP_CHARGE_FULL, value); - if (value.intval == POWER_SUPPLY_STATUS_FULL) { - battery->full_check_cnt++; - dev_info(battery->dev, - "%s: Full Check Limiter at 1st Charging (%d)\n", - __func__, battery->full_check_cnt); - } - } -#endif - #if defined(CONFIG_ENABLE_FULL_BY_SOC) if (battery->capacity >= 100 && battery->charging_mode == SEC_BATTERY_CHARGING_1ST && @@ -3634,16 +3626,12 @@ static int sec_bat_calc_unknown_wpc_temp( if (battery->support_unknown_wpcthm && battery->pdata->wpc_thermal_source && !is_wireless_fake_type(battery->cable_type)) { if (batt_temp <= (-200)) { - if (usb_temp >= 270) { - batt_temp = usb_temp + 60; - pr_info("%s :usb_temp >= 27\n", __func__); - } else if (usb_temp <= 210) { - batt_temp = usb_temp - 50; - pr_info("%s : usb_temp < 21\n", __func__); - } else { + if (usb_temp >= 270) + batt_temp = (usb_temp + 60) > 900 ? 900 : (usb_temp + 60); + else if (usb_temp <= 210) + batt_temp = (usb_temp - 50) < (-200) ? (-200) : (usb_temp - 50); + else batt_temp = (170 * usb_temp - 26100) / 60; - pr_info("%s : 21 <= usb_temp <= 27\n", __func__); - } } } return batt_temp; @@ -3871,7 +3859,7 @@ static void sec_bat_get_temperature_info( #endif #if !defined(CONFIG_SEC_FACTORY) - batt_temp = sec_bat_calc_unknown_wpc_temp(battery, batt_temp, usb_temp); + batt_temp = sec_bat_calc_unknown_wpc_temp(battery, battery->raw_bat_temp, usb_temp); #endif battery->temperature = batt_temp; @@ -5389,6 +5377,8 @@ static void sec_bat_monitor_work( old_ts = c_ts; sec_bat_get_battery_info(battery); + psy_do_property(battery->pdata->fuelgauge_name, get, + POWER_SUPPLY_EXT_PROP_INFO, value); #if defined(CONFIG_BATTERY_CISD) sec_bat_cisd_check(battery); @@ -6031,18 +6021,11 @@ static void sec_bat_cable_work(struct work_struct *work) sec_bat_set_current_event(battery, 0, SEC_BAT_CURRENT_EVENT_SELECT_PDO); sec_bat_get_input_current_in_power_list(battery); sec_bat_get_charging_current_in_power_list(battery); -#if defined(CONFIG_STEP_CHARGING) -#if defined(CONFIG_DIRECT_CHARGING) - if (!is_pd_apdo_wire_type(battery->cable_type)) { - sec_bat_reset_step_charging(battery); - } else if (is_pd_apdo_wire_type(battery->cable_type) && (battery->ta_alert_mode != OCP_NONE)) { +#if defined(CONFIG_STEP_CHARGING) && defined(CONFIG_DIRECT_CHARGING) + if (is_pd_apdo_wire_type(battery->cable_type) && (battery->ta_alert_mode != OCP_NONE)) { battery->ta_alert_mode = OCP_WA_ACTIVE; sec_bat_reset_step_charging(battery); } - -#else - sec_bat_reset_step_charging(battery); -#endif #endif #if defined(CONFIG_PDIC_PD30) if (!battery->pd_list.pd_info[battery->pd_list.now_pd_index].comm_capable @@ -6210,6 +6193,24 @@ static void sec_bat_cable_work(struct work_struct *work) current_cable_type = current_wire_status; } +#if defined(CONFIG_BATTERY_SWELLING) + if (is_nocharge_type(current_cable_type) || + (is_nocharge_type(battery->cable_type) && battery->swelling_mode == SWELLING_MODE_NONE)) { + battery->swelling_mode = SWELLING_MODE_NONE; + /* restore 4.4V float voltage */ + val.intval = battery->pdata->swelling_normal_float_voltage; + psy_do_property(battery->pdata->charger_name, set, + POWER_SUPPLY_PROP_VOLTAGE_MAX, val); + pr_info("%s: float voltage = %d\n", __func__, val.intval); + } else { +#if defined(CONFIG_STEP_CHARGING) + sec_bat_reset_step_charging(battery); +#endif + pr_info("%s: skip float_voltage setting, swelling_mode(%d)\n", + __func__, battery->swelling_mode); + } +#endif + if ((current_cable_type == battery->cable_type) && !is_slate_mode(battery) && !(battery->current_event & SEC_BAT_CURRENT_EVENT_USB_SUSPENDED)) { @@ -6240,21 +6241,6 @@ static void sec_bat_cable_work(struct work_struct *work) || (battery->muic_cable_type == ATTACHED_DEV_AFC_CHARGER_DISABLED_MUIC)) battery->max_charge_power = 0; -#if defined(CONFIG_BATTERY_SWELLING) - if (is_nocharge_type(current_cable_type) || - (is_nocharge_type(battery->cable_type) && battery->swelling_mode == SWELLING_MODE_NONE)) { - battery->swelling_mode = SWELLING_MODE_NONE; - /* restore 4.4V float voltage */ - val.intval = battery->pdata->swelling_normal_float_voltage; - psy_do_property(battery->pdata->charger_name, set, - POWER_SUPPLY_PROP_VOLTAGE_MAX, val); - pr_info("%s: float voltage = %d\n", __func__, val.intval); - } else { - pr_info("%s: skip float_voltage setting, swelling_mode(%d)\n", - __func__, battery->swelling_mode); - } -#endif - if (current_cable_type == SEC_BATTERY_CABLE_HV_TA_CHG_LIMIT) current_cable_type = SEC_BATTERY_CABLE_9V_TA; @@ -6345,6 +6331,16 @@ static void sec_bat_cable_work(struct work_struct *work) SEC_BAT_CURRENT_EVENT_USB_STATE | SEC_BAT_CURRENT_EVENT_SEND_UVDM)); + /* slate_mode needs to be clear manually since smart switch does not disable slate_mode sometimes */ + if (is_slate_mode(battery)) { + pr_info("%s: slate_mode (%d)\n", __func__, battery->slate_mode); + if (battery->slate_mode == SB_SLATE_SMART) { + battery->slate_mode = SB_SLATE_NONE; + sec_bat_set_current_event(battery, 0, SEC_BAT_CURRENT_EVENT_SLATE); + dev_info(battery->dev, + "%s: disable slate mode(smart switch) manually\n", __func__); + } + } #if defined(CONFIG_ENABLE_100MA_CHARGING_BEFORE_USB_CONFIGURED) cancel_delayed_work(&battery->slowcharging_work); #endif @@ -7350,29 +7346,74 @@ static int sec_wireless_get_property(struct power_supply *psy, return 0; } -void sec_wireless_set_tx_enable(struct sec_battery_info *battery, bool wc_tx_enable) +static void sec_wireless_test_print_sgf_data(const char *buf, int count) +{ + char temp_buf[1024] = {0, }; + int i, size = 0; + + snprintf(temp_buf, sizeof(temp_buf), "0x%x", buf[0]); + size = sizeof(temp_buf) - strlen(temp_buf); + + for (i = 1; i < count; i++) { + snprintf(temp_buf + strlen(temp_buf), size, " 0x%x", buf[i]); + size = sizeof(temp_buf) - strlen(temp_buf); + } + + pr_info("%s: %s\n", __func__, temp_buf); +} + +static ssize_t sec_wireless_sgf_show_attr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return -EINVAL; +} + +static ssize_t sec_wireless_sgf_store_attr(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { + struct power_supply *psy = dev_get_drvdata(dev); + struct sec_battery_info *battery = power_supply_get_drvdata(psy); union power_supply_propval value = {0, }; - char wpc_en_status[2]; - pr_info("@Tx_Mode %s: TX Power enable ? (%d)\n", __func__, wc_tx_enable); + if (count < 4) { + pr_err("%s: invalid data\n", __func__); + return -EINVAL; + } -#if defined(CONFIG_TX_5V_DISABLE) - if (wc_tx_enable && is_5v_charger(battery)) { - pr_info("@Tx_Mode %s : 5V charger(%d) connected, do not turn on TX\n", __func__, battery->cable_type); - sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_5V_TA, BATT_TX_EVENT_WIRELESS_TX_5V_TA); - return; + psy_do_property(battery->pdata->wireless_charger_name, get, + POWER_SUPPLY_EXT_PROP_WIRELESS_TX_ID, value); + pr_info("%s!!!(cable_type = %d, tx_id = %d, count = %ld)\n", + __func__, battery->cable_type, value.intval, count); + sec_wireless_test_print_sgf_data(buf, (int)count); + + if (is_wireless_type(battery->cable_type) && value.intval == 0xEF) { + value.strval = buf; + psy_do_property(battery->pdata->wireless_charger_name, set, + POWER_SUPPLY_EXT_PROP_WIRELESS_SGF, value); } -#endif - battery->wc_tx_enable = wc_tx_enable; + return count; +} +static DEVICE_ATTR(sgf, 0664, sec_wireless_sgf_show_attr, sec_wireless_sgf_store_attr); + +static void sec_bat_wpc_tx_en_work(struct work_struct *work) +{ + struct sec_battery_info *battery = container_of(work, + struct sec_battery_info, wpc_tx_en_work.work); + + union power_supply_propval value = {0, }; + char wpc_en_status[2]; + + pr_info("@Tx_Mode %s: tx %s\n", __func__, + battery->wc_tx_enable ? "on" : "off"); + battery->tx_minduty = battery->pdata->tx_minduty_default; battery->tx_switch_mode = TX_SWITCH_MODE_OFF; battery->tx_switch_start_soc = 0; battery->tx_switch_mode_change = false; wpc_en_status[0] = WPC_EN_TX; - if (wc_tx_enable) { + if (battery->wc_tx_enable) { /* set tx event */ sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_STATUS, (BATT_TX_EVENT_WIRELESS_TX_STATUS | BATT_TX_EVENT_WIRELESS_TX_RETRY)); @@ -7444,7 +7485,30 @@ void sec_wireless_set_tx_enable(struct sec_battery_info *battery, bool wc_tx_ena cancel_delayed_work(&battery->wpc_txpower_calc_work); #endif __pm_relax(battery->wpc_tx_wake_lock); - } + } + + pr_info("@Tx_Mode %s Done\n", __func__); + __pm_relax(battery->wpc_tx_en_wake_lock); +} + +void sec_wireless_set_tx_enable(struct sec_battery_info *battery, bool wc_tx_enable) +{ + pr_info("@Tx_Mode %s: TX Power enable ? (%d)\n", __func__, wc_tx_enable); + +#if defined(CONFIG_TX_5V_DISABLE) + if (wc_tx_enable && is_5v_charger(battery)) { + pr_info("@Tx_Mode %s : 5V charger(%d) connected, do not turn on TX\n", __func__, battery->cable_type); + sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_5V_TA, BATT_TX_EVENT_WIRELESS_TX_5V_TA); + return; + } +#endif + + battery->wc_tx_enable = wc_tx_enable; + + cancel_delayed_work(&battery->wpc_tx_en_work); + __pm_stay_awake(battery->wpc_tx_en_wake_lock); + queue_delayed_work(battery->monitor_wqueue, + &battery->wpc_tx_en_work, 0); } static void sec_wireless_otg_control(struct sec_battery_info *battery, int enable) @@ -8402,9 +8466,6 @@ static int usb_typec_handle_notification(struct notifier_block *nb, if ((*(struct pdic_notifier_struct *)usb_typec_info.pd).event == PDIC_NOTIFY_EVENT_PD_SINK_CAP || battery->update_pd_list) { pr_info("%s : update_pd_list(%d)\n", __func__, battery->update_pd_list); #if defined(CONFIG_DIRECT_CHARGING) -#if defined(CONFIG_STEP_CHARGING) - sec_bat_reset_step_charging(battery); -#endif psy_do_property(battery->pdata->charger_name, set, POWER_SUPPLY_EXT_PROP_DIRECT_CLEAR_ERR, val); #endif @@ -9236,6 +9297,7 @@ static int sec_battery_probe(struct platform_device *pdev) battery->ext_event_wake_lock = wakeup_source_register(battery->dev, "sec-battery-ext_event"); battery->wc_headroom_wake_lock = wakeup_source_register(battery->dev, "sec-battery-wc_headroom"); battery->wpc_tx_wake_lock = wakeup_source_register(battery->dev, "sec-battery-wcp-tx"); + battery->wpc_tx_en_wake_lock = wakeup_source_register(&pdev->dev, "sec-battery-wpc_tx_en"); #if defined(CONFIG_UPDATE_BATTERY_DATA) battery->batt_data_wake_lock = wakeup_source_register(battery->dev, "sec-battery-update-data"); #endif @@ -9500,6 +9562,7 @@ static int sec_battery_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&battery->monitor_work, sec_bat_monitor_work); INIT_DELAYED_WORK(&battery->cable_work, sec_bat_cable_work); INIT_DELAYED_WORK(&battery->wpc_tx_work, sec_bat_wpc_tx_work); + INIT_DELAYED_WORK(&battery->wpc_tx_en_work, sec_bat_wpc_tx_en_work); #if defined(CONFIG_CALC_TIME_TO_FULL) INIT_DELAYED_WORK(&battery->timetofull_work, sec_bat_time_to_full_work); #endif @@ -9603,6 +9666,9 @@ static int sec_battery_probe(struct platform_device *pdev) } battery->psy_wireless->supplied_to = supply_list; battery->psy_wireless->num_supplicants = ARRAY_SIZE(supply_list); + if (device_create_file(&battery->psy_wireless->dev, &dev_attr_sgf)) + dev_err(battery->dev, + "%s: failed to create sgf attr\n", __func__); ret = sec_bat_create_attrs(&battery->psy_bat->dev); if (ret) { @@ -9720,6 +9786,7 @@ static int sec_battery_probe(struct platform_device *pdev) wakeup_source_remove(battery->ext_event_wake_lock); wakeup_source_remove(battery->wc_headroom_wake_lock); wakeup_source_remove(battery->wpc_tx_wake_lock); + wakeup_source_remove(battery->wpc_tx_en_wake_lock); #if defined(CONFIG_UPDATE_BATTERY_DATA) wakeup_source_remove(battery->batt_data_wake_lock); #endif @@ -9777,6 +9844,8 @@ static int sec_battery_remove(struct platform_device *pdev) wakeup_source_remove(battery->misc_event_wake_lock); wakeup_source_remove(battery->tx_event_wake_lock); wakeup_source_remove(battery->wc_headroom_wake_lock); + wakeup_source_remove(battery->wpc_tx_wake_lock); + wakeup_source_remove(battery->wpc_tx_en_wake_lock); #if defined(CONFIG_UPDATE_BATTERY_DATA) wakeup_source_remove(battery->batt_data_wake_lock); #endif diff --git a/drivers/battery_v2/sec_battery_dt.c b/drivers/battery_v2/sec_battery_dt.c index 1a0803541..324ee2ad8 100644 --- a/drivers/battery_v2/sec_battery_dt.c +++ b/drivers/battery_v2/sec_battery_dt.c @@ -1485,6 +1485,12 @@ int sec_bat_parse_dt(struct device *dev, pdata->swelling_low_rechg_thr = 150; } + ret = of_property_read_u32(np, "battery,input_current_by_siop_20", + (unsigned int *)&pdata->input_current_by_siop_20); + if (ret) { + pr_info("%s: input_current_by_siop_20 is Empty. Not used\n", __func__); + } + pr_info("%s : SWELLING_HIGH_TEMP(%d) SWELLING_HIGH_TEMP_RECOVERY(%d)\n" "SWELLING_LOW_TEMP_1st(%d) SWELLING_LOW_TEMP_RECOVERY_1st(%d) " "SWELLING_LOW_TEMP_2nd(%d) SWELLING_LOW_TEMP_RECOVERY_2nd(%d) " @@ -1914,30 +1920,47 @@ int sec_bat_parse_dt(struct device *dev, if (ret < 0) { pr_info("%s : can't get sub_bat_enb_gpio\n", __func__); } - ret = of_property_read_u32(np, "battery,main_charging_rate", - &pdata->main_charging_rate); + + /* zone1 current ratio, 0C ~ 0.4C */ + ret = of_property_read_u32(np, "battery,main_zone1_current_rate", + &pdata->main_zone1_current_rate); if (ret) { - pr_err("%s: main_charging_rate is Empty\n", __func__); - pdata->main_charging_rate = 60; + pr_err("%s: main_zone1_current_rate is Empty\n", __func__); + pdata->main_zone1_current_rate = 50; } - ret = of_property_read_u32(np, "battery,sub_charging_rate", - &pdata->sub_charging_rate); + ret = of_property_read_u32(np, "battery,sub_zone1_current_rate", + &pdata->sub_zone1_current_rate); if (ret) { - pr_err("%s: sub_charging_rate is Empty\n", __func__); - pdata->sub_charging_rate = 50; + pr_err("%s: sub_zone1_current_rate is Empty\n", __func__); + pdata->sub_zone1_current_rate = 60; } - ret = of_property_read_u32(np, "battery,dc_main_charging_rate", - &pdata->dc_main_charging_rate); + /* zone2 current ratio, 0.4C ~ 1.1C */ + ret = of_property_read_u32(np, "battery,main_zone2_current_rate", + &pdata->main_zone2_current_rate); if (ret) { - pr_err("%s: dc_main_charging_rate is Empty\n", __func__); - pdata->dc_main_charging_rate = pdata->main_charging_rate; + pr_err("%s: main_zone2_current_rate is Empty\n", __func__); + pdata->main_zone2_current_rate = 50; } - ret = of_property_read_u32(np, "battery,dc_sub_charging_rate", - &pdata->dc_sub_charging_rate); + ret = of_property_read_u32(np, "battery,sub_zone2_current_rate", + &pdata->sub_zone2_current_rate); if (ret) { - pr_err("%s: dc_sub_charging_rate is Empty\n", __func__); - pdata->dc_sub_charging_rate = pdata->sub_charging_rate; + pr_err("%s: sub_zone2_current_rate is Empty\n", __func__); + pdata->sub_zone2_current_rate = 60; } + /* zone3 current ratio, 1.1C ~ MAX */ + ret = of_property_read_u32(np, "battery,main_zone3_current_rate", + &pdata->main_zone3_current_rate); + if (ret) { + pr_err("%s: main_zone3_current_rate is Empty\n", __func__); + pdata->main_zone3_current_rate = pdata->main_zone2_current_rate; + } + ret = of_property_read_u32(np, "battery,sub_zone3_current_rate", + &pdata->sub_zone3_current_rate); + if (ret) { + pr_err("%s: sub_zone3_current_rate is Empty\n", __func__); + pdata->sub_zone3_current_rate = pdata->sub_zone2_current_rate; + } + ret = of_property_read_u32(np, "battery,force_recharge_margin", &pdata->force_recharge_margin); if (ret) { @@ -1968,10 +1991,10 @@ int sec_bat_parse_dt(struct device *dev, pr_err("%s: min_sub_charging_current is Empty\n", __func__); pdata->min_sub_charging_current = 450; } - pr_info("%s : main rate:%d(dc %d), sub rate:%d(dc %d), recharge marging:%d, " + pr_info("%s : main ratio:%d(zn1) %d(zn2) %d(zn3), sub ratio:%d(zn1) %d(zn2) %d(zn3), recharge marging:%d, " "max main curr:%d, min main curr:%d, max sub curr:%d, min sub curr:%d \n", - __func__, pdata->main_charging_rate, pdata->dc_main_charging_rate, - pdata->sub_charging_rate, pdata->dc_sub_charging_rate, + __func__, pdata->main_zone1_current_rate, pdata->main_zone2_current_rate, pdata->main_zone3_current_rate, + pdata->sub_zone1_current_rate, pdata->sub_zone2_current_rate, pdata->sub_zone3_current_rate, pdata->force_recharge_margin, pdata->max_main_charging_current, pdata->min_main_charging_current, pdata->max_sub_charging_current, pdata->min_sub_charging_current); } diff --git a/drivers/battery_v2/sec_battery_sysfs.c b/drivers/battery_v2/sec_battery_sysfs.c index ccc2948f6..57a706bf4 100644 --- a/drivers/battery_v2/sec_battery_sysfs.c +++ b/drivers/battery_v2/sec_battery_sysfs.c @@ -1457,6 +1457,10 @@ ssize_t sec_bat_show_attrs(struct device *dev, size = sizeof(temp_buf) - strlen(temp_buf); } mutex_unlock(&pcisd->powerlock); + + /* clear daily power data */ + init_cisd_power_data(&battery->cisd); + i += scnprintf(buf + i, PAGE_SIZE - i, "%s\n", temp_buf); } break; @@ -1983,16 +1987,19 @@ ssize_t sec_bat_store_attrs( break; case BATT_SLATE_MODE: if (sscanf(buf, "%10d\n", &x) == 1) { - if (x == is_slate_mode(battery)) { + if (x == SB_SLATE_SMART) { + sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_SLATE, SEC_BAT_CURRENT_EVENT_SLATE); + battery->slate_mode = x; dev_info(battery->dev, - "%s : skip same slate mode : %d\n", __func__, x); - return count; - } else if (x == 1) { + "%s: enable smart switch slate mode : %d\n", __func__, x); + } else if (x == SB_SLATE_NORMAL) { sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_SLATE, SEC_BAT_CURRENT_EVENT_SLATE); + battery->slate_mode = x; dev_info(battery->dev, "%s: enable slate mode : %d\n", __func__, x); - } else if (x == 0) { + } else if (x == SB_SLATE_NONE) { sec_bat_set_current_event(battery, 0, SEC_BAT_CURRENT_EVENT_SLATE); + battery->slate_mode = x; dev_info(battery->dev, "%s: disable slate mode : %d\n", __func__, x); } else { diff --git a/drivers/battery_v2/sec_dual_battery.c b/drivers/battery_v2/sec_dual_battery.c index cfa8ae6b4..d1e99c74e 100644 --- a/drivers/battery_v2/sec_dual_battery.c +++ b/drivers/battery_v2/sec_dual_battery.c @@ -116,49 +116,6 @@ static int sec_dual_check_eoc_status(struct sec_dual_battery_info *battery) return POWER_SUPPLY_STATUS_CHARGING; } -/* this function dose not work after 1st full charging, this is only for 2nd full charging */ -static int sec_dual_check_each_eoc(struct sec_dual_battery_info *battery) -{ - union power_supply_propval value; - bool eoc_status = false; - - value.intval = SEC_BATTERY_CURRENT_MA; - psy_do_property(battery->pdata->main_limiter_name, get, - (enum power_supply_property)POWER_SUPPLY_EXT_PROP_CHG_CURRENT, value); - battery->main_current_avg = value.intval; - - if ((battery->main_current_avg <= battery->pdata->main_full_condition_eoc) - && (battery->main_voltage_avg >= battery->pdata->main_full_condition_vcell[battery->age_step])) { - pr_info("%s Main Batt eoc condition is done (1st charging)\n", __func__); - battery->full_total_status |= SEC_DUAL_BATTERY_MAIN_CONDITION_DONE; - /* main supplement mode enable */ - value.intval = 1; - psy_do_property(battery->pdata->main_limiter_name, set, - POWER_SUPPLY_PROP_CHARGE_FULL, value); - eoc_status = true; - } - - value.intval = SEC_BATTERY_CURRENT_MA; - psy_do_property(battery->pdata->sub_limiter_name, get, - (enum power_supply_property)POWER_SUPPLY_EXT_PROP_CHG_CURRENT, value); - battery->sub_current_avg = value.intval; - - if ((battery->sub_current_avg <= battery->pdata->sub_full_condition_eoc) - && (battery->sub_voltage_avg >= battery->pdata->sub_full_condition_vcell[battery->age_step])) { - pr_info("%s Sub Batt eoc condition is done (1st charging)\n", __func__); - battery->full_total_status |= SEC_DUAL_BATTERY_SUB_CONDITION_DONE; - /* main supplement mode enable */ - value.intval = 1; - psy_do_property(battery->pdata->sub_limiter_name, set, - POWER_SUPPLY_PROP_CHARGE_FULL, value); - eoc_status = true; - } - if (eoc_status) - return POWER_SUPPLY_STATUS_FULL; - else - return POWER_SUPPLY_STATUS_CHARGING; -} - #if 0 static int sec_dual_check_eoc_current(struct sec_dual_battery_info *battery) { @@ -267,9 +224,6 @@ static int sec_dual_battery_get_property(struct power_supply *psy, __func__, value.intval); } break; - case POWER_SUPPLY_PROP_CHARGE_FULL: - val->intval = sec_dual_check_each_eoc(battery); - break; case POWER_SUPPLY_PROP_VOLTAGE_AVG: if (value.intval == SEC_DUAL_BATTERY_MAIN) val->intval = sec_dual_battery_voltage_avg(battery, SEC_DUAL_BATTERY_MAIN, SEC_BATTERY_VOLTAGE_MV); diff --git a/drivers/battery_v2/sec_step_charging.c b/drivers/battery_v2/sec_step_charging.c index 84e1b4a35..289908af0 100644 --- a/drivers/battery_v2/sec_step_charging.c +++ b/drivers/battery_v2/sec_step_charging.c @@ -28,27 +28,38 @@ void sec_bat_reset_step_charging(struct sec_battery_info *battery) { pr_info("%s\n", __func__); - battery->step_charging_status = -1; + + if ((battery->step_charging_type) && + (battery->step_charging_status >= 0) && + (battery->step_charging_status < battery->step_charging_step)) { + + pr_info("%s: reset state about step charging(not dc step)\n", __func__); #if defined(CONFIG_DIRECT_CHARGING) - battery->dc_float_voltage_set = false; + if (!is_pd_apdo_wire_type(battery->cable_type)) + battery->pdata->charging_current[battery->cable_type].fast_charging_current = + battery->pdata->step_charging_current[battery->pdata->age_step][battery->step_charging_step-1]; #endif -} + if ((battery->step_charging_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) && + (battery->swelling_mode == SWELLING_MODE_NONE)) { + int new_fv = battery->pdata->step_charging_float_voltage[battery->pdata->age_step][battery->step_charging_step-1]; + union power_supply_propval val; -void sec_bat_exit_step_charging(struct sec_battery_info *battery) -{ - battery->pdata->charging_current[battery->cable_type].fast_charging_current = - battery->pdata->step_charging_current[battery->pdata->age_step][battery->step_charging_step-1]; - if ((battery->step_charging_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) && - (battery->swelling_mode == SWELLING_MODE_NONE)) { - union power_supply_propval val; - - pr_info("%s : float voltage = %d\n", __func__, - battery->pdata->step_charging_float_voltage[battery->pdata->age_step][battery->step_charging_step-1]); - val.intval = battery->pdata->step_charging_float_voltage[battery->pdata->age_step][battery->step_charging_step-1]; - psy_do_property(battery->pdata->charger_name, set, - POWER_SUPPLY_PROP_VOLTAGE_MAX, val); + psy_do_property(battery->pdata->charger_name, get, + POWER_SUPPLY_PROP_VOLTAGE_MAX, val); + pr_info("%s : float voltage = %d <--> %d\n", __func__, val.intval, new_fv); + + if (val.intval != new_fv) { + val.intval = new_fv; + psy_do_property(battery->pdata->charger_name, set, + POWER_SUPPLY_PROP_VOLTAGE_MAX, val); + } + } } - sec_bat_reset_step_charging(battery); + + battery->step_charging_status = -1; +#if defined(CONFIG_DIRECT_CHARGING) + battery->dc_float_voltage_set = false; +#endif } /* @@ -106,7 +117,7 @@ bool sec_bat_check_step_charging(struct sec_battery_info *battery) if (battery->step_charging_type & STEP_CHARGING_CONDITION_CHARGE_POWER) { if (battery->max_charge_power < battery->step_charging_charge_power) { /* In case of max_charge_power falling by AICL during step-charging ongoing */ - sec_bat_exit_step_charging(battery); + sec_bat_reset_step_charging(battery); return false; } } @@ -432,9 +443,8 @@ bool sec_bat_check_dc_step_charging(struct sec_battery_info *battery) if (battery->step_charging_status < 0) { pr_info("%s : step input current = %d\n", __func__, battery->pdata->dc_step_chg_val_iout[battery->pdata->age_step][step] / 2); - val.intval = battery->pdata->dc_step_chg_val_iout[battery->pdata->age_step][step] / 2; - psy_do_property(battery->pdata->charger_name, set, - POWER_SUPPLY_EXT_PROP_DIRECT_CURRENT_MAX, val); + /* updated charging current */ + sec_bat_refresh_charging_current(battery); } battery->step_charging_status = step; @@ -764,7 +774,8 @@ void sec_bat_set_aging_info_step_charging(struct sec_battery_info *battery) if (battery->pdata->dc_step_chg_val_vfloat[battery->pdata->age_step][i] > battery->pdata->chg_float_voltage) battery->pdata->dc_step_chg_val_vfloat[battery->pdata->age_step][i] = battery->pdata->chg_float_voltage; if (battery->dc_step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE) - battery->pdata->dc_step_chg_cond_vol[i] = battery->pdata->dc_step_chg_val_vfloat[battery->pdata->age_step][i]; + if (battery->pdata->dc_step_chg_cond_vol[i] > battery->pdata->chg_float_voltage) + battery->pdata->dc_step_chg_cond_vol[i] = battery->pdata->chg_float_voltage; if ((battery->dc_step_chg_type & STEP_CHARGING_CONDITION_INPUT_CURRENT) && (i < battery->dc_step_chg_step - 1)) battery->pdata->dc_step_chg_cond_iin[i] = battery->pdata->dc_step_chg_val_iout[battery->pdata->age_step][i+1] / 2; } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 9cd231a27..5a8104cc9 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -225,24 +225,35 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) blk_mq_unfreeze_queue(lo->lo_queue); } +/** + * loop_validate_block_size() - validates the passed in block size + * @bsize: size to validate + */ static int -figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) +loop_validate_block_size(unsigned short bsize) +{ + if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize)) + return -EINVAL; + + return 0; +} + +/** + * loop_set_size() - sets device size and notifies userspace + * @lo: struct loop_device to set the size for + * @size: new size of the loop device + * + * Callers must validate that the size passed into this function fits into + * a sector_t, eg using loop_validate_size() + */ +static void loop_set_size(struct loop_device *lo, loff_t size) { - loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); - sector_t x = (sector_t)size; struct block_device *bdev = lo->lo_device; - if (unlikely((loff_t)x != size)) - return -EFBIG; - if (lo->lo_offset != offset) - lo->lo_offset = offset; - if (lo->lo_sizelimit != sizelimit) - lo->lo_sizelimit = sizelimit; - set_capacity(lo->lo_disk, x); - bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9); + set_capacity(lo->lo_disk, size); + bd_set_size(bdev, size << SECTOR_SHIFT); /* let user-space know about the new size */ kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); - return 0; } static inline int @@ -911,22 +922,124 @@ static int loop_prepare_queue(struct loop_device *lo) return 0; } -static int loop_set_fd(struct loop_device *lo, fmode_t mode, - struct block_device *bdev, unsigned int arg) +static int +loop_release_xfer(struct loop_device *lo) +{ + int err = 0; + struct loop_func_table *xfer = lo->lo_encryption; + + if (xfer) { + if (xfer->release) + err = xfer->release(lo); + lo->transfer = NULL; + lo->lo_encryption = NULL; + module_put(xfer->owner); + } + return err; +} + +static int +loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, + const struct loop_info64 *i) +{ + int err = 0; + + if (xfer) { + struct module *owner = xfer->owner; + + if (!try_module_get(owner)) + return -EINVAL; + if (xfer->init) + err = xfer->init(lo, i); + if (err) + module_put(owner); + else + lo->lo_encryption = xfer; + } + return err; +} + +/** + * loop_set_status_from_info - configure device from loop_info + * @lo: struct loop_device to configure + * @info: struct loop_info64 to configure the device with + * + * Configures the loop device parameters according to the passed + * in loop_info64 configuration. + */ +static int +loop_set_status_from_info(struct loop_device *lo, + const struct loop_info64 *info) +{ + int err; + struct loop_func_table *xfer; + kuid_t uid = current_uid(); + + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) + return -EINVAL; + + err = loop_release_xfer(lo); + if (err) + return err; + + if (info->lo_encrypt_type) { + unsigned int type = info->lo_encrypt_type; + + if (type >= MAX_LO_CRYPT) + return -EINVAL; + xfer = xfer_funcs[type]; + if (xfer == NULL) + return -EINVAL; + } else + xfer = NULL; + + err = loop_init_xfer(lo, xfer, info); + if (err) + return err; + + lo->lo_offset = info->lo_offset; + lo->lo_sizelimit = info->lo_sizelimit; + memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); + memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); + lo->lo_file_name[LO_NAME_SIZE-1] = 0; + lo->lo_crypt_name[LO_NAME_SIZE-1] = 0; + + if (!xfer) + xfer = &none_funcs; + lo->transfer = xfer->transfer; + lo->ioctl = xfer->ioctl; + + lo->lo_flags = info->lo_flags; + + lo->lo_encrypt_key_size = info->lo_encrypt_key_size; + lo->lo_init[0] = info->lo_init[0]; + lo->lo_init[1] = info->lo_init[1]; + if (info->lo_encrypt_key_size) { + memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, + info->lo_encrypt_key_size); + lo->lo_key_owner = uid; + } + + return 0; +} + +static int loop_configure(struct loop_device *lo, fmode_t mode, + struct block_device *bdev, + const struct loop_config *config) { struct file *file; struct inode *inode; struct address_space *mapping; - int lo_flags = 0; int error; loff_t size; bool partscan; + unsigned short bsize; /* This is safe, since we have a reference from open(). */ __module_get(THIS_MODULE); error = -EBADF; - file = fget(arg); + file = fget(config->fd); if (!file) goto out; @@ -945,41 +1058,59 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, mapping = file->f_mapping; inode = mapping->host; + size = get_loop_size(lo, file); + + if ((config->info.lo_flags & ~LOOP_CONFIGURE_SETTABLE_FLAGS) != 0) { + error = -EINVAL; + goto out_unlock; + } + + if (config->block_size) { + error = loop_validate_block_size(config->block_size); + if (error) + goto out_unlock; + } + + error = loop_set_status_from_info(lo, &config->info); + if (error) + goto out_unlock; + if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) || !file->f_op->write_iter) - lo_flags |= LO_FLAGS_READ_ONLY; + lo->lo_flags |= LO_FLAGS_READ_ONLY; - error = -EFBIG; - size = get_loop_size(lo, file); - if ((loff_t)(sector_t)size != size) - goto out_unlock; error = loop_prepare_queue(lo); if (error) goto out_unlock; error = 0; - set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); + set_device_ro(bdev, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0); - lo->use_dio = false; + lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO; lo->lo_device = bdev; - lo->lo_flags = lo_flags; lo->lo_backing_file = file; - lo->transfer = NULL; - lo->ioctl = NULL; - lo->lo_sizelimit = 0; lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); - if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) + if (!(lo->lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) blk_queue_write_cache(lo->lo_queue, true, false); + if (config->block_size) + bsize = config->block_size; + else if (io_is_direct(lo->lo_backing_file) && inode->i_sb->s_bdev) + /* In case of direct I/O, match underlying block size */ + bsize = bdev_logical_block_size(inode->i_sb->s_bdev); + else + bsize = 512; + + blk_queue_logical_block_size(lo->lo_queue, bsize); + blk_queue_physical_block_size(lo->lo_queue, bsize); + blk_queue_io_min(lo->lo_queue, bsize); + loop_update_dio(lo); - set_capacity(lo->lo_disk, size); - bd_set_size(bdev, size << 9); loop_sysfs_init(lo); - /* let user-space know about the new size */ - kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); + loop_set_size(lo, size); set_blocksize(bdev, S_ISBLK(inode->i_mode) ? block_size(inode->i_bdev) : PAGE_SIZE); @@ -1008,43 +1139,6 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, return error; } -static int -loop_release_xfer(struct loop_device *lo) -{ - int err = 0; - struct loop_func_table *xfer = lo->lo_encryption; - - if (xfer) { - if (xfer->release) - err = xfer->release(lo); - lo->transfer = NULL; - lo->lo_encryption = NULL; - module_put(xfer->owner); - } - return err; -} - -static int -loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, - const struct loop_info64 *i) -{ - int err = 0; - - if (xfer) { - struct module *owner = xfer->owner; - - if (!try_module_get(owner)) - return -EINVAL; - if (xfer->init) - err = xfer->init(lo, i); - if (err) - module_put(owner); - else - lo->lo_encryption = xfer; - } - return err; -} - static int __loop_clr_fd(struct loop_device *lo, bool release) { struct file *filp = NULL; @@ -1192,10 +1286,11 @@ static int loop_set_status(struct loop_device *lo, const struct loop_info64 *info) { int err; - struct loop_func_table *xfer; - kuid_t uid = current_uid(); struct block_device *bdev; + kuid_t uid = current_uid(); + int prev_lo_flags; bool partscan = false; + bool size_changed = false; err = mutex_lock_killable(&loop_ctl_mutex); if (err) @@ -1210,93 +1305,55 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) err = -ENXIO; goto out_unlock; } - if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) { - err = -EINVAL; - goto out_unlock; - } if (lo->lo_offset != info->lo_offset || lo->lo_sizelimit != info->lo_sizelimit) { + size_changed = true; sync_blockdev(lo->lo_device); - kill_bdev(lo->lo_device); + invalidate_bdev(lo->lo_device); } /* I/O need to be drained during transfer transition */ blk_mq_freeze_queue(lo->lo_queue); - err = loop_release_xfer(lo); - if (err) + if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) { + /* If any pages were dirtied after kill_bdev(), try again */ + err = -EAGAIN; + pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", + __func__, lo->lo_number, lo->lo_file_name, + lo->lo_device->bd_inode->i_mapping->nrpages); goto out_unfreeze; + } - if (info->lo_encrypt_type) { - unsigned int type = info->lo_encrypt_type; - - if (type >= MAX_LO_CRYPT) { - err = -EINVAL; - goto out_unfreeze; - } - xfer = xfer_funcs[type]; - if (xfer == NULL) { - err = -EINVAL; - goto out_unfreeze; - } - } else - xfer = NULL; + prev_lo_flags = lo->lo_flags; - err = loop_init_xfer(lo, xfer, info); + err = loop_set_status_from_info(lo, info); if (err) goto out_unfreeze; - if (lo->lo_offset != info->lo_offset || - lo->lo_sizelimit != info->lo_sizelimit) { - /* kill_bdev should have truncated all the pages */ - if (lo->lo_device->bd_inode->i_mapping->nrpages) { - err = -EAGAIN; - pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", - __func__, lo->lo_number, lo->lo_file_name, - lo->lo_device->bd_inode->i_mapping->nrpages); - goto out_unfreeze; - } - if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) { - err = -EFBIG; - goto out_unfreeze; - } + /* Mask out flags that can't be set using LOOP_SET_STATUS. */ + lo->lo_flags &= LOOP_SET_STATUS_SETTABLE_FLAGS; + /* For those flags, use the previous values instead */ + lo->lo_flags |= prev_lo_flags & ~LOOP_SET_STATUS_SETTABLE_FLAGS; + /* For flags that can't be cleared, use previous values too */ + lo->lo_flags |= prev_lo_flags & ~LOOP_SET_STATUS_CLEARABLE_FLAGS; + + if (size_changed) { + loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit, + lo->lo_backing_file); + loop_set_size(lo, new_size); } loop_config_discard(lo); - memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); - memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); - lo->lo_file_name[LO_NAME_SIZE-1] = 0; - lo->lo_crypt_name[LO_NAME_SIZE-1] = 0; - - if (!xfer) - xfer = &none_funcs; - lo->transfer = xfer->transfer; - lo->ioctl = xfer->ioctl; - - if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) != - (info->lo_flags & LO_FLAGS_AUTOCLEAR)) - lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; - - lo->lo_encrypt_key_size = info->lo_encrypt_key_size; - lo->lo_init[0] = info->lo_init[0]; - lo->lo_init[1] = info->lo_init[1]; - if (info->lo_encrypt_key_size) { - memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, - info->lo_encrypt_key_size); - lo->lo_key_owner = uid; - } - /* update dio if lo_offset or transfer is changed */ __loop_update_dio(lo, lo->use_dio); out_unfreeze: blk_mq_unfreeze_queue(lo->lo_queue); - if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) && - !(lo->lo_flags & LO_FLAGS_PARTSCAN)) { - lo->lo_flags |= LO_FLAGS_PARTSCAN; + if (!err && (lo->lo_flags & LO_FLAGS_PARTSCAN) && + !(prev_lo_flags & LO_FLAGS_PARTSCAN)) { lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; bdev = lo->lo_device; partscan = true; @@ -1460,10 +1517,15 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { static int loop_set_capacity(struct loop_device *lo) { + loff_t size; + if (unlikely(lo->lo_state != Lo_bound)) return -ENXIO; - return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); + size = get_loop_size(lo, lo->lo_backing_file); + loop_set_size(lo, size); + + return 0; } static int loop_set_dio(struct loop_device *lo, unsigned long arg) @@ -1487,17 +1549,18 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) if (lo->lo_state != Lo_bound) return -ENXIO; - if (arg < 512 || arg > PAGE_SIZE || !is_power_of_2(arg)) - return -EINVAL; + err = loop_validate_block_size(arg); + if (err) + return err; if (lo->lo_queue->limits.logical_block_size != arg) { sync_blockdev(lo->lo_device); - kill_bdev(lo->lo_device); + invalidate_bdev(lo->lo_device); } blk_mq_freeze_queue(lo->lo_queue); - /* kill_bdev should have truncated all the pages */ + /* invalidate_bdev should have truncated all the pages */ if (lo->lo_queue->limits.logical_block_size != arg && lo->lo_device->bd_inode->i_mapping->nrpages) { err = -EAGAIN; @@ -1546,11 +1609,31 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct loop_device *lo = bdev->bd_disk->private_data; + void __user *argp = (void __user *) arg; int err; switch (cmd) { - case LOOP_SET_FD: - return loop_set_fd(lo, mode, bdev, arg); + case LOOP_SET_FD: { + /* + * Legacy case - pass in a zeroed out struct loop_config with + * only the file descriptor set , which corresponds with the + * default parameters we'd have used otherwise. + */ + struct loop_config config; + + memset(&config, 0, sizeof(config)); + config.fd = arg; + + return loop_configure(lo, mode, bdev, &config); + } + case LOOP_CONFIGURE: { + struct loop_config config; + + if (copy_from_user(&config, argp, sizeof(config))) + return -EFAULT; + + return loop_configure(lo, mode, bdev, &config); + } case LOOP_CHANGE_FD: return loop_change_fd(lo, bdev, arg); case LOOP_CLR_FD: @@ -1558,21 +1641,19 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_SET_STATUS: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { - err = loop_set_status_old(lo, - (struct loop_info __user *)arg); + err = loop_set_status_old(lo, argp); } break; case LOOP_GET_STATUS: - return loop_get_status_old(lo, (struct loop_info __user *) arg); + return loop_get_status_old(lo, argp); case LOOP_SET_STATUS64: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { - err = loop_set_status64(lo, - (struct loop_info64 __user *) arg); + err = loop_set_status64(lo, argp); } break; case LOOP_GET_STATUS64: - return loop_get_status64(lo, (struct loop_info64 __user *) arg); + return loop_get_status64(lo, argp); case LOOP_SET_CAPACITY: case LOOP_SET_DIRECT_IO: case LOOP_SET_BLOCK_SIZE: @@ -1724,6 +1805,7 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_CLR_FD: case LOOP_GET_STATUS64: case LOOP_SET_STATUS64: + case LOOP_CONFIGURE: arg = (unsigned long) compat_ptr(arg); /* fall through */ case LOOP_SET_FD: diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index b5d9eec26..dfa956af3 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -654,23 +654,24 @@ static unsigned long alloc_block_bdev(struct zram *zram) static void free_block_bdev(struct zram *zram, unsigned long blk_idx) { int was_set; - #ifdef CONFIG_ZRAM_LRU_WRITEBACK - spin_lock(&zram->wb_table_lock); + unsigned long flags; + + spin_lock_irqsave(&zram->wb_table_lock, flags); if (zram->wb_table[blk_idx] == 0) { count_vm_events(SQZR_COUNT, -1); atomic64_dec(&zram->stats.bd_count); - spin_unlock(&zram->wb_table_lock); + spin_unlock_irqrestore(&zram->wb_table_lock, flags); return; } zram->wb_table[blk_idx]--; atomic64_dec(&zram->stats.bd_objcnt); count_vm_events(SQZR_OBJCNT, -1); if (zram->wb_table[blk_idx] > 0) { - spin_unlock(&zram->wb_table_lock); + spin_unlock_irqrestore(&zram->wb_table_lock, flags); return; } - spin_unlock(&zram->wb_table_lock); + spin_unlock_irqrestore(&zram->wb_table_lock, flags); count_vm_events(SQZR_COUNT, -1); #endif was_set = test_and_clear_bit(blk_idx, zram->bitmap); @@ -964,10 +965,11 @@ static void zram_writeback_done(struct zram *zram, unsigned long blk_idx, unsigned int offset; unsigned int size; int i; + unsigned long flags; - spin_lock(&zram->wb_table_lock); + spin_lock_irqsave(&zram->wb_table_lock, flags); zram->wb_table[blk_idx] = count; - spin_unlock(&zram->wb_table_lock); + spin_unlock_irqrestore(&zram->wb_table_lock, flags); atomic64_add(count, &zram->stats.bd_objcnt); count_vm_events(SQZR_OBJCNT, count); @@ -1499,6 +1501,7 @@ static void zram_handle_comp_page(struct work_struct *work) unsigned int size = zw->handle & (PAGE_SIZE - 1); u8 *src, *dst; int ret; + unsigned long flags; src = kmap_atomic(src_page); zhdr = (struct zram_wb_header *)(src + offset); @@ -1525,9 +1528,9 @@ static void zram_handle_comp_page(struct work_struct *work) zram_slot_unlock(zram, handle); /* increment refcount to prevent freeing block */ - spin_lock(&zram->wb_table_lock); + spin_lock_irqsave(&zram->wb_table_lock, flags); zram->wb_table[blk_idx]++; - spin_unlock(&zram->wb_table_lock); + spin_unlock_irqrestore(&zram->wb_table_lock, flags); page_endio(dst_page, op_is_write(bio_op(bio)), blk_status_to_errno(bio->bi_status)); diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c index 4add21017..3ed10f3b7 100644 --- a/drivers/bluetooth/bluetooth-power.c +++ b/drivers/bluetooth/bluetooth-power.c @@ -289,6 +289,67 @@ static int bt_clk_disable(struct bt_power_clk_data *clk) return rc; } +static int bt_enable_bt_reset_gpios_safely(void) +{ + int rc = 0; + int bt_reset_gpio = bt_power_pdata->bt_gpio_sys_rst; + int wl_reset_gpio = bt_power_pdata->wl_gpio_sys_rst; + + if (wl_reset_gpio >= 0) { + BT_PWR_INFO("%s: BTON:Turn Bt On", __func__); + BT_PWR_INFO("%s: wl-reset-gpio(%d) value(%d)", + __func__, wl_reset_gpio, + gpio_get_value(wl_reset_gpio)); + } + + if ((wl_reset_gpio < 0) || + ((wl_reset_gpio >= 0) && + gpio_get_value(wl_reset_gpio))) { + BT_PWR_INFO("%s: BTON: Asserting BT_EN", + __func__); + rc = gpio_direction_output(bt_reset_gpio, 1); + if (rc) { + BT_PWR_ERR("%s: Unable to set direction", + __func__); + return rc; + } + bt_power_src_status[BT_RESET_GPIO] = + gpio_get_value(bt_reset_gpio); + } + + if ((wl_reset_gpio >= 0) && + (gpio_get_value(wl_reset_gpio) == 0)) { + if (gpio_get_value(bt_reset_gpio)) { + BT_PWR_INFO("%s: Wlan Off and BT On too close", + __func__); + BT_PWR_INFO("%s: Reset BT_EN", __func__); + BT_PWR_INFO("%s: Enable it after delay", + __func__); + rc = gpio_direction_output(bt_reset_gpio, 0); + if (rc) { + BT_PWR_ERR("%s:Unable to set direction", + __func__); + return rc; + } + bt_power_src_status[BT_RESET_GPIO] = + gpio_get_value(bt_reset_gpio); + } + BT_PWR_INFO("%s: 100ms delay added", __func__); + BT_PWR_INFO("%s: for AON output to fully discharge", + __func__); + msleep(100); + rc = gpio_direction_output(bt_reset_gpio, 1); + if (rc) { + BT_PWR_ERR("%s: Unable to set direction", + __func__); + return rc; + } + bt_power_src_status[BT_RESET_GPIO] = + gpio_get_value(bt_reset_gpio); + } + return rc; +} + static int bt_configure_gpios(int on) { int rc = 0; @@ -313,7 +374,7 @@ static int bt_configure_gpios(int on) bt_power_src_status[BT_RESET_GPIO] = gpio_get_value(bt_reset_gpio); msleep(50); - BT_PWR_INFO("BTON:Turn Bt Off bt-reset-gpio(%d) value(%d)\n", + BT_PWR_INFO("BTON:Turn Bt Off bt-reset-gpio(%d) value(%d)", bt_reset_gpio, gpio_get_value(bt_reset_gpio)); if (bt_sw_ctrl_gpio >= 0) { BT_PWR_INFO("BTON:Turn Bt Off"); @@ -324,14 +385,12 @@ static int bt_configure_gpios(int on) bt_power_src_status[BT_SW_CTRL_GPIO]); } - rc = gpio_direction_output(bt_reset_gpio, 1); - + rc = bt_enable_bt_reset_gpios_safely(); if (rc) { - BT_PWR_ERR("Unable to set direction\n"); - return rc; + BT_PWR_ERR("%s:bt_enable_bt_reset_gpios_safely failed", + __func__); } - bt_power_src_status[BT_RESET_GPIO] = - gpio_get_value(bt_reset_gpio); + msleep(50); /* Check if SW_CTRL is asserted */ if (bt_sw_ctrl_gpio >= 0) { @@ -385,6 +444,18 @@ static int bt_configure_gpios(int on) return rc; } +static void bt_free_gpios(void) +{ + if (bt_power_pdata->bt_gpio_sys_rst > 0) + gpio_free(bt_power_pdata->bt_gpio_sys_rst); + if (bt_power_pdata->wl_gpio_sys_rst > 0) + gpio_free(bt_power_pdata->wl_gpio_sys_rst); + if (bt_power_pdata->bt_gpio_sw_ctrl > 0) + gpio_free(bt_power_pdata->bt_gpio_sw_ctrl); + if (bt_power_pdata->bt_gpio_debug > 0) + gpio_free(bt_power_pdata->bt_gpio_debug); +} + static int bluetooth_power(int on) { int rc = 0; @@ -548,12 +619,9 @@ static int bluetooth_power(int on) if (bt_power_pdata->bt_gpio_sys_rst > 0) bt_configure_gpios(on); gpio_fail: - if (bt_power_pdata->bt_gpio_sys_rst > 0) - gpio_free(bt_power_pdata->bt_gpio_sys_rst); - if (bt_power_pdata->bt_gpio_sw_ctrl > 0) - gpio_free(bt_power_pdata->bt_gpio_sw_ctrl); - if (bt_power_pdata->bt_gpio_debug > 0) - gpio_free(bt_power_pdata->bt_gpio_debug); + //Free Gpios + bt_free_gpios(); + if (bt_power_pdata->bt_chip_clk) bt_clk_disable(bt_power_pdata->bt_chip_clk); clk_fail: @@ -822,6 +890,12 @@ static int bt_power_populate_dt_pinfo(struct platform_device *pdev) if (bt_power_pdata->bt_gpio_sys_rst < 0) BT_PWR_INFO("bt-reset-gpio not provided in devicetree"); + bt_power_pdata->wl_gpio_sys_rst = + of_get_named_gpio(pdev->dev.of_node, + "qca,wl-reset-gpio", 0); + if (bt_power_pdata->wl_gpio_sys_rst < 0) + BT_PWR_INFO("wl-reset-gpio not provided in devicetree"); + bt_power_pdata->bt_gpio_sw_ctrl = of_get_named_gpio(pdev->dev.of_node, "qca,bt-sw-ctrl-gpio", 0); diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 53324844c..2981bcb11 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include #include @@ -556,18 +556,6 @@ int mhi_queue_dma(struct mhi_device *mhi_dev, mhi_tre->dword[0] = MHI_RSCTRE_DATA_DWORD0(buf_ring->wp - buf_ring->base); mhi_tre->dword[1] = MHI_RSCTRE_DATA_DWORD1; - /* - * on RSC channel IPA HW has a minimum credit requirement before - * switching to DB mode - */ - n_free_tre = mhi_get_no_free_descriptors(mhi_dev, - DMA_FROM_DEVICE); - n_queued_tre = tre_ring->elements - n_free_tre; - read_lock_bh(&mhi_chan->lock); - if (mhi_chan->db_cfg.db_mode && - n_queued_tre < MHI_RSC_MIN_CREDITS) - ring_db = false; - read_unlock_bh(&mhi_chan->lock); } else { mhi_tre->ptr = MHI_TRE_DATA_PTR(buf_info->p_addr); mhi_tre->dword[0] = MHI_TRE_DATA_DWORD0(buf_info->len); @@ -585,12 +573,24 @@ int mhi_queue_dma(struct mhi_device *mhi_dev, if (mhi_chan->dir == DMA_TO_DEVICE) atomic_inc(&mhi_cntrl->pending_pkts); - if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl)) && ring_db) { - read_lock_bh(&mhi_chan->lock); - mhi_ring_chan_db(mhi_cntrl, mhi_chan); - read_unlock_bh(&mhi_chan->lock); + read_lock_bh(&mhi_chan->lock); + if (mhi_chan->xfer_type == MHI_XFER_RSC_DMA) { + /* + * on RSC channel IPA HW has a minimum credit requirement before + * switching to DB mode + */ + n_free_tre = mhi_get_no_free_descriptors(mhi_dev, + DMA_FROM_DEVICE); + n_queued_tre = tre_ring->elements - n_free_tre; + if (mhi_chan->db_cfg.db_mode && + n_queued_tre < MHI_RSC_MIN_CREDITS) + ring_db = false; } - + if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl)) && ring_db) + mhi_ring_chan_db(mhi_cntrl, mhi_chan); + + read_unlock_bh(&mhi_chan->lock); + read_unlock_bh(&mhi_cntrl->pm_lock); return 0; diff --git a/drivers/bus/mhi/devices/mhi_netdev.c b/drivers/bus/mhi/devices/mhi_netdev.c index e5400bec6..370175a9e 100644 --- a/drivers/bus/mhi/devices/mhi_netdev.c +++ b/drivers/bus/mhi/devices/mhi_netdev.c @@ -1104,7 +1104,9 @@ static int mhi_netdev_probe(struct mhi_device *mhi_dev, init_waitqueue_head(&mhi_netdev->alloc_event); INIT_LIST_HEAD(mhi_netdev->bg_pool); spin_lock_init(&mhi_netdev->bg_lock); - mhi_netdev->bg_pool_limit = mhi_netdev->pool_size / 4; + + /* incread bg_pool_limit size */ + mhi_netdev->bg_pool_limit = mhi_netdev->pool_size; mhi_netdev->alloc_task = kthread_run(mhi_netdev_alloc_thread, mhi_netdev, mhi_netdev->ndev->name); diff --git a/drivers/ccic/max77705_pd.c b/drivers/ccic/max77705_pd.c index 3995bdc23..5240cdce6 100755 --- a/drivers/ccic/max77705_pd.c +++ b/drivers/ccic/max77705_pd.c @@ -321,7 +321,7 @@ int max77705_get_apdo_max_power(unsigned int *pdo_pos, unsigned int *taMaxVol, u if (!(pd_noti.sink_status.power_list[i].apdo)) { max_voltage = pd_noti.sink_status.power_list[i].max_voltage; max_current = pd_noti.sink_status.power_list[i].max_current; - max_power = max_voltage*max_current; /* uW */ + max_power = (max_voltage * max_current > max_power) ? (max_voltage * max_current) : max_power; *taMaxPwr = max_power; /* mW */ } } diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 2efaf5b0e..0a8726247 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -3654,6 +3654,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) hlist_del_init(&fl->hn); spin_unlock(&fl->apps->hlock); kfree(fl->debug_buf); + fl->debug_buf_alloced_attempted = 0; if (!fl->sctx) { kfree(fl); @@ -4072,11 +4073,14 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl) { int err = 0, buf_size = 0; char strpid[PID_SIZE]; + char cur_comm[TASK_COMM_LEN]; + memcpy(cur_comm, current->comm, TASK_COMM_LEN); + cur_comm[TASK_COMM_LEN-1] = '\0'; fl->tgid = current->tgid; snprintf(strpid, PID_SIZE, "%d", current->pid); if (debugfs_root) { - buf_size = strlen(current->comm) + strlen("_") + buf_size = strlen(cur_comm) + strlen("_") + strlen(strpid) + 1; spin_lock(&fl->hlock); @@ -4092,15 +4096,16 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl) err = -ENOMEM; return err; } - snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d", - current->comm, "_", current->pid); + snprintf(fl->debug_buf, buf_size, "%.10s%s%d", + cur_comm, "_", current->pid); fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644, debugfs_root, fl, &debugfs_fops); if (IS_ERR_OR_NULL(fl->debugfs_file)) { pr_warn("Error: %s: %s: failed to create debugfs file %s\n", - current->comm, __func__, fl->debug_buf); + cur_comm, __func__, fl->debug_buf); fl->debugfs_file = NULL; kfree(fl->debug_buf); + fl->debug_buf_alloced_attempted = 0; fl->debug_buf = NULL; } } diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index d30a675cd..ad6bfde59 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1069,6 +1069,11 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, return; } + if (token != entry->client_info.token) { + mutex_unlock(&driver->dci_mutex); + return; + } + mutex_lock(&entry->buffers[data_source].buf_mutex); rsp_buf = entry->buffers[data_source].buf_cmd; @@ -1740,7 +1745,16 @@ static int diag_send_dci_pkt_remote(unsigned char *data, int len, int tag, write_len += dci_header_size; *(int *)(buf + write_len) = tag; write_len += sizeof(int); - memcpy(buf + write_len, data, len); + if ((write_len + len) < DIAG_MDM_BUF_SIZE) { + memcpy(buf + write_len, data, len); + } else { + pr_err("diag: skip writing invalid length packet, token: %d, pkt_len: %d\n", + token, (write_len + len)); + spin_lock_irqsave(&driver->dci_mempool_lock, flags); + diagmem_free(driver, buf, dci_ops_tbl[token].mempool); + spin_unlock_irqrestore(&driver->dci_mempool_lock, flags); + return -EAGAIN; + } write_len += len; *(buf + write_len) = CONTROL_CHAR; /* End Terminator */ write_len += sizeof(uint8_t); diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index d40f2f21b..fbdddc2f6 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2008-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved. */ #include @@ -3120,8 +3120,12 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, return -EINVAL; } - err = copy_to_user(buf, mask_info->update_buf_client, + if ((count - (sizeof(int))) >= mask_info->update_buf_client_len) { + err = copy_to_user(buf, mask_info->update_buf_client, mask_info->update_buf_client_len); + } else { + err = -EINVAL; + } if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); @@ -3147,8 +3151,12 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count, return -EINVAL; } - err = copy_to_user(buf, mask_info->update_buf_client, + if ((count - (sizeof(int))) >= mask_info->update_buf_client_len) { + err = copy_to_user(buf, mask_info->update_buf_client, mask_info->update_buf_client_len); + } else { + err = -EINVAL; + } if (err) { pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n", __func__, err); diff --git a/drivers/cpufreq/cpufreq_limit.c b/drivers/cpufreq/cpufreq_limit.c index 60c539940..51518dd34 100644 --- a/drivers/cpufreq/cpufreq_limit.c +++ b/drivers/cpufreq/cpufreq_limit.c @@ -44,14 +44,6 @@ #define CONSERVATIVE_BOOST 2 #define RESTRAINED_BOOST 3 -struct cpufreq_limit_handle { - struct list_head node; - unsigned long min; - unsigned long max; - char label[20]; - u64 start_msecs; -}; - static DEFINE_MUTEX(cpufreq_limit_lock); static LIST_HEAD(cpufreq_limit_requests); @@ -65,6 +57,7 @@ struct cpufreq_limit_parameter { unsigned int ltl_cpu_policy; unsigned int ltl_cpu_start; unsigned int ltl_cpu_end; + unsigned int mid_cpu_policy; unsigned int big_cpu_policy; unsigned int big_cpu_start; unsigned int big_cpu_end; @@ -77,15 +70,20 @@ struct cpufreq_limit_parameter { unsigned int ltl_min_lock; unsigned int ltl_divider; - bool use_hotplug_out; + bool use_hotplug_out; unsigned int hmp_boost_type; unsigned int hmp_boost_active; - int hmp_prev_boost_type; + int hmp_prev_boost_type; /* set limit of max freq limit for guarantee performance */ unsigned int ltl_limit_max_freq; + + unsigned int over_limit; + int cur_orig_min; + int cur_orig_max; }; +/* for SM8250 */ struct cpufreq_limit_parameter param = { .freq_count = 0, .table_initialized = false, @@ -93,6 +91,7 @@ struct cpufreq_limit_parameter param = { .ltl_cpu_policy = 0, .ltl_cpu_start = 0, .ltl_cpu_end = 3, + .mid_cpu_policy = 4, .big_cpu_policy = 7, .big_cpu_start = 4, .big_cpu_end = 7, @@ -107,11 +106,58 @@ struct cpufreq_limit_parameter param = { .hmp_boost_type = CONSERVATIVE_BOOST, .hmp_boost_active = 0, - .hmp_prev_boost_type = 0, + .hmp_prev_boost_type = 0, .ltl_limit_max_freq = 1113600, + + .over_limit = -1, + .cur_orig_min = -1, + .cur_orig_max = -1, }; +static struct cpufreq_limit_handle + cpufreq_limit_handle_list[DVFS_MAX_ID] = { + { + .name = "none", + .id = DVFS_NO_ID + }, + { + .name = "touch", + .id = DVFS_TOUCH_ID + }, + { + .name = "finger", + .id = DVFS_FINGER_ID + }, + { + .name = "multi-touch", + .id = DVFS_MULTI_TOUCH_ID + }, + { + .name = "argos", + .id = DVFS_ARGOS_ID + }, +#ifdef CONFIG_USB_AUDIO_ENHANCED_DETECT_TIME + { + .name = "boost-host", + .id = DVFS_BOOST_HOST_ID + }, +#endif + { + .name = "user_min", + .id = DVFS_USER_MIN_ID + }, + { + .name = "user_max", + .id = DVFS_USER_MAX_ID + }, +}; + +struct cpufreq_limit_handle *cpufreq_limit_get_handle(int id) +{ + return &cpufreq_limit_handle_list[id]; +} + void cpufreq_limit_corectl(int freq) { unsigned int cpu; @@ -139,7 +185,7 @@ void cpufreq_limit_corectl(int freq) } } -bool cpufreq_limit_make_table(void) +static bool cpufreq_limit_make_table(void) { int i, count = 0; int freq_count = 0; @@ -386,14 +432,14 @@ static int cpufreq_limit_adjust_freq(struct cpufreq_policy *policy, *min *= param.ltl_divider; if (*max >= param.big_min_freq) - *max = policy->cpuinfo.max_freq; + *max = policy->user_policy.max; else *max *= param.ltl_divider; } else { if (*min >= param.big_min_freq) { hmp_boost_active = 1; } else { - *min = policy->cpuinfo.min_freq; + *min = policy->user_policy.min; hmp_boost_active = 0; } @@ -401,7 +447,7 @@ static int cpufreq_limit_adjust_freq(struct cpufreq_policy *policy, pr_debug("%s: big_min_freq(%u), max(%lu)\n", __func__, param.big_min_freq, *max); } else { - *max = policy->cpuinfo.min_freq; + *max = policy->user_policy.min; hmp_boost_active = 0; } @@ -414,122 +460,87 @@ static int cpufreq_limit_adjust_freq(struct cpufreq_policy *policy, return 0; } - -/** - * cpufreq_limit_get - limit min_freq or max_freq, return cpufreq_limit_handle - * @min_freq limit minimum frequency (0: none) - * @max_freq limit maximum frequency (0: none) - * @label a literal description string of this request - */ -struct cpufreq_limit_handle *cpufreq_limit_get(unsigned long min_freq, - unsigned long max_freq, char *label) +int cpufreq_limit_get(unsigned long freq, + struct cpufreq_limit_handle *handle) { - struct cpufreq_limit_handle *handle; - int i, found; ktime_t curr_time; u64 msecs64; - if (max_freq && max_freq < min_freq) - return ERR_PTR(-EINVAL); + if (!param.table_initialized) + return -EAGAIN; mutex_lock(&cpufreq_limit_lock); - found = 0; - list_for_each_entry(handle, &cpufreq_limit_requests, node) { - if (!strncmp(handle->label, label, strlen(handle->label))) { - found = 1; - pr_debug("%s: %s is found in list\n", __func__, - handle->label); - break; - } - } - - if (found) { - if (handle->min == min_freq - && handle->max == max_freq) { - pr_info("%s: %s same values(%lu,%lu) entered. just return.\n", - __func__, handle->label, - handle->min, handle->max); - mutex_unlock(&cpufreq_limit_lock); - return handle; - } - } - - if (!found) { - handle = kzalloc(sizeof(*handle), GFP_KERNEL); - if (!handle) { - pr_err("%s: alloc fail for %s .\n", __func__, label); - mutex_unlock(&cpufreq_limit_lock); - return ERR_PTR(-ENOMEM); - } - - if (strlen(label) < sizeof(handle->label)) - strlcpy(handle->label, label, - sizeof(handle->label)); - else - strlcpy(handle->label, label, - sizeof(handle->label) - 1); - - list_add_tail(&handle->node, &cpufreq_limit_requests); - } - - handle->min = min_freq; - handle->max = max_freq; + handle->freq = freq; curr_time = ktime_get(); msecs64 = ktime_to_ns(curr_time); do_div(msecs64, NSEC_PER_MSEC); handle->start_msecs = msecs64; + if (!handle->requested) { + list_add_tail(&handle->node, &cpufreq_limit_requests); + handle->requested = true; + } - pr_debug("%s: %s,%lu,%lu\n", __func__, handle->label, handle->min, - handle->max); + pr_debug("%s: %s, %lu\n", __func__, handle->name, handle->freq); mutex_unlock(&cpufreq_limit_lock); - /* Re-evaluate policy to trigger adjust notifier for online CPUs */ - get_online_cpus(); + cpufreq_update_policy(param.ltl_cpu_policy); + cpufreq_update_policy(param.mid_cpu_policy); + cpufreq_update_policy(param.big_cpu_policy); - for_each_online_cpu(i) - cpufreq_update_policy(i); - - put_online_cpus(); - - return handle; + return 0; } -/** - * cpufreq_limit_put - release of a limit of min_freq or max_freq, free - * a cpufreq_limit_handle - * @handle a cpufreq_limit_handle that has been requested - */ int cpufreq_limit_put(struct cpufreq_limit_handle *handle) { - int i; - - if (handle == NULL || IS_ERR(handle)) - return -EINVAL; - - pr_debug("%s: %s,%lu,%lu\n", __func__, handle->label, handle->min, - handle->max); + pr_debug("%s: %s, %lu\n", __func__, handle->name, handle->freq); mutex_lock(&cpufreq_limit_lock); - list_del(&handle->node); + if (handle->requested) { + list_del(&handle->node); + handle->requested = false; + } mutex_unlock(&cpufreq_limit_lock); - get_online_cpus(); - for_each_online_cpu(i) - cpufreq_update_policy(i); - put_online_cpus(); + cpufreq_update_policy(param.ltl_cpu_policy); + cpufreq_update_policy(param.mid_cpu_policy); + cpufreq_update_policy(param.big_cpu_policy); - kfree(handle); return 0; } +int cpufreq_limit_get_cur_min(void) +{ + return param.cur_orig_min; +} + +int cpufreq_limit_get_cur_max(void) +{ + return param.cur_orig_max; +} + +void cpufreq_limit_set_over_limit(unsigned int val) +{ + param.over_limit = val; + + cpufreq_update_policy(param.ltl_cpu_policy); + cpufreq_update_policy(param.mid_cpu_policy); + cpufreq_update_policy(param.big_cpu_policy); +} + +unsigned int cpufreq_limit_get_over_limit(void) +{ + return param.over_limit; +} + static int cpufreq_limit_notifier_policy(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_policy *policy = data; struct cpufreq_limit_handle *handle; unsigned long min = 0, max = ULONG_MAX; + int min_id = DVFS_NO_ID; #if defined(USE_MATCH_CPU_VOL_MIN_FREQ) unsigned long adjust_min = 0; #endif @@ -537,21 +548,23 @@ static int cpufreq_limit_notifier_policy(struct notifier_block *nb, unsigned long adjust_max = 0; #endif - if (val != CPUFREQ_ADJUST) goto done; mutex_lock(&cpufreq_limit_lock); + list_for_each_entry(handle, &cpufreq_limit_requests, node) { - if (handle->min > min) - min = handle->min; - if (handle->max && handle->max < max) - max = handle->max; + if (handle->id == DVFS_USER_MAX_ID && handle->freq < max) + max = handle->freq; + else if (handle->freq > min) { + min = handle->freq; + min_id = handle->id; + } } - pr_debug("CPUFREQ(%d): %s: umin=%d,umax=%d\n", + pr_debug("++ CPUFREQ(%d): %s: user(%d ~ %d), pol(%d ~ %d), set(%lu ~ %lu), over(%d)\n", policy->cpu, __func__, - policy->user_policy.min, policy->user_policy.max); + policy->user_policy.min, policy->user_policy.max, policy->min, policy->max, min, max, param.over_limit); mutex_unlock(&cpufreq_limit_lock); @@ -579,18 +592,25 @@ static int cpufreq_limit_notifier_policy(struct notifier_block *nb, } #endif + param.cur_orig_min = min; + param.cur_orig_max = max; + if (!min && max == ULONG_MAX) { cpufreq_limit_hmp_boost(0); + param.cur_orig_min = -1; + param.cur_orig_max = -1; goto done; } if (!min) { - min = policy->cpuinfo.min_freq; + min = policy->user_policy.min; set_ltl_divider(policy, &min); + param.cur_orig_min = -1; } if (max == ULONG_MAX) { - max = policy->cpuinfo.max_freq; + max = policy->user_policy.max; set_ltl_divider(policy, &max); + param.cur_orig_max = -1; } /* @@ -613,11 +633,25 @@ static int cpufreq_limit_notifier_policy(struct notifier_block *nb, pr_debug("%s: limiting cpu%d cpufreq to %lu-%lu\n", __func__, policy->cpu, min, max); + /* for over limit */ + if (param.over_limit != -1 && param.cur_orig_max != -1 + && (int)param.over_limit > param.cur_orig_max + && (param.cur_orig_min >= param.big_min_freq) + && (min_id == DVFS_USER_MIN_ID || min_id == DVFS_TOUCH_ID)) { + max = param.over_limit; + + pr_debug("%s: min over max: cpu%d cpufreq to %lu-%lu\n", __func__, + policy->cpu, min, max); + } + cpufreq_verify_within_limits(policy, min, max); pr_debug("%s: limited cpu%d cpufreq to %u-%u\n", __func__, policy->cpu, policy->min, policy->max); done: + pr_debug("-- CPUFREQ(%d): %s: user(%d ~ %d), pol(%d ~ %d), set(%lu ~ %lu), over(%d)\n", + policy->cpu, __func__, + policy->user_policy.min, policy->user_policy.max, policy->min, policy->max, min, max, param.over_limit); return 0; } @@ -641,15 +675,15 @@ static ssize_t show_cpufreq_limit_requests(struct kobject *kobj, mutex_lock(&cpufreq_limit_lock); len += snprintf(buf + len, MAX_BUF_SIZE, - "%s\t\t%s\t%s\t\%s\n", - "label", "min", "max", "since"); + "%s\t\t%s\t\t%s\n", + "name", "freq", "since"); list_for_each_entry(handle, &cpufreq_limit_requests, node) { sincesecs64 = msecs64 - handle->start_msecs; len += snprintf(buf + len, MAX_BUF_SIZE, - "%s\t%lu\t%lu\t\%llu\n", handle->label, - handle->min, handle->max, sincesecs64); + "%s\t\t%lu\t\t%llu\n", handle->name, + handle->freq, sincesecs64); } mutex_unlock(&cpufreq_limit_lock); diff --git a/drivers/fingerprint/qbt2000_common.c b/drivers/fingerprint/qbt2000_common.c index cef7d5462..1542ea142 100644 --- a/drivers/fingerprint/qbt2000_common.c +++ b/drivers/fingerprint/qbt2000_common.c @@ -213,9 +213,10 @@ static int qbt2000_noise_control(struct qbt2000_drvdata *drvdata, int control) int rc = 0; if (control == QBT2000_NOISE_UNBLOCK) { - drvdata->noise_onoff_flag = QBT2000_NOISE_UNBLOCK; - rc = set_wacom_ble_charge_mode(true); - pr_info("%d, rc:%d\n", control, rc); + rc = set_wacom_ble_charge_mode(true); /* 0:pass, etc:fail */ + if (rc == 0) + drvdata->noise_onoff_flag = QBT2000_NOISE_UNBLOCK; + pr_info("%d, rc:%d, flag:%d\n", control, rc, drvdata->noise_onoff_flag); } else if ((control == QBT2000_NOISE_BLOCK) && (drvdata->noise_onoff_flag == QBT2000_NOISE_UNBLOCK)) { drvdata->noise_onoff_flag = QBT2000_NOISE_BLOCK; while (retry--) { diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 91fd04be2..147b1e6b3 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2609,7 +2609,7 @@ static int check_vma(unsigned long hostptr, u64 size) return false; cur = vma->vm_end; -} + } return true; } diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c index 75e5ed3d5..b573467ec 100644 --- a/drivers/input/misc/qpnp-power-on.c +++ b/drivers/input/misc/qpnp-power-on.c @@ -289,12 +289,11 @@ static u32 s1_delay[PON_S1_COUNT_MAX + 1] = { }; #ifdef CONFIG_SEC_PM -#define PONOFF_UNKNOWN 99 static const char * const sec_pon_reason[] = { /* PON_PON_REASON1 */ "HARDRST", "SMPL", "RTC", "DC", "USB", "PON1", "CBL", "KPD", - [PONOFF_UNKNOWN] = "UNKNOWN" + "UNKNOWN" }; static const char * const sec_poff_reason[] = { @@ -316,7 +315,7 @@ static const char * const sec_poff_reason[] = { /* PON_S3_RESET_REASON */ "S3_FAUNT_N", "S3_PBS_WD", "S3_PBS_NACK", "S3_KPDRES", - [PONOFF_UNKNOWN] = "UNKNOWN" + "UNKNOWN" }; #endif @@ -2601,7 +2600,7 @@ static int qpnp_pon_read_hardware_info(struct qpnp_pon *pon, bool sys_reset) if (index > -1) pon_index[num_pmic] = index; else - pon_index[num_pmic] = PONOFF_UNKNOWN; + pon_index[num_pmic] = ARRAY_SIZE(sec_pon_reason) - 1; #endif cold_boot = sys_reset_dev ? !_qpnp_pon_is_warm_reset(sys_reset_dev) : !_qpnp_pon_is_warm_reset(pon); @@ -2644,7 +2643,7 @@ static int qpnp_pon_read_hardware_info(struct qpnp_pon *pon, bool sys_reset) if (index > -1) poff_index[num_pmic] = index; else - poff_index[num_pmic] = PONOFF_UNKNOWN; + poff_index[num_pmic] = ARRAY_SIZE(sec_poff_reason) - 1; num_pmic++; #endif if (index >= ARRAY_SIZE(qpnp_poff_reason) || index < 0 || diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index a39b21505..465d5c5e4 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1349,6 +1349,7 @@ source "drivers/input/touchscreen/stm/fts1ba90a/Kconfig" source "drivers/input/touchscreen/novatek/nt36523/Kconfig" source "drivers/input/touchscreen/melfas/mss100/Kconfig" source "drivers/input/touchscreen/zinitix/zt7650/Kconfig" +source "drivers/input/touchscreen/stm/fts5cu56a/Kconfig" config TOUCHSCREEN_SYNAPTICS_TCM bool "Synaptics TCM Touchscreen Driver" diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 27cff5a08..bc0df1361 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -126,3 +126,4 @@ obj-$(CONFIG_TOUCHSCREEN_FTS1BA90A) += stm/fts1ba90a/ obj-$(CONFIG_TOUCHSCREEN_NOVATEK_NT36523) += novatek/nt36523/ obj-$(CONFIG_TOUCHSCREEN_MELFAS_MSS100) += melfas/mss100/ obj-$(CONFIG_TOUCHSCREEN_ZINITIX_ZT7650) += zinitix/zt7650/ +obj-$(CONFIG_TOUCHSCREEN_STM_FTS5CU56A) += stm/fts5cu56a/ \ No newline at end of file diff --git a/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts.c b/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts.c index 6ff2e2c3a..77053aec8 100755 --- a/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts.c +++ b/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts.c @@ -822,6 +822,13 @@ static void sec_ts_sponge_dump_flush(struct sec_ts_data *ts, int dump_area) } /* dump all events at once */ + if (ts->sponge_dump_event * ts->sponge_dump_format > SEC_TS_MAX_SPONGE_DUMP_BUFFER) { + input_err(true, &ts->client->dev, "%s: wrong sponge dump read size(%d)\n", + __func__, ts->sponge_dump_event * ts->sponge_dump_format); + vfree(sec_spg_dat); + return; + } + ret = ts->sec_ts_read_sponge(ts, sec_spg_dat, ts->sponge_dump_event * ts->sponge_dump_format); if (ret < 0) { input_err(true, &ts->client->dev, "%s: Failed to read sponge\n", __func__); diff --git a/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts_fn.c b/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts_fn.c index b4aab5a32..11a837107 100755 --- a/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts_fn.c +++ b/drivers/input/touchscreen/sec_ts/y79a_c/sec_ts_fn.c @@ -742,6 +742,11 @@ static ssize_t get_lp_dump(struct device *dev, struct device_attribute *attr, ch sec_spg_dat[1] = 0; } + if (dump_cnt * ts->sponge_dump_format > SEC_TS_MAX_SPONGE_DUMP_BUFFER) { + input_err(true, &ts->client->dev, "%s: wrong sponge dump read size (%d)\n", + __func__, dump_cnt * ts->sponge_dump_format); + goto out; + } ret = ts->sec_ts_read_sponge(ts, sec_spg_dat, dump_cnt * ts->sponge_dump_format); if (ret < 0) { input_err(true, &ts->client->dev, "%s: Failed to read sponge\n", __func__); diff --git a/drivers/input/touchscreen/stm/fts5cu56a/Kconfig b/drivers/input/touchscreen/stm/fts5cu56a/Kconfig new file mode 100644 index 000000000..a5a71aec6 --- /dev/null +++ b/drivers/input/touchscreen/stm/fts5cu56a/Kconfig @@ -0,0 +1,12 @@ +# +# STMicroelectronics TOUCH driver configuration +# + +config TOUCHSCREEN_STM_FTS5CU56A + tristate "STMicroelectronics i2c multitouch touchscreen with FingerTipS" + depends on I2C + help + Say Y here to enable STMicroelectronics touchscreen support. + If unsure, say N. + To compile this driver as a module, choose M here: the + module will be called STM_ts. diff --git a/drivers/input/touchscreen/stm/fts5cu56a/Makefile b/drivers/input/touchscreen/stm/fts5cu56a/Makefile new file mode 100644 index 000000000..510337820 --- /dev/null +++ b/drivers/input/touchscreen/stm/fts5cu56a/Makefile @@ -0,0 +1,3 @@ +ccflags-y += -Wformat + +obj-$(CONFIG_TOUCHSCREEN_STM_FTS5CU56A) += fts_ts.o fts_fwu.o diff --git a/drivers/input/touchscreen/stm/fts5cu56a/fts_fwu.c b/drivers/input/touchscreen/stm/fts5cu56a/fts_fwu.c new file mode 100644 index 000000000..c43dfca47 --- /dev/null +++ b/drivers/input/touchscreen/stm/fts5cu56a/fts_fwu.c @@ -0,0 +1,1042 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fts_ts.h" +#include + +#define FTS_DEFAULT_UMS_FW "/sdcard/Firmware/TSP/stm.fw" +#define FTS_DEFAULT_SPU_FW "/spu/TSP/ffu_tsp.fw" +#define FTSFILE_SIGNATURE 0xAA55AA55 + +enum { + BUILT_IN = 0, + UMS, + NONE, + SPU, +}; + +/** + * @brief Type definitions - header structure of firmware file (ftb) + */ + +struct fts_header { + u32 signature; + u32 ftb_ver; + u32 target; + u32 fw_id; + u32 fw_ver; + u32 cfg_id; + u32 cfg_ver; + u8 fw_area_bs; // bs : block size + u8 panel_area_bs; + u8 cx_area_bs; + u8 cfg_area_bs; + u32 reserved1; + u32 ext_release_ver; + u8 project_id; + u8 ic_name; + u8 module_ver; + u8 reserved2; + u32 sec0_size; + u32 sec1_size; + u32 sec2_size; + u32 sec3_size; + u32 hdr_crc; +} __packed; + +#define FW_HEADER_SIZE 64 + +#define WRITE_CHUNK_SIZE 1024 +/* + * FTS9CU80F : 64K + * FTS5CU56A : 32K + */ +#define DRAM_SIZE (32 * 1024) // 32kB + +#define CODE_ADDR_START 0x00000000 +#define CX_ADDR_START 0x00007000 +#define CONFIG_ADDR_START 0x00007C00 + +#define SIGNEDKEY_SIZE (256) + +int FTS_Check_DMA_StartAndDone(struct fts_ts_info *info) +{ + int timeout = 60; + u8 regAdd[6] = { 0xFA, 0x20, 0x00, 0x00, 0x71, 0xC0 }; + u8 val[1]; + + info->fts_write_reg(info, ®Add[0], 6); + fts_delay(10); + + do { + info->fts_read_reg(info, ®Add[0], 5, (u8 *)val, 1); + + if ((val[0] & 0x80) != 0x80) + break; + + fts_delay(50); + timeout--; + } while (timeout != 0); + + if (timeout == 0) { + input_err(true, &info->client->dev, "%s: Time Over\n", __func__); + return -1; + } + + return 0; +} + +static int FTS_Check_Erase_Done(struct fts_ts_info *info) +{ + int timeout = 60; // 3 sec timeout + u8 regAdd[5] = { 0xFA, 0x20, 0x00, 0x00, 0x6A }; + u8 val[1]; + + do { + info->fts_read_reg(info, ®Add[0], 5, (u8 *)val, 1); + + if ((val[0] & 0x80) != 0x80) + break; + + fts_delay(50); + timeout--; + } while (timeout != 0); + + if (timeout == 0) { + input_err(true, &info->client->dev, "%s: Time Over\n", __func__); + return -1; + } + + return 0; +} + +int fts_fw_fillFlash(struct fts_ts_info *info, u32 address, u8 *data, int size) +{ + int remaining, index = 0; + int toWrite = 0; + int byteBlock = 0; + int wheel = 0; + u32 addr = 0; + int rc; + int delta; + + u8 buff[WRITE_CHUNK_SIZE + 5] = {0}; + u8 buff2[12] = {0}; + + remaining = size; + while (remaining > 0) { + byteBlock = 0; + addr = 0x00100000; + + while ((byteBlock < DRAM_SIZE) && remaining > 0) { + if (remaining >= WRITE_CHUNK_SIZE) { + if ((byteBlock + WRITE_CHUNK_SIZE) <= DRAM_SIZE) { + toWrite = WRITE_CHUNK_SIZE; + remaining -= WRITE_CHUNK_SIZE; + byteBlock += WRITE_CHUNK_SIZE; + } else { + delta = DRAM_SIZE - byteBlock; + toWrite = delta; + remaining -= delta; + byteBlock += delta; + } + } else { + if ((byteBlock + remaining) <= DRAM_SIZE) { + toWrite = remaining; + byteBlock += remaining; + remaining = 0; + } else { + delta = DRAM_SIZE - byteBlock; + toWrite = delta; + remaining -= delta; + byteBlock += delta; + } + } + + index = 0; + buff[index++] = 0xFA; + buff[index++] = (u8) ((addr & 0xFF000000) >> 24); + buff[index++] = (u8) ((addr & 0x00FF0000) >> 16); + buff[index++] = (u8) ((addr & 0x0000FF00) >> 8); + buff[index++] = (u8) ((addr & 0x000000FF)); + + memcpy(&buff[index], data, toWrite); + + rc = info->fts_write_reg(info, &buff[0], index + toWrite); + if (rc <= 0) { + input_err(true, &info->client->dev, + "%s failed to write i2c register. ret:%d\n", + __func__, rc); + return -1; + } + fts_delay(5); + + addr += toWrite; + data += toWrite; + } + + input_info(true, &info->client->dev, "%s: Write %d Bytes\n", __func__, byteBlock); + + //configuring the DMA + byteBlock = byteBlock / 4 - 1; + + index = 0; + buff2[index++] = 0xFA; + buff2[index++] = 0x20; + buff2[index++] = 0x00; + buff2[index++] = 0x00; + buff2[index++] = 0x72; + buff2[index++] = 0x00; + buff2[index++] = 0x00; + + addr = address + ((wheel * DRAM_SIZE) / 4); + buff2[index++] = (u8) ((addr & 0x000000FF)); + buff2[index++] = (u8) ((addr & 0x0000FF00) >> 8); + buff2[index++] = (u8) (byteBlock & 0x000000FF); + buff2[index++] = (u8) ((byteBlock & 0x0000FF00) >> 8); + buff2[index++] = 0x00; + + rc = info->fts_write_reg(info, &buff2[0], index); + if (rc <= 0) { + input_err(true, &info->client->dev, + "%s failed to write i2c register. ret:%d\n", + __func__, rc); + return -1; + } + fts_delay(10); + + rc = FTS_Check_DMA_StartAndDone(info); + if (rc < 0) + return -1; + + wheel++; + } + + return 0; +} + +static int fts_fw_burn(struct fts_ts_info *info, u8 *fw_data) +{ + const struct fts_header *fw_header; + u8 *pFWData; + int rc; + int i; + u8 regAdd[FTS_EVENT_SIZE] = {0}; + int NumberOfMainBlock = 0; + + fw_header = (struct fts_header *) &fw_data[0]; + + if ((fw_header->fw_area_bs) > 0) + NumberOfMainBlock = fw_header->fw_area_bs; + else + NumberOfMainBlock = 26; // original value + + // System Reset + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x24; regAdd[5] = 0x81; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + + fts_delay(50); + + // System Reset and Hold + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x24; regAdd[5] = 0x01; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + fts_delay(200); + + // Enable UVLO + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x1B; regAdd[5] = 0x66; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + fts_delay(30); + + // Flash Auto Power Down + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x68; regAdd[5] = 0x13; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + fts_delay(30); + + // Change application mode + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x25; regAdd[5] = 0x20; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + fts_delay(200); + + // Unlock Flash + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0xDE; regAdd[5] = 0x03; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + fts_delay(200); + + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x6B; regAdd[5] = 0x00; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + fts_delay(50); + + + //==================== Erase Partial Flash ==================== + input_info(true, &info->client->dev, "%s: Start Flash(Main Block) Erasing\n", __func__); + for (i = 0; i < NumberOfMainBlock; i++) { + + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x6A; + regAdd[5] = (0x80 + i) & 0xFF; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + rc = FTS_Check_Erase_Done(info); + if (rc < 0) + return rc; + } + + input_info(true, &info->client->dev, "%s: Start Flash(Config Block) Erasing\n", __func__); + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x6B; regAdd[5] = 0x00; + info->fts_write_reg(info, ®Add[0], 6); + fts_delay(50); + + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x6A; + regAdd[5] = (0x80 + 31) & 0xFF; + info->fts_write_reg(info, ®Add[0], 6); + + rc = FTS_Check_Erase_Done(info); + if (rc < 0) + return rc; + // Code Area + if (fw_header->sec0_size > 0) { + pFWData = (u8 *) &fw_data[FW_HEADER_SIZE]; + + input_info(true, &info->client->dev, "%s: Start Flashing for Code\n", __func__); + rc = fts_fw_fillFlash(info, CODE_ADDR_START, &pFWData[0], fw_header->sec0_size); + if (rc < 0) + return rc; + + input_info(true, &info->client->dev, "%s: Finished total flashing %ld Bytes for Code\n", + __func__, (long)fw_header->sec0_size); + } + + // Config Area + if (fw_header->sec1_size > 0) { + input_info(true, &info->client->dev, "%s: Start Flashing for Config\n", __func__); + pFWData = (u8 *) &fw_data[FW_HEADER_SIZE + fw_header->sec0_size]; + rc = fts_fw_fillFlash(info, CONFIG_ADDR_START, &pFWData[0], fw_header->sec1_size); + if (rc < 0) + return rc; + input_info(true, &info->client->dev, "%s: Finished total flashing %ld Bytes for Config\n", + __func__, (long)fw_header->sec1_size); + } + + // CX Area + if (fw_header->sec2_size > 0) { + input_info(true, &info->client->dev, "%s: Start Flashing for CX\n", __func__); + pFWData = (u8 *) &fw_data[FW_HEADER_SIZE + fw_header->sec0_size + fw_header->sec1_size]; + rc = fts_fw_fillFlash(info, CX_ADDR_START, &pFWData[0], fw_header->sec2_size); + if (rc < 0) + return rc; + input_info(true, &info->client->dev, "%s: Finished total flashing %ld Bytes for CX\n", + __func__, (long)fw_header->sec2_size); + } + + regAdd[0] = 0xFA; regAdd[1] = 0x20; regAdd[2] = 0x00; + regAdd[3] = 0x00; regAdd[4] = 0x24; regAdd[5] = 0x80; + rc = info->fts_write_reg(info, ®Add[0], 6); + if (rc < 0) + return rc; + fts_delay(200); + + // System Reset + info->fts_systemreset(info, 0); + + return 0; +} + +int fts_fw_wait_for_event(struct fts_ts_info *info, u8 *result, u8 result_cnt) +{ + int rc = 0; + int i; + bool matched = false; + u8 regAdd; + u8 data[FTS_EVENT_SIZE]; + int retry = 0; + + memset(data, 0x0, FTS_EVENT_SIZE); + + regAdd = FTS_READ_ONE_EVENT; + rc = -1; + while (info->fts_read_reg(info, ®Add, 1, (u8 *)data, FTS_EVENT_SIZE)) { + for (i = 0; i < result_cnt; i++) { + if (data[i] != result[i]) { + matched = false; + break; + } + matched = true; + } + + if (matched == true) { + rc = 0; + break; + } + + if (data[0] == FTS_EVENT_ERROR_REPORT) { + input_info(true, &info->client->dev, "%s: Error detected %02X,%02X,%02X,%02X,%02X,%02X\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + } + + if (retry++ > FTS_RETRY_COUNT * 15) { + rc = -1; + input_err(true, &info->client->dev, "%s: Time Over (%02X,%02X,%02X,%02X,%02X,%02X)\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + } + fts_delay(20); + } + + return rc; +} + +int fts_fw_wait_for_echo_event(struct fts_ts_info *info, u8 *cmd, u8 cmd_cnt, int delay) +{ + int rc = 0; + int i; + bool matched = false; + u8 regAdd; + u8 data[FTS_EVENT_SIZE]; + int retry = 0; + + mutex_lock(&info->wait_for); + + rc = info->fts_write_reg(info, cmd, cmd_cnt); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: failed to write command\n", __func__); + mutex_unlock(&info->wait_for); + return rc; + } + + if (delay) + fts_delay(delay); + + memset(data, 0x0, FTS_EVENT_SIZE); + + regAdd = FTS_READ_ONE_EVENT; + rc = -1; + while (info->fts_read_reg(info, ®Add, 1, (u8 *)data, FTS_EVENT_SIZE)) { + if (data[0] != 0x00) + input_info(true, &info->client->dev, + "%s: event %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], + data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); + + if ((data[0] == FTS_EVENT_STATUS_REPORT) && (data[1] == 0x01)) { // Check command ECHO + int loop_cnt; + + if (cmd_cnt > 4) + loop_cnt = 4; + else + loop_cnt = cmd_cnt; + + for (i = 0; i < loop_cnt; i++) { + if (data[i + 2] != cmd[i]) { + matched = false; + break; + } + matched = true; + } + + if (matched == true) { + rc = 0; + break; + } + } else if (data[0] == FTS_EVENT_ERROR_REPORT) { + input_info(true, &info->client->dev, "%s: Error detected %02X,%02X,%02X,%02X,%02X,%02X\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + if (retry >= FTS_RETRY_COUNT) + break; + } + + if (retry++ > FTS_RETRY_COUNT * 50) { + rc = -1; + input_err(true, &info->client->dev, "%s: Time Over (%02X,%02X,%02X,%02X,%02X,%02X)\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + } + fts_delay(20); + } + + mutex_unlock(&info->wait_for); + + return rc; +} + +/* block on winner model / use other tablet models */ +static void fts_set_factory_history_data(struct fts_ts_info *info, u8 level) +{ + int ret; + u8 regaddr[3] = { 0 }; + u8 wlevel; + + switch (level) { + case OFFSET_FAC_NOSAVE: + input_info(true, &info->client->dev, "%s: not save to flash area\n", __func__); + return; + case OFFSET_FAC_SUB: + wlevel = OFFSET_FW_SUB; + break; + case OFFSET_FAC_MAIN: + wlevel = OFFSET_FW_MAIN; + break; + default: + input_info(true, &info->client->dev, "%s: wrong level %d\n", __func__, level); + return; + } + + regaddr[0] = 0xC7; + regaddr[1] = 0x04; + regaddr[2] = wlevel; + + ret = info->fts_write_reg(info, regaddr, 3); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: failed to write factory level %d\n", __func__, wlevel); + return; + } + + regaddr[0] = 0xA4; + regaddr[1] = 0x05; + regaddr[2] = 0x04; /* panel configuration area */ + ret = fts_fw_wait_for_echo_event(info, regaddr, 3, 200); + if (ret < 0) + return; + + input_info(true, &info->client->dev, "%s: save to flash area, level=%d\n", __func__, wlevel); + return; +} + +#ifdef TCLM_CONCEPT +int fts_tclm_execute_force_calibration(struct i2c_client *client, int cal_mode) +{ + struct fts_ts_info *info = (struct fts_ts_info *)i2c_get_clientdata(client); + + return fts_execute_autotune(info, true); +} +#endif + +int fts_execute_autotune(struct fts_ts_info *info, bool IsSaving) +{ + u8 regAdd[FTS_EVENT_SIZE] = {0,}; + u8 DataType = 0x00; + int rc; + + input_info(true, &info->client->dev, "%s: start\n", __func__); + + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + + fts_delay(10); + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + fts_interrupt_set(info, INT_DISABLE); + + // w A4 00 03 + if (IsSaving == true) { + // full panel init + regAdd[0] = 0xA4; regAdd[1] = 0x00; regAdd[2] = 0x03; + + rc = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 500); +#ifdef TCLM_CONCEPT + if (info->tdata->nvdata.cal_fail_cnt == 0xFF) + info->tdata->nvdata.cal_fail_cnt = 0; + if (rc < 0) { + info->tdata->nvdata.cal_fail_cnt++; + info->tdata->nvdata.cal_fail_falg = 0; + } else { + info->tdata->nvdata.cal_fail_falg = SEC_CAL_PASS; + info->is_cal_done = true; + } + info->tdata->tclm_write(info->tdata->client, SEC_TCLM_NVM_ALL_DATA); + /* interrupt is enabled by tclm write */ + fts_interrupt_set(info, INT_DISABLE); +#endif + if (rc < 0) { + input_info(true, &info->client->dev, "%s: timeout\n", __func__); + goto ERROR; + } + } else { + // SS ATune + //DataType = 0x0C; + DataType = 0x3F; + + regAdd[0] = 0xA4; regAdd[1] = 0x03; regAdd[2] = (u8)DataType; regAdd[3] = 0x00; + + rc = fts_fw_wait_for_echo_event(info, ®Add[0], 4, 500); + if (rc < 0) { + input_info(true, &info->client->dev, "%s: timeout\n", __func__); + goto ERROR; + } + } + + /* block on winner model / use other tablet models */ + fts_set_factory_history_data(info, info->factory_position); + if (IsSaving == true) + fts_panel_ito_test(info, SAVE_MISCAL_REF_RAW); + +ERROR: + + info->factory_position = OFFSET_FAC_NOSAVE; + fts_interrupt_set(info, INT_ENABLE); + + fts_set_scanmode(info, info->scan_mode); + return rc; +} + +static const int fts_fw_updater(struct fts_ts_info *info, u8 *fw_data) +{ + const struct fts_header *header; + int retval; + int retry; + u16 fw_main_version; + + if (!fw_data) { + input_err(true, &info->client->dev, "%s: Firmware data is NULL\n", + __func__); + return -ENODEV; + } + + header = (struct fts_header *)fw_data; + fw_main_version = (u16)header->ext_release_ver; + + input_info(true, &info->client->dev, + "%s: Starting firmware update : 0x%04X\n", __func__, + fw_main_version); + + retry = 0; + + fts_interrupt_set(info, INT_DISABLE); + while (1) { + retval = fts_fw_burn(info, fw_data); + if (retval >= 0) { + info->fts_get_version_info(info); + + if (fw_main_version == info->fw_main_version_of_ic) { + input_info(true, &info->client->dev, + "%s: Success Firmware update\n", + __func__); + info->fw_corruption = false; + + retval = info->fts_systemreset(info, 0); + + if (retval == -FTS_ERROR_BROKEN_OSC_TRIM) { + retval = fts_osc_trim_recovery(info); + if (retval < 0) + input_err(true, &info->client->dev, "%s: Failed to recover osc trim\n", __func__); + else + info->fw_corruption = false; + } + + fts_set_scanmode(info, info->scan_mode); + retval = 0; + break; + } + } + + if (retry++ > 3) { + input_err(true, &info->client->dev, "%s: Fail Firmware update\n", + __func__); + retval = -1; + break; + } + } + fts_interrupt_set(info, INT_ENABLE); + + return retval; +} + +int fts_fw_update_on_probe(struct fts_ts_info *info) +{ + int retval = 0; + const struct firmware *fw_entry = NULL; + u8 *fw_data = NULL; + char fw_path[FTS_MAX_FW_PATH]; + const struct fts_header *header; +#ifdef TCLM_CONCEPT + bool restore_cal = false; + int ret = 0; +#endif + +#ifdef TCLM_CONCEPT + if (info->tdata->support_tclm_test) { + ret = sec_tclm_test_on_probe(info->tdata); + if (ret < 0) + input_info(true, &info->client->dev, "%s: SEC_TCLM_NVM_ALL_DATA i2c read fail", __func__); + } +#endif + + if (info->board->bringup == 1) + return 0; + + if (info->board->firmware_name) { + info->firmware_name = info->board->firmware_name; + } else { + input_err(true, &info->client->dev, "%s: firmware name does not declair in dts\n", __func__); + goto exit_fwload; + } + + snprintf(fw_path, FTS_MAX_FW_PATH, "%s", info->firmware_name); + input_info(true, &info->client->dev, "%s: Load firmware : %s, TSP_ID : %d\n", __func__, fw_path, info->board->tsp_id); + + retval = request_firmware(&fw_entry, fw_path, &info->client->dev); + if (retval) { + input_err(true, &info->client->dev, + "%s: Firmware image %s not available\n", __func__, + fw_path); + goto done; + } + + fw_data = (u8 *)fw_entry->data; + header = (struct fts_header *)fw_data; + + info->fw_version_of_bin = (u16)header->fw_ver; + info->fw_main_version_of_bin = (u16)header->ext_release_ver; + info->config_version_of_bin = (u16)header->cfg_ver; + info->project_id_of_bin = header->project_id; + info->ic_name_of_bin = header->ic_name; + info->module_version_of_bin = header->module_ver; + + input_info(true, &info->client->dev, + "%s: [BIN] Firmware Ver: 0x%04X, Config Ver: 0x%04X, Main Ver: 0x%04X\n", __func__, + info->fw_version_of_bin, + info->config_version_of_bin, + info->fw_main_version_of_bin); + input_info(true, &info->client->dev, + "%s: [BIN] Project ID: 0x%02X, IC Name: 0x%02X, Module Ver: 0x%02X\n", + __func__, info->project_id_of_bin, + info->ic_name_of_bin, info->module_version_of_bin); + + if (info->board->bringup == 2) { + input_err(true, &info->client->dev, "%s: skip fw_update for bringup\n", __func__); + retval = FTS_NOT_ERROR; + goto done; + } + + if (info->checksum_result) + retval = FTS_NEED_FW_UPDATE; + else if (info->ic_name_of_ic == 0xFF && info->project_id_of_ic == 0xFF && info->module_version_of_ic == 0xFF) + retval = FTS_NEED_FW_UPDATE; + else if (info->ic_name_of_ic != info->ic_name_of_bin) + retval = FTS_NOT_UPDATE; + else if (info->project_id_of_ic != info->project_id_of_bin) + retval = FTS_NEED_FW_UPDATE; + else if (info->module_version_of_ic != info->module_version_of_bin) + retval = FTS_NOT_UPDATE; + else if ((info->fw_main_version_of_ic < info->fw_main_version_of_bin) + || ((info->config_version_of_ic < info->config_version_of_bin)) + || ((info->fw_version_of_ic < info->fw_version_of_bin))) + retval = FTS_NEED_FW_UPDATE; + else + retval = FTS_NOT_ERROR; + + /* ic fw ver > bin fw ver && force is false */ + if (retval != FTS_NEED_FW_UPDATE) { + input_err(true, &info->client->dev, "%s: skip fw update\n", __func__); + + goto done; + } + + retval = fts_fw_updater(info, fw_data); + if (retval < 0) + goto done; + +#ifdef TCLM_CONCEPT + ret = info->tdata->tclm_read(info->tdata->client, SEC_TCLM_NVM_ALL_DATA); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: SEC_TCLM_NVM_ALL_DATA i2c read fail", __func__); + goto done; + } + + input_info(true, &info->client->dev, "%s: tune_fix_ver [%04X] afe_base [%04X]\n", + __func__, info->tdata->nvdata.tune_fix_ver, info->tdata->afe_base); + + if ((info->tdata->tclm_level > TCLM_LEVEL_CLEAR_NV) && + ((info->tdata->nvdata.tune_fix_ver == 0xffff) + || (info->tdata->afe_base > info->tdata->nvdata.tune_fix_ver))) { + /* tune version up case */ + sec_tclm_root_of_cal(info->tdata, CALPOSITION_TUNEUP); + restore_cal = true; + } else if (info->tdata->tclm_level == TCLM_LEVEL_CLEAR_NV) { + /* firmup case */ + sec_tclm_root_of_cal(info->tdata, CALPOSITION_FIRMUP); + restore_cal = true; + } + + if (restore_cal) { + input_info(true, &info->client->dev, "%s: RUN OFFSET CALIBRATION\n", __func__); + if (sec_execute_tclm_package(info->tdata, 0) < 0) + input_err(true, &info->client->dev, "%s: sec_execute_tclm_package fail\n", __func__); + } +#endif + +done: +#ifdef TCLM_CONCEPT + sec_tclm_root_of_cal(info->tdata, CALPOSITION_NONE); +#endif + if (fw_entry) + release_firmware(fw_entry); +exit_fwload: + return retval; +} +EXPORT_SYMBOL(fts_fw_update_on_probe); + +static int fts_load_fw_from_kernel(struct fts_ts_info *info, + const char *fw_path) +{ + int retval; + const struct firmware *fw_entry = NULL; + u8 *fw_data = NULL; + + if (!fw_path) { + input_err(true, &info->client->dev, "%s: Firmware name is not defined\n", + __func__); + return -EINVAL; + } + + input_info(true, &info->client->dev, "%s: Load firmware : %s\n", __func__, + fw_path); + + retval = request_firmware(&fw_entry, fw_path, &info->client->dev); + + if (retval) { + input_err(true, &info->client->dev, + "%s: Firmware image %s not available\n", __func__, + fw_path); + goto done; + } + + fw_data = (u8 *)fw_entry->data; + + info->fts_systemreset(info, 20); + +#ifdef TCLM_CONCEPT + sec_tclm_root_of_cal(info->tdata, CALPOSITION_TESTMODE); +#endif + + retval = fts_fw_updater(info, fw_data); + if (retval) + input_err(true, &info->client->dev, "%s: failed update firmware\n", + __func__); + +#ifdef TCLM_CONCEPT + input_info(true, &info->client->dev, "%s: RUN OFFSET CALIBRATION\n", __func__); + if (sec_execute_tclm_package(info->tdata, 0) < 0) + input_err(true, &info->client->dev, "%s: sec_execute_tclm_package fail\n", __func__); + + sec_tclm_root_of_cal(info->tdata, CALPOSITION_NONE); +#endif + info->fw_corruption = false; + +done: + if (fw_entry) + release_firmware(fw_entry); + + return retval; +} + +static int fts_load_fw_from_ums(struct fts_ts_info *info, int type) +{ + struct file *fp; + mm_segment_t old_fs; + long fw_size, nread; + int error = 0; + int spu_ret = 0; + int ori_size = 0; + char file_path[100]; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + switch (type) { + case TSP_TYPE_EXTERNAL_FW: + snprintf(file_path, sizeof(file_path), TSP_PATH_EXTERNAL_FW); + break; + case TSP_TYPE_EXTERNAL_FW_SIGNED: + snprintf(file_path, sizeof(file_path), TSP_PATH_EXTERNAL_FW_SIGNED); + break; + case TSP_TYPE_SPU_FW_SIGNED: + snprintf(file_path, sizeof(file_path), TSP_PATH_SPU_FW_SIGNED); + break; + default: + return -ENODEV; + } + + fp = filp_open(file_path, O_RDONLY, 0400); + if (IS_ERR(fp)) { + input_err(true, &info->client->dev, "%s: failed to open %s.\n", __func__, file_path); + error = -ENOENT; + goto open_err; + } + + fw_size = fp->f_path.dentry->d_inode->i_size; + + if (fw_size > 0) { + u8 *fw_data; + const struct fts_header *header; + + fw_data = kzalloc(fw_size, GFP_KERNEL); + if (!fw_data) { + error = -ENOMEM; + goto alloc_err; + } + + nread = vfs_read(fp, (char __user *)fw_data, + fw_size, &fp->f_pos); + + input_info(true, &info->client->dev, + "%s: start, file path %s, size %ld Bytes\n", + __func__, file_path, fw_size); + + if (nread != fw_size) { + input_err(true, &info->client->dev, + "%s: failed to read firmware file, nread %ld Bytes\n", + __func__, nread); + error = -EIO; + } else { + header = (struct fts_header *)fw_data; + if (header->signature == FTSFILE_SIGNATURE) { + /* If FFU firmware version is lower than IC's version, do not run update routine */ + if (type == TSP_TYPE_EXTERNAL_FW_SIGNED || type == TSP_TYPE_SPU_FW_SIGNED) { + /* digest 32, signature 512 TSP 3 */ + ori_size = fw_size - SPU_METADATA_SIZE(TSP); + + spu_ret = spu_firmware_signature_verify("TSP", fw_data, fw_size); + if (ori_size != spu_ret) { + error = -1; + input_err(true, &info->client->dev, + "%s: signature verify failed: spu_ret:%d, ori_size:%d", + __func__, spu_ret, ori_size); + kfree(fw_data); + goto alloc_err; + } + } + + if (type == TSP_TYPE_SPU_FW_SIGNED) { + if ((info->fw_main_version_of_ic < (u16)header->ext_release_ver) + || (info->config_version_of_ic < (u16)header->cfg_ver) + || (info->fw_version_of_ic < (u16)header->fw_ver)) { + input_info(true, &info->client->dev, "%s: run spu update\n", __func__); + } else { + error = 0; + input_info(true, &info->client->dev, "%s: skip spu update\n", __func__); + kfree(fw_data); + goto alloc_err; + } + } else if (type == TSP_TYPE_EXTERNAL_FW_SIGNED) { + if ((info->ic_name_of_ic == header->ic_name) && + (info->project_id_of_ic == header->project_id)) { + input_info(true, &info->client->dev, "%s: run external fw update\n", __func__); + } else { + error = 0; + input_info(true, &info->client->dev, "%s: skip external fw update\n", __func__); + kfree(fw_data); + goto alloc_err; + } + } + info->fts_systemreset(info, 0); + + input_info(true, &info->client->dev, + "%s: [UMS] Firmware Ver: 0x%04X, Main Version : 0x%04X\n", + __func__, (u16)header->fw_ver, (u16)header->ext_release_ver); +#ifdef TCLM_CONCEPT + sec_tclm_root_of_cal(info->tdata, CALPOSITION_TESTMODE); +#endif + + error = fts_fw_updater(info, fw_data); + +#ifdef TCLM_CONCEPT + input_info(true, &info->client->dev, "%s: RUN OFFSET CALIBRATION\n", __func__); + if (sec_execute_tclm_package(info->tdata, 0) < 0) + input_err(true, &info->client->dev, "%s: sec_execute_tclm_package fail\n", __func__); + + sec_tclm_root_of_cal(info->tdata, CALPOSITION_NONE); +#endif + } else { + error = -1; + input_err(true, &info->client->dev, + "%s: File type is not match with FTS64 file. [%8x]\n", + __func__, header->signature); + } + } + + if (error < 0) + input_err(true, &info->client->dev, "%s: failed update firmware\n", + __func__); + + kfree(fw_data); + } + +alloc_err: + filp_close(fp, NULL); + +open_err: + set_fs(old_fs); + return error; +} + +int fts_fw_update_on_hidden_menu(struct fts_ts_info *info, int update_type) +{ + int retval = 0; + + /* Factory cmd for firmware update + * argument represent what is source of firmware like below. + * + * 0 : [BUILT_IN] Getting firmware which is for user. + * 1 : [UMS] Getting firmware from sd card. + * 2 : none + */ + switch (update_type) { + case BUILT_IN: + retval = fts_load_fw_from_kernel(info, info->firmware_name); + break; + case UMS: +#if defined(CONFIG_SAMSUNG_PRODUCT_SHIP) + retval = fts_load_fw_from_ums(info, TSP_TYPE_EXTERNAL_FW_SIGNED); +#else + retval = fts_load_fw_from_ums(info, TSP_TYPE_EXTERNAL_FW); +#endif + break; + case SPU: + retval = fts_load_fw_from_ums(info, TSP_TYPE_SPU_FW_SIGNED); + break; + default: + input_err(true, &info->client->dev, "%s: Not support command[%d]\n", + __func__, update_type); + break; + } + + fts_check_custom_library(info); + + return retval; +} +EXPORT_SYMBOL(fts_fw_update_on_hidden_menu); diff --git a/drivers/input/touchscreen/stm/fts5cu56a/fts_sec.c b/drivers/input/touchscreen/stm/fts5cu56a/fts_sec.c new file mode 100644 index 000000000..a3e3c1eca --- /dev/null +++ b/drivers/input/touchscreen/stm/fts5cu56a/fts_sec.c @@ -0,0 +1,7612 @@ +#ifdef SEC_TSP_FACTORY_TEST + +#define BUFFER_MAX ((256 * 1024) - 16) + +enum { + TYPE_RAW_DATA = 0x30, // only for winner, etc 0x31 + TYPE_FILTERED_RAW_DATA = 0x31, // only for winner + TYPE_BASELINE_DATA = 0x32, + TYPE_STRENGTH_DATA = 0x33, +}; + +enum { + BUILT_IN = 0, + UMS, +}; + +enum ito_error_type { + ITO_FORCE_SHRT_GND = 0x60, + ITO_SENSE_SHRT_GND = 0x61, + ITO_FORCE_SHRT_VDD = 0x62, + ITO_SENSE_SHRT_VDD = 0x63, + ITO_FORCE_SHRT_FORCE = 0x64, + ITO_SENSE_SHRT_SENSE = 0x65, + ITO_FORCE_OPEN = 0x66, + ITO_SENSE_OPEN = 0x67, + ITO_KEY_OPEN = 0x68 +}; + +#define FTS_COMP_DATA_HEADER_SIZE 16 + +enum fts_nvm_data_type { /* Write Command */ + FTS_NVM_OFFSET_FAC_RESULT = 1, + FTS_NVM_OFFSET_CAL_COUNT, + FTS_NVM_OFFSET_DISASSEMBLE_COUNT, + FTS_NVM_OFFSET_TUNE_VERSION, + FTS_NVM_OFFSET_CAL_POSITION, + FTS_NVM_OFFSET_HISTORY_QUEUE_COUNT, + FTS_NVM_OFFSET_HISTORY_QUEUE_LASTP, + FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO, + FTS_NVM_OFFSET_CAL_FAIL_FLAG, + FTS_NVM_OFFSET_CAL_FAIL_COUNT, +}; + +struct fts_nvm_data_map { + int type; + int offset; + int length; +}; + +#define NVM_CMD(mtype, moffset, mlength) .type = mtype, .offset = moffset, .length = mlength + +/* This Flash Meory Map is FIXED by STM firmware + * Do not change MAP. + */ +struct fts_nvm_data_map nvm_data[] = { + {NVM_CMD(0, 0x00, 0),}, + {NVM_CMD(FTS_NVM_OFFSET_FAC_RESULT, 0x00, 1),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_CAL_COUNT, 0x01, 1),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_DISASSEMBLE_COUNT, 0x02, 1),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_TUNE_VERSION, 0x03, 2),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_CAL_POSITION, 0x05, 1),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_HISTORY_QUEUE_COUNT, 0x06, 1),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_HISTORY_QUEUE_LASTP, 0x07, 1),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO, 0x08, 20),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_CAL_FAIL_FLAG, 0x1C, 1),}, /* SEC */ + {NVM_CMD(FTS_NVM_OFFSET_CAL_FAIL_COUNT, 0x1D, 1),}, /* SEC */ +}; +#define FTS_NVM_OFFSET_ALL 31 + +static void fw_update(void *device_data); +static void get_fw_ver_bin(void *device_data); +static void get_fw_ver_ic(void *device_data); +static void get_config_ver(void *device_data); +static void get_threshold(void *device_data); +static void module_off_master(void *device_data); +static void module_on_master(void *device_data); +static void get_chip_vendor(void *device_data); +static void get_chip_name(void *device_data); +static void run_jitter_test(void *device_data); +static void run_mutual_jitter(void *device_data); +static void run_self_jitter(void *device_data); +static void run_jitter_delta_test(void *device_data); +static void get_wet_mode(void *device_data); +static void get_x_num(void *device_data); +static void get_y_num(void *device_data); +static void get_checksum_data(void *device_data); +static void check_fw_corruption(void *device_data); +static void run_reference_read(void *device_data); +static void get_reference(void *device_data); +static void run_rawcap_read(void *device_data); +static void run_rawcap_read_all(void *device_data); +static void get_rawcap(void *device_data); +static void run_lp_single_ended_rawcap_read(void *device_data); +static void run_lp_single_ended_rawcap_read_all(void *device_data); +static void run_low_frequency_rawcap_read(void *device_data); +static void run_low_frequency_rawcap_read_all(void *device_data); +static void run_high_frequency_rawcap_read(void *device_data); +static void run_high_frequency_rawcap_read_all(void *device_data); +static void run_delta_read(void *device_data); +static void get_delta(void *device_data); +static void run_rawdata_read_all(void *device_data); +#ifdef TCLM_CONCEPT +static void get_pat_information(void *device_data); +static void set_external_factory(void *device_data); +static void tclm_test_cmd(void *device_data); +static void get_calibration(void *device_data); +#endif +static void run_ix_data_read(void *device_data); +static void run_ix_data_read_all(void *device_data); +static void run_self_raw_read(void *device_data); +static void run_factory_miscalibration(void *device_data); +static void run_miscalibration(void *device_data); +static void run_self_raw_read_all(void *device_data); +static void run_trx_short_test(void *device_data); +static void check_connection(void *device_data); +static void get_cx_data(void *device_data); +static void run_active_cx_data_read(void *device_data); +static void run_multi_mutual_cx_data_read(void *device_data); +static void run_cx_data_read(void *device_data); +static void get_cx_all_data(void *device_data); +static void run_cx_gap_data_x_all(void *device_data); +static void run_cx_gap_data_y_all(void *device_data); +static void run_rawdata_gap_data_rx_all(void *device_data); +static void run_rawdata_gap_data_tx_all(void *device_data); +static void run_prox_intensity_read_all(void *device_data); +static void get_strength_all_data(void *device_data); + +static void set_tsp_test_result(void *device_data); +static void get_tsp_test_result(void *device_data); +static void increase_disassemble_count(void *device_data); +static void get_disassemble_count(void *device_data); +static void get_osc_trim_error(void *device_data); +static void get_osc_trim_info(void *device_data); +static void run_snr_non_touched(void *device_data); +static void run_snr_touched(void *device_data); +/* +static void run_elvss_test(void *device_data); +*/ +#ifdef CONFIG_GLOVE_TOUCH +static void glove_mode(void *device_data); +#endif +static void clear_cover_mode(void *device_data); +static void report_rate(void *device_data); +#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) +static void interrupt_control(void *device_data); +#endif + +static void set_wirelesscharger_mode(void *device_data); +static void set_grip_data(void *device_data); +static void dead_zone_enable(void *device_data); +static void drawing_test_enable(void *device_data); +static void spay_enable(void *device_data); +static void aot_enable(void *device_data); +static void aod_enable(void *device_data); +static void singletap_enable(void *device_data); +static void set_aod_rect(void *device_data); +static void get_aod_rect(void *device_data); +static void fod_enable(void *device_data); +static void set_fod_rect(void *device_data); +static void external_noise_mode(void *device_data); +static void brush_enable(void *device_data); +static void set_touchable_area(void *device_data); +static void debug(void *device_data); +static void factory_cmd_result_all(void *device_data); +static void factory_cmd_result_all_imagetest(void *device_data); +static void run_force_calibration(void *device_data); +static void set_factory_level(void *device_data); +static void fix_active_mode(void *device_data); +static void touch_aging_mode(void *device_data); +static void run_sram_test(void *device_data); +static void set_rear_selfie_mode(void *device_data); +static void ear_detect_enable(void *device_data); +static void pocket_mode_enable(void *device_data); +static void set_sip_mode(void *device_data); +static void set_note_mode(void *device_data); +static void set_game_mode(void *device_data); +static void not_support_cmd(void *device_data); + +static ssize_t fts_scrub_position(struct device *dev, + struct device_attribute *attr, char *buf); + +struct sec_cmd ft_commands[] = { + {SEC_CMD("fw_update", fw_update),}, + {SEC_CMD("get_fw_ver_bin", get_fw_ver_bin),}, + {SEC_CMD("get_fw_ver_ic", get_fw_ver_ic),}, + {SEC_CMD("get_config_ver", get_config_ver),}, + {SEC_CMD("get_threshold", get_threshold),}, + {SEC_CMD("module_off_master", module_off_master),}, + {SEC_CMD("module_on_master", module_on_master),}, + {SEC_CMD("module_off_slave", not_support_cmd),}, + {SEC_CMD("module_on_slave", not_support_cmd),}, + {SEC_CMD("get_chip_vendor", get_chip_vendor),}, + {SEC_CMD("get_chip_name", get_chip_name),}, + {SEC_CMD("run_jitter_test", run_jitter_test),}, + {SEC_CMD("run_mutual_jitter", run_mutual_jitter),}, + {SEC_CMD("run_self_jitter", run_self_jitter),}, + {SEC_CMD("run_jitter_delta_test", run_jitter_delta_test),}, + {SEC_CMD("get_wet_mode", get_wet_mode),}, + {SEC_CMD("get_module_vendor", not_support_cmd),}, + {SEC_CMD("get_x_num", get_x_num),}, + {SEC_CMD("get_y_num", get_y_num),}, + {SEC_CMD("get_checksum_data", get_checksum_data),}, + {SEC_CMD("get_crc_check", check_fw_corruption),}, + {SEC_CMD("run_reference_read", run_reference_read),}, + {SEC_CMD("get_reference", get_reference),}, + {SEC_CMD("run_rawcap_read", run_rawcap_read),}, + {SEC_CMD("run_rawcap_read_all", run_rawcap_read_all),}, + {SEC_CMD("get_rawcap", get_rawcap),}, + {SEC_CMD("run_lp_single_ended_rawcap_read", run_lp_single_ended_rawcap_read),}, + {SEC_CMD("run_lp_single_ended_rawcap_read_all", run_lp_single_ended_rawcap_read_all),}, + {SEC_CMD("run_low_frequency_rawcap_read", run_low_frequency_rawcap_read),}, + {SEC_CMD("run_low_frequency_rawcap_read_all", run_low_frequency_rawcap_read_all),}, + {SEC_CMD("run_high_frequency_rawcap_read", run_high_frequency_rawcap_read),}, + {SEC_CMD("run_high_frequency_rawcap_read_all", run_high_frequency_rawcap_read_all),}, + {SEC_CMD("run_delta_read", run_delta_read),}, + {SEC_CMD("get_delta", get_delta),}, + {SEC_CMD("run_cs_raw_read_all", run_rawcap_read_all),}, + {SEC_CMD("run_prox_intensity_read_all", run_prox_intensity_read_all),}, + {SEC_CMD("run_cs_delta_read_all", get_strength_all_data),}, + {SEC_CMD("run_rawdata_read_all_for_ghost", run_rawdata_read_all),}, +#ifdef TCLM_CONCEPT + {SEC_CMD("get_pat_information", get_pat_information),}, + {SEC_CMD("set_external_factory", set_external_factory),}, + {SEC_CMD("tclm_test_cmd", tclm_test_cmd),}, + {SEC_CMD("get_calibration", get_calibration),}, +#endif + {SEC_CMD("run_ix_data_read", run_ix_data_read),}, + {SEC_CMD("run_ix_data_read_all", run_ix_data_read_all),}, + {SEC_CMD("run_self_raw_read", run_self_raw_read),}, + {SEC_CMD("run_self_raw_read_all", run_self_raw_read_all),}, + {SEC_CMD("run_factory_miscalibration", run_factory_miscalibration),}, + {SEC_CMD("run_miscalibration", run_miscalibration),}, + {SEC_CMD("run_trx_short_test", run_trx_short_test),}, + {SEC_CMD("check_connection", check_connection),}, + {SEC_CMD("get_cx_data", get_cx_data),}, + {SEC_CMD("run_active_cx_data_read", run_active_cx_data_read),}, + {SEC_CMD("run_multi_mutual_cx_data_read", run_multi_mutual_cx_data_read),}, + {SEC_CMD("run_cx_data_read", run_cx_data_read),}, + {SEC_CMD("run_cx_data_read_all", get_cx_all_data),}, + {SEC_CMD("get_cx_all_data", get_cx_all_data),}, + {SEC_CMD("run_cx_gap_data_rx_all", run_cx_gap_data_x_all),}, + {SEC_CMD("run_cx_gap_data_tx_all", run_cx_gap_data_y_all),}, + {SEC_CMD("run_rawdata_gap_data_rx_all", run_rawdata_gap_data_rx_all),}, + {SEC_CMD("run_rawdata_gap_data_tx_all", run_rawdata_gap_data_tx_all),}, + {SEC_CMD("get_strength_all_data", get_strength_all_data),}, + {SEC_CMD("set_tsp_test_result", set_tsp_test_result),}, + {SEC_CMD("get_tsp_test_result", get_tsp_test_result),}, + {SEC_CMD("increase_disassemble_count", increase_disassemble_count),}, + {SEC_CMD("get_disassemble_count", get_disassemble_count),}, + {SEC_CMD("get_osc_trim_error", get_osc_trim_error),}, + {SEC_CMD("get_osc_trim_info", get_osc_trim_info),}, + {SEC_CMD("run_snr_non_touched", run_snr_non_touched),}, + {SEC_CMD("run_snr_touched", run_snr_touched),}, +/* + {SEC_CMD("run_elvss_test", run_elvss_test),}, +*/ +#ifdef CONFIG_GLOVE_TOUCH + {SEC_CMD_H("glove_mode", glove_mode),}, +#endif + {SEC_CMD_H("clear_cover_mode", clear_cover_mode),}, + {SEC_CMD("report_rate", report_rate),}, +#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) + {SEC_CMD("interrupt_control", interrupt_control),}, +#endif + {SEC_CMD("set_wirelesscharger_mode", set_wirelesscharger_mode),}, + {SEC_CMD("set_grip_data", set_grip_data),}, + {SEC_CMD("dead_zone_enable", dead_zone_enable),}, + {SEC_CMD("drawing_test_enable", drawing_test_enable),}, + {SEC_CMD_H("spay_enable", spay_enable),}, + {SEC_CMD_H("aot_enable", aot_enable),}, + {SEC_CMD_H("aod_enable", aod_enable),}, + {SEC_CMD_H("singletap_enable", singletap_enable),}, + {SEC_CMD("set_aod_rect", set_aod_rect),}, + {SEC_CMD("get_aod_rect", get_aod_rect),}, + {SEC_CMD_H("fod_enable", fod_enable),}, + {SEC_CMD("set_fod_rect", set_fod_rect),}, + {SEC_CMD_H("external_noise_mode", external_noise_mode),}, + {SEC_CMD_H("brush_enable", brush_enable),}, + {SEC_CMD_H("set_touchable_area", set_touchable_area),}, + {SEC_CMD("debug", debug),}, + {SEC_CMD("factory_cmd_result_all", factory_cmd_result_all),}, + {SEC_CMD("factory_cmd_result_all_imagetest", factory_cmd_result_all_imagetest),}, + {SEC_CMD("run_force_calibration", run_force_calibration),}, + {SEC_CMD("set_factory_level", set_factory_level),}, + {SEC_CMD("fix_active_mode", fix_active_mode),}, + {SEC_CMD("touch_aging_mode", touch_aging_mode),}, + {SEC_CMD("run_sram_test", run_sram_test),}, + {SEC_CMD_H("set_rear_selfie_mode", set_rear_selfie_mode),}, + {SEC_CMD_H("ear_detect_enable", ear_detect_enable),}, + {SEC_CMD_H("pocket_mode_enable", pocket_mode_enable),}, + {SEC_CMD("set_sip_mode", set_sip_mode),}, + {SEC_CMD_H("set_note_mode", set_note_mode),}, + {SEC_CMD("set_game_mode", set_game_mode),}, + {SEC_CMD("not_support_cmd", not_support_cmd),}, +}; + +/* read param */ +static ssize_t hardware_param_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[516]; + char tbuff[128]; + char temp[128]; + + memset(buff, 0x00, sizeof(buff)); + + /* ito_check */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TITO\":\"%02X%02X%02X%02X\",", + info->ito_test[0], info->ito_test[1], + info->ito_test[2], info->ito_test[3]); + strlcat(buff, tbuff, sizeof(buff)); + + /* muli_count */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TMUL\":\"%d\",", info->multi_count); + strlcat(buff, tbuff, sizeof(buff)); + + /* wet_mode */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TWET\":\"%d\",", info->wet_count); + strlcat(buff, tbuff, sizeof(buff)); + + /* noise_mode */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TNOI\":\"%d\",", info->noise_count); + strlcat(buff, tbuff, sizeof(buff)); + + /* comm_err_count */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TCOM\":\"%d\",", info->comm_err_count); + strlcat(buff, tbuff, sizeof(buff)); + + /* module_id */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TMOD\":\"ST%02X%04X%02X%c%01X\",", + info->panel_revision, info->fw_main_version_of_ic, + info->test_result.data[0], +#ifdef TCLM_CONCEPT + info->tdata->tclm_string[info->tdata->nvdata.cal_position].s_name, + info->tdata->nvdata.cal_count & 0xF); +#else + '0', 0); +#endif + strlcat(buff, tbuff, sizeof(buff)); + + /* vendor_id */ + memset(tbuff, 0x00, sizeof(tbuff)); + if (info->board->firmware_name) { + memset(temp, 0x00, sizeof(temp)); + snprintf(temp, 9, "%s", info->board->firmware_name + 8); + + snprintf(tbuff, sizeof(tbuff), "\"TVEN\":\"STM_%s\",", temp); + } else { + snprintf(tbuff, sizeof(tbuff), "\"TVEN\":\"STM\","); + } + strlcat(buff, tbuff, sizeof(buff)); + + /* checksum */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TCHK\":\"%d\",", info->checksum_result); + strlcat(buff, tbuff, sizeof(buff)); + + /* all_touch_count */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TTCN\":\"%d\",\"TACN\":\"%d\",\"TSCN\":\"%d\",", + info->all_finger_count, info->all_aod_tap_count, + info->all_spay_count); + strlcat(buff, tbuff, sizeof(buff)); + + /* xenosensor_detect_count */ + memset(tbuff, 0x00, sizeof(tbuff)); + snprintf(tbuff, sizeof(tbuff), "\"TXEN\":\"%02d/%02d_%02d:%02d:%02d_%d,%d_%d\",", + (info->xenosensor_detect_count > 0) ? info->xenosensor_time.tm_mon + 1 : info->xenosensor_time.tm_mon, + info->xenosensor_time.tm_mday, info->xenosensor_time.tm_hour, info->xenosensor_time.tm_min, + info->xenosensor_time.tm_sec, info->xenosensor_detect_x, info->xenosensor_detect_y, + info->xenosensor_detect_count); + strlcat(buff, tbuff, sizeof(buff)); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return snprintf(buf, SEC_CMD_BUF_SIZE, "%s", buff); +} + +/* clear param */ +static ssize_t hardware_param_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + info->multi_count = 0; + info->wet_count = 0; + info->noise_count = 0; + info->comm_err_count = 0; + info->checksum_result = 0; + info->all_finger_count = 0; + info->all_aod_tap_count = 0; + info->all_spay_count = 0; + info->xenosensor_detect_count = 0; + memset(&info->xenosensor_time, 0, sizeof(info->xenosensor_time)); + info->xenosensor_detect_x = 0; + info->xenosensor_detect_y = 0; + + return count; +} + +static ssize_t read_ambient_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + input_info(true, &info->client->dev, + "\"TAMB_MAX\":\"%d\",\"TAMB_MAX_TX\":\"%d\",\"TAMB_MAX_RX\":\"%d\"" + "\"TAMB_MIN\":\"%d\",\"TAMB_MIN_TX\":\"%d\",\"TAMB_MIN_RX\":\"%d\"", + info->rawcap_max, info->rawcap_max_tx, info->rawcap_max_rx, + info->rawcap_min, info->rawcap_min_tx, info->rawcap_min_rx); + + return snprintf(buf, SEC_CMD_BUF_SIZE, + "\"TAMB_MAX\":\"%d\",\"TAMB_MAX_TX\":\"%d\",\"TAMB_MAX_RX\":\"%d\"," + "\"TAMB_MIN\":\"%d\",\"TAMB_MIN_TX\":\"%d\",\"TAMB_MIN_RX\":\"%d\"", + info->rawcap_max, info->rawcap_max_tx, info->rawcap_max_rx, + info->rawcap_min, info->rawcap_min_tx, info->rawcap_min_rx); +} + +static ssize_t sensitivity_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + unsigned char wbuf[3] = { 0 }; + unsigned long value = 0; + int ret = 0; + + if (count > 2) + return -EINVAL; + + ret = kstrtoul(buf, 10, &value); + if (ret != 0) + return ret; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", __func__); + return -EPERM; + } + + wbuf[0] = FTS_CMD_SENSITIVITY_MODE; + + switch (value) { + case 0: + wbuf[1] = 0xFF; /* disable */ + break; + case 1: + wbuf[1] = 0x24; /* enable */ + wbuf[2] = 0x01; + info->sensitivity_mode = 1; + break; + case 2: + wbuf[1] = 0x24; /* flex mode enable */ + wbuf[2] = 0x02; + info->sensitivity_mode = 2; + break; + default: + break; + } + + ret = fts_write_reg(info, wbuf, 3); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: write failed. ret: %d\n", __func__, ret); + return ret; + } + + fts_delay(30); + + input_info(true, &info->client->dev, "%s: %ld\n", __func__, value); + return count; +} + +static ssize_t sensitivity_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + u8 *rbuf; + u8 reg_read = FTS_READ_SENSITIVITY_VALUE; + int ret, i; + s16 value[10]; + u8 count = 9; + char *buffer; + ssize_t len; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", __func__); + return -EPERM; + } + + if (info->sensitivity_mode == 2) /* flex mode */ + count = 12; + + rbuf = kzalloc(count * 2, GFP_KERNEL); + if (!rbuf) + return -ENOMEM; + + buffer = kzalloc(SEC_CMD_BUF_SIZE, GFP_KERNEL); + if (!buffer) { + kfree(rbuf); + return -ENOMEM; + } + + ret = info->fts_read_reg(info, ®_read, 1, rbuf, count * 2); + if (ret < 0) { + kfree(rbuf); + kfree(buffer); + input_err(true, &info->client->dev, "%s: read failed ret = %d\n", __func__, ret); + return ret; + } + + for (i = 0; i < count; i++) { + char temp[16]; + + memset(temp, 0x00, 16); + value[i] = rbuf[i * 2] + (rbuf[i * 2 + 1] << 8); + snprintf(temp, 16, "%d,", value[i]); + strlcat(buffer, temp, SEC_CMD_BUF_SIZE); + } + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buffer); + len = snprintf(buf, SEC_CMD_BUF_SIZE, "%s", buffer); + + kfree(rbuf); + kfree(buffer); + + return len; +} + +/* + * read_support_feature function + * returns the bit combination of specific feature that is supported. + */ +static ssize_t read_support_feature(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u32 feature = 0; + + if (info->board->enable_settings_aot) + feature |= INPUT_FEATURE_ENABLE_SETTINGS_AOT; + + if (info->board->sync_reportrate_120) + feature |= INPUT_FEATURE_ENABLE_SYNC_RR120; + + if (info->board->support_open_short_test) + feature |= INPUT_FEATURE_SUPPORT_OPEN_SHORT_TEST; + + if (info->board->support_mis_calibration_test) + feature |= INPUT_FEATURE_SUPPORT_MIS_CALIBRATION_TEST; + + snprintf(buff, sizeof(buff), "%d", feature); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return snprintf(buf, SEC_CMD_BUF_SIZE, "%s", buff); +} + +#ifdef FTS_SUPPORT_SPONGELIB +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE +ssize_t get_lp_dump(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info; + + u8 string_data[10] = {0, }; + u16 current_index; + u8 dump_format, dump_num; + u16 dump_start, dump_end; + int i, j, ret; + u16 addr; + u8 buffer[30]; + u8 position = FTS_SPONGE_LP_DUMP_DATA_FORMAT_10_LEN; + + if (!sec) + return -ENODEV; + + info = container_of(sec, struct fts_ts_info, sec); + + if (!info->lp_dump) + return -ENOMEM; + + if (!info->use_sponge) + return -ENODEV; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + goto read_buf; + } + + if (info->reset_is_on_going) { + input_err(true, &info->client->dev, "%s: reset is ongoing\n", + __func__); + goto read_buf; + } + + if (info->lp_dump_readmore == 0) + goto read_buf; + + fts_interrupt_set(info, INT_DISABLE); + + addr = FTS_CMD_SPONGE_LP_DUMP; + + ret = info->fts_read_from_sponge(info, addr, string_data, 4); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: Failed to read from Sponge, addr=0x%X\n", __func__, addr); + if (buf) + snprintf(buf, SEC_CMD_BUF_SIZE, + "NG, Failed to read from Sponge, addr=0x%X", addr); + fts_interrupt_set(info, INT_ENABLE); + goto out; + } + + dump_format = string_data[0]; + dump_num = string_data[1]; + dump_start = FTS_CMD_SPONGE_LP_DUMP + 4; + dump_end = dump_start + (dump_format * (dump_num - 1)); + + if (dump_format > 10) { + input_err(true, &info->client->dev, + "%s: abnormal data:0x%X, 0x%X\n", __func__, string_data[0], string_data[1]); + if (buf) + snprintf(buf, SEC_CMD_BUF_SIZE, "%s", + "NG, Failed to read from dump format"); + fts_interrupt_set(info, INT_ENABLE); + goto out; + } + + current_index = (string_data[3] & 0xFF) << 8 | (string_data[2] & 0xFF); + if (current_index > dump_end || current_index < dump_start) { + input_err(true, &info->client->dev, + "Failed to Sponge LP log %d\n", current_index); + if (buf) + snprintf(buf, SEC_CMD_BUF_SIZE, + "NG, Failed to Sponge LP log, current_index=%d", + current_index); + fts_interrupt_set(info, INT_ENABLE); + goto out; + } + + input_info(true, &info->client->dev, "%s: DEBUG format=%d, num=%d, start=%d, end=%d, current_index=%d\n", + __func__, dump_format, dump_num, dump_start, dump_end, current_index); + + for (i = dump_num - 1 ; i >= 0 ; i--) { + u16 string_addr; + int value, j; + + if (current_index < (dump_format * i)) + string_addr = (dump_format * dump_num) + current_index - (dump_format * i); + else + string_addr = current_index - (dump_format * i); + + if (string_addr < dump_start) + string_addr += (dump_format * dump_num); + + addr = string_addr; + + ret = info->fts_read_from_sponge(info, addr, string_data, dump_format); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: Failed to read from Sponge, addr=0x%X\n", __func__, addr); + if (buf) + snprintf(buf, SEC_CMD_BUF_SIZE, + "NG, Failed to read from Sponge, addr=0x%X", addr); + fts_interrupt_set(info, INT_ENABLE); + goto out; + } + + value = 0; + + for (j = 0; j < 10; j++) + value += string_data[j]; + + if (value == 0) + continue; + + info->lp_dump[info->lp_dump_index] = (string_addr >> 8) & 0xFF; + info->lp_dump[info->lp_dump_index + 1] = string_addr & 0xFF; + + for (j = 0; j < 10; j += 2) { + info->lp_dump[info->lp_dump_index + 2 + j] = string_data[j + 1]; + info->lp_dump[info->lp_dump_index + 2 + j + 1] = string_data[j]; + } + info->lp_dump_index += position; + + if (info->lp_dump_index >= position * FTS_SPONGE_LP_DUMP_LENGTH) + info->lp_dump_index = 0; + } + + fts_interrupt_set(info, INT_ENABLE); + +read_buf: + if (buf) { + int pos = info->lp_dump_index; + + for (i = 0; i < FTS_SPONGE_LP_DUMP_LENGTH; i++) { + if (pos >= FTS_SPONGE_LP_DUMP_DATA_FORMAT_10_LEN * FTS_SPONGE_LP_DUMP_LENGTH) + pos = 0; + + if (info->lp_dump[pos] == 0 && info->lp_dump[pos + 1] == 0) { + pos += position; + continue; + } + + snprintf(buffer, sizeof(buffer), "%d: ", info->lp_dump[pos] << 8 | info->lp_dump[pos + 1]); + strlcat(buf, buffer, PAGE_SIZE); + memset(buffer, 0x00, sizeof(buffer)); + for (j = 0; j < 10; j++) { + snprintf(buffer, sizeof(buffer), "%02x", info->lp_dump[pos + 2 + j]); + strlcat(buf, buffer, PAGE_SIZE); + memset(buffer, 0x00, sizeof(buffer)); + } + snprintf(buffer, sizeof(buffer), "\n"); + strlcat(buf, buffer, PAGE_SIZE); + memset(buffer, 0x00, sizeof(buffer)); + + pos += position; + } + } +out: + info->lp_dump_readmore = 0; + + if (buf) { + if (strlen(buf) == 0) + snprintf(buf, SEC_CMD_BUF_SIZE, "%s", "empty"); + + return strlen(buf); + } + + return ret; +} +#else +static ssize_t get_lp_dump(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + u8 string_data[10] = {0, }; + u16 current_index; + u16 dump_start, dump_end, dump_cnt; + int i, ret, dump_area, dump_gain; + unsigned char *sec_spg_dat; + u8 dump_clear_packet = 0x01; + u16 addr; + + if (!info->use_sponge) + return -ENODEV; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + return snprintf(buf, SEC_CMD_BUF_SIZE, "%s", "TSP turned off"); + } + + /* preparing dump buffer */ + sec_spg_dat = vmalloc(FTS_MAX_SPONGE_DUMP_BUFFER); + if (!sec_spg_dat) { + input_err(true, &info->client->dev, "%s : Failed!!\n", __func__); + return snprintf(buf, SEC_CMD_BUF_SIZE, "vmalloc failed"); + } + memset(sec_spg_dat, 0, FTS_MAX_SPONGE_DUMP_BUFFER); + + fts_interrupt_set(info, INT_DISABLE); + + addr = FTS_CMD_SPONGE_LP_DUMP_CUR_IDX; + + ret = info->fts_read_from_sponge(info, addr, string_data, 2); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: Failed to read from Sponge, addr=0x%X\n", __func__, addr); + snprintf(buf, SEC_CMD_BUF_SIZE, + "NG, Failed to read from Sponge, addr=0x%X", addr); + goto out; + } + + if (info->sponge_inf_dump) + dump_gain = 2; + else + dump_gain = 1; + + current_index = (string_data[1] & 0xFF) << 8 | (string_data[0] & 0xFF); + dump_start = FTS_CMD_SPONGE_LP_DUMP_EVENT; + dump_end = dump_start + (info->sponge_dump_format * ((info->sponge_dump_event * dump_gain) - 1)); + + if (current_index > dump_end || current_index < dump_start) { + input_err(true, &info->client->dev, + "Failed to Sponge LP log %d\n", current_index); + snprintf(buf, SEC_CMD_BUF_SIZE, + "NG, Failed to Sponge LP log, current_index=%d", + current_index); + goto out; + } + + /* legacy get_lp_dump */ + input_info(true, &info->client->dev, "%s: DEBUG format=%d, num=%d, start=%d, end=%d, current_index=%d\n", + __func__, info->sponge_dump_format, info->sponge_dump_event, dump_start, dump_end, current_index); + + for (i = (info->sponge_dump_event * dump_gain) - 1 ; i >= 0 ; i--) { + u16 data0, data1, data2, data3, data4; + char buff[30] = {0, }; + u16 string_addr; + + if (current_index < (info->sponge_dump_format * i)) + string_addr = (info->sponge_dump_format * info->sponge_dump_event * dump_gain) + current_index - (info->sponge_dump_format * i); + else + string_addr = current_index - (info->sponge_dump_format * i); + + if (string_addr < dump_start) + string_addr += (info->sponge_dump_format * info->sponge_dump_event * dump_gain); + + addr = string_addr; + + ret = info->fts_read_from_sponge(info, addr, string_data, info->sponge_dump_format); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: Failed to read from Sponge, addr=0x%X\n", __func__, addr); + snprintf(buf, SEC_CMD_BUF_SIZE, + "NG, Failed to read from Sponge, addr=0x%X", addr); + goto out; + } + + data0 = (string_data[1] & 0xFF) << 8 | (string_data[0] & 0xFF); + data1 = (string_data[3] & 0xFF) << 8 | (string_data[2] & 0xFF); + data2 = (string_data[5] & 0xFF) << 8 | (string_data[4] & 0xFF); + data3 = (string_data[7] & 0xFF) << 8 | (string_data[6] & 0xFF); + data4 = (string_data[9] & 0xFF) << 8 | (string_data[8] & 0xFF); + + if (data0 || data1 || data2 || data3 || data4) { + if (info->sponge_dump_format == 10) { + snprintf(buff, sizeof(buff), + "%d: %04x%04x%04x%04x%04x\n", + string_addr, data0, data1, data2, data3, data4); + } else { + snprintf(buff, sizeof(buff), + "%d: %04x%04x%04x%04x\n", + string_addr, data0, data1, data2, data3); + } + strlcat(buf, buff, PAGE_SIZE); + } + } + + if (info->sponge_inf_dump) { + if (current_index >= info->sponge_dump_border) { + dump_cnt = ((current_index - (info->sponge_dump_border)) / info->sponge_dump_format) + 1; + dump_area = 1; + addr = info->sponge_dump_border; + } else { + dump_cnt = ((current_index - FTS_CMD_SPONGE_LP_DUMP_EVENT) / info->sponge_dump_format) + 1; + dump_area = 0; + addr = FTS_CMD_SPONGE_LP_DUMP_EVENT; + } + + ret = info->fts_read_from_sponge(info, addr, sec_spg_dat, dump_cnt * info->sponge_dump_format); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Failed to read sponge\n", __func__); + goto out; + } + + for (i = 0 ; i <= dump_cnt ; i++) { + int e_offset = i * info->sponge_dump_format; + char ibuff[30] = {0, }; + u16 edata[5]; + + edata[0] = (sec_spg_dat[1 + e_offset] & 0xFF) << 8 | (sec_spg_dat[0 + e_offset] & 0xFF); + edata[1] = (sec_spg_dat[3 + e_offset] & 0xFF) << 8 | (sec_spg_dat[2 + e_offset] & 0xFF); + edata[2] = (sec_spg_dat[5 + e_offset] & 0xFF) << 8 | (sec_spg_dat[4 + e_offset] & 0xFF); + edata[3] = (sec_spg_dat[7 + e_offset] & 0xFF) << 8 | (sec_spg_dat[6 + e_offset] & 0xFF); + edata[4] = (sec_spg_dat[9 + e_offset] & 0xFF) << 8 | (sec_spg_dat[8 + e_offset] & 0xFF); + + if (edata[0] || edata[1] || edata[2] || edata[3] || edata[4]) { + snprintf(ibuff, sizeof(ibuff), "%03d: %04x%04x%04x%04x%04x\n", + i + (info->sponge_dump_event * dump_area), + edata[0], edata[1], edata[2], edata[3], edata[4]); + sec_tsp_sponge_log(ibuff); + } + } + + info->sponge_dump_delayed_flag = false; + ret = fts_write_to_sponge(info, FTS_CMD_SPONGE_DUMP_FLUSH, + &dump_clear_packet, 1); + if (ret < 0) + input_err(true, &info->client->dev, "%s: Failed to clear sponge dump\n", __func__); + } + +out: + vfree(sec_spg_dat); + fts_interrupt_set(info, INT_ENABLE); + + return strlen(buf); +} +#endif +#endif + +static ssize_t prox_power_off_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + input_info(true, &info->client->dev, "%s: %d\n", __func__, + info->prox_power_off); + + return snprintf(buf, SEC_CMD_BUF_SIZE, "%d", info->prox_power_off); +} + +static ssize_t prox_power_off_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + int ret, data; + + ret = kstrtoint(buf, 10, &data); + if (ret < 0) + return ret; + + input_info(true, &info->client->dev, "%s: %d\n", __func__, data); + + info->prox_power_off = data; + + return count; +} + +static ssize_t protos_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + input_info(true, &info->client->dev, "%s: %d\n", __func__, info->hover_event); + + return snprintf(buf, SEC_CMD_BUF_SIZE, "%d", info->hover_event != 3 ? 0 : 3); +} + +static ssize_t protos_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + int ret; + u8 data[2]; + + ret = kstrtou8(buf, 8, &data[1]); + if (ret < 0) + return ret; + + data[0] = FTS_CMD_SET_EAR_DETECT; + + ret = fts_write_reg(info, data, 2); + input_info(true, &info->client->dev, "%s: set %d: ret:%d\n", __func__, data[1], ret); + + return count; +} + +static ssize_t fts_fod_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + if (!info->board->support_fod) { + input_err(true, &info->client->dev, "%s: fod is not supported\n", __func__); + return snprintf(buf, SEC_CMD_BUF_SIZE, "NG"); + } + + input_info(true, &info->client->dev, "%s: x:%d/%d y:%d/%d size:%d\n", + __func__, info->fod_x, info->ForceChannelLength, + info->fod_y, info->SenseChannelLength, info->fod_vi_size); + + return snprintf(buf, SEC_CMD_BUF_SIZE, "%d,%d,%d,%d,%d\n", + info->fod_x, info->fod_y, info->fod_vi_size, + info->ForceChannelLength, info->SenseChannelLength); +} + +static ssize_t fts_fod_position_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[3] = { 0 }; + int i; + + if (!info->board->support_fod) { + input_err(true, &info->client->dev, "%s: fod is not supported\n", __func__); + return snprintf(buf, SEC_CMD_BUF_SIZE, "NG"); + } + + if (!info->fod_vi_size) { + input_err(true, &info->client->dev, "%s: fod vi size is 0\n", __func__); + return snprintf(buf, SEC_CMD_BUF_SIZE, "NG"); + } + + if (!info->fod_vi_data) { + input_err(true, &info->client->dev, "%s: fod vi data is null\n", __func__); + return snprintf(buf, SEC_CMD_BUF_SIZE, "NG"); + } + + for (i = 0; i < info->fod_vi_size; i++) { + snprintf(buff, 3, "%02X", info->fod_vi_data[i]); + strlcat(buf, buff, SEC_CMD_BUF_SIZE); + } + + return strlen(buf); +} + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE +static ssize_t dualscreen_policy_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + int ret, value; + + if (!info->board->support_flex_mode) + return count; + + ret = kstrtoint(buf, 10, &value); + if (ret < 0) + return ret; + + input_info(true, &info->client->dev, "%s: power_state[%d] %sfolding\n", + __func__, info->fts_power_state, info->flip_status_current ? "" : "un"); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN && info->flip_status_current == FTS_STATUS_UNFOLDING) { + cancel_delayed_work(&info->switching_work); + schedule_work(&info->switching_work.work); + } + + return count; +} +#endif + +static DEVICE_ATTR(hw_param, 0664, hardware_param_show, hardware_param_store); +static DEVICE_ATTR(read_ambient_info, 0444, read_ambient_info_show, NULL); +static DEVICE_ATTR(sensitivity_mode, 0664, sensitivity_mode_show, sensitivity_mode_store); +static DEVICE_ATTR(scrub_pos, 0444, fts_scrub_position, NULL); +static DEVICE_ATTR(support_feature, 0444, read_support_feature, NULL); +#ifdef FTS_SUPPORT_SPONGELIB +static DEVICE_ATTR(get_lp_dump, 0444, get_lp_dump, NULL); +#endif +static DEVICE_ATTR(prox_power_off, 0664, prox_power_off_show, prox_power_off_store); +static DEVICE_ATTR(virtual_prox, 0664, protos_event_show, protos_event_store); +static DEVICE_ATTR(fod_info, 0444, fts_fod_info_show, NULL); +static DEVICE_ATTR(fod_pos, 0444, fts_fod_position_show, NULL); +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE +static DEVICE_ATTR(dualscreen_policy, 0664, NULL, dualscreen_policy_store); +#endif +static struct attribute *sec_touch_facotry_attributes[] = { + &dev_attr_scrub_pos.attr, + &dev_attr_hw_param.attr, + &dev_attr_read_ambient_info.attr, + &dev_attr_sensitivity_mode.attr, + &dev_attr_support_feature.attr, +#ifdef FTS_SUPPORT_SPONGELIB + &dev_attr_get_lp_dump.attr, +#endif + &dev_attr_prox_power_off.attr, + &dev_attr_virtual_prox.attr, + &dev_attr_fod_info.attr, + &dev_attr_fod_pos.attr, +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + &dev_attr_dualscreen_policy.attr, +#endif + NULL, +}; + +static struct attribute_group sec_touch_factory_attr_group = { + .attrs = sec_touch_facotry_attributes, +}; + +static ssize_t fts_get_cmoffset_dump(struct fts_ts_info *info, char *buf, u8 position) +{ + u8 regaddr[4] = { 0 }; + u8 *rbuff; + int ret, i, j, size = info->SenseChannelLength * info->ForceChannelLength; + u32 signature; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: Touch is stopped\n", __func__); + return -EPERM; + } + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + input_err(true, &info->client->dev, "%s: Touch is LP mode\n", __func__); + return -EPERM; + } + + if (info->reset_is_on_going) { + input_err(true, &info->client->dev, "%s: Reset is ongoing!\n", __func__); + return -EPERM; + } + + if (info->sec.cmd_is_running) { + input_err(true, &info->client->dev, "%s: cmd is running\n", __func__); + return -EBUSY; + } + + rbuff = kzalloc(size, GFP_KERNEL); + if (!rbuff) { + input_err(true, &info->client->dev, "%s: alloc failed\n", __func__); + return -ENOMEM; + } + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + fts_interrupt_set(info, INT_DISABLE); + + fts_release_all_finger(info); + + /* Request SEC factory debug data from flash */ + regaddr[0] = 0xA4; + regaddr[1] = 0x06; + regaddr[2] = 0x92; + regaddr[3] = position; + ret = fts_fw_wait_for_echo_event(info, regaddr, 4, 0); + if (ret < 0) { + snprintf(buf, info->proc_cmoffset_size, "NG, failed to request data, %d", ret); + goto out; + } + + /* read header info */ + regaddr[0] = 0xA6; + regaddr[1] = 0x00; + regaddr[2] = 0x00; + ret = info->fts_read_reg(info, ®addr[0], 3, rbuff, 8); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: read header failed. ret: %d\n", __func__, ret); + snprintf(buf, info->proc_cmoffset_size, "NG, failed to read header, %d", ret); + goto out; + } + + signature = rbuff[3] << 24 | rbuff[2] << 16 | rbuff[1] << 8 | rbuff[0]; + input_info(true, &info->client->dev, + "%s: position:%d, signature:%08X (%X), validation:%X, try count:%X\n", + __func__, position, signature, SEC_OFFSET_SIGNATURE, rbuff[4], rbuff[5]); + + if (signature != SEC_OFFSET_SIGNATURE) { + input_err(true, &info->client->dev, "%s: cmoffset[%d], signature is mismatched\n", + __func__, position); + snprintf(buf, info->proc_cmoffset_size, "signature mismatched %08X\n", signature); + goto out; + } + + /* read history data */ + regaddr[0] = 0xA6; + regaddr[1] = 0x00; + regaddr[2] = (u8)info->SenseChannelLength; + ret = info->fts_read_reg(info, ®addr[0], 3, rbuff, size); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: read data failed. ret: %d\n", __func__, ret); + snprintf(buf, info->proc_cmoffset_size, "NG, failed to read data %d", ret); + goto out; + } + + memset(buf, 0x00, info->proc_cmoffset_size); + for (i = 0; i < info->ForceChannelLength; i++) { + char buff[4] = { 0 }; + + for (j = 0; j < info->SenseChannelLength; j++) { + snprintf(buff, sizeof(buff), " %d", rbuff[i * info->SenseChannelLength + j]); + strlcat(buf, buff, info->proc_cmoffset_size); + } + snprintf(buff, sizeof(buff), "\n"); + strlcat(buf, buff, info->proc_cmoffset_size); + } + +out: + input_err(true, &info->client->dev, "%s: pos:%d, buf size:%zu\n", __func__, position, strlen(buf)); + + fts_interrupt_set(info, INT_ENABLE); + kfree(rbuff); + return strlen(buf); +} + +static void enter_factory_mode(struct fts_ts_info *info, bool fac_mode) +{ + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) + return; + + info->fts_systemreset(info, 50); + + fts_release_all_finger(info); + + if (fac_mode) { + // Auto-Tune without saving + fts_execute_autotune(info, false); + + fts_delay(50); + } + + fts_set_scanmode(info, info->scan_mode); + + fts_delay(50); +} + +static int fts_check_index(struct fts_ts_info *info) +{ + struct sec_cmd_data *sec = &info->sec; + char buff[SEC_CMD_STR_LEN] = { 0 }; + int node; + + if (sec->cmd_param[0] < 0 + || sec->cmd_param[0] >= info->SenseChannelLength + || sec->cmd_param[1] < 0 + || sec->cmd_param[1] >= info->ForceChannelLength) { + + snprintf(buff, sizeof(buff), "%s", "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + input_err(true, &info->client->dev, "%s: parameter error: %u,%u\n", + __func__, sec->cmd_param[0], sec->cmd_param[1]); + node = -1; + return node; + } + node = sec->cmd_param[1] * info->SenseChannelLength + sec->cmd_param[0]; + input_info(true, &info->client->dev, "%s: node = %d\n", __func__, node); + return node; +} + +static ssize_t fts_scrub_position(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sec_cmd_data *sec = dev_get_drvdata(dev); + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + input_info(true, &info->client->dev, "%s: %d %d %d\n", + __func__, info->scrub_id, info->scrub_x, info->scrub_y); + snprintf(buff, sizeof(buff), "%d %d %d", info->scrub_id, info->scrub_x, info->scrub_y); + + info->scrub_x = 0; + info->scrub_y = 0; + + return snprintf(buf, SEC_CMD_BUF_SIZE, "%s\n", buff); +} + +static void not_support_cmd(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + + sec_cmd_set_default_result(sec); + snprintf(buff, sizeof(buff), "%s", "NA"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_NOT_APPLICABLE; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void fw_update(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[64] = { 0 }; + int retval = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "%s", "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + retval = fts_fw_update_on_hidden_menu(info, sec->cmd_param[0]); + + if (retval < 0) { + snprintf(buff, sizeof(buff), "%s", "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + input_err(true, &info->client->dev, "%s: failed [%d]\n", __func__, retval); + } else { + snprintf(buff, sizeof(buff), "%s", "OK"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: success [%d]\n", __func__, retval); + } +} + +static int fts_get_channel_info(struct fts_ts_info *info) +{ + int rc = -1; + u8 regAdd[1] = { FTS_READ_PANEL_INFO }; + u8 data[FTS_EVENT_SIZE] = { 0 }; + + memset(data, 0x0, FTS_EVENT_SIZE); + + rc = info->fts_read_reg(info, regAdd, 1, data, 11); + if (rc < 0) { + info->ForceChannelLength = 0; + info->SenseChannelLength = 0; + input_err(true, &info->client->dev, "%s: Get channel info Read Fail!!\n", __func__); + return rc; + } + + info->ForceChannelLength = data[8]; // Number of TX CH + info->SenseChannelLength = data[9]; // Number of RX CH + + if (!(info->ForceChannelLength > 0 && info->ForceChannelLength < FTS_MAX_NUM_FORCE && + info->SenseChannelLength > 0 && info->SenseChannelLength < FTS_MAX_NUM_SENSE)) { + info->ForceChannelLength = FTS_MAX_NUM_FORCE; + info->SenseChannelLength = FTS_MAX_NUM_SENSE; + input_err(true, &info->client->dev, "%s: set channel num based on max value, check it!\n", __func__); + } + + info->ICXResolution = (data[0] << 8) | data[1]; // X resolution of IC + info->ICYResolution = (data[2] << 8) | data[3]; // Y resolution of IC + + input_info(true, &info->client->dev, "%s: RX:Sense(%02d) TX:Force(%02d) resolution:(IC)x:%d y:%d, (DT)x:%d,y:%d\n", + __func__, info->SenseChannelLength, info->ForceChannelLength, + info->ICXResolution, info->ICYResolution, info->board->max_x, info->board->max_y); + + if (info->ICXResolution > 0 && info->ICXResolution < FTS_MAX_X_RESOLUTION && + info->ICYResolution > 0 && info->ICYResolution < FTS_MAX_Y_RESOLUTION && + info->board->max_x != info->ICXResolution && info->board->max_y != info->ICYResolution) { + info->board->max_x = info->ICXResolution; + info->board->max_y = info->ICYResolution; + input_err(true, &info->client->dev, "%s: set resolution based on ic value, check it!\n", __func__); + } + + return rc; +} + +static void fts_print_channel(struct fts_ts_info *info, s16 *tx_data, s16 *rx_data) +{ + unsigned char *pStr = NULL; + unsigned char pTmp[16] = { 0 }; + int len, max_num = 0; + int i = 0, k = 0; + int tx_count = info->ForceChannelLength; + int rx_count = info->SenseChannelLength; + + if (tx_count > 20) + max_num = 10; + else + max_num = tx_count; + + if (!max_num) + return; + + len = 7 * (max_num + 1); + pStr = vzalloc(len); + if (!pStr) + return; + + /* Print TX channel */ + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " TX"); + strlcat(pStr, pTmp, len); + + for (k = 0; k < max_num; k++) { + snprintf(pTmp, sizeof(pTmp), " %02d", k); + strlcat(pStr, pTmp, len); + } + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " +"); + strlcat(pStr, pTmp, len); + + for (k = 0; k < max_num; k++) { + snprintf(pTmp, sizeof(pTmp), "------"); + strlcat(pStr, pTmp, len); + } + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " | "); + strlcat(pStr, pTmp, len); + + for (i = 0; i < tx_count; i++) { + if (i && i % max_num == 0) { + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " | "); + strlcat(pStr, pTmp, len); + } + + snprintf(pTmp, sizeof(pTmp), " %5d", tx_data[i]); + strlcat(pStr, pTmp, len); + } + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + /* Print RX channel */ + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " RX"); + strlcat(pStr, pTmp, len); + + for (k = 0; k < max_num; k++) { + snprintf(pTmp, sizeof(pTmp), " %02d", k); + strlcat(pStr, pTmp, len); + } + + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " +"); + strlcat(pStr, pTmp, len); + + for (k = 0; k < max_num; k++) { + snprintf(pTmp, sizeof(pTmp), "------"); + strlcat(pStr, pTmp, len); + } + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " | "); + strlcat(pStr, pTmp, len); + + for (i = 0; i < rx_count; i++) { + if (i && i % max_num == 0) { + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + memset(pStr, 0x0, len); + snprintf(pTmp, sizeof(pTmp), " | "); + strlcat(pStr, pTmp, len); + } + + snprintf(pTmp, sizeof(pTmp), " %5d", rx_data[i]); + strlcat(pStr, pTmp, len); + } + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + vfree(pStr); +} + +void fts_print_frame(struct fts_ts_info *info, short *min, short *max) +{ + int i = 0; + int j = 0; + u8 *pStr = NULL; + u8 pTmp[16] = { 0 }; + + pStr = kzalloc(BUFFER_MAX, GFP_KERNEL); + if (pStr == NULL) + return; + + snprintf(pTmp, 4, " "); + strlcat(pStr, pTmp, BUFFER_MAX); + + for (i = 0; i < info->SenseChannelLength; i++) { + snprintf(pTmp, 6, "Rx%02d ", i); + strlcat(pStr, pTmp, BUFFER_MAX); + } + + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + memset(pStr, 0x0, 6 * (info->SenseChannelLength + 1)); + snprintf(pTmp, 2, " +"); + strlcat(pStr, pTmp, BUFFER_MAX); + + for (i = 0; i < info->SenseChannelLength; i++) { + snprintf(pTmp, 6, "------"); + strlcat(pStr, pTmp, BUFFER_MAX); + } + + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + + for (i = 0; i < info->ForceChannelLength; i++) { + memset(pStr, 0x0, 6 * (info->SenseChannelLength + 1)); + snprintf(pTmp, 7, "Tx%02d | ", i); + strlcat(pStr, pTmp, BUFFER_MAX); + + for (j = 0; j < info->SenseChannelLength; j++) { + snprintf(pTmp, 6, "%5d ", info->pFrame[(i * info->SenseChannelLength) + j]); + strlcat(pStr, pTmp, BUFFER_MAX); + + if (info->pFrame[(i * info->SenseChannelLength) + j] < *min) { + *min = info->pFrame[(i * info->SenseChannelLength) + j]; + if (info->rawcap_lock) { + info->rawcap_min = *min; + info->rawcap_min_tx = i; + info->rawcap_min_rx = j; + } + } + + if (info->pFrame[(i * info->SenseChannelLength) + j] > *max) { + *max = info->pFrame[(i * info->SenseChannelLength) + j]; + if (info->rawcap_lock) { + info->rawcap_max = *max; + info->rawcap_max_tx = i; + info->rawcap_max_rx = j; + } + } + } + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + } + + input_raw_info_d(true, &info->client->dev, "%s, min:%d, max:%d\n", __func__, *min, *max); + + kfree(pStr); +} + +int fts_read_frame(struct fts_ts_info *info, u8 type, short *min, short *max) +{ + struct FTS_SyncFrameHeader *pSyncFrameHeader; + + u8 regAdd[8] = { 0 }; + + unsigned int totalbytes = 0; + u8 *pRead; + int rc = 0; + int ret = 0; + int i = 0; + int retry = 10; + + pRead = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 3 + 1, GFP_KERNEL); + if (!pRead) + return -ENOMEM; + + /* Request Data Type */ + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = (u8)type; + info->fts_write_reg(info, ®Add[0], 3); + fts_delay(50); + + do { + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + ret = info->fts_read_reg(info, ®Add[0], 3, &pRead[0], FTS_COMP_DATA_HEADER_SIZE); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, ret); + rc = -3; + goto ErrorExit; + } + + pSyncFrameHeader = (struct FTS_SyncFrameHeader *) &pRead[0]; + + if ((pSyncFrameHeader->header == 0xA5) && (pSyncFrameHeader->host_data_mem_id == type)) + break; + + fts_delay(100); + } while (retry--); + + if (retry == 0) { + input_err(true, &info->client->dev, + "%s: didn't match header or id. header = %02X, id = %02X\n", + __func__, pSyncFrameHeader->header, pSyncFrameHeader->host_data_mem_id); + rc = -4; + goto ErrorExit; + } + + totalbytes = (info->ForceChannelLength * info->SenseChannelLength * 2); + + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = FTS_COMP_DATA_HEADER_SIZE + pSyncFrameHeader->dbg_frm_len; + ret = info->fts_read_reg(info, ®Add[0], 3, &pRead[0], totalbytes); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, ret); + rc = -5; + goto ErrorExit; + } + + for (i = 0; i < totalbytes / 2; i++) + info->pFrame[i] = (short)(pRead[i * 2] + (pRead[i * 2 + 1] << 8)); + + switch (type) { + case TYPE_RAW_DATA: + input_raw_info_d(true, &info->client->dev, "%s", "[Raw Data]\n"); + break; + case TYPE_STRENGTH_DATA: + input_raw_info_d(true, &info->client->dev, "%s: [Strength Data]\n", __func__); + break; + case TYPE_BASELINE_DATA: + input_raw_info_d(true, &info->client->dev, "%s: [Baseline Data]\n", __func__); + break; + } + + fts_print_frame(info, min, max); + +ErrorExit: + kfree(pRead); + return rc; +} + +int fts_read_nonsync_frame(struct fts_ts_info *info, short *min, short *max) +{ + struct FTS_SyncFrameHeader *pSyncFrameHeader; + + u8 regAdd[8] = { 0 }; + + unsigned int totalbytes = 0; + u8 *pRead; + int rc = 0; + int ret = 0; + int i = 0; + int retry = 10; + + input_info(true, &info->client->dev, "%s\n", __func__); + + pRead = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 3 + 1, GFP_KERNEL); + if (!pRead) + return -ENOMEM; + + /* Request System Information */ + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = 0x01; + info->fts_write_reg(info, ®Add[0], 3); + fts_delay(50); + + do { + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + ret = info->fts_read_reg(info, ®Add[0], 3, &pRead[0], FTS_COMP_DATA_HEADER_SIZE); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, ret); + rc = -3; + goto ErrorExit; + } + + pSyncFrameHeader = (struct FTS_SyncFrameHeader *) &pRead[0]; + + if ((pSyncFrameHeader->header == 0xA5) && (pSyncFrameHeader->host_data_mem_id == 0x01)) + break; + + fts_delay(100); + } while (retry--); + + if (retry == 0) { + input_err(true, &info->client->dev, + "%s: didn't match header or id. header = %02X, id = %02X\n", + __func__, pSyncFrameHeader->header, pSyncFrameHeader->host_data_mem_id); + rc = -4; + goto ErrorExit; + } + + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x88; // ms screen rawdata + ret = info->fts_read_reg(info, ®Add[0], 3, &pRead[0], 2); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, ret); + rc = -5; + goto ErrorExit; + } + + totalbytes = (info->ForceChannelLength * info->SenseChannelLength * 2); + + regAdd[0] = 0xA6; + regAdd[1] = (u8)pRead[1]; + regAdd[2] = (u8)pRead[0]; + ret = info->fts_read_reg(info, ®Add[0], 3, &pRead[0], totalbytes); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, ret); + rc = -6; + goto ErrorExit; + } + + for (i = 0; i < totalbytes / 2; i++) + info->pFrame[i] = (short)(pRead[i * 2] + (pRead[i * 2 + 1] << 8)); + + fts_print_frame(info, min, max); + +ErrorExit: + kfree(pRead); + return rc; +} + +void fts_get_sec_ito_test_result(struct fts_ts_info *info) +{ + struct sec_cmd_data *sec = &info->sec; + struct fts_sec_panel_test_result result[10]; + u8 regAdd[3] = { 0 }; + u8 data[sizeof(struct fts_sec_panel_test_result) * 10 + 2] = { 0 }; + int ret, i, max_count = 0; + u8 length = sizeof(data); + u8 buff[100] = { 0 }; + u8 pos_buf[6] = { 0 }; + + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = 0x94; + + ret = fts_fw_wait_for_echo_event(info, regAdd, 3, 0); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to get echo, %d\n", __func__, ret); + goto done; + } + + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + ret = info->fts_read_reg(info, regAdd, 3, data, length); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to read data, %d\n", __func__, ret); + goto done; + } + + memcpy(result, &data[2], length - 2); + memset(info->ito_result, 0x00, FTS_ITO_RESULT_PRINT_SIZE); + + snprintf(buff, sizeof(buff), "%s: test count - sub:%d, main:%d\n", __func__, data[0], data[1]); + input_info(true, &info->client->dev, "%s", buff); + strlcat(info->ito_result, buff, FTS_ITO_RESULT_PRINT_SIZE); + + snprintf(buff, sizeof(buff), "ITO: / TX_GAP_MAX / RX_GAP_MAX\n"); + input_info(true, &info->client->dev, "%s", buff); + strlcat(info->ito_result, buff, FTS_ITO_RESULT_PRINT_SIZE); + + for (i = 0; i < 10; i++) { + switch (result[i].flag) { + case OFFSET_FAC_SUB: + snprintf(pos_buf, sizeof(pos_buf), "SUB "); + break; + case OFFSET_FAC_MAIN: + snprintf(pos_buf, sizeof(pos_buf), "MAIN"); + break; + case OFFSET_FAC_NOSAVE: + default: + snprintf(pos_buf, sizeof(pos_buf), "NONE"); + break; + } + + snprintf(buff, sizeof(buff), "ITO: [%3d] %d-%s / Tx%02d,Rx%02d: %3d / Tx%02d,Rx%02d: %3d\n", + result[i].num_of_test, result[i].flag, pos_buf, + result[i].tx_of_txmax_gap, result[i].rx_of_txmax_gap, + result[i].max_of_tx_gap, + result[i].tx_of_rxmax_gap, result[i].rx_of_rxmax_gap, + result[i].max_of_rx_gap); + input_info(true, &info->client->dev, "%s", buff); + strlcat(info->ito_result, buff, FTS_ITO_RESULT_PRINT_SIZE); + + /* when count is over 200, it restart from 1 */ + if (result[i].num_of_test > result[max_count].num_of_test + 100) + continue; + if (result[i].num_of_test > result[max_count].num_of_test) + max_count = i; + if (result[i].num_of_test == 1 && result[max_count].num_of_test == 200) + max_count = i; + } + + input_info(true, &info->client->dev, "%s: latest test is %d\n", + __func__, result[max_count].num_of_test); + +done: + if (sec->cmd_all_factory_state != SEC_CMD_STATUS_RUNNING) + return; + + if (ret < 0) { + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "CH_OPEN/SHORT_TEST_X"); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "CH_OPEN/SHORT_TEST_Y"); + } else { + snprintf(buff, sizeof(buff), "0,%d", result[max_count].max_of_rx_gap); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "CH_OPEN/SHORT_TEST_X"); + snprintf(buff, sizeof(buff), "0,%d", result[max_count].max_of_tx_gap); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "CH_OPEN/SHORT_TEST_Y"); + } +} + +int fts_set_sec_ito_test_result(struct fts_ts_info *info) +{ + struct sec_cmd_data *sec = &info->sec; + u8 regAdd[3] = { 0 }; + int ret = -EINVAL; + u8 buff[10] = { 0 }; + + if (!info->factory_position) { + input_err(true, &info->client->dev, "%s: not save, factory level = %d\n", + __func__, info->factory_position); + goto out; + } + + regAdd[0] = 0xC7; + regAdd[1] = 0x06; + regAdd[2] = info->factory_position; + ret = info->fts_write_reg(info, regAdd, 3); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to write fac position, %d\n", __func__, ret); + goto out; + } + + regAdd[0] = 0xA4; + regAdd[1] = 0x05; + regAdd[2] = 0x04; + + ret = fts_fw_wait_for_echo_event(info, regAdd, 3, 200); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to get echo, %d\n", __func__, ret); + goto out; + } + + input_info(true, &info->client->dev, "%s: position %d result is saved\n", __func__, info->factory_position); + return 0; + +out: + if (sec->cmd_all_factory_state != SEC_CMD_STATUS_RUNNING) + return ret; + + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "CH_OPEN/SHORT_TEST_X"); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "CH_OPEN/SHORT_TEST_Y"); + return ret; +} + +int fts_fw_wait_for_jitter_result(struct fts_ts_info *info, u8 *reg, u8 count, s16 *ret1, s16 *ret2) +{ + int rc = 0; + u8 regAdd; + u8 data[FTS_EVENT_SIZE]; + int retry = 0; + + mutex_lock(&info->wait_for); + + rc = info->fts_write_reg(info, reg, count); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: failed to write command\n", __func__); + mutex_unlock(&info->wait_for); + return rc; + } + + memset(data, 0x0, FTS_EVENT_SIZE); + + regAdd = FTS_READ_ONE_EVENT; + rc = -1; + while (info->fts_read_reg(info, ®Add, 1, (u8 *)data, FTS_EVENT_SIZE)) { + if (data[0] != 0x00) + input_info(true, &info->client->dev, + "%s: event %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); + + if ((data[0] == FTS_EVENT_JITTER_RESULT) && (data[1] == 0x03)) { // Check Jitter result + if (data[2] == FTS_EVENT_JITTER_MUTUAL_MAX) { + *ret2 = (s16)((data[3] << 8) + data[4]); + input_info(true, &info->client->dev, "%s: Mutual max jitter Strength : %d, RX:%d, TX:%d\n", + __func__, *ret2, data[5], data[6]); + } else if (data[2] == FTS_EVENT_JITTER_MUTUAL_MIN) { + *ret1 = (s16)((data[3] << 8) + data[4]); + input_info(true, &info->client->dev, "%s: Mutual min jitter Strength : %d, RX:%d, TX:%d\n", + __func__, *ret1, data[5], data[6]); + rc = 0; + break; + } else if (data[2] == FTS_EVENT_JITTER_SELF_TX_P2P) { + *ret1 = (s16)((data[3] << 8) + data[4]); + input_info(true, &info->client->dev, "%s: Self TX P2P jitter Strength : %d, TX:%d\n", + __func__, *ret1, data[6]); + } else if (data[2] == FTS_EVENT_JITTER_SELF_RX_P2P) { + *ret2 = (s16)((data[3] << 8) + data[4]); + input_info(true, &info->client->dev, "%s: Self RX P2P jitter Strength : %d, RX:%d\n", + __func__, *ret2, data[5]); + rc = 0; + break; + } + } else if (data[0] == FTS_EVENT_ERROR_REPORT) { + input_info(true, &info->client->dev, "%s: Error detected %02X,%02X,%02X,%02X,%02X,%02X\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + } + + if (retry++ > FTS_RETRY_COUNT * 10) { + rc = -1; + input_err(true, &info->client->dev, "%s: Time Over (%02X,%02X,%02X,%02X,%02X,%02X)\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + } + fts_delay(20); + } + + mutex_unlock(&info->wait_for); + return rc; +} + +static void run_jitter_test(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[4] = { 0 }; + int ret; + s16 mutual_min = 0, mutual_max = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN || + info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + info->fts_systemreset(info, 0); + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + /* lock active scan mode */ + regAdd[0] = 0xA0; + regAdd[1] = 0x03; + regAdd[2] = 0x00; + info->fts_write_reg(info, ®Add[0], 3); + fts_delay(10); + + // Mutual jitter. + regAdd[0] = 0xC7; + regAdd[1] = 0x08; + regAdd[2] = 0x64; //100 frame + regAdd[3] = 0x00; + + ret = fts_fw_wait_for_jitter_result(info, regAdd, 4, &mutual_min, &mutual_max); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to read Mutual jitter\n", __func__); + goto ERROR; + } + + info->fts_systemreset(info, 0); + fts_set_scanmode(info, info->scan_mode); + + fts_interrupt_set(info, INT_ENABLE); + + snprintf(buff, sizeof(buff), "%d", mutual_max); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MUTUAL_JITTER"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return; + +ERROR: + info->fts_systemreset(info, 0); + fts_set_scanmode(info, info->scan_mode); + + fts_interrupt_set(info, INT_ENABLE); + + snprintf(buff, sizeof(buff), "NG"); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MUTUAL_JITTER"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + input_info(true, &info->client->dev, "%s: Fail %s\n", __func__, buff); + + return; +} + +static void run_mutual_jitter(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[4] = { 0 }; + int ret; + s16 mutual_min = 0, mutual_max = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN || + info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + info->fts_systemreset(info, 0); + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + //lock active scan mode. + fts_fix_active_mode(info, true); + + // Mutual jitter. + regAdd[0] = 0xC7; + regAdd[1] = 0x08; + regAdd[2] = 0x64; //100 frame + regAdd[3] = 0x00; + + ret = fts_fw_wait_for_jitter_result(info, regAdd, 4, &mutual_min, &mutual_max); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to read Mutual jitter\n", __func__); + goto ERROR; + } + + info->fts_systemreset(info, 0); + fts_set_scanmode(info, info->scan_mode); + + fts_interrupt_set(info, INT_ENABLE); + + snprintf(buff, sizeof(buff), "%d,%d", mutual_min, mutual_max); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MUTUAL_JITTER"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + input_raw_info_d(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return; + +ERROR: + info->fts_systemreset(info, 0); + fts_set_scanmode(info, info->scan_mode); + + fts_interrupt_set(info, INT_ENABLE); + + snprintf(buff, sizeof(buff), "NG"); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MUTUAL_JITTER"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + input_raw_info_d(true, &info->client->dev, "%s: Fail %s\n", __func__, buff); + + return; +} + +static void run_self_jitter(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[4] = { 0 }; + int ret; + s16 tx_p2p = 0, rx_p2p = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN || + info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + info->fts_systemreset(info, 0); + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + /* lock active scan mode */ + regAdd[0] = 0xA0; + regAdd[1] = 0x03; + regAdd[2] = 0x00; + info->fts_write_reg(info, ®Add[0], 3); + fts_delay(10); + + /* Self jitter */ + regAdd[0] = 0xC7; + regAdd[1] = 0x0A; + regAdd[2] = 0x64; /* 100 frame */ + regAdd[3] = 0x00; + + ret = fts_fw_wait_for_jitter_result(info, regAdd, 4, &tx_p2p, &rx_p2p); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to read Self jitter\n", __func__); + goto ERROR; + } + + info->fts_systemreset(info, 0); + fts_set_scanmode(info, info->scan_mode); + + fts_interrupt_set(info, INT_ENABLE); + + snprintf(buff, sizeof(buff), "%d,%d", tx_p2p, rx_p2p); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "SELF_JITTER"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + input_raw_info_d(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return; + +ERROR: + info->fts_systemreset(info, 0); + fts_set_scanmode(info, info->scan_mode); + + fts_interrupt_set(info, INT_ENABLE); + + snprintf(buff, sizeof(buff), "NG"); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "SELF_JITTER"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + input_raw_info_d(true, &info->client->dev, "%s: Fail %s\n", __func__, buff); + + return; + +} + +static void run_jitter_delta_test(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 reg[4] = { 0 }; + int ret; + int result = -1; + int retry = 0; + u8 data[FTS_EVENT_SIZE]; + s16 min_of_min = 0; + s16 max_of_min = 0; + s16 min_of_max = 0; + s16 max_of_max = 0; + s16 min_of_avg = 0; + s16 max_of_avg = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN || + info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + goto OUT_JITTER_DELTA; + } + + info->fts_systemreset(info, 0); + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + mutex_lock(&info->wait_for); + + /* lock active scan mode */ + reg[0] = 0xA0; + reg[1] = 0x03; + reg[2] = 0x00; + ret = info->fts_write_reg(info, ®[0], 3); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to set active mode\n", __func__); + mutex_unlock(&info->wait_for); + goto OUT_JITTER_DELTA; + } + fts_delay(10); + + /* jitter delta + 1000 frame*/ + reg[0] = 0xC7; + reg[1] = 0x08; + reg[2] = 0xE8; + reg[3] = 0x03; + ret = info->fts_write_reg(info, ®[0], 4); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to write command\n", __func__); + mutex_unlock(&info->wait_for); + goto OUT_JITTER_DELTA; + } + + memset(data, 0x0, FTS_EVENT_SIZE); + + reg[0] = FTS_READ_ONE_EVENT; + while (info->fts_read_reg(info, ®[0], 1, data, FTS_EVENT_SIZE)) { + if ((data[0] == FTS_EVENT_JITTER_RESULT) && (data[1] == 0x03)) { + if (data[2] == FTS_EVENT_JITTER_MUTUAL_MAX) { + min_of_max = data[3] << 8 | data[4]; + max_of_max = data[8] << 8 | data[9]; + input_info(true, &info->client->dev, "%s: MAX: min:%d, max:%d\n", __func__, min_of_max, max_of_max); + } else if (data[2] == FTS_EVENT_JITTER_MUTUAL_MIN) { + min_of_min = data[3] << 8 | data[4]; + max_of_min = data[8] << 8 | data[9]; + input_info(true, &info->client->dev, "%s: MIN: min:%d, max:%d\n", __func__, min_of_min, max_of_min); + } else if (data[2] == FTS_EVENT_JITTER_MUTUAL_AVG) { + min_of_avg = data[3] << 8 | data[4]; + max_of_avg = data[8] << 8 | data[9]; + input_info(true, &info->client->dev, "%s: AVG: min:%d, max:%d\n", __func__, min_of_avg, max_of_avg); + result = 0; + break; + } + } else if (data[0] == FTS_EVENT_ERROR_REPORT) { + input_info(true, &info->client->dev, "%s: Error detected %02X,%02X,%02X,%02X,%02X,%02X\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + } + + /* waiting 10 seconds */ + if (retry++ > FTS_RETRY_COUNT * 50) { + input_err(true, &info->client->dev, "%s: Time Over (%02X,%02X,%02X,%02X,%02X,%02X)\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + } + fts_delay(20); + } + mutex_unlock(&info->wait_for); + +OUT_JITTER_DELTA: + + info->fts_systemreset(info, 0); + fts_set_scanmode(info, info->scan_mode); + + fts_interrupt_set(info, INT_ENABLE); + + if (result < 0) + snprintf(buff, sizeof(buff), "NG"); + else + snprintf(buff, sizeof(buff), "%d,%d,%d,%d,%d,%d", min_of_min, max_of_min, min_of_max, max_of_max, min_of_avg, max_of_avg); + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + char buffer[SEC_CMD_STR_LEN] = { 0 }; + + snprintf(buffer, sizeof(buffer), "%d,%d", min_of_min, max_of_min); + sec_cmd_set_cmd_result_all(sec, buffer, strnlen(buffer, sizeof(buffer)), "JITTER_DELTA_MIN"); + + memset(buffer, 0x00, sizeof(buffer)); + snprintf(buffer, sizeof(buffer), "%d,%d", min_of_max, max_of_max); + sec_cmd_set_cmd_result_all(sec, buffer, strnlen(buffer, sizeof(buffer)), "JITTER_DELTA_MAX"); + + memset(buffer, 0x00, sizeof(buffer)); + snprintf(buffer, sizeof(buffer), "%d,%d", min_of_avg, max_of_avg); + sec_cmd_set_cmd_result_all(sec, buffer, strnlen(buffer, sizeof(buffer)), "JITTER_DELTA_AVG"); + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +void fts_checking_miscal(struct fts_ts_info *info) +{ + u8 regAdd[3] = { 0 }; + u8 data[2] = { 0 }; + u16 miscal_thd = 0; + int ret; + short min = 0x7FFF; + short max = 0x8000; + + info->miscal_result = MISCAL_PASS; + + info->fts_systemreset(info, 0); + fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + fts_interrupt_set(info, INT_DISABLE); + + fts_release_all_finger(info); + + /* get the raw data after C7 02 : mis cal test */ + regAdd[0] = 0xC7; + regAdd[1] = 0x02; + + info->fts_write_reg(info, ®Add[0], 2); + msleep(300); + input_raw_info_d(true, &info->client->dev, "%s: [miscal diff data]\n", __func__); + fts_read_nonsync_frame(info, &min, &max); + + regAdd[0] = 0xC7; + regAdd[1] = 0x0B; + ret = info->fts_read_reg(info, regAdd, 2, data, 2); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: failed to read miscal threshold\n", __func__); + return; + } + + miscal_thd = data[0] << 8 | data[1]; + + if (max > miscal_thd) + info->miscal_result = MISCAL_FAIL; + + if (min < -miscal_thd) + info->miscal_result = MISCAL_FAIL; + + fts_set_scanmode(info, info->scan_mode); + + input_raw_info_d(true, &info->client->dev, "%s: mis cal threshold:%d/%d, min/max :%d/%d, miscal:%s\n", + __func__, miscal_thd, -miscal_thd, min, max, info->miscal_result == MISCAL_PASS ? "PASS" : "FAIL"); +} + +int fts_panel_ito_test(struct fts_ts_info *info, int testmode) +{ + u8 cmd = FTS_READ_ONE_EVENT; + u8 regAdd[4] = { 0 }; + u8 data[FTS_EVENT_SIZE]; + int i; + bool matched = false; + int retry = 0; + int result = 0; + + result = info->fts_systemreset(info, 0); + if (result < 0) { + input_info(true, &info->client->dev, "%s: fts_systemreset fail (%d)\n", __func__, result); + return result; + } + + fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + regAdd[0] = 0xA4; + regAdd[1] = 0x04; + switch (testmode) { + case OPEN_TEST: + regAdd[2] = 0x00; + regAdd[3] = 0x30; + break; + + case OPEN_SHORT_CRACK_TEST: + case SAVE_MISCAL_REF_RAW: + default: + regAdd[2] = 0xFF; + regAdd[3] = 0x01; + break; + } + + info->fts_write_reg(info, ®Add[0], 4); // ITO test command + fts_delay(100); + + memset(info->ito_test, 0x0, 4); + + memset(data, 0x0, FTS_EVENT_SIZE); + while (info->fts_read_reg(info, &cmd, 1, (u8 *)data, FTS_EVENT_SIZE)) { + if ((data[0] == FTS_EVENT_STATUS_REPORT) && (data[1] == 0x01)) { // Check command ECHO - finished + for (i = 0; i < 4; i++) { + if (data[i + 2] != regAdd[i]) { + matched = false; + break; + } + matched = true; + } + + if (matched == true) + break; + } else if (data[0] == FTS_EVENT_ERROR_REPORT) { + info->ito_test[0] = data[0]; + info->ito_test[1] = data[1]; + info->ito_test[2] = data[2]; + info->ito_test[3] = 0x00; + result = -ITO_FAIL; + + switch (data[1]) { + case ITO_FORCE_SHRT_GND: + input_info(true, &info->client->dev, "%s: Force channel [%d] short to GND\n", + __func__, data[2]); + result = -ITO_FAIL_SHORT; + break; + + case ITO_SENSE_SHRT_GND: + input_info(true, &info->client->dev, "%s: Sense channel [%d] short to GND\n", + __func__, data[2]); + result = ITO_FAIL_SHORT; + break; + + case ITO_FORCE_SHRT_VDD: + input_info(true, &info->client->dev, "%s: Force channel [%d] short to VDD\n", + __func__, data[2]); + result = -ITO_FAIL_SHORT; + break; + + case ITO_SENSE_SHRT_VDD: + input_info(true, &info->client->dev, "%s: Sense channel [%d] short to VDD\n", + __func__, data[2]); + result = -ITO_FAIL_SHORT; + break; + + case ITO_FORCE_SHRT_FORCE: + input_info(true, &info->client->dev, "%s: Force channel [%d] short to force\n", + __func__, data[2]); + result = -ITO_FAIL_SHORT; + break; + + case ITO_SENSE_SHRT_SENSE: + input_info(true, &info->client->dev, "%s: Sennse channel [%d] short to sense\n", + __func__, data[2]); + result = -ITO_FAIL_SHORT; + break; + + case ITO_FORCE_OPEN: + input_info(true, &info->client->dev, "%s: Force channel [%d] open\n", + __func__, data[2]); + result = -ITO_FAIL_OPEN; + break; + + case ITO_SENSE_OPEN: + input_info(true, &info->client->dev, "%s: Sense channel [%d] open\n", + __func__, data[2]); + result = -ITO_FAIL_OPEN; + break; + + case ITO_KEY_OPEN: + input_info(true, &info->client->dev, "%s: Key channel [%d] open\n", + __func__, data[2]); + result = -ITO_FAIL_OPEN; + break; + + default: + input_info(true, &info->client->dev, "%s: unknown event %02x %02x %02x %02x %02x %02x %02x %02x\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + break; + } + } + + if (retry++ > 50) { + result = -ITO_FAIL; + input_err(true, &info->client->dev, "%s: Time over - wait for result of ITO test\n", __func__); + break; + } + fts_delay(20); + } + + if (fts_set_sec_ito_test_result(info) >= 0) + fts_get_sec_ito_test_result(info); + + info->fts_systemreset(info, 0); + + if (info->flip_enable) { + fts_set_cover_type(info, true); + } else { + info->touch_functions = (info->touch_functions & (~FTS_TOUCHTYPE_BIT_COVER)) | + FTS_TOUCHTYPE_DEFAULT_ENABLE; +#ifdef CONFIG_GLOVE_TOUCH + if (info->glove_enabled) + info->touch_functions = info->touch_functions | FTS_TOUCHTYPE_BIT_GLOVE; + else + info->touch_functions = info->touch_functions & (~FTS_TOUCHTYPE_BIT_GLOVE); +#endif + } + + regAdd[0] = FTS_CMD_SET_GET_TOUCHTYPE; + regAdd[1] = (u8)(info->touch_functions & 0xFF); + regAdd[2] = (u8)(info->touch_functions >> 8); + fts_write_reg(info, ®Add[0], 3); + fts_delay(10); + +#ifdef FTS_SUPPORT_TA_MODE + if (info->TA_Pluged) { + u8 wiredCharger; + + regAdd[0] = FTS_CMD_SET_GET_CHARGER_MODE; + fts_read_reg(info, ®Add[0], 1, &data[0], 1); + wiredCharger = data[0] | FTS_BIT_CHARGER_MODE_WIRE_CHARGER; + regAdd[1] = { wiredCharger }; + fts_write_reg(info, ®Add[0], 2); + fts_delay(10); + } +#endif + + info->touch_count = 0; + + fts_set_scanmode(info, info->scan_mode); + + input_raw_info_d(true, &info->client->dev, "%s: mode:%d [%s] %02X %02X %02X %02X\n", + __func__, testmode, result < 0 ? "FAIL" : "PASS", + info->ito_test[0], info->ito_test[1], + info->ito_test[2], info->ito_test[3]); + + return result; +} + +static void get_fw_ver_bin(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + + sec_cmd_set_default_result(sec); + + snprintf(buff, sizeof(buff), "ST%02X%02X%02X%02X", + info->ic_name_of_bin, + info->project_id_of_bin, + info->module_version_of_bin, + info->fw_main_version_of_bin & 0xFF); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "FW_VER_BIN"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_fw_ver_ic(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + char model_ver[7] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "FW_VER_IC"); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "FW_MODEL"); + } + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + fts_get_version_info(info); + + snprintf(buff, sizeof(buff), "ST%02X%02X%02X%02X", + info->ic_name_of_ic, + info->project_id_of_ic, + info->module_version_of_ic, + info->fw_main_version_of_ic & 0xFF); + snprintf(model_ver, sizeof(model_ver), "ST%02X%02X", + info->ic_name_of_ic, + info->project_id_of_ic); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "FW_VER_IC"); + sec_cmd_set_cmd_result_all(sec, model_ver, strnlen(model_ver, sizeof(model_ver)), "FW_MODEL"); + } + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_config_ver(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[20] = { 0 }; + + snprintf(buff, sizeof(buff), "ST_%04X", + info->config_version_of_ic); + + sec_cmd_set_default_result(sec); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_threshold(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + u8 regAdd[2]; + u8 buff[16] = { 0 }; + u8 data[5] = { 0 }; + u16 finger_threshold = 0; + int rc; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + sec->cmd_state = SEC_CMD_STATUS_RUNNING; + + regAdd[0] = FTS_CMD_SET_GET_TOUCH_MODE_FOR_THRESHOLD; + regAdd[1] = 0x00; + info->fts_write_reg(info, ®Add[0], 2); + fts_delay(50); + + regAdd[0] = FTS_CMD_SET_GET_TOUCH_THRESHOLD; + rc = info->fts_read_reg(info, ®Add[0], 1, data, 2); + if (rc <= 0) { + input_err(true, &info->client->dev, "%s: Get threshold Read Fail!! [Data : %2X%2X]\n", + __func__, data[0], data[1]); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + finger_threshold = (u16)(data[0] << 8 | data[1]); + + snprintf(buff, sizeof(buff), "%d", finger_threshold); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void module_off_master(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[3] = { 0 }; + int ret = 0; + + ret = fts_stop_device(info); + + if (ret == 0) + snprintf(buff, sizeof(buff), "OK"); + else + snprintf(buff, sizeof(buff), "NG"); + + sec_cmd_set_default_result(sec); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (strncmp(buff, "OK", 2) == 0) + sec->cmd_state = SEC_CMD_STATUS_OK; + else + sec->cmd_state = SEC_CMD_STATUS_FAIL; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void module_on_master(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[3] = { 0 }; + int ret = 0; + + ret = fts_start_device(info); + + if (ret == 0) + snprintf(buff, sizeof(buff), "OK"); + else + snprintf(buff, sizeof(buff), "NG"); + + sec_cmd_set_default_result(sec); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (strncmp(buff, "OK", 2) == 0) + sec->cmd_state = SEC_CMD_STATUS_OK; + else + sec->cmd_state = SEC_CMD_STATUS_FAIL; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_chip_vendor(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + + snprintf(buff, sizeof(buff), "STM"); + sec_cmd_set_default_result(sec); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "IC_VENDOR"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_chip_name(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + + if (info->firmware_name) + memcpy(buff, info->firmware_name + 8, 9); + else + snprintf(buff, 10, "FTS"); + + sec_cmd_set_default_result(sec); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "IC_NAME"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_wet_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[3] = { 0 }; + u8 data[2] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "WET_MODE"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + regAdd[0] = 0xC7; + regAdd[1] = 0x03; + ret = info->fts_read_reg(info, ®Add[0], 2, &data[0], 1); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: [ERROR] failed to read\n", __func__); + snprintf(buff, sizeof(buff), "%s", "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "WET_MODE"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + snprintf(buff, sizeof(buff), "%d", data[0]); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "WET_MODE"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_x_num(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + + sec_cmd_set_default_result(sec); + snprintf(buff, sizeof(buff), "%d", info->ForceChannelLength); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_y_num(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + + sec_cmd_set_default_result(sec); + snprintf(buff, sizeof(buff), "%d", info->SenseChannelLength); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_checksum_data(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + int rc; + u32 checksum_data; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + info->fts_systemreset(info, 0); + + rc = info->fts_get_sysinfo_data(info, FTS_SI_CONFIG_CHECKSUM, 4, (u8 *)&checksum_data); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: Get checksum data Read Fail!! [Data : %08X]\n", + __func__, checksum_data); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + fts_reinit(info, false); + + snprintf(buff, sizeof(buff), "%08X", checksum_data); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void check_fw_corruption(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[16] = { 0 }; + int rc; + + sec_cmd_set_default_result(sec); + + if (info->fw_corruption) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + rc = fts_fw_corruption_check(info); + if (rc == -FTS_ERROR_FW_CORRUPTION) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + fts_reinit(info, false); + } + } + info->fw_corruption = false; + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_reference_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short min = 0x7FFF; + short max = 0x8000; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + fts_read_frame(info, TYPE_BASELINE_DATA, &min, &max); + snprintf(buff, sizeof(buff), "%d,%d", min, max); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_reference(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short val = 0; + int node = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + node = fts_check_index(info); + if (node < 0) + return; + + val = info->pFrame[node]; + snprintf(buff, sizeof(buff), "%d", val); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_rawcap_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short min = 0x7FFF; + short max = 0x8000; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "RAW_DATA"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + fts_read_frame(info, TYPE_RAW_DATA, &min, &max); + snprintf(buff, sizeof(buff), "%d,%d", min, max); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "RAW_DATA"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_rawcap_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short min = 0x7FFF; + short max = 0x8000; + char *all_strbuff; + int i, j; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + all_strbuff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 7 + 1, GFP_KERNEL); + if (!all_strbuff) { + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + + enter_factory_mode(info, true); + fts_read_frame(info, TYPE_RAW_DATA, &min, &max); + + for (j = 0; j < info->ForceChannelLength; j++) { + for (i = 0; i < info->SenseChannelLength; i++) { + snprintf(buff, sizeof(buff), "%d,", info->pFrame[j * info->SenseChannelLength + i]); + strlcat(all_strbuff, buff, info->ForceChannelLength * info->SenseChannelLength * 7); + } + } + enter_factory_mode(info, false); + + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, all_strbuff, strlen(all_strbuff)); + input_info(true, &info->client->dev, "%s: %ld\n", __func__, strlen(all_strbuff)); + kfree(all_strbuff); +} + +static void run_nonsync_rawcap_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short min = 0x7FFF; + short max = 0x8000; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "RAW_DATA"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + + fts_read_nonsync_frame(info, &min, &max); + + snprintf(buff, sizeof(buff), "%d,%d", min, max); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "RAW_DATA"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + + +static void run_nonsync_rawcap_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short min = 0x7FFF; + short max = 0x8000; + char *all_strbuff; + int i, j; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + all_strbuff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 7 + 1, GFP_KERNEL); + if (!all_strbuff) { + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + +// enter_factory_mode(info, true); +// fts_read_frame(info, TYPE_RAW_DATA, &min, &max); + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + fts_read_nonsync_frame(info, &min, &max); + + for (j = 0; j < info->ForceChannelLength; j++) { + for (i = 0; i < info->SenseChannelLength; i++) { + snprintf(buff, sizeof(buff), "%d,", info->pFrame[j * info->SenseChannelLength + i]); + strlcat(all_strbuff, buff, info->ForceChannelLength * info->SenseChannelLength * 7); + } + } + enter_factory_mode(info, false); + + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, all_strbuff, strlen(all_strbuff)); + input_info(true, &info->client->dev, "%s: %ld\n", __func__, strlen(all_strbuff)); + kfree(all_strbuff); +} + +static void get_rawcap(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short val = 0; + int node = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + node = fts_check_index(info); + if (node < 0) + return; + + val = info->pFrame[node]; + snprintf(buff, sizeof(buff), "%d", val); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +#if 0 +static void get_rawcap_gap_data(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int rx_max = 0, tx_max = 0, ii; + + for (ii = 0; ii < (info->SenseChannelLength * info->ForceChannelLength); ii++) { + /* rx(x) rawcap gap max */ + if ((ii + 1) % (info->SenseChannelLength) != 0) + rx_max = max(rx_max, (int)abs(info->pFrame[ii + 1] - info->pFrame[ii])); + + /* tx(y) rawcap gap max */ + if (ii < (info->ForceChannelLength - 1) * info->SenseChannelLength) + tx_max = max(tx_max, (int)abs(info->pFrame[ii + info->SenseChannelLength] - info->pFrame[ii])); + } + + input_raw_info_d(true, &info->client->dev, "%s: rx max:%d, tx max:%d\n", __func__, rx_max, tx_max); + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + snprintf(buff, sizeof(buff), "%d,%d", 0, rx_max); + sec_cmd_set_cmd_result_all(sec, buff, SEC_CMD_STR_LEN, "RAW_DATA_GAP_RX"); + snprintf(buff, sizeof(buff), "%d,%d", 0, tx_max); + sec_cmd_set_cmd_result_all(sec, buff, SEC_CMD_STR_LEN, "RAW_DATA_GAP_TX"); + } +} +#endif + +static void run_lp_single_ended_rawcap_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regaddr[4] = { 0xA4, 0x0A, 0x01, 0x00 }; + int ret; + short min = 0x7FFF; + short max = 0x8000; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + info->fts_systemreset(info, 0); + + fts_interrupt_set(info, INT_DISABLE); + + /* Request to Prepare single ended raw data from flash */ + + ret = fts_fw_wait_for_echo_event(info, regaddr, 4, 0); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: timeout, ret: %d\n", __func__, ret); + goto out; + } + +// run_nonsync_rawcap_read(sec); + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + fts_read_nonsync_frame(info, &min, &max); + + fts_interrupt_set(info, INT_ENABLE); + fts_set_scanmode(info, info->scan_mode); + + snprintf(buff, sizeof(buff), "%d,%d", min, max); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MUTUAL_RAW"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return; + +out: + fts_interrupt_set(info, INT_ENABLE); + fts_set_scanmode(info, info->scan_mode); + + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MUTUAL_RAW"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + input_info(true, &info->client->dev, "%s: fail : %s\n", __func__, buff); + + return; +} + +static void run_lp_single_ended_rawcap_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regaddr[4] = { 0xA4, 0x0A, 0x01, 0x00 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + + enter_factory_mode(info, true); + + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + fts_delay(30); + + fts_interrupt_set(info, INT_DISABLE); + + /* Request to Prepare single ended raw data from flash */ + + ret = fts_fw_wait_for_echo_event(info, regaddr, 4, 0); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: timeout, ret: %d\n", __func__, ret); + goto out; + } + + fts_interrupt_set(info, INT_ENABLE); + +// run_rawcap_read_all(sec); + run_nonsync_rawcap_read_all(sec); + +// enter_factory_mode(info, false); + fts_set_scanmode(info, info->scan_mode); + + return; + +out: + fts_interrupt_set(info, INT_ENABLE); +// enter_factory_mode(info, false); + fts_set_scanmode(info, info->scan_mode); + + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; +} + +// Micro Short Test +static void run_low_frequency_rawcap_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[4] = { 0xA4, 0x04, 0x00, 0xC0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + fts_delay(30); + + fts_interrupt_set(info, INT_DISABLE); + + /* Request to Prepare Hight Frequency(ITO) raw data from flash */ + + ret = fts_fw_wait_for_echo_event(info, regAdd, 4, 30); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: timeout, ret: %d\n", __func__, ret); + goto out; + } + + fts_interrupt_set(info, INT_ENABLE); + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + run_nonsync_rawcap_read(sec); + + fts_set_scanmode(info, info->scan_mode); + + return; + +out: + fts_interrupt_set(info, INT_ENABLE); + fts_set_scanmode(info, info->scan_mode); + + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; +} + +static void run_low_frequency_rawcap_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[4] = { 0xA4, 0x04, 0x00, 0xC0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + + enter_factory_mode(info, true); + + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + fts_delay(30); + + fts_interrupt_set(info, INT_DISABLE); + + /* Request to Prepare Hight Frequency(ITO) raw data from flash */ + + ret = fts_fw_wait_for_echo_event(info, regAdd, 4, 30); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: timeout, ret: %d\n", __func__, ret); + goto out; + } + + fts_interrupt_set(info, INT_ENABLE); + +// run_rawcap_read_all(sec); + run_nonsync_rawcap_read_all(sec); + + return; + +out: + fts_interrupt_set(info, INT_ENABLE); + fts_set_scanmode(info, info->scan_mode); + + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; +} + +static void run_high_frequency_rawcap_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[4] = { 0xA4, 0x04, 0xFF, 0x01 }; + int ret; + int i, j; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + fts_delay(30); + + fts_interrupt_set(info, INT_DISABLE); + + /* Request to Prepare Hight Frequency(ITO) raw data from flash */ + + ret = fts_fw_wait_for_echo_event(info, regAdd, 4, 100); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: timeout, ret: %d\n", __func__, ret); + goto out; + } + + fts_interrupt_set(info, INT_ENABLE); + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + run_nonsync_rawcap_read(sec); + + fts_set_scanmode(info, info->scan_mode); + + pr_info("sec_input: %s - correlation\n", __func__); + for (i = 0; i < info->ForceChannelLength; i++) { + pr_info("sec_input: [%2d] ", i); + for (j = 0; j < info->SenseChannelLength; j++) + pr_cont("%d, ", info->pFrame[(i * info->SenseChannelLength) + j]); + pr_cont("\n"); + } + + return; + +out: + fts_interrupt_set(info, INT_ENABLE); + fts_set_scanmode(info, info->scan_mode); + + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; +} + +static void run_high_frequency_rawcap_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[4] = { 0xA4, 0x04, 0xFF, 0x01 }; + int ret; + int i, j; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + + enter_factory_mode(info, true); + + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + fts_delay(30); + + fts_interrupt_set(info, INT_DISABLE); + + /* Request to Prepare Hight Frequency(ITO) raw data from flash */ + + ret = fts_fw_wait_for_echo_event(info, regAdd, 4, 100); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: timeout, ret: %d\n", __func__, ret); + goto out; + } + + fts_interrupt_set(info, INT_ENABLE); + +// run_rawcap_read_all(sec); + run_nonsync_rawcap_read_all(sec); + fts_set_scanmode(info, info->scan_mode); + + pr_info("sec_input: %s - correlation\n", __func__); + for (i = 0; i < info->ForceChannelLength; i++) { + pr_info("sec_input: [%2d] ", i); + for (j = 0; j < info->SenseChannelLength; j++) + pr_cont("%d, ", info->pFrame[(i * info->SenseChannelLength) + j]); + pr_cont("\n"); + } + + return; + +out: + fts_set_scanmode(info, info->scan_mode); + + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; +} + +static void run_delta_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short min = 0x7FFF; + short max = 0x8000; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + fts_read_frame(info, TYPE_STRENGTH_DATA, &min, &max); + snprintf(buff, sizeof(buff), "%d,%d", min, max); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_prox_intensity_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + u8 reg[2]; + u8 thd_data[4]; + u8 sum_data[4]; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + memset(thd_data, 0x00, 4); + memset(sum_data, 0x00, 4); + + /* Threshold */ + reg[0] = 0xC7; + reg[1] = 0x0C; + ret = info->fts_read_reg(info, ®[0], 2, &thd_data[0], 4); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to read thd_data\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + /* Sum */ + reg[0] = 0xC7; + reg[1] = 0x0D; + ret = info->fts_read_reg(info, ®[0], 2, &sum_data[0], 4); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to read sum_data\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + snprintf(buff, sizeof(buff), "SUM_X:%d THD_X:%d SUM_Y:%d THD_Y:%d", + (sum_data[0] << 8) + sum_data[1], (sum_data[2] << 8) + sum_data[3], + (thd_data[0] << 8) + thd_data[1], (thd_data[2] << 8) + thd_data[3]); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + +} + +static void get_strength_all_data(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short min = 0x7FFF; + short max = 0x8000; + char *all_strbuff; + int i, j; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + all_strbuff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 7 + 1, GFP_KERNEL); + if (!all_strbuff) { + input_err(true, &info->client->dev, "%s: alloc failed\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + fts_read_frame(info, TYPE_STRENGTH_DATA, &min, &max); + + for (i = 0; i < info->ForceChannelLength; i++) { + for (j = 0; j < info->SenseChannelLength; j++) { + snprintf(buff, sizeof(buff), "%d,", info->pFrame[(i * info->SenseChannelLength) + j]); + strlcat(all_strbuff, buff, info->ForceChannelLength * info->SenseChannelLength * 7); + } + } + + sec->cmd_state = SEC_CMD_STATUS_OK; + + sec_cmd_set_cmd_result(sec, all_strbuff, strlen(all_strbuff)); + input_info(true, &info->client->dev, "%s: %ld\n", __func__, strlen(all_strbuff)); + kfree(all_strbuff); +} + +static void get_delta(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short val = 0; + int node = 0; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + node = fts_check_index(info); + if (node < 0) + return; + + val = info->pFrame[node]; + snprintf(buff, sizeof(buff), "%d", val); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +int fts_get_hf_data(struct fts_ts_info *info) +{ + u8 regAdd[4] = { 0 }; + int ret; + short min = 0x7FFF; + short max = 0x8000; + + info->fts_systemreset(info, 0); + + fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + input_info(true, &info->client->dev, "%s\n", __func__); + + regAdd[0] = 0xA4; + regAdd[1] = 0x04; + regAdd[2] = 0xFF; + regAdd[3] = 0x01; + ret = fts_fw_wait_for_echo_event(info, ®Add[0], 4, 100); + if (ret < 0) + goto out; + + ret = fts_read_frame(info, TYPE_RAW_DATA, &min, &max); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed to get rawdata\n", __func__); + +out: + info->fts_systemreset(info, 0); + + fts_set_cover_type(info, info->flip_enable); + + fts_delay(10); + + if (info->charger_mode) { + fts_wirelesscharger_mode(info); + fts_delay(10); + } + + if (!info->flip_enable) + fts_set_scanmode(info, info->scan_mode); + else + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + + return ret; +} + +static void run_rawdata_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + input_raw_data_clear(MAIN_TOUCH); +#endif + info->rawdata_read_lock = true; + + input_raw_info_d(true, &info->client->dev, + "%s: start (noise:%d, wet:%d, tc:%d, folding:%s)##\n", + __func__, info->touch_noise_status, info->wet_mode, + info->touch_count, info->flip_status_current ? "close" : "open"); + + run_rawcap_read(sec); + run_self_raw_read(sec); + fts_checking_miscal(info); + run_cx_data_read(sec); + run_ix_data_read(sec); + fts_panel_ito_test(info, OPEN_SHORT_CRACK_TEST); + fts_get_hf_data(info); + run_mutual_jitter(sec); + + info->rawdata_read_lock = false; + + snprintf(buff, sizeof(buff), "OK"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + input_raw_info_d(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +void fts_run_rawdata_read_all(struct fts_ts_info *info) +{ + struct sec_cmd_data *sec = &info->sec; + + run_rawdata_read_all(sec); +} + +#ifdef TCLM_CONCEPT +static void get_pat_information(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[50] = { 0 }; + + sec_cmd_set_default_result(sec); + +#ifdef CONFIG_SEC_FACTORY + if (info->factory_position == 1) { + sec_tclm_initialize(info->tdata); + fts_tclm_data_read(info->client, SEC_TCLM_NVM_ALL_DATA); + } +#endif + /* fixed tune version will be saved at excute autotune */ + snprintf(buff, sizeof(buff), "C%02XT%04X.%4s%s%c%d%c%d%c%d", + info->tdata->nvdata.cal_count, info->tdata->nvdata.tune_fix_ver, + info->tdata->tclm_string[info->tdata->nvdata.cal_position].f_name, + (info->tdata->tclm_level == TCLM_LEVEL_LOCKDOWN) ? ".L " : " ", + info->tdata->cal_pos_hist_last3[0], info->tdata->cal_pos_hist_last3[1], + info->tdata->cal_pos_hist_last3[2], info->tdata->cal_pos_hist_last3[3], + info->tdata->cal_pos_hist_last3[4], info->tdata->cal_pos_hist_last3[5]); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void set_external_factory(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + info->tdata->external_factory = true; + snprintf(buff, sizeof(buff), "OK"); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} +#endif + +static void fts_read_ix_data(struct fts_ts_info *info, bool allnode) +{ + struct sec_cmd_data *sec = &info->sec; + char buff[SEC_CMD_STR_LEN] = { 0 }; + int rc; + u16 max_tx_ix_sum = 0; + u16 min_tx_ix_sum = 0xFFFF; + u16 max_rx_ix_sum = 0; + u16 min_rx_ix_sum = 0xFFFF; + u8 *data; + u8 regAdd[FTS_EVENT_SIZE]; + u8 dataID; + u16 force_ix_data[100]; + u16 sense_ix_data[100]; + + int buff_size, j; + char *mbuff = NULL; + int num, n, a, fzero; + char cnum; + int i = 0; + u16 comp_start_tx_addr, comp_start_rx_addr; + unsigned int rx_num, tx_num; + + data = kzalloc((info->ForceChannelLength + info->SenseChannelLength) * 2 + 1, GFP_KERNEL); + if (!data) + return; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); // Clear FIFO + + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + // Request compensation data type + dataID = 0x52; + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = dataID; // SS - CX total + rc = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: failed to request data\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + fts_interrupt_set(info, INT_ENABLE); + goto out; + } + fts_interrupt_set(info, INT_ENABLE); + + // Read Header + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + rc = info->fts_read_reg(info, ®Add[0], 3, &data[0], FTS_COMP_DATA_HEADER_SIZE); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: failed to read header\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + if ((data[0] != 0xA5) && (data[1] != dataID)) { + input_err(true, &info->client->dev, "%s: header mismatch\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + tx_num = data[4]; + rx_num = data[5]; + + /* Read TX IX data */ + comp_start_tx_addr = (u16)FTS_COMP_DATA_HEADER_SIZE; + regAdd[0] = 0xA6; + regAdd[1] = (u8)(comp_start_tx_addr >> 8); + regAdd[2] = (u8)(comp_start_tx_addr & 0xFF); + rc = info->fts_read_reg(info, ®Add[0], 3, &data[0], tx_num * 2); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: failed to read TX IX data\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + for (i = 0; i < tx_num; i++) { + force_ix_data[i] = data[2 * i] | data[2 * i + 1] << 8; + + if (max_tx_ix_sum < force_ix_data[i]) + max_tx_ix_sum = force_ix_data[i]; + if (min_tx_ix_sum > force_ix_data[i]) + min_tx_ix_sum = force_ix_data[i]; + + } + + /* Read RX IX data */ + comp_start_rx_addr = (u16)(FTS_COMP_DATA_HEADER_SIZE + (tx_num * 2)); + regAdd[0] = 0xA6; + regAdd[1] = (u8)(comp_start_rx_addr >> 8); + regAdd[2] = (u8)(comp_start_rx_addr & 0xFF); + rc = info->fts_read_reg(info, ®Add[0], 3, &data[0], rx_num * 2); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: failed to read RX IX\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + for (i = 0; i < rx_num; i++) { + sense_ix_data[i] = data[2 * i] | data[2 * i + 1] << 8; + + if (max_rx_ix_sum < sense_ix_data[i]) + max_rx_ix_sum = sense_ix_data[i]; + if (min_rx_ix_sum > sense_ix_data[i]) + min_rx_ix_sum = sense_ix_data[i]; + } + + fts_print_channel(info, force_ix_data, sense_ix_data); + + input_raw_info_d(true, &info->client->dev, "%s: MIN_TX_IX_SUM : %d MAX_TX_IX_SUM : %d\n", + __func__, min_tx_ix_sum, max_tx_ix_sum); + input_raw_info_d(true, &info->client->dev, "%s: MIN_RX_IX_SUM : %d MAX_RX_IX_SUM : %d\n", + __func__, min_rx_ix_sum, max_rx_ix_sum); + + if (allnode == true) { + buff_size = (info->ForceChannelLength + info->SenseChannelLength + 2) * 5; + mbuff = kzalloc(buff_size, GFP_KERNEL); + } + if (mbuff != NULL) { + char *pBuf = mbuff; + + for (i = 0; i < info->ForceChannelLength; i++) { + num = force_ix_data[i]; + n = 100000; + fzero = 0; + for (j = 5; j > 0; j--) { + n = n / 10; + a = num / n; + if (a) + fzero = 1; + cnum = a + '0'; + num = num - a*n; + if (fzero) + *pBuf++ = cnum; + } + if (!fzero) + *pBuf++ = '0'; + *pBuf++ = ','; + } + for (i = 0; i < info->SenseChannelLength; i++) { + num = sense_ix_data[i]; + n = 100000; + fzero = 0; + for (j = 5; j > 0; j--) { + n = n / 10; + a = num / n; + if (a) + fzero = 1; + cnum = a + '0'; + num = num - a * n; + if (fzero) + *pBuf++ = cnum; + } + if (!fzero) + *pBuf++ = '0'; + if (i < (info->SenseChannelLength - 1)) + *pBuf++ = ','; + } + + sec_cmd_set_cmd_result(sec, mbuff, buff_size); + sec->cmd_state = SEC_CMD_STATUS_OK; + kfree(mbuff); + return; + } + + if (allnode == true) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "%d,%d,%d,%d", + min_tx_ix_sum, max_tx_ix_sum, min_rx_ix_sum, max_rx_ix_sum); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + +out: + kfree(data); + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + char ret_buff[SEC_CMD_STR_LEN] = { 0 }; + + snprintf(ret_buff, sizeof(ret_buff), "%d,%d", min_rx_ix_sum, max_rx_ix_sum); + sec_cmd_set_cmd_result_all(sec, ret_buff, strnlen(ret_buff, sizeof(ret_buff)), "IX_DATA_X"); + snprintf(ret_buff, sizeof(ret_buff), "%d,%d", min_tx_ix_sum, max_tx_ix_sum); + sec_cmd_set_cmd_result_all(sec, ret_buff, strnlen(ret_buff, sizeof(ret_buff)), "IX_DATA_Y"); + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_ix_data_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + sec_cmd_set_default_result(sec); + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + fts_read_ix_data(info, false); +} + +static void run_ix_data_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + sec_cmd_set_default_result(sec); + + enter_factory_mode(info, true); + fts_read_ix_data(info, true); + enter_factory_mode(info, false); +} + +static void fts_read_self_raw_frame(struct fts_ts_info *info, bool allnode) +{ + struct sec_cmd_data *sec = &info->sec; + char buff[SEC_CMD_STR_LEN] = { 0 }; + struct FTS_SyncFrameHeader *pSyncFrameHeader; + u8 regAdd[FTS_EVENT_SIZE] = {0}; + u8 *data; + s16 self_force_raw_data[100]; + s16 self_sense_raw_data[100]; + int Offset = 0; + u8 count = 0; + int i; + int ret; + int totalbytes; + int retry = 10; + s16 min_tx_self_raw_data = S16_MAX; + s16 max_tx_self_raw_data = S16_MIN; + s16 min_rx_self_raw_data = S16_MAX; + s16 max_rx_self_raw_data = S16_MIN; + + data = kzalloc((info->ForceChannelLength + info->SenseChannelLength) * 2 + 1, GFP_KERNEL); + if (!data) + return; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + // Request Data Type + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = TYPE_RAW_DATA; + info->fts_write_reg(info, ®Add[0], 3); + + do { + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + ret = info->fts_read_reg(info, ®Add[0], 3, &data[0], FTS_COMP_DATA_HEADER_SIZE); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + pSyncFrameHeader = (struct FTS_SyncFrameHeader *) &data[0]; + + if ((pSyncFrameHeader->header == 0xA5) && (pSyncFrameHeader->host_data_mem_id == TYPE_RAW_DATA)) + break; + + fts_delay(100); + } while (retry--); + + if (retry == 0) { + input_err(true, &info->client->dev, "%s: didn't match header or id. header = %02X, id = %02X\n", + __func__, pSyncFrameHeader->header, pSyncFrameHeader->host_data_mem_id); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + Offset = FTS_COMP_DATA_HEADER_SIZE + pSyncFrameHeader->dbg_frm_len + + (pSyncFrameHeader->ms_force_len * pSyncFrameHeader->ms_sense_len * 2); + + totalbytes = (pSyncFrameHeader->ss_force_len + pSyncFrameHeader->ss_sense_len) * 2; + + regAdd[0] = 0xA6; + regAdd[1] = (u8)(Offset >> 8); + regAdd[2] = (u8)(Offset & 0xFF); + ret = info->fts_read_reg(info, ®Add[0], 3, &data[0], totalbytes); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + Offset = 0; + for (count = 0; count < (info->ForceChannelLength); count++) { + self_force_raw_data[count] = (s16)(data[count * 2 + Offset] + (data[count * 2 + 1 + Offset] << 8)); + + if (max_tx_self_raw_data < self_force_raw_data[count]) + max_tx_self_raw_data = self_force_raw_data[count]; + if (min_tx_self_raw_data > self_force_raw_data[count]) + min_tx_self_raw_data = self_force_raw_data[count]; + } + + Offset = (info->ForceChannelLength * 2); + for (count = 0; count < info->SenseChannelLength; count++) { + self_sense_raw_data[count] = (s16)(data[count * 2 + Offset] + (data[count * 2 + 1 + Offset] << 8)); + + if (max_rx_self_raw_data < self_sense_raw_data[count]) + max_rx_self_raw_data = self_sense_raw_data[count]; + if (min_rx_self_raw_data > self_sense_raw_data[count]) + min_rx_self_raw_data = self_sense_raw_data[count]; + } + + fts_print_channel(info, self_force_raw_data, self_sense_raw_data); + + input_raw_info_d(true, &info->client->dev, "%s: MIN_TX_SELF_RAW: %d MAX_TX_SELF_RAW : %d\n", + __func__, (s16)min_tx_self_raw_data, (s16)max_tx_self_raw_data); + input_raw_info_d(true, &info->client->dev, "%s: MIN_RX_SELF_RAW : %d MIN_RX_SELF_RAW : %d\n", + __func__, (s16)min_rx_self_raw_data, (s16)max_rx_self_raw_data); + + if (allnode == true) { + char *mbuff; + char temp[10] = { 0 }; + + mbuff = kzalloc((info->ForceChannelLength + info->SenseChannelLength + 2) * 10, GFP_KERNEL); + if (!mbuff) + goto out; + for (i = 0; i < (info->ForceChannelLength); i++) { + snprintf(temp, sizeof(temp), "%d,", (s16)self_force_raw_data[i]); + strlcat(mbuff, temp, sizeof(mbuff)); + } + for (i = 0; i < (info->SenseChannelLength); i++) { + snprintf(temp, sizeof(temp), "%d,", (s16)self_sense_raw_data[i]); + strlcat(mbuff, temp, sizeof(mbuff)); + } + + sec_cmd_set_cmd_result(sec, mbuff, sizeof(mbuff)); + sec->cmd_state = SEC_CMD_STATUS_OK; + kfree(mbuff); + return; + } + + snprintf(buff, sizeof(buff), "%d,%d,%d,%d", + (s16)min_tx_self_raw_data, (s16)max_tx_self_raw_data, + (s16)min_rx_self_raw_data, (s16)max_rx_self_raw_data); + sec->cmd_state = SEC_CMD_STATUS_OK; +out: + kfree(data); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + char ret_buff[SEC_CMD_STR_LEN] = { 0 }; + + snprintf(ret_buff, sizeof(ret_buff), "%d,%d", (s16)min_rx_self_raw_data, (s16)max_rx_self_raw_data); + sec_cmd_set_cmd_result_all(sec, ret_buff, strnlen(ret_buff, sizeof(ret_buff)), "SELF_RAW_DATA_X"); + snprintf(ret_buff, sizeof(ret_buff), "%d,%d", (s16)min_tx_self_raw_data, (s16)max_tx_self_raw_data); + sec_cmd_set_cmd_result_all(sec, ret_buff, strnlen(ret_buff, sizeof(ret_buff)), "SELF_RAW_DATA_Y"); + } + sec_cmd_set_cmd_result(sec, &buff[0], strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_self_raw_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + sec_cmd_set_default_result(sec); + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + fts_read_self_raw_frame(info, false); +} + +static void run_self_raw_read_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + sec_cmd_set_default_result(sec); + + enter_factory_mode(info, true); + fts_read_self_raw_frame(info, true); + enter_factory_mode(info, false); +} + +static void run_factory_miscalibration(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN]; + char data[FTS_EVENT_SIZE]; + char echo; + int ret; + int retry = 200; + short min, max; + + sec_cmd_set_default_result(sec); + + fts_interrupt_set(info, INT_DISABLE); + + memset(data, 0x00, sizeof(data)); + memset(buff, 0x00, sizeof(buff)); + + data[0] = 0xC7; + data[1] = 0x02; + + ret = info->fts_write_reg(info, data, 2); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: write failed: %d\n", __func__, ret); + goto error; + } + + /* maximum timeout 2sec ? */ + while (retry-- >= 0) { + memset(data, 0x00, sizeof(data)); + echo = FTS_READ_ONE_EVENT; + ret = info->fts_read_reg(info, &echo, 1, data, FTS_EVENT_SIZE); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: read failed: %d\n", __func__, ret); + goto error; + } + + input_info(true, &info->client->dev, "%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + fts_delay(10); + + if (data[0] == 0x03 || data[0] == 0xF3) { + max = data[3] << 8 | data[2]; + min = data[5] << 8 | data[4]; + + break; + } + if (retry == 0) + goto error; + } + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + snprintf(buff, sizeof(buff), "%d,%d", min, max); + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MIS_CAL"); + } else { + if (data[0] == 0x03) { + snprintf(buff, sizeof(buff), "OK,%d,%d", min, max); + } else { + snprintf(buff, sizeof(buff), "NG,%d,%d", min, max); + } + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + fts_reinit(info, false); + fts_interrupt_set(info, INT_ENABLE); + return; + +error: + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + fts_reinit(info, false); + + fts_interrupt_set(info, INT_ENABLE); +} + +static void run_miscalibration(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN]; + char data[FTS_EVENT_SIZE]; + char echo; + int ret; + int retry = 200; + short min, max; + + sec_cmd_set_default_result(sec); + + fts_interrupt_set(info, INT_DISABLE); + + memset(data, 0x00, sizeof(data)); + memset(buff, 0x00, sizeof(buff)); + + data[0] = 0xA4; + data[1] = 0x0B; + data[2] = 0x00; + data[3] = 0xC0; + + ret = info->fts_write_reg(info, data, 4); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: write failed: %d\n", __func__, ret); + goto error; + } + + /* maximum timeout 2sec ? */ + while (retry-- >= 0) { + memset(data, 0x00, sizeof(data)); + echo = FTS_READ_ONE_EVENT; + ret = info->fts_read_reg(info, &echo, 1, data, FTS_EVENT_SIZE); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: read failed: %d\n", __func__, ret); + goto error; + } + + input_info(true, &info->client->dev, "%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + fts_delay(10); + + if (data[0] == 0x03 || data[0] == 0xF3) { + max = data[3] << 8 | data[2]; + min = data[5] << 8 | data[4]; + + break; + } + if (retry == 0) + goto error; + } + + if (data[0] == 0x03) { + snprintf(buff, sizeof(buff), "OK,%d,%d", min, max); + } else { + snprintf(buff, sizeof(buff), "NG,%d,%d", min, max); + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + fts_reinit(info, false); + fts_interrupt_set(info, INT_ENABLE); + return; +error: + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + fts_reinit(info, false); + + fts_interrupt_set(info, INT_ENABLE); +} + +int fts_panel_test_result(struct fts_ts_info *info, int type) +{ + u8 data[FTS_EVENT_SIZE]; + u8 cmd = FTS_READ_ONE_EVENT; + uint8_t regAdd[4] = { 0 }; + bool matched = false; + int retry = 0; + int i = 0; + int result = 0; + short temp_min = 32767, temp_max = -32768; + + bool cheked_short_to_gnd = false; + bool cheked_short_to_vdd = false; + bool cheked_short = false; + bool cheked_open = false; + char tempv[25] = {0}; + char temph[30] = {0}; + struct sec_cmd_data *sec = &info->sec; + + char buff[SEC_CMD_STR_LEN] = {0}; + u8 *result_buff = NULL; + int size = 4095; + + result_buff = kzalloc(size, GFP_KERNEL); + if (!result_buff) { + input_err(true, &info->client->dev, "%s: result_buff kzalloc fail!\n", __func__); + goto alloc_fail; + } + + regAdd[0] = 0xA4; + regAdd[1] = 0x04; + regAdd[2] = 0xFC; + regAdd[3] = 0x09; + + info->fts_write_reg(info, ®Add[0], 4); + fts_delay(100); + + memset(info->ito_test, 0x0, 4); + + memset(data, 0x0, FTS_EVENT_SIZE); + while (info->fts_read_reg(info, &cmd, 1, (u8 *)data, FTS_EVENT_SIZE)) { + memset(tempv, 0x00, 25); + memset(temph, 0x00, 30); + if ((data[0] == FTS_EVENT_STATUS_REPORT) && (data[1] == 0x01)) { + for (i = 0; i < 4; i++) { + if (data[i + 2] != regAdd[i]) { + matched = false; + break; + } + matched = true; + } + if (matched == true) + break; + + } else if (data[0] == FTS_EVENT_ERROR_REPORT) { + info->ito_test[0] = data[0]; + info->ito_test[1] = data[1]; + info->ito_test[2] = data[2]; + info->ito_test[3] = 0x00; + + switch (data[1]) { + case ITO_FORCE_SHRT_GND: + case ITO_SENSE_SHRT_GND: + input_info(true, &info->client->dev, "%s: TX/RX_SHORT_TO_GND:%cX[%d]\n", + __func__, data[1] == ITO_FORCE_SHRT_VDD ? 'T' : 'R', data[2]); + if (type != SHORT_TEST) + break; + if (!cheked_short_to_gnd) { + snprintf(temph, 30, "TX/RX_SHORT_TO_GND:"); + strlcat(result_buff, temph, size); + cheked_short_to_gnd = true; + } + snprintf(tempv, sizeof(tempv), "%c%d,", data[1] == ITO_FORCE_SHRT_GND ? 'T' : 'R', data[2]); + strlcat(result_buff, tempv, size); + result = ITO_FAIL_SHORT; + break; + case ITO_FORCE_SHRT_VDD: + case ITO_SENSE_SHRT_VDD: + input_info(true, &info->client->dev, "%s: TX/RX_SHORT_TO_VDD:%cX[%d]\n", + __func__, data[1] == ITO_FORCE_SHRT_VDD ? 'T' : 'R', data[2]); + if (type != SHORT_TEST) + break; + if (!cheked_short_to_vdd) { + snprintf(temph, 30, "TX/RX_SHORT_TO_VDD:"); + strlcat(result_buff, temph, size); + cheked_short_to_vdd = true; + } + snprintf(tempv, sizeof(tempv), "%c%d,", data[1] == ITO_FORCE_SHRT_VDD ? 'T' : 'R', data[2]); + strlcat(result_buff, tempv, size); + result = -ITO_FAIL_SHORT; + break; + case ITO_FORCE_SHRT_FORCE: + case ITO_SENSE_SHRT_SENSE: + input_info(true, &info->client->dev, "%s: TX/RX_SHORT:%cX[%d]\n", + __func__, data[1] == ITO_FORCE_SHRT_FORCE ? 'T' : 'R', data[2]); + if (type != SHORT_TEST) + break; + if (!cheked_short) { + snprintf(temph, 30, "TX/RX_SHORT:"); + strlcat(result_buff, temph, size); + cheked_short = true; + } + snprintf(tempv, sizeof(tempv), "%c%d,", data[1] == ITO_FORCE_SHRT_FORCE ? 'T' : 'R', data[2]); + strlcat(result_buff, tempv, size); + result = -ITO_FAIL_SHORT; + break; + case ITO_FORCE_OPEN: + case ITO_SENSE_OPEN: + input_info(true, &info->client->dev, "%s: TX/RX_OPEN:%cX[%d]\n", + __func__, data[1] == ITO_FORCE_OPEN ? 'T' : 'R', data[2]); + if (type != OPEN_TEST) + break; + if (!cheked_open) { + snprintf(temph, 30, "TX/RX_OPEN:"); + strlcat(result_buff, temph, size); + cheked_open = true; + } + snprintf(tempv, sizeof(tempv), "%c%d,", data[1] == ITO_FORCE_OPEN ? 'T' : 'R', data[2]); + strlcat(result_buff, tempv, size); + result = -ITO_FAIL_OPEN; + break; + default: + input_info(true, &info->client->dev, "%s: unknown event %02x %02x %02x %02x %02x %02x %02x %02x\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + break; + } + } + + if (retry++ > 50) { + input_err(true, &info->client->dev, "%s: Time over - wait for result of ITO test\n", __func__); + goto test_fail; + } + fts_delay(20); + } + + /* read rawdata */ +// fts_read_frame(info, TYPE_RAW_DATA, &temp_min, &temp_max); + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + fts_read_nonsync_frame(info, &temp_min, &temp_max); + + if (type == OPEN_TEST && result == -ITO_FAIL_OPEN) { + snprintf(result_buff, sizeof(result_buff), "NG"); + sec_cmd_set_cmd_result(sec, result_buff, strnlen(result_buff, sizeof(result_buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + } else if (type == SHORT_TEST && result == -ITO_FAIL_SHORT) { + snprintf(result_buff, sizeof(result_buff), "NG"); + sec_cmd_set_cmd_result(sec, result_buff, strnlen(result_buff, sizeof(result_buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + } else { + snprintf(result_buff, sizeof(result_buff), "OK"); + sec_cmd_set_cmd_result(sec, result_buff, strnlen(result_buff, sizeof(result_buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + + input_info(true, &info->client->dev, "%s: %s\n", __func__, result_buff); + kfree(result_buff); + + return result; + +test_fail: + kfree(result_buff); +alloc_fail: + snprintf(buff, 30, "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + return -ITO_FAIL; +} + +static void run_trx_short_test(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int result = 0; + int type = 0; + char test[32]; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is lp mode\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + if (sec->cmd_param[0] == 1 && sec->cmd_param[1] == 0) { + input_err(true, &info->client->dev, + "%s: %s: seperate cm1 test open / short test result\n", __func__, buff); + + snprintf(buff, sizeof(buff), "%s", "CONT"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + return; + } + + if (sec->cmd_param[0] == 1 && sec->cmd_param[1] == 1) { + type = OPEN_TEST; + } else if (sec->cmd_param[0] == 1 && sec->cmd_param[1] == 2) { + type = SHORT_TEST; + } else if (sec->cmd_param[0] > 1) { + u8 result_buff[10]; + + snprintf(result_buff, sizeof(result_buff), "NA"); + sec_cmd_set_cmd_result(sec, result_buff, strnlen(result_buff, sizeof(result_buff))); + sec->cmd_state = SEC_CMD_STATUS_NOT_APPLICABLE; + + input_info(true, &info->client->dev, "%s : not supported test case\n", __func__); + return; + } + + input_info(true, &info->client->dev, "%s : CM%d factory_position[%d]\n", + __func__, sec->cmd_param[0], info->factory_position); + fts_interrupt_set(info, INT_DISABLE); + + result = fts_panel_test_result(info, type); + + fts_interrupt_set(info, INT_ENABLE); + + /* reinit */ + info->fts_systemreset(info, 0); + fts_reinit(info, false); + + info->touch_count = 0; + + if (sec->cmd_param[1]) + snprintf(test, sizeof(test), "TEST=%d,%d", sec->cmd_param[0], sec->cmd_param[1]); + else + snprintf(test, sizeof(test), "TEST=%d", sec->cmd_param[0]); + + if (result == 0) + sec_cmd_send_event_to_user(sec, test, "RESULT=PASS"); + else + sec_cmd_send_event_to_user(sec, test, "RESULT=FAIL"); + + input_info(true, &info->client->dev, "%s : test done\n", __func__); + return; +} + +static void check_connection(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + ret = fts_panel_ito_test(info, OPEN_TEST); + if (ret == 0) + snprintf(buff, sizeof(buff), "OK"); + else + snprintf(buff, sizeof(buff), "NG"); + + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_cx_data(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + short val = 0; + int node = 0; + + sec_cmd_set_default_result(sec); + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + node = fts_check_index(info); + if (node < 0) + return; + + if (info->cx_data) + val = info->cx_data[node]; + snprintf(buff, sizeof(buff), "%d", val); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + +} + +static int read_ms_cx_data(struct fts_ts_info *info, u8 *cx_min, u8 *cx_max) +{ + u8 *rdata; + u8 regAdd[FTS_EVENT_SIZE] = { 0 }; + u8 dataID; + u16 comp_start_addr; + int txnum, rxnum, i, j, ret = 0; + u8 *pStr = NULL; + u8 pTmp[16] = { 0 }; + + pStr = kzalloc(7 * (info->SenseChannelLength + 1), GFP_KERNEL); + if (pStr == NULL) + return -ENOMEM; + + rdata = kzalloc(info->ForceChannelLength * info->SenseChannelLength, GFP_KERNEL); + if (!rdata) + return -ENOMEM; + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); // Clear FIFO + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + fts_delay(20); + + // Request compensation data type + dataID = 0x11; // MS - LP + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = dataID; + ret = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to request data\n", __func__); + fts_interrupt_set(info, INT_ENABLE); + goto out; + } + + // Read Header + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + ret = info->fts_read_reg(info, ®Add[0], 3, &rdata[0], FTS_COMP_DATA_HEADER_SIZE); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to read header\n", __func__); + fts_interrupt_set(info, INT_ENABLE); + goto out; + } + + fts_interrupt_set(info, INT_ENABLE); + + if ((rdata[0] != 0xA5) && (rdata[1] != dataID)) { + input_info(true, &info->client->dev, "%s: failed to read signature data of header.\n", __func__); + ret = -EIO; + goto out; + } + + txnum = rdata[4]; + rxnum = rdata[5]; + + comp_start_addr = (u16)FTS_COMP_DATA_HEADER_SIZE; + regAdd[0] = 0xA6; + regAdd[1] = (u8)(comp_start_addr >> 8); + regAdd[2] = (u8)(comp_start_addr & 0xFF); + ret = info->fts_read_reg(info, ®Add[0], 3, &rdata[0], txnum * rxnum); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to read data\n", __func__); + goto out; + } + + *cx_min = *cx_max = rdata[0]; + for (j = 0; j < info->ForceChannelLength; j++) { + memset(pStr, 0x0, 7 * (info->SenseChannelLength + 1)); + snprintf(pTmp, sizeof(pTmp), "Tx%02d | ", j); + strlcat(pStr, pTmp, 7 * (info->SenseChannelLength + 1)); + + for (i = 0; i < info->SenseChannelLength; i++) { + snprintf(pTmp, sizeof(pTmp), "%3d", rdata[j * info->SenseChannelLength + i]); + strlcat(pStr, pTmp, 7 * (info->SenseChannelLength + 1)); + *cx_min = min(*cx_min, rdata[j * info->SenseChannelLength + i]); + *cx_max = max(*cx_max, rdata[j * info->SenseChannelLength + i]); + } + input_raw_info(true, &info->client->dev, "%s\n", pStr); + } + input_raw_info(true, &info->client->dev, "cx min:%d, cx max:%d\n", *cx_min, *cx_max); + + if (info->cx_data) + memcpy(&info->cx_data[0], &rdata[0], info->ForceChannelLength * info->SenseChannelLength); + +out: + kfree(rdata); + kfree(pStr); + return ret; +} + +#define NORMAL_CX2 0 /* single driving */ +#define ACTIVE_CX2 1 /* multi driving */ + +static int read_ms_cx2_data(struct fts_ts_info *info, u8 active, s8 *cx_min, s8 *cx_max) +{ + s8 *rdata = NULL; + u8 cdata[FTS_COMP_DATA_HEADER_SIZE]; + u8 regAdd[FTS_EVENT_SIZE] = { 0 }; + u8 dataID = 0; + u16 comp_start_addr; + int txnum, rxnum, i, j, ret = 0; + u8 *pStr = NULL; + u8 pTmp[16] = { 0 }; + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); // Clear FIFO + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + fts_delay(20); + + // Request compensation data type + if (active == NORMAL_CX2) + dataID = 0x11; // MS - LP + else if (active == ACTIVE_CX2) + dataID = 0x10; // MS - ACTIVE + + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = dataID; + + ret = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + if (ret < 0) { + fts_interrupt_set(info, INT_ENABLE); + return ret; + } + + // Read Header + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + ret = info->fts_read_reg(info, ®Add[0], 3, &cdata[0], FTS_COMP_DATA_HEADER_SIZE); + if (ret < 0) { + fts_interrupt_set(info, INT_ENABLE); + return ret; + } + fts_interrupt_set(info, INT_ENABLE); + + if ((cdata[0] != 0xA5) && (cdata[1] != dataID)) { + input_info(true, &info->client->dev, "%s: failed to read signature data of header.\n", __func__); + ret = -EIO; + return ret; + } + + txnum = cdata[4]; + rxnum = cdata[5]; + + rdata = kzalloc(txnum * rxnum, GFP_KERNEL); + if (!rdata) + return -ENOMEM; + + comp_start_addr = (u16)FTS_COMP_DATA_HEADER_SIZE; + regAdd[0] = 0xA6; + regAdd[1] = (u8)(comp_start_addr >> 8); + regAdd[2] = (u8)(comp_start_addr & 0xFF); + ret = info->fts_read_reg(info, ®Add[0], 3, &rdata[0], txnum * rxnum); + if (ret < 0) + goto out; + + pStr = kzalloc(7 * (rxnum + 1), GFP_KERNEL); + if (!pStr) { + ret = -ENOMEM; + goto out; + } + + *cx_min = *cx_max = rdata[0]; + for (i = 0; i < txnum; i++) { + memset(pStr, 0x0, 7 * (rxnum + 1)); + snprintf(pTmp, sizeof(pTmp), "Tx%02d | ", i); + strlcat(pStr, pTmp, 7 * (rxnum + 1)); + + for (j = 0; j < rxnum; j++) { + snprintf(pTmp, sizeof(pTmp), "%4d", rdata[i * rxnum + j]); + strlcat(pStr, pTmp, 7 * (rxnum + 1)); + + *cx_min = min(*cx_min, rdata[i * rxnum + j]); + *cx_max = max(*cx_max, rdata[i * rxnum + j]); + } + input_raw_info_d(true, &info->client->dev, "%s\n", pStr); + } + input_raw_info_d(true, &info->client->dev, "cx min:%d, cx max:%d\n", *cx_min, *cx_max); + + /* info->cx_data length: Force * Sense */ + if (info->cx_data && active == NORMAL_CX2) + memcpy(&info->cx_data[0], &rdata[0], info->ForceChannelLength * info->SenseChannelLength); + + kfree(pStr); +out: + kfree(rdata); + return ret; +} + +static void run_active_cx_data_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + char buff_minmax[SEC_CMD_STR_LEN] = { 0 }; + int rc; + s8 cx_min, cx_max; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "ACTIVE_CX2_DATA"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s: start\n", __func__); + + rc = read_ms_cx2_data(info, ACTIVE_CX2, &cx_min, &cx_max); + if (rc < 0) { + snprintf(buff, sizeof(buff), "NG"); + snprintf(buff_minmax, sizeof(buff_minmax), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff_minmax, sizeof(buff_minmax), "%d,%d", cx_min, cx_max); + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff_minmax, strnlen(buff_minmax, sizeof(buff_minmax)), "ACTIVE_CX2_DATA"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_multi_mutual_cx_data_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[FTS_EVENT_SIZE] = { 0 }; + u8 *data; + u8 dataID; + u16 sense_cx_data[100]; + u16 comp_start_rx_addr; + unsigned int rx_num, tx_num; + int rc, i, ret; + + u16 max_sense_cx = 0; + u16 min_sense_cx = 0xFFFF; + + input_info(true, &info->client->dev, "%s\n", __func__); + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + goto out; + } + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + // Request compensation data type + dataID = 0x56; + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = dataID; // Multi Mutual CX data + + rc = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + + fts_interrupt_set(info, INT_ENABLE); + + if (rc < 0) + goto out; + + data = kzalloc((info->ForceChannelLength + info->SenseChannelLength) * 2 + 1, GFP_KERNEL); + if (!data) { + input_err(true, &info->client->dev, "%s: data kzalloc fail!\n", __func__); + goto out; + } + + // Read Header + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + info->fts_read_reg(info, ®Add[0], 3, &data[0], FTS_COMP_DATA_HEADER_SIZE); + + if ((data[0] != 0xA5) && (data[1] != dataID)) { + kfree(data); + goto out; + } + + tx_num = data[4]; + rx_num = data[5]; + + /* Read Multi Mutual CX - RX data */ + comp_start_rx_addr = FTS_COMP_DATA_HEADER_SIZE + (((tx_num * 2) + rx_num) * 2); + regAdd[0] = 0xA6; + regAdd[1] = (u8)(comp_start_rx_addr >> 8); + regAdd[2] = (u8)(comp_start_rx_addr & 0xFF); + ret = info->fts_read_reg(info, ®Add[0], 3, &data[0], rx_num * 2); + if (ret < 0) { + kfree(data); + goto out; + } + + for (i = 0; i < rx_num; i++) { + sense_cx_data[i] = data[2 * i] | data[2 * i + 1] << 8; + + if (max_sense_cx < sense_cx_data[i]) + max_sense_cx = sense_cx_data[i]; + if (min_sense_cx > sense_cx_data[i]) + min_sense_cx = sense_cx_data[i]; + } + + kfree(data); + + snprintf(buff, sizeof(buff), "%d,%d", min_sense_cx, max_sense_cx); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MULTI_MUTUAL_CX"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return; + +out: + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "MULTI_MUTUAL_CX"); + + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_cx_data_read(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + char buff_minmax[SEC_CMD_STR_LEN] = { 0 }; + int rc; + u8 cx_min, cx_max; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "CX_DATA"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s: start\n", __func__); + + rc = read_ms_cx_data(info, &cx_min, &cx_max); + if (rc < 0) { + snprintf(buff, sizeof(buff), "NG"); + snprintf(buff_minmax, sizeof(buff_minmax), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff_minmax, sizeof(buff_minmax), "%d,%d", cx_min, cx_max); + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff_minmax, strnlen(buff_minmax, sizeof(buff_minmax)), "CX_DATA"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_cx_all_data(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int rc, i, j; + u8 cx_min, cx_max; + char *all_strbuff; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + input_raw_info_d(true, &info->client->dev, "%s\n", __func__); + + input_info(true, &info->client->dev, "%s: start\n", __func__); + + rc = read_ms_cx_data(info, &cx_min, &cx_max); + + /* do not systemreset in COB type */ + if (info->board->chip_on_board) + fts_set_scanmode(info, info->scan_mode); + else + enter_factory_mode(info, false); + if (rc < 0) { + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + all_strbuff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 4 + 1, GFP_KERNEL); + if (!all_strbuff) { + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + /* Read compensation data */ + if (info->cx_data) { + for (j = 0; j < info->ForceChannelLength; j++) { + for (i = 0; i < info->SenseChannelLength; i++) { + snprintf(buff, sizeof(buff), "%d,", info->cx_data[j * info->SenseChannelLength + i]); + strlcat(all_strbuff, buff, info->ForceChannelLength * info->SenseChannelLength * 4 + 1); + } + } + } + + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, all_strbuff, strlen(all_strbuff)); + input_info(true, &info->client->dev, "%s: %ld\n", __func__, strlen(all_strbuff)); + kfree(all_strbuff); +} + +static void get_cx_gap_data(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int rx_max = 0, tx_max = 0, ii; + + for (ii = 0; ii < (info->SenseChannelLength * info->ForceChannelLength); ii++) { + /* rx(x) gap max */ + if ((ii + 1) % (info->SenseChannelLength) != 0) + rx_max = max(rx_max, (int)abs(info->cx_data[ii + 1] - info->cx_data[ii])); + + /* tx(y) gap max */ + if (ii < (info->ForceChannelLength - 1) * info->SenseChannelLength) + tx_max = max(tx_max, (int)abs(info->cx_data[ii + info->SenseChannelLength] - info->cx_data[ii])); + } + + input_raw_info_d(true, &info->client->dev, "%s: max: rx:%d, tx:%d\n", __func__, rx_max, tx_max); + + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) { + snprintf(buff, sizeof(buff), "0,%d", rx_max); + sec_cmd_set_cmd_result_all(sec, buff, SEC_CMD_STR_LEN, "CX_DATA_GAP_X"); + snprintf(buff, sizeof(buff), "0,%d", tx_max); + sec_cmd_set_cmd_result_all(sec, buff, SEC_CMD_STR_LEN, "CX_DATA_GAP_Y"); + } +} + +static void run_cx_gap_data_x_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char *buff = NULL; + int ii, jj; + char temp[5] = { 0 }; + + sec_cmd_set_default_result(sec); + + buff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 5, GFP_KERNEL); + if (!buff) { + snprintf(temp, sizeof(temp), "NG"); + sec_cmd_set_cmd_result(sec, temp, strnlen(temp, sizeof(temp))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + for (ii = 0; ii < info->ForceChannelLength; ii++) { + for (jj = 0; jj < info->SenseChannelLength - 1; jj++) { + snprintf(temp, sizeof(temp), "%d,", + abs(info->cx_data[(ii * info->SenseChannelLength) + jj + 1] - + info->cx_data[(ii * info->SenseChannelLength) + jj])); + strlcat(buff, temp, info->ForceChannelLength * info->SenseChannelLength * 5); + memset(temp, 0x00, 5); + } + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, info->ForceChannelLength * info->SenseChannelLength * 5)); + sec->cmd_state = SEC_CMD_STATUS_OK; + kfree(buff); +} + +static void run_cx_gap_data_y_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char *buff = NULL; + int ii, jj; + char temp[5] = { 0 }; + + sec_cmd_set_default_result(sec); + + buff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 5, GFP_KERNEL); + if (!buff) { + snprintf(temp, sizeof(temp), "NG"); + sec_cmd_set_cmd_result(sec, temp, strnlen(temp, sizeof(temp))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + for (ii = 0; ii < info->ForceChannelLength - 1; ii++) { + for (jj = 0; jj < info->SenseChannelLength; jj++) { + snprintf(temp, sizeof(temp), "%d,", + abs(info->cx_data[((ii + 1) * info->SenseChannelLength) + jj] - + info->cx_data[(ii * info->SenseChannelLength) + jj])); + strlcat(buff, temp, info->ForceChannelLength * info->SenseChannelLength * 5); + memset(temp, 0x00, 5); + } + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, info->ForceChannelLength * info->SenseChannelLength * 5)); + sec->cmd_state = SEC_CMD_STATUS_OK; + kfree(buff); +} + +static void run_rawdata_gap_data_rx_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char *buff = NULL; + int ii; + char temp[5] = { 0 }; + + sec_cmd_set_default_result(sec); + + buff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 5, GFP_KERNEL); + if (!buff) { + snprintf(temp, sizeof(temp), "NG"); + sec_cmd_set_cmd_result(sec, temp, strnlen(temp, sizeof(temp))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + for (ii = 0; ii < (info->SenseChannelLength * info->ForceChannelLength); ii++) { + if ((ii + 1) % (info->SenseChannelLength) != 0) { + snprintf(temp, sizeof(temp), "%d,", (int)abs(info->pFrame[ii + 1] - info->pFrame[ii])); + strlcat(buff, temp, info->ForceChannelLength * info->SenseChannelLength * 5); + memset(temp, 0x00, 5); + } + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, info->ForceChannelLength * info->SenseChannelLength * 5)); + sec->cmd_state = SEC_CMD_STATUS_OK; + kfree(buff); +} + +static void run_rawdata_gap_data_tx_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char *buff = NULL; + int ii; + char temp[5] = { 0 }; + + sec_cmd_set_default_result(sec); + + buff = kzalloc(info->ForceChannelLength * info->SenseChannelLength * 5, GFP_KERNEL); + if (!buff) { + snprintf(temp, sizeof(temp), "NG"); + sec_cmd_set_cmd_result(sec, temp, strnlen(temp, sizeof(temp))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + for (ii = 0; ii < (info->SenseChannelLength * info->ForceChannelLength); ii++) { + if (ii < (info->ForceChannelLength - 1) * info->SenseChannelLength) { + snprintf(temp, sizeof(temp), "%d,", + (int)abs(info->pFrame[ii + info->SenseChannelLength] - info->pFrame[ii])); + strlcat(buff, temp, info->ForceChannelLength * info->SenseChannelLength * 5); + memset(temp, 0x00, 5); + } + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, info->ForceChannelLength * info->SenseChannelLength * 5)); + sec->cmd_state = SEC_CMD_STATUS_OK; + kfree(buff); +} + +static void factory_cmd_result_all(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + sec->item_count = 0; + memset(sec->cmd_result_all, 0x00, SEC_CMD_RESULT_STR_LEN); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + sec->cmd_all_factory_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + sec->cmd_all_factory_state = SEC_CMD_STATUS_RUNNING; + + get_chip_vendor(sec); + get_chip_name(sec); + get_fw_ver_bin(sec); + get_fw_ver_ic(sec); + + enter_factory_mode(info, true); + +// run_lp_single_ended_rawcap_read(sec); /* Mutual raw */ + run_rawcap_read(sec); + run_self_raw_read(sec); + + fts_set_scanmode(info, FTS_SCAN_MODE_SCAN_OFF); + fts_release_all_finger(info); + + // have to check items +// get_strength_all_data(sec); /* jitter data */ +// run_high_frequency_rawcap_read(sec); /* micro_open */ +// get_rawcap_gap_data(sec); /* micro_open rawcap gap */ +// run_low_frequency_rawcap_read(sec); /* micro_short gap diff */ + +// run_active_cx_data_read(sec); + run_cx_data_read(sec); + get_cx_gap_data(sec); + run_ix_data_read(sec); + + get_wet_mode(sec); + + /* do not systemreset in COB type */ + if (info->board->chip_on_board) + fts_set_scanmode(info, info->scan_mode); + else + enter_factory_mode(info, false); + + run_mutual_jitter(sec); + run_self_jitter(sec); + run_factory_miscalibration(sec); + + if (info->board->support_sram_test) + run_sram_test(sec); + + sec->cmd_all_factory_state = SEC_CMD_STATUS_OK; + +out: + input_info(true, &info->client->dev, "%s: %d%s\n", __func__, sec->item_count, sec->cmd_result_all); +} + +static void factory_cmd_result_all_imagetest(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + + sec->item_count = 0; + memset(sec->cmd_result_all, 0x00, SEC_CMD_RESULT_STR_LEN); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + sec->cmd_all_factory_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + sec->cmd_all_factory_state = SEC_CMD_STATUS_RUNNING; + + run_jitter_delta_test(sec); + + sec->cmd_all_factory_state = SEC_CMD_STATUS_OK; + +out: + input_info(true, &info->client->dev, "%s: %d%s\n", __func__, sec->item_count, sec->cmd_result_all); +} + +static void set_factory_level(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: Touch is stopped!\n", __func__); + goto NG; + } + + if (sec->cmd_param[0] < OFFSET_FAC_SUB || sec->cmd_param[0] > OFFSET_FAC_MAIN) { + input_err(true, &info->client->dev, + "%s: cmd data is abnormal, %d\n", __func__, sec->cmd_param[0]); + goto NG; + } + + info->factory_position = sec->cmd_param[0]; + + input_info(true, &info->client->dev, "%s: %d\n", __func__, info->factory_position); + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + return; + +NG: + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); +} + +int fts_get_tsp_test_result(struct fts_ts_info *info) +{ + u8 data; + int ret; + + ret = get_nvm_data(info, FTS_NVM_OFFSET_FAC_RESULT, &data); + if (ret < 0) + goto err_read; + + if (data == 0xFF) + data = 0; + + info->test_result.data[0] = data; + +err_read: + return ret; +} +EXPORT_SYMBOL(fts_get_tsp_test_result); + +static void get_tsp_test_result(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + ret = fts_get_tsp_test_result(info); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: get failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "M:%s, M:%d, A:%s, A:%d", + info->test_result.module_result == 0 ? "NONE" : + info->test_result.module_result == 1 ? "FAIL" : + info->test_result.module_result == 2 ? "PASS" : "A", + info->test_result.module_count, + info->test_result.assy_result == 0 ? "NONE" : + info->test_result.assy_result == 1 ? "FAIL" : + info->test_result.assy_result == 2 ? "PASS" : "A", + info->test_result.assy_count); + + sec_cmd_set_cmd_result(sec, buff, strlen(buff)); + sec->cmd_state = SEC_CMD_STATUS_OK; + } +} + +/* FACTORY TEST RESULT SAVING FUNCTION + * bit 3 ~ 0 : OCTA Assy + * bit 7 ~ 4 : OCTA module + * param[0] : OCTA module(1) / OCTA Assy(2) + * param[1] : TEST NONE(0) / TEST FAIL(1) / TEST PASS(2) : 2 bit + */ +static void set_tsp_test_result(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + ret = fts_get_tsp_test_result(info); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: get failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + sec->cmd_state = SEC_CMD_STATUS_RUNNING; + + if (sec->cmd_param[0] == TEST_OCTA_ASSAY) { + info->test_result.assy_result = sec->cmd_param[1]; + if (info->test_result.assy_count < 3) + info->test_result.assy_count++; + + } else if (sec->cmd_param[0] == TEST_OCTA_MODULE) { + info->test_result.module_result = sec->cmd_param[1]; + if (info->test_result.module_count < 3) + info->test_result.module_count++; + } + + input_info(true, &info->client->dev, "%s: [0x%X] M:%s, M:%d, A:%s, A:%d\n", + __func__, info->test_result.data[0], + info->test_result.module_result == 0 ? "NONE" : + info->test_result.module_result == 1 ? "FAIL" : + info->test_result.module_result == 2 ? "PASS" : "A", + info->test_result.module_count, + info->test_result.assy_result == 0 ? "NONE" : + info->test_result.assy_result == 1 ? "FAIL" : + info->test_result.assy_result == 2 ? "PASS" : "A", + info->test_result.assy_count); + + ret = set_nvm_data(info, FTS_NVM_OFFSET_FAC_RESULT, info->test_result.data); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: set failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +int fts_get_disassemble_count(struct fts_ts_info *info) +{ + u8 data; + int ret; + + ret = get_nvm_data(info, FTS_NVM_OFFSET_DISASSEMBLE_COUNT, &data); + if (ret < 0) + goto err_read; + + if (data == 0xFF) + data = 0; + + info->disassemble_count = data; + +err_read: + return ret; +} + +static void increase_disassemble_count(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + ret = fts_get_disassemble_count(info); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: get failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + sec->cmd_state = SEC_CMD_STATUS_RUNNING; + + if (info->disassemble_count < 0xFE) + info->disassemble_count++; + + ret = set_nvm_data(info, FTS_NVM_OFFSET_DISASSEMBLE_COUNT, &info->disassemble_count); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: set failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_disassemble_count(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + ret = fts_get_disassemble_count(info); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: get failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "%d", info->disassemble_count); + + sec_cmd_set_cmd_result(sec, buff, strlen(buff)); + sec->cmd_state = SEC_CMD_STATUS_OK; + } +} + +static void get_osc_trim_error(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + ret = info->fts_systemreset(info, 0); + if (ret == -FTS_ERROR_BROKEN_OSC_TRIM) { + snprintf(buff, sizeof(buff), "1"); + } else { + snprintf(buff, sizeof(buff), "0"); + } + fts_set_scanmode(info, info->scan_mode); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "OSC_TRIM_ERR"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void get_osc_trim_info(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + unsigned char data[4]; + unsigned char regAdd[3]; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + ret = info->fts_get_sysinfo_data(info, FTS_SI_OSC_TRIM_INFO, 2, data); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: system info read failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + regAdd[0] = 0xA6; + regAdd[1] = data[1]; + regAdd[2] = data[0]; + + memset(data, 0x00, 4); + ret = info->fts_read_reg(info, regAdd, 3, data, 4); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: osc trim info read failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + snprintf(buff, sizeof(buff), "%02X%02X%02X%02X", data[0], data[1], data[2], data[3]); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "OSC_TRIM_INFO"); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_snr_non_touched(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 address[5] = { 0 }; + u16 status; + int ret = 0; + int wait_time = 0; + int retry_cnt = 0; + + input_info(true, &info->client->dev, "%s\n", __func__); + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + goto out_init; + } + + if (sec->cmd_param[0] < 1 || sec->cmd_param[0] > 1000) { + input_err(true, &info->client->dev, "%s: strange value frame:%d\n", + __func__, sec->cmd_param[0]); + goto out_init; + } + + fts_fix_active_mode(info, true); + + /* enter SNR mode */ + address[0] = 0x70; + address[1] = 0x25; + ret = info->fts_write_reg(info, &address[0], 2); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: i2c_write failed\n", __func__); + goto out; + } + + /* start Non-touched Peak Noise */ + address[0] = 0xC7; + address[1] = 0x09; + address[2] = 0x01; + address[3] = (u8)(sec->cmd_param[0] & 0xff); + address[4] = (u8)(sec->cmd_param[0] >> 8); + ret = info->fts_write_reg(info, &address[0], 5); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: i2c_write failed\n", __func__); + goto out; + } + + + wait_time = (sec->cmd_param[0] * 1000) / 120 + (sec->cmd_param[0] * 1000) % 120; + + fts_delay(wait_time); + + retry_cnt = 50; + address[0] = 0x72; + while ((info->fts_read_reg(info, &address[0], 1, (u8 *)&status, 2) > 0) && (retry_cnt-- > 0)) { + if (status == 1) + break; + fts_delay(20); + } + + if (status == 0) { + input_err(true, &info->client->dev, "%s: failed non-touched status:%d\n", __func__, status); + goto out; + } + + snprintf(buff, sizeof(buff), "OK"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + /* EXIT SNR mode */ + address[0] = 0x70; + address[1] = 0x00; + info->fts_write_reg(info, &address[0], 2); + fts_fix_active_mode(info, false); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return; + +out: + address[0] = 0x70; + address[1] = 0x00; + info->fts_write_reg(info, &address[0], 2); + fts_fix_active_mode(info, false); + +out_init: + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_snr_touched(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + struct stm_ts_snr_result_cmd snr_cmd_result; + struct stm_ts_snr_result snr_result; + char buff[SEC_CMD_STR_LEN] = { 0 }; + char tbuff[SEC_CMD_STR_LEN] = { 0 }; + u8 address[5] = { 0 }; + int ret = 0; + int wait_time = 0; + int retry_cnt = 0; + int i = 0; + + input_info(true, &info->client->dev, "%s\n", __func__); + + sec_cmd_set_default_result(sec); + memset(&snr_result, 0, sizeof(struct stm_ts_snr_result)); + memset(&snr_cmd_result, 0, sizeof(struct stm_ts_snr_result_cmd)); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + goto out_init; + } + + if (sec->cmd_param[0] < 1 || sec->cmd_param[0] > 1000) { + input_err(true, &info->client->dev, "%s: strange value frame:%d\n", + __func__, sec->cmd_param[0]); + goto out_init; + } + + fts_fix_active_mode(info, true); + + /* enter SNR mode */ + address[0] = 0x70; + address[1] = 0x25; + ret = info->fts_write_reg(info, &address[0], 2); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: i2c_write failed\n", __func__); + goto out; + } + + /* start touched Peak Noise */ + address[0] = 0xC7; + address[1] = 0x09; + address[2] = 0x02; + address[3] = (u8)(sec->cmd_param[0] & 0xff); + address[4] = (u8)(sec->cmd_param[0] >> 8); + ret = info->fts_write_reg(info, &address[0], 5); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: i2c_write failed\n", __func__); + goto out; + } + + wait_time = (sec->cmd_param[0] * 1000) / 120 + (sec->cmd_param[0] * 1000) % 120; + + fts_delay(wait_time); + + retry_cnt = 50; + address[0] = 0x72; + while ((info->fts_read_reg(info, &address[0], 1, (u8 *)&snr_cmd_result, 6) > 0) && (retry_cnt-- > 0)) { + if (snr_cmd_result.status == 1) + break; + fts_delay(20); + } + + if (snr_cmd_result.status == 0) { + input_err(true, &info->client->dev, "%s: failed non-touched status:%d\n", __func__, snr_cmd_result.status); + goto out; + } else { + input_info(true, &info->client->dev, "%s: status:%d, point:%d, average:%d\n", __func__, + snr_cmd_result.status, snr_cmd_result.point, snr_cmd_result.average); + } + + address[0] = 0x72; + ret = info->fts_read_reg(info, &address[0], 1, (u8 *)&snr_result, sizeof(struct stm_ts_snr_result)); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: i2c_write failed size:%ld\n", __func__, sizeof(struct stm_ts_snr_result)); + goto out; + } + + for (i = 0; i < 9; i++) { + input_info(true, &info->client->dev, "%s: average:%d, snr1:%d, snr2:%d\n", __func__, + snr_result.result[i].average, snr_result.result[i].snr1, snr_result.result[i].snr2); + snprintf(tbuff, sizeof(tbuff), "%d,%d,%d,", + snr_result.result[i].average, + snr_result.result[i].snr1, + snr_result.result[i].snr2); + strlcat(buff, tbuff, sizeof(buff)); + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + + /* EXIT SNR mode */ + address[0] = 0x70; + address[1] = 0x00; + info->fts_write_reg(info, &address[0], 2); + fts_fix_active_mode(info, false); + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + + return; +out: + address[0] = 0x70; + address[1] = 0x00; + info->fts_write_reg(info, &address[0], 2); + fts_fix_active_mode(info, false); +out_init: + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +/* +static void run_elvss_test(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + u8 data[FTS_EVENT_SIZE + 1]; + int retry = 10; + + sec_cmd_set_default_result(sec); + snprintf(buff, sizeof(buff), "NG"); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + return; + } + + info->fts_systemreset(info, 0); + fts_interrupt_set(info, INT_DISABLE); + + memset(data, 0x00, 8); + + data[0] = 0xA4; + data[1] = 0x04; + data[2] = 0x00; + data[3] = 0x04; + + ret = info->fts_write_reg(info, data, 4); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: write failed. ret: %d\n", __func__, ret); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + fts_reinit(info, false); + fts_interrupt_set(info, INT_ENABLE); + return; + } + + memset(data, 0x00, FTS_EVENT_SIZE); + data[0] = FTS_READ_ONE_EVENT; + while (info->fts_read_reg(info, &data[0], 1, &data[1], FTS_EVENT_SIZE) > 0) { + input_info(true, &info->client->dev, + "%s: %02X: %02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X\n", + __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], + data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); + + if (data[1] == FTS_EVENT_ERROR_REPORT) { + break; + } else if (data[1] == 0x03) { + snprintf(buff, sizeof(buff), "OK"); + break; + } else if (retry < 0) { + break; + } + retry--; + fts_delay(50); + + } + + fts_reinit(info, false); + fts_interrupt_set(info, INT_ENABLE); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_OK; + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} +*/ +int set_nvm_data_by_size(struct fts_ts_info *info, u8 offset, int length, u8 *buf) +{ + u8 regAdd[256] = { 0 }; + u8 remaining, index, sendinglength; + int ret; + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); // Clear FIFO + + fts_release_all_finger(info); + + remaining = length; + index = 0; + sendinglength = 0; + + while (remaining) { + regAdd[0] = 0xC7; + regAdd[1] = 0x01; + regAdd[2] = offset + index; + + // write data up to 12 bytes available + if (remaining < 13) { + memcpy(®Add[3], &buf[index], remaining); + sendinglength = remaining; + } else { + memcpy(®Add[3], &buf[index], 12); + index += 12; + sendinglength = 12; + } + + ret = fts_write_reg(info, ®Add[0], sendinglength + 3); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: write failed. ret: %d\n", __func__, ret); + return ret; + } + remaining -= sendinglength; + } + + fts_interrupt_set(info, INT_DISABLE); + + // Save to flash + regAdd[0] = 0xA4; + regAdd[1] = 0x05; + regAdd[2] = 0x04; // panel configuration area + + ret = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 200); + if (ret < 0) + input_err(true, &info->client->dev, + "%s: failed to get echo. ret: %d\n", __func__, ret); + + fts_interrupt_set(info, INT_ENABLE); + + return ret; +} + +int set_nvm_data(struct fts_ts_info *info, u8 type, u8 *buf) +{ + return set_nvm_data_by_size(info, nvm_data[type].offset, nvm_data[type].length, buf); +} + +int get_nvm_data_by_size(struct fts_ts_info *info, u8 offset, int length, u8 *nvdata) +{ + u8 regAdd[3] = {0}; + u8 data[128] = { 0 }; + int ret; + + info->fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); // Clear FIFO + + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_DISABLE); + + // Request SEC factory debug data from flash + regAdd[0] = 0xA4; + regAdd[1] = 0x06; + regAdd[2] = 0x90; + + ret = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: timeout. ret: %d\n", __func__, ret); + fts_interrupt_set(info, INT_ENABLE); + return ret; + } + + fts_interrupt_set(info, INT_ENABLE); + + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = offset; + + ret = fts_read_reg(info, ®Add[0], 3, data, length + 1); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: read failed. ret: %d\n", __func__, ret); + return ret; + } + + memcpy(nvdata, &data[0], length); + + input_raw_info_d(true, &info->client->dev, "%s: offset [%d], length [%d]\n", + __func__, offset, length); + + return ret; +} + +int get_nvm_data(struct fts_ts_info *info, int type, u8 *nvdata) +{ + int size = sizeof(nvm_data) / sizeof(struct fts_nvm_data_map); + + if (type >= size) + return -EINVAL; + + return get_nvm_data_by_size(info, nvm_data[type].offset, nvm_data[type].length, nvdata); +} + +#ifdef TCLM_CONCEPT +int fts_tclm_data_read(struct i2c_client *client, int address) +{ + struct fts_ts_info *info = i2c_get_clientdata(client); + int ret = 0; + int i = 0; + u8 nbuff[FTS_NVM_OFFSET_ALL]; + u16 ic_version; + + switch (address) { + case SEC_TCLM_NVM_OFFSET_IC_FIRMWARE_VER: + ret = info->fts_get_version_info(info); + ic_version = (info->module_version_of_ic << 8) | (info->fw_main_version_of_ic & 0xFF); + return ic_version; + case SEC_TCLM_NVM_ALL_DATA: + ret = get_nvm_data_by_size(info, nvm_data[FTS_NVM_OFFSET_FAC_RESULT].offset, + FTS_NVM_OFFSET_ALL, nbuff); + if (ret < 0) + return ret; + info->tdata->nvdata.cal_count = nbuff[nvm_data[FTS_NVM_OFFSET_CAL_COUNT].offset]; + info->tdata->nvdata.tune_fix_ver = (nbuff[nvm_data[FTS_NVM_OFFSET_TUNE_VERSION].offset] << 8) | + nbuff[nvm_data[FTS_NVM_OFFSET_TUNE_VERSION].offset + 1]; + info->tdata->nvdata.cal_position = nbuff[nvm_data[FTS_NVM_OFFSET_CAL_POSITION].offset]; + info->tdata->nvdata.cal_pos_hist_cnt = nbuff[nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_COUNT].offset]; + info->tdata->nvdata.cal_pos_hist_lastp = nbuff[nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_LASTP].offset]; + for (i = nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].offset; + i < nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].offset + + nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].length; i++) + info->tdata->nvdata.cal_pos_hist_queue[i - nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].offset] = nbuff[i]; + + info->tdata->nvdata.cal_fail_falg = nbuff[nvm_data[FTS_NVM_OFFSET_CAL_FAIL_FLAG].offset]; + info->tdata->nvdata.cal_fail_cnt = nbuff[nvm_data[FTS_NVM_OFFSET_CAL_FAIL_COUNT].offset]; + info->fac_nv = nbuff[nvm_data[FTS_NVM_OFFSET_FAC_RESULT].offset]; + info->disassemble_count = nbuff[nvm_data[FTS_NVM_OFFSET_DISASSEMBLE_COUNT].offset]; + return ret; + case SEC_TCLM_NVM_TEST: + input_info(true, &info->client->dev, "%s: dt: tclm_level [%d] afe_base [%04X]\n", + __func__, info->tdata->tclm_level, info->tdata->afe_base); + ret = get_nvm_data_by_size(info, FTS_NVM_OFFSET_ALL + SEC_TCLM_NVM_OFFSET, + SEC_TCLM_NVM_OFFSET_LENGTH, info->tdata->tclm); + if (info->tdata->tclm[0] != 0xFF) { + info->tdata->tclm_level = info->tdata->tclm[0]; + info->tdata->afe_base = (info->tdata->tclm[1] << 8) | info->tdata->tclm[2]; + input_info(true, &info->client->dev, "%s: nv: tclm_level [%d] afe_base [%04X]\n", + __func__, info->tdata->tclm_level, info->tdata->afe_base); + } + return ret; + default: + return ret; + } +} + +int fts_tclm_data_write(struct i2c_client *client, int address) +{ + struct fts_ts_info *info = i2c_get_clientdata(client); + int ret = 1; + int i = 0; + u8 nbuff[FTS_NVM_OFFSET_ALL]; + + switch (address) { + case SEC_TCLM_NVM_ALL_DATA: + memset(nbuff, 0x00, FTS_NVM_OFFSET_ALL); + nbuff[nvm_data[FTS_NVM_OFFSET_FAC_RESULT].offset] = info->fac_nv; + nbuff[nvm_data[FTS_NVM_OFFSET_DISASSEMBLE_COUNT].offset] = info->disassemble_count; + nbuff[nvm_data[FTS_NVM_OFFSET_CAL_COUNT].offset] = info->tdata->nvdata.cal_count; + nbuff[nvm_data[FTS_NVM_OFFSET_TUNE_VERSION].offset] = (u8)(info->tdata->nvdata.tune_fix_ver >> 8); + nbuff[nvm_data[FTS_NVM_OFFSET_TUNE_VERSION].offset + 1] = (u8)(0xff & info->tdata->nvdata.tune_fix_ver); + nbuff[nvm_data[FTS_NVM_OFFSET_CAL_POSITION].offset] = info->tdata->nvdata.cal_position; + nbuff[nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_COUNT].offset] = info->tdata->nvdata.cal_pos_hist_cnt; + nbuff[nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_LASTP].offset] = info->tdata->nvdata.cal_pos_hist_lastp; + for (i = nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].offset; + i < nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].offset + + nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].length; i++) + nbuff[i] = info->tdata->nvdata.cal_pos_hist_queue[i - nvm_data[FTS_NVM_OFFSET_HISTORY_QUEUE_ZERO].offset]; + nbuff[nvm_data[FTS_NVM_OFFSET_CAL_FAIL_FLAG].offset] = info->tdata->nvdata.cal_fail_falg; + nbuff[nvm_data[FTS_NVM_OFFSET_CAL_FAIL_COUNT].offset] = info->tdata->nvdata.cal_fail_cnt; + ret = set_nvm_data_by_size(info, nvm_data[FTS_NVM_OFFSET_FAC_RESULT].offset, FTS_NVM_OFFSET_ALL, nbuff); + return ret; + case SEC_TCLM_NVM_TEST: + ret = set_nvm_data_by_size(info, FTS_NVM_OFFSET_ALL + SEC_TCLM_NVM_OFFSET, + SEC_TCLM_NVM_OFFSET_LENGTH, info->tdata->tclm); + return ret; + default: + return ret; + } +} + +static void tclm_test_cmd(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + struct sec_tclm_data *data = info->tdata; + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret = 0; + + sec_cmd_set_default_result(sec); + + if (!info->tdata->support_tclm_test) + goto not_support; + + ret = tclm_test_command(data, sec->cmd_param[0], sec->cmd_param[1], sec->cmd_param[2], buff); + if (ret < 0) + sec->cmd_state = SEC_CMD_STATUS_FAIL; + else + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + return; + +not_support: + snprintf(buff, sizeof(buff), "%s", "NA"); + sec->cmd_state = SEC_CMD_STATUS_NOT_APPLICABLE; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); +} + +static void get_calibration(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (!info->tdata->support_tclm_test) + goto not_support; + + snprintf(buff, sizeof(buff), "%d", info->is_cal_done); + + info->is_cal_done = false; + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + return; + +not_support: + snprintf(buff, sizeof(buff), "%s", "NA"); + sec->cmd_state = SEC_CMD_STATUS_NOT_APPLICABLE; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); +} +#endif + +#ifdef CONFIG_GLOVE_TOUCH +static void glove_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[3] = {0}; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + info->glove_enabled = sec->cmd_param[0]; + + if (info->fts_power_state != FTS_POWER_STATE_POWERDOWN && info->reinit_done) { + if (info->glove_enabled) + info->touch_functions = info->touch_functions | FTS_TOUCHTYPE_BIT_GLOVE | + FTS_TOUCHTYPE_DEFAULT_ENABLE; + else + info->touch_functions = (info->touch_functions & (~FTS_TOUCHTYPE_BIT_GLOVE)) | + FTS_TOUCHTYPE_DEFAULT_ENABLE; + } + + regAdd[0] = FTS_CMD_SET_GET_TOUCHTYPE; + regAdd[1] = (u8)(info->touch_functions & 0xFF); + regAdd[2] = (u8)(info->touch_functions >> 8); + fts_write_reg(info, ®Add[0], 3); + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} +#endif + +static void clear_cover_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 3) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + if (sec->cmd_param[0] > 1) { + info->flip_enable = true; + info->cover_type = sec->cmd_param[1]; + } else { + info->flip_enable = false; + } + + if (info->fts_power_state != FTS_POWER_STATE_POWERDOWN && info->reinit_done) { + if (info->flip_enable) + fts_set_cover_type(info, true); + else + fts_set_cover_type(info, false); + } + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +}; + +static void report_rate(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 scan_rate; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 255) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + + scan_rate = sec->cmd_param[0]; + fts_change_scan_rate(info, scan_rate); + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + +out: + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) +static void interrupt_control(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + int enables = sec->cmd_param[0]; + + if (enables) + fts_irq_enable(info, true); + else + fts_irq_enable(info, false); + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + +out: + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} +#endif + +static void set_wirelesscharger_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + info->charger_mode = sec->cmd_param[0]; + + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 3) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + info->charger_mode = sec->cmd_param[0]; + + fts_wirelesscharger_mode(info); + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + +out: + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +}; + +/********************************************************************* + * flag 1 : set edge handler + * 2 : set (portrait, normal) edge zone data + * 4 : set (portrait, normal) dead zone data + * 8 : set landscape mode data + * 16 : mode clear + * data + * 0x00, FFF (y start), FFF (y end), FF(direction) + * 0x01, FFFF (edge zone) + * 0x02, FF (up x), FF (down x), FFFF (y) + * 0x03, FF (mode), FFF (edge), FFF (dead zone) + * case + * edge handler set : 0x00.... + * booting time : 0x00... + 0x01... + * normal mode : 0x02... (+0x01...) + * landscape mode : 0x03... + * landscape -> normal (if same with old data) : 0x03, 0 + * landscape -> normal (etc) : 0x02.... + 0x03, 0 + *********************************************************************/ + +void fts_set_grip_data_to_ic(struct fts_ts_info *info, u8 flag) +{ + u8 data[4] = { 0 }; + u8 regAdd[11] = {FTS_CMD_SET_FUNCTION_ONOFF, }; + + input_info(true, &info->client->dev, "%s: flag: %02X (clr,lan,nor,edg,han)\n", __func__, flag); + + memset(®Add[1], 0x00, 10); + + if (flag & G_SET_EDGE_HANDLER) { + if (info->grip_edgehandler_direction == 0) { + data[0] = 0x0; + data[1] = 0x0; + data[2] = 0x0; + data[3] = 0x0; + } else { + data[0] = (info->grip_edgehandler_start_y >> 4) & 0xFF; + data[1] = (info->grip_edgehandler_start_y << 4 & 0xF0) | + ((info->grip_edgehandler_end_y >> 8) & 0xF); + data[2] = info->grip_edgehandler_end_y & 0xFF; + data[3] = info->grip_edgehandler_direction & 0x3; + } + + regAdd[1] = FTS_FUNCTION_EDGE_HANDLER; + regAdd[2] = data[0]; + regAdd[3] = data[1]; + regAdd[4] = data[2]; + regAdd[5] = data[3]; + + fts_write_reg(info, regAdd, 6); + } + + if (flag & G_SET_EDGE_ZONE) { + /* ex) C1 07 00 3E 00 3E + * - 0x003E(60) px : Grip Right zone + * - 0x003E(60) px : Grip Left zone + */ + regAdd[1] = FTS_FUNCTION_EDGE_AREA; + regAdd[2] = (info->grip_edge_range >> 8) & 0xFF; + regAdd[3] = info->grip_edge_range & 0xFF; + regAdd[4] = (info->grip_edge_range >> 8) & 0xFF; + regAdd[5] = info->grip_edge_range & 0xFF; + + fts_write_reg(info, regAdd, 6); + } + + if (flag & G_SET_NORMAL_MODE) { + /* ex) C1 08 1E 1E 00 00 + * - 0x1E (30) px : upper X range + * - 0x1E (30) px : lower X range + * - 0x0000 (0) px : division Y + */ + regAdd[1] = FTS_FUNCTION_DEAD_ZONE; + regAdd[2] = info->grip_deadzone_up_x & 0xFF; + regAdd[3] = info->grip_deadzone_dn_x & 0xFF; + regAdd[4] = (info->grip_deadzone_y >> 8) & 0xFF; + regAdd[5] = info->grip_deadzone_y & 0xFF; + + fts_write_reg(info, regAdd, 6); + } + + if (flag & G_SET_LANDSCAPE_MODE) { + /* ex) C1 09 01 00 3C 00 3C 00 1E + * - 0x01 : horizontal mode + * - 0x03C (60) px : Grip zone range (Right) + * - 0x03C (60) px : Grip zone range (Left) + * - 0x01E (30) px : Reject zone range (Left/Right) + */ + regAdd[1] = FTS_FUNCTION_LANDSCAPE_MODE; + regAdd[2] = info->grip_landscape_mode; + regAdd[3] = (info->grip_landscape_edge >> 8) & 0xFF; + regAdd[4] = info->grip_landscape_edge & 0xFF; + regAdd[5] = (info->grip_landscape_edge >> 8) & 0xFF; + regAdd[6] = info->grip_landscape_edge & 0xFF; + regAdd[7] = (info->grip_landscape_deadzone >> 8) & 0xFF; + regAdd[8] = info->grip_landscape_deadzone & 0xFF; + + fts_write_reg(info, regAdd, 9); + + /*ex) C1 0A 01 00 3C 00 3C 00 1E 00 1E + * - 0x01(1) : Enable function + * - 0x003C (60) px : Grip Top zone range + * - 0x001E (60) px : Grip Bottom zone range + * - 0x001E (30) px : Reject Top zone range + * - 0x001E (30) px : Reject Bottom zone range + */ + regAdd[1] = FTS_FUNCTION_LANDSCAPE_TOP_BOTTOM; + regAdd[2] = info->grip_landscape_mode; + regAdd[3] = (info->grip_landscape_top_gripzone >> 8) & 0xFF; + regAdd[4] = info->grip_landscape_top_gripzone & 0xFF; + regAdd[5] = (info->grip_landscape_bottom_gripzone >> 8) & 0xFF; + regAdd[6] = info->grip_landscape_bottom_gripzone & 0xFF; + regAdd[7] = (info->grip_landscape_top_deadzone >> 8) & 0xFF; + regAdd[8] = info->grip_landscape_top_deadzone & 0xFF; + regAdd[9] = (info->grip_landscape_bottom_deadzone >> 8) & 0xFF; + regAdd[10] = info->grip_landscape_bottom_deadzone & 0xFF; + + fts_write_reg(info, regAdd, 11); + } + + if (flag & G_CLR_LANDSCAPE_MODE) { + memset(®Add[1], 0x00, 10); + + /* ex) C1 09 00 00 00 00 00 00 00 + * - 0x00 : Apply previous vertical mode value for grip zone and reject zone range + */ + regAdd[1] = FTS_FUNCTION_LANDSCAPE_MODE; + regAdd[2] = info->grip_landscape_mode; + + fts_write_reg(info, regAdd, 9); + + /*ex) C1 0A 00 00 00 00 00 00 00 00 00 + * - Disable function + */ + regAdd[1] = FTS_FUNCTION_LANDSCAPE_TOP_BOTTOM; + + fts_write_reg(info, regAdd, 11); + } +} + +/* + * index + * 0 : set edge handler + * 1 : portrait (normal) mode + * 2 : landscape mode + * data + * 0, X (direction), X (y start), X (y end) + * direction : 0 (off), 1 (left), 2 (right) + * ex) echo set_grip_data,0,2,600,900 > cmd + * + * + * 1, X (edge zone), X (dead zone up x), X (dead zone down x), X (dead zone y) + * ex) echo set_grip_data,1,200,10,50,1500 > cmd + * + * 2, 1 (landscape mode), X (edge zone), X (dead zone), X (dead zone top y), X (dead zone bottom y) + * ex) echo set_grip_data,2,1,200,100,120,0 > cmd + * + * 2, 0 (portrait mode) + * ex) echo set_grip_data,2,0 > cmd + */ +static void set_grip_data(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 mode = G_NONE; + + sec_cmd_set_default_result(sec); + + memset(buff, 0, sizeof(buff)); + + mutex_lock(&info->device_mutex); + + if (sec->cmd_param[0] == 0) { // edge handler + if (sec->cmd_param[1] == 0) { // clear + info->grip_edgehandler_direction = 0; + } else if (sec->cmd_param[1] < 3) { + info->grip_edgehandler_direction = sec->cmd_param[1]; + info->grip_edgehandler_start_y = sec->cmd_param[2]; + info->grip_edgehandler_end_y = sec->cmd_param[3]; + } else { + input_err(true, &info->client->dev, "%s: cmd1 is abnormal, %d (%d)\n", + __func__, sec->cmd_param[1], __LINE__); + goto err_grip_data; + } + + mode = mode | G_SET_EDGE_HANDLER; + fts_set_grip_data_to_ic(info, mode); + } else if (sec->cmd_param[0] == 1) { // normal mode + if (info->grip_edge_range != sec->cmd_param[1]) + mode = mode | G_SET_EDGE_ZONE; + + info->grip_edge_range = sec->cmd_param[1]; + info->grip_deadzone_up_x = sec->cmd_param[2]; + info->grip_deadzone_dn_x = sec->cmd_param[3]; + info->grip_deadzone_y = sec->cmd_param[4]; + mode = mode | G_SET_NORMAL_MODE; + + if (info->grip_landscape_mode == 1) { + info->grip_landscape_mode = 0; + mode = mode | G_CLR_LANDSCAPE_MODE; + } + + fts_set_grip_data_to_ic(info, mode); + } else if (sec->cmd_param[0] == 2) { // landscape mode + if (sec->cmd_param[1] == 0) { // normal mode + info->grip_landscape_mode = 0; + mode = mode | G_CLR_LANDSCAPE_MODE; + } else if (sec->cmd_param[1] == 1) { + info->grip_landscape_mode = 1; + info->grip_landscape_edge = sec->cmd_param[2]; + info->grip_landscape_deadzone = sec->cmd_param[3]; + info->grip_landscape_top_deadzone = sec->cmd_param[4]; + info->grip_landscape_bottom_deadzone = sec->cmd_param[5]; + info->grip_landscape_top_gripzone = sec->cmd_param[6]; + info->grip_landscape_bottom_gripzone = sec->cmd_param[7]; + mode = mode | G_SET_LANDSCAPE_MODE; + } else { + input_err(true, &info->client->dev, "%s: cmd1 is abnormal, %d (%d)\n", + __func__, sec->cmd_param[1], __LINE__); + goto err_grip_data; + } + + fts_set_grip_data_to_ic(info, mode); + } else { + input_err(true, &info->client->dev, "%s: cmd0 is abnormal, %d", __func__, sec->cmd_param[0]); + goto err_grip_data; + } + + mutex_unlock(&info->device_mutex); + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + return; + +err_grip_data: + mutex_unlock(&info->device_mutex); + + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); +} + +static void dead_zone_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[3] = {FTS_CMD_SET_FUNCTION_ONOFF, FTS_FUNCTION_ENABLE_DEAD_ZONE, 0x00}; + int ret; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + if (sec->cmd_param[0] == 0) + regAdd[2] = 0x01; /* dead zone disable */ + else + regAdd[2] = 0x00; /* dead zone enable */ + + ret = info->fts_write_reg(info, regAdd, 3); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + else + input_info(true, &info->client->dev, "%s: reg:%d, ret: %d\n", __func__, sec->cmd_param[0], ret); + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void drawing_test_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + snprintf(buff, sizeof(buff), "NA"); + sec->cmd_state = SEC_CMD_STATUS_NOT_APPLICABLE; + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void spay_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0]) + info->lowpower_flag |= FTS_MODE_SPAY; + else + info->lowpower_flag &= ~FTS_MODE_SPAY; + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void aot_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0]) + info->lowpower_flag |= FTS_MODE_DOUBLETAP_WAKEUP; + else + info->lowpower_flag &= ~FTS_MODE_DOUBLETAP_WAKEUP; + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + input_info(true, &info->client->dev, "%s: %d\n", __func__, sec->cmd_param[0]); +} + +static void aod_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0]) + info->lowpower_flag |= FTS_MODE_AOD; + else + info->lowpower_flag &= ~FTS_MODE_AOD; + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + input_info(true, &info->client->dev, "%s: %d\n", __func__, sec->cmd_param[0]); +} + +static void singletap_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0]) + info->lowpower_flag |= FTS_MODE_SINGLETAP; + else + info->lowpower_flag &= ~FTS_MODE_SINGLETAP; + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + input_info(true, &info->client->dev, "%s: %d\n", __func__, sec->cmd_param[0]); +} + +static void set_aod_rect(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 data[8] = {0, }; + int i, ret = -1; + + sec_cmd_set_default_result(sec); + +#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) + input_info(true, &info->client->dev, "%s: w:%d, h:%d, x:%d, y:%d\n", + __func__, sec->cmd_param[0], sec->cmd_param[1], + sec->cmd_param[2], sec->cmd_param[3]); +#endif + + for (i = 0; i < 4; i++) { + data[i * 2] = sec->cmd_param[i] & 0xFF; + data[i * 2 + 1] = (sec->cmd_param[i] >> 8) & 0xFF; + info->rect_data[i] = sec->cmd_param[i]; + } + +#ifdef FTS_SUPPORT_SPONGELIB + if (!info->use_sponge) + goto NG; + + ret = info->fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_AOD_RECT, data, sizeof(data)); +#endif + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + goto NG; + } + + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + if (sec->cmd_param[0] == 0 && sec->cmd_param[1] == 0 && + sec->cmd_param[2] == 0 && sec->cmd_param[3] == 0) { + + input_info(true, &info->client->dev, "%s: sync -> async base scan\n", __func__); + ret = fts_set_hsync_scanmode(info, FTS_CMD_LPM_ASYNC_SCAN); + } else { + + input_info(true, &info->client->dev, "%s: sync base scan\n", __func__); + ret = fts_set_hsync_scanmode(info, FTS_CMD_LPM_SYNC_SCAN); + } + + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: Failed to send command!", __func__); + goto NG; + } + } + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + return; +NG: + + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); +} + +static void get_aod_rect(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 data[8] = {0, }; + u16 rect_data[4] = {0, }; + int i, ret = -1; + + sec_cmd_set_default_result(sec); + +#ifdef FTS_SUPPORT_SPONGELIB + if (!info->use_sponge) + goto NG; + + ret = info->fts_read_from_sponge(info, FTS_CMD_SPONGE_OFFSET_AOD_RECT, data, sizeof(data)); +#endif + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + goto NG; + } + + for (i = 0; i < 4; i++) + rect_data[i] = (data[i * 2 + 1] & 0xFF) << 8 | (data[i * 2] & 0xFF); + +#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) + input_info(true, &info->client->dev, "%s: w:%d, h:%d, x:%d, y:%d\n", + __func__, rect_data[0], rect_data[1], rect_data[2], rect_data[3]); +#endif + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + return; +NG: + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); +} + +static void fod_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + int ret = 0; + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0]) + info->lowpower_flag |= FTS_MODE_PRESS; + else + info->lowpower_flag &= ~FTS_MODE_PRESS; + + info->press_prop = !!sec->cmd_param[1]; + + input_info(true, &info->client->dev, "%s: %s, fast:%d, 0x%02X\n", + __func__, sec->cmd_param[0] ? "on" : "off", + info->press_prop, info->lowpower_flag); + + ret = info->fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_MODE, + &info->lowpower_flag, sizeof(info->lowpower_flag)); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: failed. ret: %d\n", __func__, ret); + snprintf(buff, sizeof(buff), "%s", "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + fts_set_press_property(info); + fts_set_fod_finger_merge(info); + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; +out: + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); +} + +int fts_set_fod_rect(struct fts_ts_info *info) +{ + int i, ret; + u8 data[8]; + u32 sum = 0; + + for (i = 0; i < 4; i++) { + data[i * 2] = info->fod_rect_data[i] & 0xFF; + data[i * 2 + 1] = (info->fod_rect_data[i] >> 8) & 0xFF; + sum += info->fod_rect_data[i]; + } + + if (!sum) /* no data */ + return 0; + + input_info(true, &info->client->dev, "%s: l:%d, t:%d, r:%d, b:%d\n", + __func__, info->fod_rect_data[0], info->fod_rect_data[1], + info->fod_rect_data[2], info->fod_rect_data[3]); + + ret = info->fts_write_to_sponge(info, FTS_CMD_SPONGE_FOD_RECT, data, sizeof(data)); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + + return ret; +} + +static void set_fod_rect(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int i, ret; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] > info->board->max_x + || sec->cmd_param[1] > info->board->max_y + || sec->cmd_param[2] > info->board->max_x + || sec->cmd_param[3] > info->board->max_y) { + input_err(true, &info->client->dev, "%s: Abnormal fod_rect data\n", __func__); + goto NG; + } + + input_info(true, &info->client->dev, "%s: l:%d, t:%d, r:%d, b:%d\n", + __func__, sec->cmd_param[0], sec->cmd_param[1], + sec->cmd_param[2], sec->cmd_param[3]); + + for (i = 0; i < 4; i++) + info->fod_rect_data[i] = sec->cmd_param[i]; + + ret = fts_set_fod_rect(info); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + goto NG; + } + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + return; +NG: + + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); +} + +/* + * Enable or disable external_noise_mode + * + * If mode has EXT_NOISE_MODE_MAX, + * then write enable cmd for all enabled mode. (set as ts->external_noise_mode bit value) + * This routine need after IC power reset. TSP IC need to be re-wrote all enabled modes. + * + * Else if mode has specific value like EXT_NOISE_MODE_MONITOR, + * then write enable/disable cmd about for that mode's latest setting value. + * + * If you want to add new mode, + * please define new enum value like EXT_NOISE_MODE_MONITOR, + * then set cmd for that mode like below. (it is in this function) + * noise_mode_cmd[EXT_NOISE_MODE_MONITOR] = SEC_TS_CMD_SET_MONITOR_NOISE_MODE; + */ +int fts_set_external_noise_mode(struct fts_ts_info *info, u8 mode) +{ + int i, ret, fail_count = 0; + u8 mode_bit_to_set, check_bit, mode_enable; + u8 noise_mode_cmd[EXT_NOISE_MODE_MAX] = { 0 }; + u8 regAdd[3] = {FTS_CMD_SET_FUNCTION_ONOFF, 0x00, 0x00}; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: Touch is stopped!\n", __func__); + return -ENODEV; + } + + if (mode == EXT_NOISE_MODE_MAX) { + /* write all enabled mode */ + mode_bit_to_set = info->external_noise_mode; + } else { + /* make enable or disable the specific mode */ + mode_bit_to_set = 1 << mode; + } + + input_info(true, &info->client->dev, "%s: %sable %d\n", __func__, + info->external_noise_mode & mode_bit_to_set ? "en" : "dis", mode_bit_to_set); + + /* set cmd for each mode */ + noise_mode_cmd[EXT_NOISE_MODE_MONITOR] = FTS_FUNCTION_SET_MONITOR_NOISE_MODE; + + /* write mode */ + for (i = EXT_NOISE_MODE_NONE + 1; i < EXT_NOISE_MODE_MAX; i++) { + check_bit = 1 << i; + if (mode_bit_to_set & check_bit) { + mode_enable = !!(info->external_noise_mode & check_bit); + regAdd[1] = noise_mode_cmd[i]; + regAdd[2] = mode_enable; + + ret = info->fts_write_reg(info, regAdd, 3); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to set %02X %02X %02X\n", + __func__, regAdd[0], regAdd[1], regAdd[2]); + fail_count++; + } + } + } + + if (fail_count != 0) + return -EIO; + else + return 0; +} + +/* + * Enable or disable specific external_noise_mode (sec_cmd) + * + * This cmd has 2 params. + * param 0 : the mode that you want to change. + * param 1 : enable or disable the mode. + * + * For example, + * enable EXT_NOISE_MODE_MONITOR mode, + * write external_noise_mode,1,1 + * disable EXT_NOISE_MODE_MONITOR mode, + * write external_noise_mode,1,0 + */ +static void external_noise_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] <= EXT_NOISE_MODE_NONE || sec->cmd_param[0] >= EXT_NOISE_MODE_MAX || + sec->cmd_param[1] < 0 || sec->cmd_param[1] > 1) { + input_err(true, &info->client->dev, "%s: not support param\n", __func__); + goto NG; + } + + if (sec->cmd_param[1] == 1) + info->external_noise_mode |= 1 << sec->cmd_param[0]; + else + info->external_noise_mode &= ~(1 << sec->cmd_param[0]); + + ret = fts_set_external_noise_mode(info, sec->cmd_param[0]); + if (ret < 0) + goto NG; + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + return; + +NG: + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); +} + +static void brush_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[3] = {FTS_CMD_SET_FUNCTION_ONOFF, FTS_FUNCTION_ENABLE_BRUSH_MODE, 0x00}; + int ret; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + info->brush_mode = sec->cmd_param[0]; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + input_info(true, &info->client->dev, + "%s: set brush mode %s\n", __func__, info->brush_mode ? "enable" : "disable"); + + if (info->brush_mode == 0) + regAdd[2] = 0x00; /* 0: Disable Artcanvas min phi mode */ + else + regAdd[2] = 0x01; /* 1: Enable Artcanvas min phi mode */ + + ret = info->fts_write_reg(info, ®Add[0], 3); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: failed to set brush mode\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + +out: + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void set_touchable_area(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[3] = {FTS_CMD_SET_FUNCTION_ONOFF, FTS_FUNCTION_SET_TOUCHABLE_AREA, 0x00}; + int ret; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + info->touchable_area = sec->cmd_param[0]; + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + input_info(true, &info->client->dev, + "%s: set 16:9 mode %s\n", __func__, info->touchable_area ? "enable" : "disable"); + + if (info->touchable_area == 0) + regAdd[2] = 0x00; /* 0: Disable 16:9 mode */ + else + regAdd[2] = 0x01; /* 1: Enable 16:9 mode */ + + ret = info->fts_write_reg(info, ®Add[0], 3); + if (ret < 0) { + input_err(true, &info->client->dev, + "%s: failed to set 16:9 mode\n", __func__); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + +out: + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void debug(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + info->debug_string = sec->cmd_param[0]; + + input_info(true, &info->client->dev, "%s: command is %d\n", __func__, info->debug_string); + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_force_calibration(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + bool touch_on = false; + + sec_cmd_set_default_result(sec); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: [ERROR] Touch is stopped\n", + __func__); + snprintf(buff, sizeof(buff), "NG"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_FAIL; +#ifdef TCLM_CONCEPT + info->tdata->external_factory = false; +#endif + return; + } + + if (info->rawdata_read_lock == 1) { + input_err(true, &info->client->dev, "%s: ramdump mode is running, %d\n", + __func__, info->rawdata_read_lock); + goto autotune_fail; + } + + if (info->touch_count > 0) { + touch_on = true; + input_err(true, &info->client->dev, "%s: finger on touch(%d)\n", __func__, info->touch_count); + } + + info->fts_systemreset(info, 0); + + fts_release_all_finger(info); + + if (touch_on) { + input_err(true, &info->client->dev, "%s: finger! do not run autotune\n", __func__); + } else { + input_info(true, &info->client->dev, "%s: run autotune\n", __func__); + + input_err(true, &info->client->dev, "%s: RUN OFFSET CALIBRATION\n", __func__); + if (fts_execute_autotune(info, true) < 0) { + fts_set_scanmode(info, info->scan_mode); + goto autotune_fail; + } +#ifdef TCLM_CONCEPT + /* devide tclm case */ + sec_tclm_case(info->tdata, sec->cmd_param[0]); + + input_info(true, &info->client->dev, "%s: param, %d, %c, %d\n", __func__, + sec->cmd_param[0], sec->cmd_param[0], info->tdata->root_of_calibration); + + if (sec_execute_tclm_package(info->tdata, 1) < 0) + input_err(true, &info->client->dev, + "%s: sec_execute_tclm_package\n", __func__); + + sec_tclm_root_of_cal(info->tdata, CALPOSITION_NONE); +#endif + } + + fts_set_scanmode(info, info->scan_mode); + + if (touch_on) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); +#ifdef TCLM_CONCEPT + info->tdata->external_factory = false; +#endif + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); + return; + +autotune_fail: +#ifdef TCLM_CONCEPT + info->tdata->external_factory = false; +#endif + fts_interrupt_set(info, INT_ENABLE); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void fix_active_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + if (info->fts_power_state == FTS_POWER_STATE_ACTIVE) + fts_fix_active_mode(info, !!sec->cmd_param[0]); + info->fix_active_mode = !!sec->cmd_param[0]; + } + + snprintf(buff, sizeof(buff), "OK"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void touch_aging_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + char regAdd[3]; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + info->touch_aging_mode = sec->cmd_param[0]; + + if (info->touch_aging_mode) { + regAdd[0] = 0xA0; + regAdd[1] = 0x03; + regAdd[2] = 0x20; + + info->fts_write_reg(info, ®Add[0], 3); + } else { + fts_reinit(info, false); + } + } + snprintf(buff, sizeof(buff), "OK"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void run_sram_test(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN]; + u8 regAdd; + u8 data[FTS_EVENT_SIZE]; + int rc, retry = 0; + + sec_cmd_set_default_result(sec); + + info->fts_systemreset(info, 0); + + fts_interrupt_set(info, INT_DISABLE); + mutex_lock(&info->wait_for); + + regAdd = FTS_CMD_RUN_SRAM_TEST; + rc = info->fts_write_reg(info, ®Add, 1); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: failed to write cmd\n", __func__); + goto error; + } + + fts_delay(300); + + memset(data, 0x0, FTS_EVENT_SIZE); + rc = -EIO; + regAdd = FTS_READ_ONE_EVENT; + while (info->fts_read_reg(info, ®Add, 1, data, FTS_EVENT_SIZE) > 0) { + if (data[0] != 0x00) + input_info(true, &info->client->dev, + "%s: event %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + + if (data[0] == FTS_EVENT_PASS_REPORT && data[1] == FTS_EVENT_SRAM_TEST_RESULT) { + rc = 0; /* PASS */ + break; + } else if (data[0] == FTS_EVENT_ERROR_REPORT && data[1] == FTS_EVENT_SRAM_TEST_RESULT) { + rc = 1; /* FAIL */ + break; + } + + if (retry++ > FTS_RETRY_COUNT * 25) { + input_err(true, &info->client->dev, + "%s: Time Over (%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X)\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + break; + } + fts_delay(20); + } + +error: + mutex_unlock(&info->wait_for); + + if (rc < 0) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "%d", rc); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + if (sec->cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) + sec_cmd_set_cmd_result_all(sec, buff, strnlen(buff, sizeof(buff)), "SRAM"); + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + + fts_reinit(info, false); + fts_interrupt_set(info, INT_ENABLE); +} + +static void set_rear_selfie_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + info->rear_selfie_mode = sec->cmd_param[0]; + snprintf(buff, sizeof(buff), "OK"); + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void ear_detect_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 data[2]; + int ret; + + sec_cmd_set_default_result(sec); + + if (!info->board->support_ear_detect || sec->cmd_param[0] < 0 || sec->cmd_param[0] > 3) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + info->ed_enable = sec->cmd_param[0]; + snprintf(buff, sizeof(buff), "OK"); + + data[0] = FTS_CMD_SET_EAR_DETECT; + data[1] = info->ed_enable; + + ret = fts_write_reg(info, data, 2); + input_info(true, &info->client->dev, "%s: %s, ret = %d\n", + __func__, info->ed_enable ? "enable" : "disable", ret); + } + + if (info->board->hw_i2c_reset) { + cancel_delayed_work_sync(&info->fw_reset_work); + if (info->ed_enable == 3) { + info->fw_reset_cmd = 0x01; + } else { + info->fw_reset_cmd = 0x00; + } + schedule_work(&info->fw_reset_work.work); + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void pocket_mode_enable(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 data[2]; + int ret; + + sec_cmd_set_default_result(sec); + + if (!info->board->support_ear_detect || sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + info->pocket_mode = sec->cmd_param[0]; + snprintf(buff, sizeof(buff), "OK"); + + data[0] = FTS_CMD_SET_POCKET_MODE; + data[1] = info->pocket_mode; + + ret = fts_write_reg(info, data, 2); + input_info(true, &info->client->dev, "%s: %s, ret = %d\n", + __func__, info->pocket_mode ? "enable" : "disable", ret); + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void set_sip_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + ret = fts_set_sip_mode(info, (u8)sec->cmd_param[0]); + if (ret < 0) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} + +static void set_note_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + u8 regAdd[3]; + int ret; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + input_err(true, &info->client->dev, + "%s: wrong param %d\n", __func__, sec->cmd_param[0]); + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + goto out; + } + + regAdd[0] = FTS_CMD_SET_FUNCTION_ONOFF; + regAdd[1] = FTS_FUNCTION_SET_NOTE_MODE; + regAdd[2] = sec->cmd_param[0] & 0xFF; + + input_info(true, &info->client->dev, "%s: %s\n", + __func__, sec->cmd_param[0] ? "enable" : "disable"); + + ret = fts_write_reg(info, regAdd, 3); + if (ret < 0) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + +out: + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); +} + +static void set_game_mode(void *device_data) +{ + struct sec_cmd_data *sec = (struct sec_cmd_data *)device_data; + struct fts_ts_info *info = container_of(sec, struct fts_ts_info, sec); + char buff[SEC_CMD_STR_LEN] = { 0 }; + int ret; + u8 reg[3] = { 0 }; + + sec_cmd_set_default_result(sec); + + if (sec->cmd_param[0] < 0 || sec->cmd_param[0] > 1) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + reg[0] = FTS_CMD_SET_FUNCTION_ONOFF; + reg[1] = FTS_FUNCTION_SET_GAME_MODE; + reg[2] = sec->cmd_param[0]; + ret = fts_write_reg(info, reg, 3); + if (ret < 0) { + snprintf(buff, sizeof(buff), "NG"); + sec->cmd_state = SEC_CMD_STATUS_FAIL; + } else { + snprintf(buff, sizeof(buff), "OK"); + sec->cmd_state = SEC_CMD_STATUS_OK; + } + } + + sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); + sec->cmd_state = SEC_CMD_STATUS_WAITING; + sec_cmd_set_cmd_exit(sec); + + input_info(true, &info->client->dev, "%s: %s\n", __func__, buff); +} +#endif + diff --git a/drivers/input/touchscreen/stm/fts5cu56a/fts_ts.c b/drivers/input/touchscreen/stm/fts5cu56a/fts_ts.c new file mode 100644 index 000000000..82fcb79cb --- /dev/null +++ b/drivers/input/touchscreen/stm/fts5cu56a/fts_ts.c @@ -0,0 +1,4425 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** + * + * File Name : fts.c + * Authors : AMS(Analog Mems Sensor) Team + * Description : FTS Capacitive touch screen controller (FingerTipS) + * + ******************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE + * PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT. + * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, + * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE + * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING + * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS. + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SEC_SYSFS +#include +#endif +#include "fts_ts.h" + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) +#include +#include +#endif + +#ifdef CONFIG_OF +#ifndef USE_OPEN_CLOSE +#define USE_OPEN_CLOSE +#undef CONFIG_PM +#endif +#endif + +#ifdef USE_OPEN_CLOSE +static int fts_input_open(struct input_dev *dev); +static void fts_input_close(struct input_dev *dev); +#ifdef USE_OPEN_DWORK +static void fts_open_work(struct work_struct *work); +#endif +#endif + +static int fts_stop_device(struct fts_ts_info *info); +static int fts_start_device(struct fts_ts_info *info); + +static void fts_reset(struct fts_ts_info *info, unsigned int ms); +static void fts_reset_work(struct work_struct *work); +static void fts_read_info_work(struct work_struct *work); +static void fts_fw_reset_work(struct work_struct *work); +//static void fts_lfd_ctrl_work(struct work_struct *work); +//static void fts_lfd_ctrl(struct fts_ts_info *info, int touch_count); + +#if defined(CONFIG_TOUCHSCREEN_DUMP_MODE) +#include +static void tsp_dump(void); +static void fts_sponge_dump_flush(struct fts_ts_info *info, int dump_area); +static void dump_tsp_rawdata(struct work_struct *work); +struct delayed_work *p_debug_work; +#endif + +#if (!defined(CONFIG_PM)) && !defined(USE_OPEN_CLOSE) +static int fts_suspend(struct i2c_client *client, pm_message_t mesg); +static int fts_resume(struct i2c_client *client); +#endif +int fts_systemreset(struct fts_ts_info *info, unsigned int msec); + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) +static irqreturn_t fts_filter_interrupt(struct fts_ts_info *info); + +static irqreturn_t fts_interrupt_handler(int irq, void *handle); + +static ssize_t fts_secure_touch_enable_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t fts_secure_touch_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t fts_secure_touch_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static struct device_attribute attrs[] = { + __ATTR(secure_touch_enable, (0664), + fts_secure_touch_enable_show, + fts_secure_touch_enable_store), + __ATTR(secure_touch, (0444), + fts_secure_touch_show, + NULL), +}; + +static ssize_t fts_secure_touch_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d", atomic_read(&info->st_enabled)); +} + +/* + * Accept only "0" and "1" valid values. + * "0" will reset the st_enabled flag, then wake up the reading process. + * The bus driver is notified via pm_runtime that it is not required to stay + * awake anymore. + * It will also make sure the queue of events is emptied in the controller, + * in case a touch happened in between the secure touch being disabled and + * the local ISR being ungated. + * "1" will set the st_enabled flag and clear the st_pending_irqs flag. + * The bus driver is requested via pm_runtime to stay awake. + */ +static ssize_t fts_secure_touch_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + unsigned long value; + int err = 0; + + if (count > 2) { + input_err(true, &info->client->dev, + "%s: cmd length is over (%s,%d)!!\n", + __func__, buf, (int)strlen(buf)); + return -EINVAL; + } + + err = kstrtoul(buf, 10, &value); + if (err != 0) { + input_err(true, &info->client->dev, "%s: failed to read:%d\n", + __func__, err); + return err; + } + + err = count; + + switch (value) { + case 0: + if (atomic_read(&info->st_enabled) == 0) { + input_err(true, &info->client->dev, "%s: already disabled, pending:%d\n", + __func__, atomic_read(&info->st_pending_irqs)); + break; + } + + fts_delay(200); + + pm_runtime_put_sync(info->client->adapter->dev.parent); + + atomic_set(&info->st_enabled, 0); + + sysfs_notify(&info->input_dev->dev.kobj, NULL, "secure_touch"); + + fts_delay(10); + + fts_interrupt_handler(info->client->irq, info); + + complete_all(&info->st_powerdown); + complete(&info->st_interrupt); + + input_info(true, &info->client->dev, "%s: disabled\n", __func__); + + break; + + case 1: + if (info->reset_is_on_going) { + input_err(true, &info->client->dev, "%s: reset is on going becuse i2c fail\n", + __func__); + return -EBUSY; + } + + if (atomic_read(&info->st_enabled)) { + input_err(true, &info->client->dev, "%s: already enabled, pending:%d\n", + __func__, atomic_read(&info->st_pending_irqs)); + err = -EBUSY; + break; + } + + fts_delay(200); + + /* synchronize_irq -> disable_irq + enable_irq + * concern about timing issue. + */ + fts_interrupt_set(info, INT_DISABLE); + + /* Release All Finger */ + fts_release_all_finger(info); + + if (pm_runtime_get_sync(info->client->adapter->dev.parent) < 0) { + input_err(true, &info->client->dev, "%s: pm_runtime_get failed\n", __func__); + err = -EIO; + fts_interrupt_set(info, INT_ENABLE); + break; + } + + reinit_completion(&info->st_powerdown); + reinit_completion(&info->st_interrupt); + atomic_set(&info->st_enabled, 1); + atomic_set(&info->st_pending_irqs, 0); + + fts_interrupt_set(info, INT_ENABLE); + + input_info(true, &info->client->dev, "%s: enabled\n", __func__); + + break; + + default: + input_err(true, &info->client->dev, "%s: unsupported value: %lu\n", __func__, value); + err = -EINVAL; + break; + } +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + if (info->ss_drv) + info->ss_drv->is_running = value; +#endif + return err; +} + +static ssize_t fts_secure_touch_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + int val = 0; + + if (atomic_read(&info->st_enabled) == 0) { + input_err(true, &info->client->dev, "%s: secure_touch is not enabled, st_pending_irqs: %d\n", + __func__, atomic_read(&info->st_pending_irqs)); + return -EBADF; + } + + if (atomic_cmpxchg(&info->st_pending_irqs, -1, 0) == -1) { + input_err(true, &info->client->dev, "%s: st_pending_irqs: %d\n", + __func__, atomic_read(&info->st_pending_irqs)); + return -EINVAL; + } + + if (atomic_cmpxchg(&info->st_pending_irqs, 1, 0) == 1) { + val = 1; + input_info(true, &info->client->dev, "%s: st_pending_irqs: %d, val: %d\n", + __func__, atomic_read(&info->st_pending_irqs), val); + } + + complete(&info->st_interrupt); + + return scnprintf(buf, PAGE_SIZE, "%u", val); +} + +static void fts_secure_touch_init(struct fts_ts_info *info) +{ + init_completion(&info->st_powerdown); + init_completion(&info->st_interrupt); +} + +static void fts_secure_touch_stop(struct fts_ts_info *info, int blocking) +{ + mutex_lock(&info->st_lock); + if (atomic_read(&info->st_enabled)) { + atomic_set(&info->st_pending_irqs, -1); + sysfs_notify(&info->input_dev->dev.kobj, NULL, "secure_touch"); + + if (blocking) + wait_for_completion_interruptible(&info->st_powerdown); + } + mutex_unlock(&info->st_lock); +} + +static irqreturn_t fts_filter_interrupt(struct fts_ts_info *info) +{ + if (atomic_read(&info->st_enabled)) { + if (atomic_cmpxchg(&info->st_pending_irqs, 0, 1) == 0) + sysfs_notify(&info->input_dev->dev.kobj, NULL, "secure_touch"); + else + input_info(true, &info->client->dev, "%s: st_pending_irqs: %d\n", + __func__, atomic_read(&info->st_pending_irqs)); + + return IRQ_HANDLED; + } + return IRQ_NONE; +} +#endif + +int fts_write_reg(struct fts_ts_info *info, + u8 *reg, u16 num_com) +{ + struct i2c_msg xfer_msg[2]; + int ret; + int retry = FTS_TS_I2C_RETRY_CNT; + u8 *buff; + + if (!info->resume_done.done) { + ret = wait_for_completion_interruptible_timeout(&info->resume_done, msecs_to_jiffies(500)); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: resume is not handled:%d\n", __func__, ret); + return -EIO; + } + } + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: Sensor stopped\n", __func__); + goto exit; + } + +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + if (atomic_read(&info->st_enabled)) { + input_err(true, &info->client->dev, + "%s: TSP no accessible from Linux, TUI is enabled!\n", __func__); + return -EIO; + } +#endif + + buff = kzalloc(num_com, GFP_KERNEL); + if (!buff) + return -ENOMEM; + memcpy(buff, reg, num_com); + + mutex_lock(&info->i2c_mutex); + + xfer_msg[0].addr = info->client->addr; + xfer_msg[0].len = num_com; + xfer_msg[0].flags = 0; + xfer_msg[0].buf = buff; + + do { + ret = i2c_transfer(info->client->adapter, xfer_msg, 1); + if (ret < 0) { + info->comm_err_count++; + input_err(true, &info->client->dev, + "%s failed(%d). ret:%d, addr:%x, cnt:%d\n", + __func__, retry, ret, xfer_msg[0].addr, info->comm_err_count); + usleep_range(10 * 1000, 10 * 1000); + } else { + break; + } + } while (--retry > 0); + + mutex_unlock(&info->i2c_mutex); + + if (retry == 0) { + input_err(true, &info->client->dev, "%s: I2C read over retry limit\n", __func__); + ret = -EIO; + + if (info->debug_string & FTS_DEBUG_SEND_UEVENT) + sec_cmd_send_event_to_user(&info->sec, NULL, "RESULT=I2C"); +#ifdef USE_POR_AFTER_I2C_RETRY + if (info->probe_done && !info->reset_is_on_going) + schedule_delayed_work(&info->reset_work, msecs_to_jiffies(10)); +#endif + } + + if (info->debug_string & FTS_DEBUG_PRINT_I2C_WRITE_CMD) { + int i; + + pr_info("sec_input: i2c_cmd: W: "); + for (i = 0; i < num_com; i++) + pr_cont("%02X ", buff[i]); + pr_cont("\n"); + + } + + kfree(buff); + + return ret; + +exit: + return 0; +} + +int fts_read_reg(struct fts_ts_info *info, u8 *reg, int cnum, + u8 *buf, int num) +{ + struct i2c_msg xfer_msg[2]; + int ret; + int retry = FTS_TS_I2C_RETRY_CNT; + u8 *buff; + u8 *msg_buff; + + if (!info->resume_done.done) { + ret = wait_for_completion_interruptible_timeout(&info->resume_done, msecs_to_jiffies(500)); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: resume is not handled:%d\n", __func__, ret); + return -EIO; + } + } + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: Sensor stopped\n", __func__); + goto exit; + } + +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + if (atomic_read(&info->st_enabled)) { + input_err(true, &info->client->dev, + "%s: TSP no accessible from Linux, TUI is enabled!\n", __func__); + return -EIO; + } +#endif + + msg_buff = kzalloc(cnum, GFP_KERNEL); + if (!msg_buff) + return -ENOMEM; + + memcpy(msg_buff, reg, cnum); + + buff = kzalloc(num, GFP_KERNEL); + if (!buff) { + kfree(msg_buff); + return -ENOMEM; + } + + mutex_lock(&info->i2c_mutex); + + xfer_msg[0].addr = info->client->addr; + xfer_msg[0].len = cnum; + xfer_msg[0].flags = 0; + xfer_msg[0].buf = msg_buff; + + xfer_msg[1].addr = info->client->addr; + xfer_msg[1].len = num; + xfer_msg[1].flags = I2C_M_RD; + xfer_msg[1].buf = buff; + + do { + ret = i2c_transfer(info->client->adapter, xfer_msg, 2); + if (ret < 0) { + info->comm_err_count++; + input_err(true, &info->client->dev, + "%s failed(%d). ret:%d, addr:%x, cnt:%d\n", + __func__, retry, ret, xfer_msg[0].addr, info->comm_err_count); + usleep_range(10 * 1000, 10 * 1000); + } else { + break; + } + } while (--retry > 0); + + mutex_unlock(&info->i2c_mutex); + + if (retry == 0) { + input_err(true, &info->client->dev, "%s: I2C read over retry limit\n", __func__); + + if (info->debug_string & FTS_DEBUG_SEND_UEVENT) + sec_cmd_send_event_to_user(&info->sec, NULL, "RESULT=I2C"); +#ifdef USE_POR_AFTER_I2C_RETRY + if (info->probe_done && !info->reset_is_on_going) + schedule_delayed_work(&info->reset_work, msecs_to_jiffies(10)); +#endif + } + + if (info->debug_string & FTS_DEBUG_PRINT_I2C_READ_CMD) { + int i; + + pr_info("sec_input: i2c_cmd: R: "); + for (i = 0; i < cnum; i++) + pr_cont("%02X ", msg_buff[i]); + pr_cont("|"); + for (i = 0; i < num; i++) + pr_cont("%02X ", buff[i]); + pr_cont("\n"); + + } + + memcpy(buf, buff, num); + kfree(msg_buff); + kfree(buff); + + return ret; + +exit: + return 0; +} + +#ifdef FTS_SUPPORT_SPONGELIB +#ifdef CONFIG_SEC_FACTORY +static void fts_disable_sponge(struct fts_ts_info *info) +{ + u8 regAdd[3] = {FTS_CMD_SET_FUNCTION_ONOFF, FTS_FUNCTION_ENABLE_SPONGE_LIB, 0x00}; + int ret = 0; + + ret = fts_write_reg(info, ®Add[0], 3); + input_info(true, &info->client->dev, "%s: Sponge Library Disabled, ret = %d\n", __func__, ret); +} +#endif + +static int fts_read_from_sponge(struct fts_ts_info *info, + u16 offset, u8 *data, int length) +{ + u8 sponge_reg[3]; + u8 *buf; + int rtn; + +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + if (atomic_read(&info->st_enabled)) { + input_err(true, &info->client->dev, + "%s: TSP no accessible from Linux, TUI is enabled!\n", __func__); + return -EIO; + } +#endif + + offset += FTS_CMD_SPONGE_ACCESS; + sponge_reg[0] = 0xAA; + sponge_reg[1] = (offset >> 8) & 0xFF; + sponge_reg[2] = offset & 0xFF; + + buf = kzalloc(length, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + rtn = fts_read_reg(info, sponge_reg, 3, buf, length); + if (rtn >= 0) + memcpy(data, &buf[0], length); + else + input_err(true, &info->client->dev, "%s: failed\n", __func__); + + kfree(buf); + return rtn; +} + +/* + * int fts_write_to_sponge(struct fts_ts_info *, u16 *, u8 *, int) + * send command or write specific value to the sponge area. + * sponge area means guest image or display lab firmware.. etc.. + */ +static int fts_write_to_sponge(struct fts_ts_info *info, + u16 offset, u8 *data, int length) +{ + u8 *regAdd; + int ret = 0; + + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: Sensor stopped\n", __func__); + return 0; + } + +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + if (atomic_read(&info->st_enabled)) { + input_err(true, &info->client->dev, + "%s: TSP no accessible from Linux, TUI is enabled!\n", __func__); + return -EIO; + } +#endif + regAdd = kzalloc(3 + length, GFP_KERNEL); + + offset += FTS_CMD_SPONGE_ACCESS; + regAdd[0] = FTS_CMD_SPONGE_READ_WRITE_CMD; + regAdd[1] = (offset >> 8) & 0xFF; + regAdd[2] = offset & 0xFF; + + memcpy(®Add[3], &data[0], length); + + ret = fts_write_reg(info, ®Add[0], 3 + length); + if (ret <= 0) { + input_err(true, &info->client->dev, + "%s: sponge command is failed. ret: %d\n", __func__, ret); + } + + // Notify Command + regAdd[0] = FTS_CMD_SPONGE_NOTIFY_CMD; + regAdd[1] = (offset >> 8) & 0xFF; + regAdd[2] = offset & 0xFF; + + ret = fts_write_reg(info, ®Add[0], 3); + if (ret <= 0) { + input_err(true, &info->client->dev, + "%s: sponge notify is failed.\n", __func__); + kfree(regAdd); + return ret; + } + + input_info(true, &info->client->dev, + "%s: sponge notify is OK[0x%02X].\n", __func__, *data); + kfree(regAdd); + + return ret; +} + +int fts_check_custom_library(struct fts_ts_info *info) +{ + struct fts_sponge_information *sponge_info; + + u8 regAdd[3] = { 0xA4, 0x06, 0x91 }; + u8 data[sizeof(struct fts_sponge_information)] = { 0 }; + int ret = -1; + + fts_interrupt_set(info, INT_DISABLE); + + ret = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + if (ret < 0) + goto out; + + fts_interrupt_set(info, INT_ENABLE); + + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = 0x00; + ret = fts_read_reg(info, ®Add[0], 3, &data[0], sizeof(struct fts_sponge_information)); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + goto out; + } + + sponge_info = (struct fts_sponge_information *) &data[0]; + + input_info(true, &info->client->dev, + "%s: (%d) model name %s\n", + __func__, ret, sponge_info->sponge_model_name); + info->use_sponge = true; + + if (info->use_sponge) { + ret = fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_MODE, + &info->lowpower_flag, sizeof(info->lowpower_flag)); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to write lowpower flag. ret: %d\n", __func__, ret); + goto out; + } + + memset(regAdd, 0x00, 3); + ret = fts_read_from_sponge(info, FTS_CMD_SPONGE_FOD_INFO, regAdd, 3); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed to read FOD INFO. ret: %d\n", __func__, ret); + goto out; + } + info->fod_x = regAdd[0]; + info->fod_y = regAdd[1]; + info->fod_vi_size = regAdd[2]; + input_info(true, &info->client->dev, "%s: fod_x:%d, fod_y:%d, fod_vi_size:%d\n", + __func__, info->fod_x, info->fod_y, info->fod_vi_size); + + /* read dump info */ + ret = fts_read_from_sponge(info, FTS_CMD_SPONGE_LP_DUMP, regAdd, 2); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Failed to read dump_data. ret: %d\n", __func__, ret); + goto out; + } + if (!info->fod_vi_data) { + info->fod_vi_data = devm_kzalloc(&info->client->dev, info->fod_vi_size, GFP_KERNEL); + if (!info->fod_vi_data) + return -ENOMEM; + } + + info->sponge_inf_dump = (regAdd[0] & FTS_SPONGE_DUMP_INF_MASK) >> FTS_SPONGE_DUMP_INF_SHIFT; + info->sponge_dump_format = regAdd[0] & FTS_SPONGE_DUMP_EVENT_MASK; + info->sponge_dump_event = regAdd[1]; + info->sponge_dump_border = FTS_CMD_SPONGE_LP_DUMP_EVENT + + (info->sponge_dump_format * info->sponge_dump_event); + info->sponge_dump_border_lsb = info->sponge_dump_border & 0xFF; + info->sponge_dump_border_msb = (info->sponge_dump_border & 0xFF00) >> 8; + + input_info(true, &info->client->dev, "%s sponge_dump format %x event %x\n", + __func__, info->sponge_dump_format, info->sponge_dump_event); + } + +out: + input_err(true, &info->client->dev, "%s: use %s\n", + __func__, info->use_sponge ? "SPONGE" : "VENDOR"); + + return ret; +} + +int fts_set_press_property(struct fts_ts_info *info) +{ + int ret = 0; + + if (!info->board->support_fod) + return 0; + + ret = info->fts_write_to_sponge(info, FTS_CMD_SPONGE_PRESS_PROPERTY, + &info->press_prop, sizeof(info->press_prop)); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + + input_info(true, &info->client->dev, "%s: %d\n", __func__, info->press_prop); + + return ret; +} +#endif + +void fts_delay(unsigned int ms) +{ + if (ms < 20) + usleep_range(ms * 1000, ms * 1000); + else + msleep(ms); +} + +void fts_command(struct fts_ts_info *info, u8 cmd, bool checkEcho) +{ + u8 regAdd = 0; + int ret = 0; + + fts_interrupt_set(info, INT_DISABLE); + + regAdd = cmd; + + if (checkEcho) + ret = fts_fw_wait_for_echo_event(info, ®Add, 1, 0); + else + ret = fts_write_reg(info, ®Add, 1); + if (ret < 0) + input_err(true, &info->client->dev, + "%s: failed to write command(0x%02X), ret = %d\n", __func__, cmd, ret); + + fts_interrupt_set(info, INT_ENABLE); +} + +int fts_set_scanmode(struct fts_ts_info *info, u8 scan_mode) +{ + u8 regAdd[3] = { 0xA0, 0x00, scan_mode }; + int rc; + + fts_interrupt_set(info, INT_DISABLE); + + rc = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + if (rc < 0) { + input_info(true, &info->client->dev, "%s: timeout, ret = %d\n", __func__, rc); + fts_interrupt_set(info, INT_ENABLE); + return rc; + } + + fts_interrupt_set(info, INT_ENABLE); + input_info(true, &info->client->dev, "%s: 0x%02X\n", __func__, scan_mode); + + return 0; +} + +int fts_set_opmode(struct fts_ts_info *info, u8 mode) +{ + int ret; + u8 regAdd[2] = {FTS_CMD_SET_GET_OPMODE, mode}; + + ret = fts_write_reg(info, ®Add[0], 2); + if (ret <= 0) + input_err(true, &info->client->dev, "%s: Failed to write opmode", __func__); + + fts_delay(5); + + if (info->lowpower_flag) { + regAdd[0] = FTS_CMD_WRITE_WAKEUP_GESTURE; + regAdd[1] = 0x02; + ret = fts_write_reg(info, ®Add[0], 2); + if (ret <= 0) + input_err(true, &info->client->dev, "%s: Failed to send lowpower flag command", __func__); + } + + return ret; +} + +void fts_set_fod_finger_merge(struct fts_ts_info *info) +{ + int ret; + u8 regAdd[2] = {FTS_CMD_SET_FOD_FINGER_MERGE, 0}; + + if (!info->board->support_fod) + return; + + if (info->lowpower_flag & FTS_MODE_PRESS) + regAdd[1] = 1; + else + regAdd[1] = 0; + + mutex_lock(&info->sponge_mutex); + input_info(true, &info->client->dev, "%s: %d\n", __func__, regAdd[1]); + + ret = fts_write_reg(info, regAdd, 2); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed\n", __func__); + mutex_unlock(&info->sponge_mutex); +} + +static void fts_set_cover_type(struct fts_ts_info *info, bool enable) +{ + int ret; + u8 regAdd[3] = {0}; + + input_info(true, &info->client->dev, "%s: %d\n", __func__, info->cover_type); + + switch (info->cover_type) { + case FTS_VIEW_WIRELESS: + case FTS_VIEW_COVER: + case FTS_VIEW_WALLET: + case FTS_FLIP_WALLET: + case FTS_LED_COVER: + case FTS_MONTBLANC_COVER: + case FTS_CLEAR_FLIP_COVER: + case FTS_QWERTY_KEYBOARD_EUR: + case FTS_QWERTY_KEYBOARD_KOR: + case FTS_CLEAR_SIDE_VIEW_COVER: + case FTS_MINI_SVIEW_WALLET_COVER: + info->cover_cmd = (u8)info->cover_type; + break; + case FTS_CHARGER_COVER: + case FTS_COVER_NOTHING1: + case FTS_COVER_NOTHING2: + default: + info->cover_cmd = 0; + input_err(true, &info->client->dev, "%s: not change touch state, %d\n", + __func__, info->cover_type); + break; + } + + if (enable) { + regAdd[0] = FTS_CMD_SET_GET_COVERTYPE; + regAdd[1] = info->cover_cmd; + ret = fts_write_reg(info, ®Add[0], 2); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Failed to send covertype command: %d", + __func__, info->cover_cmd); + } + + info->touch_functions = info->touch_functions | FTS_TOUCHTYPE_BIT_COVER | + FTS_TOUCHTYPE_DEFAULT_ENABLE; + + } else { + info->touch_functions = (info->touch_functions & (~FTS_TOUCHTYPE_BIT_COVER)) | + FTS_TOUCHTYPE_DEFAULT_ENABLE; + } + + regAdd[0] = FTS_CMD_SET_GET_TOUCHTYPE; + regAdd[1] = (u8)(info->touch_functions & 0xFF); + regAdd[2] = (u8)(info->touch_functions >> 8); + ret = fts_write_reg(info, ®Add[0], 3); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Failed to send touch type command: 0x%02X%02X", + __func__, regAdd[1], regAdd[2]); + } +} + +void fts_set_grip_type(struct fts_ts_info *info, u8 set_type) +{ + u8 mode = G_NONE; + + input_info(true, &info->client->dev, "%s: re-init grip(%d), edh:%d, edg:%d, lan:%d\n", __func__, + set_type, info->grip_edgehandler_direction, info->grip_edge_range, info->grip_landscape_mode); + + /* edge handler */ + if (info->grip_edgehandler_direction != 0) + mode |= G_SET_EDGE_HANDLER; + + if (set_type == GRIP_ALL_DATA) { + /* edge */ + mode |= G_SET_EDGE_ZONE; + + /* dead zone */ + if (info->grip_landscape_mode == 1) /* default 0 mode, 32 */ + mode |= G_SET_LANDSCAPE_MODE; + else + mode |= G_SET_NORMAL_MODE; + } + + if (mode) + fts_set_grip_data_to_ic(info, mode); + +} + +static void fts_wirelesscharger_mode(struct fts_ts_info *info) +{ + u8 regAdd[2] = {FTS_CMD_SET_GET_CHARGER_MODE, (u8)info->charger_mode}; + int ret; + + input_info(true, &info->client->dev, "%s: Set charger mode CMD[%2X]\n", __func__, regAdd[1]); + ret = fts_write_reg(info, regAdd, 2); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); +} + +static int fts_set_sip_mode(struct fts_ts_info *info, u8 enable) +{ + u8 regAdd[3]; + int ret; + + regAdd[0] = FTS_CMD_SET_FUNCTION_ONOFF; + regAdd[1] = FTS_FUNCTION_ENABLE_SIP_MODE; + if (enable) + regAdd[2] = 0x01; + else + regAdd[2] = 0x00; + + info->sip_mode = enable; + input_info(true, &info->client->dev, "%s: %s\n", __func__, enable ? "enable" : "disable"); + ret = fts_write_reg(info, regAdd, 3); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + + return ret; +} + +void fts_change_scan_rate(struct fts_ts_info *info, u8 rate) +{ + u8 regAdd[2] = {FTS_CMD_SET_GET_REPORT_RATE, rate}; + int ret = 0; + + ret = fts_write_reg(info, ®Add[0], 2); + + input_dbg(true, &info->client->dev, "%s: scan rate (%d Hz), ret = %d\n", __func__, regAdd[1], ret); +} + +void fts_interrupt_set(struct fts_ts_info *info, int enable) +{ + struct irq_desc *desc = irq_to_desc(info->irq); + + mutex_lock(&info->irq_mutex); + + if (enable) { + while (desc->depth > 0) + enable_irq(info->irq); + } else { + disable_irq(info->irq); + } + + input_info(true, &info->client->dev, "%s: %s\n", __func__, enable ? "Enable" : "Disable"); + mutex_unlock(&info->irq_mutex); +} + +void fts_ic_interrupt_set(struct fts_ts_info *info, int enable) +{ + u8 regAdd[3] = { 0xA4, 0x01, 0x00 }; + + if (enable) + regAdd[2] = 0x01; + else + regAdd[2] = 0x00; + + fts_write_reg(info, ®Add[0], 3); + fts_delay(10); +} + +static int fts_read_chip_id(struct fts_ts_info *info) +{ + u8 regAdd = FTS_READ_DEVICE_ID; + u8 val[5] = {0}; + int ret; + + ret = fts_read_reg(info, ®Add, 1, &val[0], 5); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + return ret; + } + + input_info(true, &info->client->dev, "%s: %c %c %02X %02X %02X\n", + __func__, val[0], val[1], val[2], val[3], val[4]); + + if ((val[2] != FTS_ID0) && (val[3] != FTS_ID1)) + return -FTS_ERROR_INVALID_CHIP_ID; + + return ret; +} + +static int fts_read_chip_id_hw(struct fts_ts_info *info) +{ + u8 regAdd[5] = { 0xFA, 0x20, 0x00, 0x00, 0x00 }; + u8 val[8] = {0}; + int ret; + + ret = fts_read_reg(info, regAdd, 5, &val[0], 8); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", __func__, ret); + return ret; + } + + input_info(true, &info->client->dev, "%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", + __func__, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]); + + if ((val[0] == FTS_ID1) && (val[1] == FTS_ID0)) + return FTS_NOT_ERROR; + + return -FTS_ERROR_INVALID_CHIP_ID; +} + +int fts_osc_trim_recovery(struct fts_ts_info *info) +{ + u8 regAdd[3]; + int rc; + + input_info(true, &info->client->dev, "%s\n", __func__); + + fts_interrupt_set(info, INT_DISABLE); + + /* OSC trim error recovery command. */ + regAdd[0] = 0xA4; + regAdd[1] = 0x00; + regAdd[2] = 0x05; + + rc = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 800); + if (rc < 0) { + rc = -FTS_ERROR_BROKEN_OSC_TRIM; + goto out; + } + + /* save panel configuration area */ + regAdd[0] = 0xA4; + regAdd[1] = 0x05; + regAdd[2] = 0x04; + + rc = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 100); + if (rc < 0) { + rc = -FTS_ERROR_BROKEN_OSC_TRIM; + goto out; + } + + fts_delay(500); + rc = fts_systemreset(info, 0); + fts_delay(50); + +out: + fts_interrupt_set(info, INT_ENABLE); + + return rc; +} + +static int fts_wait_for_ready(struct fts_ts_info *info) +{ + struct fts_event_status *p_event_status; + int rc; + u8 regAdd[3]; + u8 data[FTS_EVENT_SIZE]; + int retry = 0; + int err_cnt = 0; + + mutex_lock(&info->wait_for); + + fts_interrupt_set(info, INT_DISABLE); + + memset(data, 0x0, FTS_EVENT_SIZE); + + regAdd[0] = FTS_READ_ONE_EVENT; + rc = -1; + while (fts_read_reg(info, ®Add[0], 1, (u8 *)data, FTS_EVENT_SIZE) > 0) { + p_event_status = (struct fts_event_status *) &data[0]; + + if ((p_event_status->stype == FTS_EVENT_STATUSTYPE_INFORMATION) && + (p_event_status->status_id == FTS_INFO_READY_STATUS)) { + rc = 0; + break; + } + + if (data[0] == FTS_EVENT_ERROR_REPORT) { + input_err(true, &info->client->dev, + "%s: Err detected %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + + // check if config / cx / panel configuration area is corrupted + if (((data[1] >= 0x20) && (data[1] <= 0x23)) || ((data[1] >= 0xA0) && (data[1] <= 0xA8))) { + rc = -FTS_ERROR_FW_CORRUPTION; + info->checksum_result = 1; + info->fw_corruption = true; + input_err(true, &info->client->dev, "%s: flash corruption\n", __func__); + break; + } + + /* + * F3 24 / 25 / 29 / 2A / 2D / 34: the flash about OSC TRIM value is broken. + */ + if (data[1] == 0x24 || data[1] == 0x25 || data[1] == 0x29 || data[1] == 0x2A || data[1] == 0x2D || data[1] == 0x34) { + input_err(true, &info->client->dev, "%s: osc trim is broken\n", __func__); + rc = -FTS_ERROR_BROKEN_OSC_TRIM; + info->fw_corruption = true; + break; + } + + if (err_cnt++ > 32) { + rc = -FTS_ERROR_EVENT_ID; + break; + } + continue; + } + + if (retry++ > FTS_RETRY_COUNT) { + rc = -FTS_ERROR_TIMEOUT; + if (data[0] == 0 && data[1] == 0 && data[2] == 0) + rc = -FTS_ERROR_TIMEOUT_ZERO; + + input_err(true, &info->client->dev, "%s: Time Over\n", __func__); + + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER) + schedule_delayed_work(&info->reset_work, msecs_to_jiffies(10)); + break; + } + fts_delay(20); + } + + input_info(true, &info->client->dev, + "%s: %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\n", + __func__, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + + fts_interrupt_set(info, INT_ENABLE); + + mutex_unlock(&info->wait_for); + + return rc; +} + +int fts_systemreset(struct fts_ts_info *info, unsigned int msec) +{ + u8 regAdd[6] = { 0xFA, 0x20, 0x00, 0x00, 0x24, 0x81 }; + int rc; + + input_info(true, &info->client->dev, "%s\n", __func__); + + fts_interrupt_set(info, INT_DISABLE); + + fts_write_reg(info, ®Add[0], 6); + + fts_delay(msec + 10); + + rc = fts_wait_for_ready(info); + + fts_release_all_finger(info); + + fts_interrupt_set(info, INT_ENABLE); + + return rc; +} + +int fts_fw_corruption_check(struct fts_ts_info *info) +{ + u8 regAdd[6] = { 0xFA, 0x20, 0x00, 0x00, 0x24, 0x81 }; + u8 val = 0; + int rc; + + fts_interrupt_set(info, INT_DISABLE); + + /* fts_systemreset */ + rc = fts_write_reg(info, ®Add[0], 6); + if (rc < 0) { + rc = -FTS_I2C_ERROR; + goto out; + } + fts_delay(10); + + /* Firmware Corruption Check */ + regAdd[0] = 0xFA; + regAdd[1] = 0x20; + regAdd[2] = 0x00; + regAdd[3] = 0x00; + regAdd[4] = 0x78; + rc = fts_read_reg(info, regAdd, 5, &val, 1); + if (rc < 0) { + rc = -FTS_I2C_ERROR; + goto out; + } + if (val & 0x03) { // Check if crc error + input_err(true, &info->client->dev, "%s: firmware corruption. CRC status:%02X\n", + __func__, val & 0x03); + rc = -FTS_ERROR_FW_CORRUPTION; + } else { + rc = 0; + } + +out: + fts_interrupt_set(info, INT_ENABLE); + + return rc; +} + +int fts_get_sysinfo_data(struct fts_ts_info *info, u8 sysinfo_addr, u8 read_cnt, u8 *data) +{ + int ret; + int rc = 0; + u8 *buff = NULL; + + u8 regAdd[3] = { 0xA4, 0x06, 0x01 }; // request system information + + fts_interrupt_set(info, INT_DISABLE); + ret = fts_fw_wait_for_echo_event(info, ®Add[0], 3, 0); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: timeout wait for event\n", __func__); + rc = -1; + goto ERROR; + } + + regAdd[0] = 0xA6; + regAdd[1] = 0x00; + regAdd[2] = sysinfo_addr; + + buff = kzalloc(read_cnt, GFP_KERNEL); + if (!buff) { + rc = -2; + goto ERROR; + } + + ret = fts_read_reg(info, ®Add[0], 3, &buff[0], read_cnt); + if (ret <= 0) { + input_err(true, &info->client->dev, "%s: failed. ret: %d\n", + __func__, ret); + kfree(buff); + rc = -3; + goto ERROR; + } + + memcpy(data, &buff[0], read_cnt); + kfree(buff); + +ERROR: + fts_interrupt_set(info, INT_ENABLE); + return rc; +} + +int fts_get_version_info(struct fts_ts_info *info) +{ + int rc; + u8 regAdd = FTS_READ_FW_VERSION; + u8 data[FTS_VERSION_SIZE] = { 0 }; + + memset(data, 0x0, FTS_VERSION_SIZE); + + rc = fts_read_reg(info, ®Add, 1, (u8 *)data, FTS_VERSION_SIZE); + + info->fw_version_of_ic = (data[0] << 8) + data[1]; + info->config_version_of_ic = (data[2] << 8) + data[3]; + info->fw_main_version_of_ic = data[4] + (data[5] << 8); + info->project_id_of_ic = data[6]; + info->ic_name_of_ic = data[7]; + info->module_version_of_ic = data[8]; + + input_info(true, &info->client->dev, + "%s: [IC] Firmware Ver: 0x%04X, Config Ver: 0x%04X, Main Ver: 0x%04X\n", + __func__, info->fw_version_of_ic, + info->config_version_of_ic, info->fw_main_version_of_ic); + input_info(true, &info->client->dev, + "%s: [IC] Project ID: 0x%02X, IC Name: 0x%02X, Module Ver: 0x%02X\n", + __func__, info->project_id_of_ic, + info->ic_name_of_ic, info->module_version_of_ic); + + return rc; +} + +int fts_fix_active_mode(struct fts_ts_info *info, bool enable) +{ + u8 regAdd[3] = {0xA0, 0x00, 0x00}; + int ret; + + if (enable) { + regAdd[1] = 0x03; + regAdd[2] = 0x00; + } else { + regAdd[1] = 0x00; + regAdd[2] = 0x01; + } + + ret = fts_write_reg(info, ®Add[0], 3); + if (ret < 0) + input_info(true, &info->client->dev, "%s: err: %d\n", __func__, ret); + else + input_info(true, &info->client->dev, "%s: %s\n", __func__, + enable ? "fix" : "release"); + + fts_delay(10); + + return ret; +} + +/* Added for samsung dependent codes such as Factory test, + * Touch booster, Related debug sysfs. + */ +#include "fts_sec.c" + +struct fts_ts_info *g_fts_info; + +static ssize_t fts_tsp_cmoffset_all_read(struct file *file, char __user *buf, + size_t len, loff_t *offset) +{ + struct fts_ts_info *info; + static ssize_t retlen; + ssize_t retlen_sdc = 0, retlen_sub = 0, retlen_main = 0; + ssize_t count; + loff_t pos = *offset; +#ifdef CONFIG_SEC_FACTORY + int ret; +#endif + + if (!g_fts_info) { + pr_err("%s %s: dev is null\n", SECLOG, __func__); + return 0; + } + info = g_fts_info; + + + if (pos == 0) { +#ifdef CONFIG_SEC_FACTORY + ret = fts_get_cmoffset_dump(info, info->cmoffset_sdc_proc, OFFSET_FW_SDC); + if (ret < 0) + input_err(true, &info->client->dev, + "%s: SDC fail use boot time value\n", __func__); + ret = fts_get_cmoffset_dump(info, info->cmoffset_sub_proc, OFFSET_FW_SUB); + if (ret < 0) + input_err(true, &info->client->dev, + "%s: SUB fail use boot time value\n", __func__); + ret = fts_get_cmoffset_dump(info, info->cmoffset_main_proc, OFFSET_FW_MAIN); + if (ret < 0) + input_err(true, &info->client->dev, + "%s: MAIN fail use boot time value\n", __func__); +#endif + retlen_sdc = strlen(info->cmoffset_sdc_proc); + retlen_sub = strlen(info->cmoffset_sub_proc); + retlen_main = strlen(info->cmoffset_main_proc); + + info->cmoffset_all_proc = kzalloc(info->proc_cmoffset_all_size, GFP_KERNEL); + if (!info->cmoffset_all_proc) { + input_err(true, &info->client->dev, "%s: kzalloc fail (cmoffset_all_proc)\n", __func__); + return 0; + } + + strlcat(info->cmoffset_all_proc, info->cmoffset_sdc_proc, info->proc_cmoffset_all_size); + strlcat(info->cmoffset_all_proc, info->cmoffset_sub_proc, info->proc_cmoffset_all_size); + strlcat(info->cmoffset_all_proc, info->cmoffset_main_proc, info->proc_cmoffset_all_size); + + retlen = strlen(info->cmoffset_all_proc); + + input_info(true, &info->client->dev, "%s: retlen[%ld], retlen_sdc[%ld], retlen_sub[%ld], retlen_main[%ld]\n", + __func__, retlen, retlen_sdc, retlen_sub, retlen_main); + } + + if (pos >= retlen) + return 0; + + count = min(len, (size_t)(retlen - pos)); + + input_info(true, &info->client->dev, "%s: total:%ld count:%ld\n", __func__, retlen, count); + + if (copy_to_user(buf, info->cmoffset_all_proc + pos, count)) { + input_err(true, &info->client->dev, "%s: copy_to_user error!\n", __func__); + return -EFAULT; + } + + *offset += count; + + if (count < len) { + input_info(true, &info->client->dev, "%s: print all & free cmoffset_all_proc\n", __func__); + if (info->cmoffset_all_proc) + kfree(info->cmoffset_all_proc); + retlen = 0; + } + + return count; +} + +static ssize_t fts_tsp_cmoffset_read(struct file *file, char __user *buf, + size_t len, loff_t *offset) +{ + pr_info("[sec_input] %s called offset:%d\n", __func__, (int)*offset); + return fts_tsp_cmoffset_all_read(file, buf, len, offset); +} + +static const struct file_operations tsp_cmoffset_all_file_ops = { + .owner = THIS_MODULE, + .read = fts_tsp_cmoffset_read, + .llseek = generic_file_llseek, +}; + +static void fts_init_proc(struct fts_ts_info *info) +{ + struct proc_dir_entry *entry_cmoffset_all; + + info->proc_cmoffset_size = (info->SenseChannelLength * info->ForceChannelLength * 4 + 100) * 2; + info->proc_cmoffset_all_size = info->proc_cmoffset_size * 3; /* sdc sub main */ + + info->cmoffset_sdc_proc = kzalloc(info->proc_cmoffset_size, GFP_KERNEL); + if (!info->cmoffset_sdc_proc) + return; + + info->cmoffset_sub_proc = kzalloc(info->proc_cmoffset_size, GFP_KERNEL); + if (!info->cmoffset_sub_proc) + goto err_alloc_sub; + + info->cmoffset_main_proc = kzalloc(info->proc_cmoffset_size, GFP_KERNEL); + if (!info->cmoffset_main_proc) + goto err_alloc_main; + + entry_cmoffset_all = proc_create("tsp_cmoffset_all", S_IFREG | S_IRUGO, NULL, &tsp_cmoffset_all_file_ops); + if (!entry_cmoffset_all) { + input_err(true, &info->client->dev, "%s: failed to create /proc/tsp_cmoffset_all\n", __func__); + goto err_cmoffset_proc_create; + } + proc_set_size(entry_cmoffset_all, info->proc_cmoffset_all_size); + + g_fts_info = info; + input_info(true, &info->client->dev, "%s: done\n", __func__); + return; + +err_cmoffset_proc_create: + kfree(info->cmoffset_main_proc); +err_alloc_main: + kfree(info->cmoffset_sub_proc); +err_alloc_sub: + kfree(info->cmoffset_sdc_proc); + + info->cmoffset_sdc_proc = NULL; + info->cmoffset_sub_proc = NULL; + info->cmoffset_main_proc = NULL; + + input_err(true, &info->client->dev, "%s: failed\n", __func__); +} + +static int fts_init(struct fts_ts_info *info) +{ + u8 retry = 3; + u8 regAdd[8] = { 0 }; + int rc; + u8 data[FTS_EVENT_SIZE] = { 0 }; + + rc = fts_read_reg(info, ®Add[0], 1, (u8 *)data, FTS_EVENT_SIZE); + if (rc == -ENOTCONN) { + return rc; + } + + do { + rc = fts_fw_corruption_check(info); + if (rc == -FTS_ERROR_FW_CORRUPTION) { + info->checksum_result = 1; + break; + } else if (rc < 0) { + goto reset; + } + + rc = fts_wait_for_ready(info); +reset: + if (rc < 0) { + if (rc == -FTS_ERROR_BROKEN_OSC_TRIM) { + break; + } else if (info->checksum_result) { + break; + } else if (rc == -FTS_ERROR_TIMEOUT_ZERO) { + rc = fts_read_chip_id_hw(info); + if (rc == FTS_NOT_ERROR) { + info->checksum_result = 1; + input_err(true, &info->client->dev, "%s: config corruption\n", __func__); + break; + } + } + fts_reset(info, 20); + } else { + break; + } + } while (--retry); + + fts_get_version_info(info); + + if (rc == -FTS_ERROR_BROKEN_OSC_TRIM) { + rc = fts_osc_trim_recovery(info); + if (rc < 0) + input_err(true, &info->client->dev, "%s: Failed to recover osc trim\n", __func__); + } + + if (0/*!info->checksum_result && rc < 0*/) { + input_err(true, &info->client->dev, "%s: Failed to system reset\n", __func__); + return FTS_ERROR_TIMEOUT; + } + + if (info->checksum_result) { + info->fw_version_of_ic = 0; + info->config_version_of_ic = 0; + info->fw_main_version_of_ic = 0; + } + + input_err(true, &info->client->dev, "%s: read chip : hw\n", __func__); + + rc = fts_read_chip_id_hw(info); + + input_err(true, &info->client->dev, "%s: read chip : sw\n", __func__); + rc = fts_read_chip_id(info); + if (rc < 0) { + fts_reset(info, 500); /* Delay to discharge the IC from ESD or On-state.*/ + + input_err(true, &info->client->dev, "%s: Reset caused by chip id error\n", __func__); + + rc = fts_read_chip_id(info); + //if (rc < 0) + // return 1; + } + + + rc = fts_fw_update_on_probe(info); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: Failed to firmware update\n", + __func__); + return FTS_ERROR_FW_UPDATE_FAIL; + } +#ifdef SEC_TSP_FACTORY_TEST + rc = fts_get_channel_info(info); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: read failed rc = %d\n", __func__, rc); + return 1; + } + + info->pFrame = kzalloc(info->SenseChannelLength * info->ForceChannelLength * 2 + 1, GFP_KERNEL); + if (!info->pFrame) + return 1; + + info->cx_data = kzalloc(info->SenseChannelLength * info->ForceChannelLength + 1, GFP_KERNEL); + if (!info->cx_data) { + kfree(info->pFrame); + return 1; + } + + info->ito_result = kzalloc(FTS_ITO_RESULT_PRINT_SIZE, GFP_KERNEL); + if (!info->ito_result) { + kfree(info->cx_data); + kfree(info->pFrame); + return 1; + } + +#if defined(FTS_SUPPORT_SPONGELIB) && defined(CONFIG_SEC_FACTORY) + if (info->use_sponge) + fts_disable_sponge(info); +#endif +#endif + + /* fts driver set functional feature */ + info->touch_count = 0; + + info->flip_enable = false; + info->mainscr_disable = false; + + info->deepsleep_mode = false; + + info->touch_opmode = FTS_OPMODE_NORMAL; + + info->charger_mode = FTS_BIT_CHARGER_MODE_NORMAL; + + info->lowpower_flag = 0x00; + +#ifdef TCLM_CONCEPT + info->tdata->external_factory = false; +#endif + + info->touch_functions = FTS_TOUCHTYPE_DEFAULT_ENABLE; + regAdd[0] = FTS_CMD_SET_GET_TOUCHTYPE; + regAdd[1] = (u8)(info->touch_functions & 0xFF); + regAdd[2] = (u8)(info->touch_functions >> 8); + fts_write_reg(info, ®Add[0], 3); + fts_delay(10); + + fts_command(info, FTS_CMD_FORCE_CALIBRATION, true); + + fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + info->scan_mode = FTS_SCAN_MODE_DEFAULT; + + fts_set_scanmode(info, info->scan_mode); + + info->lp_dump = kzalloc(FTS_SPONGE_LP_DUMP_DATA_FORMAT_10_LEN * FTS_SPONGE_LP_DUMP_LENGTH, GFP_KERNEL); + + input_info(true, &info->client->dev, "%s: Initialized\n", __func__); + + return 0; +} + +int fts_set_temp(struct fts_ts_info *info, bool bforced) +{ + int ret = 0; + u8 temp_data = 0; + u8 regAdd[2] = {0x3C, 0x00}; + + if (!info->psy) + info->psy = power_supply_get_by_name("battery"); + + if (!info->psy) { + input_err(true, &info->client->dev, "%s: Cannot find power supply\n", __func__); + return -1; + } + + ret = power_supply_get_property(info->psy, POWER_SUPPLY_PROP_TEMP, &info->psy_value); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Couldn't get aicl settled value ret=%d\n", __func__, ret); + return ret; + } + + temp_data = (u8)(info->psy_value.intval / 10); + if (bforced || info->tsp_temp_data != temp_data) { + + regAdd[1] = temp_data; + ret = fts_write_reg(info, ®Add[0], 2); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Failed to write\n", __func__); + return ret; + } + + info->tsp_temp_data = temp_data; + input_info(true, &info->client->dev, "%s set temperature:%d\n", __func__, (s8)temp_data); + } else { + input_dbg(true, &info->client->dev, "%s skip temperature:%d\n", __func__, (s8)temp_data); + } + + return ret; +} + + +static void fts_print_info(struct fts_ts_info *info) +{ + struct irq_desc *desc = irq_to_desc(info->irq); + + if (!info) + return; + if (!info->client) + return; + + info->print_info_cnt_open++; + + if (info->print_info_cnt_open > 0xfff0) + info->print_info_cnt_open = 0; + + if (info->touch_count == 0) + info->print_info_cnt_release++; + + input_info(true, &info->client->dev, + "noise:%x,%x tc:%d iq:%d depth:%d lp:%x flip:%d wet:%d selfie:%d // v:%04X cal:%02X,C%02XT%04X.%4s%s Cal_flag:%s,%d // #%d %d\n", + info->touch_noise_status, info->touch_noise_reason, info->touch_count, + gpio_get_value(info->board->irq_gpio), desc->depth, + info->lowpower_flag, info->flip_status_current, info->wet_mode, info->rear_selfie_mode, + (info->module_version_of_ic << 8) | (info->fw_main_version_of_ic & 0xFF), + info->test_result.data[0], +#ifdef TCLM_CONCEPT + info->tdata->nvdata.cal_count, info->tdata->nvdata.tune_fix_ver, + info->tdata->tclm_string[info->tdata->nvdata.cal_position].f_name, + (info->tdata->tclm_level == TCLM_LEVEL_LOCKDOWN) ? ".L" : " ", + (info->tdata->nvdata.cal_fail_falg == SEC_CAL_PASS) ? "Success" : "Fail", + info->tdata->nvdata.cal_fail_cnt, +#else + 0, 0, " ", " ", " ", 0, +#endif + info->print_info_cnt_open, info->print_info_cnt_release); +} + +static void fts_print_info_work(struct work_struct *work) +{ + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + work_print_info.work); + + fts_print_info(info); + + if (info->sec.cmd_is_running) { + input_err(true, &info->client->dev, "%s: skip sec_ts_set_temp, cmd running\n", __func__); + } else { + if (info->touch_count) { + info->tsp_temp_data_skip = true; + input_err(true, &info->client->dev, "%s: skip sec_ts_set_temp, t_cnt(%d)\n", __func__, info->touch_count); + } else { + info->tsp_temp_data_skip = false; + fts_set_temp(info, false); + } + } + + schedule_delayed_work(&info->work_print_info, msecs_to_jiffies(TOUCH_PRINT_INFO_DWORK_TIME)); +} + +/************************************************************ +* 720 * 1480 : <48 96 60> indicator: 24dp navigator:48dp edge:60px dpi=320 +* 1080 * 2220 : 4096 * 4096 : <133 266 341> (approximately value) +************************************************************/ + +static void location_detect(struct fts_ts_info *info, char *loc, int x, int y) +{ + int i; + + for (i = 0; i < FTS_TS_LOCATION_DETECT_SIZE; ++i) + loc[i] = 0; + + if (x < info->board->area_edge) + strcat(loc, "E."); + else if (x < (info->board->max_x - info->board->area_edge)) + strcat(loc, "C."); + else + strcat(loc, "e."); + + if (y < info->board->area_indicator) + strcat(loc, "S"); + else if (y < (info->board->max_y - info->board->area_navigation)) + strcat(loc, "C"); + else + strcat(loc, "N"); +} + +static const char finger_mode[10] = {'N', '1', '2', 'G', '4', 'P'}; + +static u8 fts_event_handler_type_b(struct fts_ts_info *info) +{ + u8 regAdd; + int left_event_count = 0; + int EventNum = 0; + u8 TouchID = 0, event_id = 0; + u8 data[FTS_FIFO_MAX * FTS_EVENT_SIZE] = {0}; + u8 *event_buff; + struct fts_event_coordinate *p_event_coord; + struct fts_gesture_status *p_gesture_status; + struct fts_event_status *p_event_status; + + u8 prev_action = 0; + char location[FTS_TS_LOCATION_DETECT_SIZE] = { 0 }; + + regAdd = FTS_READ_ONE_EVENT; + fts_read_reg(info, ®Add, 1, (u8 *)&data[0 * FTS_EVENT_SIZE], FTS_EVENT_SIZE); + left_event_count = (data[7] & 0x1F); + + if (left_event_count >= FTS_FIFO_MAX) + left_event_count = FTS_FIFO_MAX - 1; + + if (left_event_count > 0) { + regAdd = FTS_READ_ALL_EVENT; + fts_read_reg(info, ®Add, 1, (u8 *)&data[1 * FTS_EVENT_SIZE], FTS_EVENT_SIZE * (left_event_count)); + } + + do { + /* for event debugging */ + if (info->debug_string & 0x1) + input_info(true, &info->client->dev, "[%d] %02X %02X %02X %02X %02X %02X %02X %02X\n", + EventNum, data[EventNum * FTS_EVENT_SIZE+0], data[EventNum * FTS_EVENT_SIZE+1], + data[EventNum * FTS_EVENT_SIZE+2], data[EventNum * FTS_EVENT_SIZE+3], + data[EventNum * FTS_EVENT_SIZE+4], data[EventNum * FTS_EVENT_SIZE+5], + data[EventNum * FTS_EVENT_SIZE+6], data[EventNum * FTS_EVENT_SIZE+7]); + + event_buff = (u8 *) &data[EventNum * FTS_EVENT_SIZE]; + event_id = event_buff[0] & 0x3; + + switch (event_id) { + case FTS_STATUS_EVENT: + p_event_status = (struct fts_event_status *)event_buff; + + if (p_event_status->stype > 0) + input_info(true, &info->client->dev, "%s: STATUS %02X %02X %02X %02X %02X %02X %02X %02X\n", + __func__, event_buff[0], event_buff[1], event_buff[2], + event_buff[3], event_buff[4], event_buff[5], + event_buff[6], event_buff[7]); + + if ((p_event_status->stype == FTS_EVENT_STATUSTYPE_ERROR) && + (p_event_status->status_id == FTS_ERR_EVENT_QUEUE_FULL)) { + input_err(true, &info->client->dev, "%s: IC Event Queue is full\n", __func__); + fts_release_all_finger(info); + } + + if ((p_event_status->stype == FTS_EVENT_STATUSTYPE_ERROR) && + (p_event_status->status_id == FTS_ERR_EVENT_ESD)) { + input_err(true, &info->client->dev, "%s: ESD detected. run reset\n", __func__); + if (!info->reset_is_on_going) + schedule_delayed_work(&info->reset_work, msecs_to_jiffies(10)); + } + + if ((p_event_status->stype == FTS_EVENT_STATUSTYPE_INFORMATION) && + (p_event_status->status_id == FTS_INFO_READY_STATUS)) { + if (p_event_status->status_data_1 == 0x10) { + input_err(true, &info->client->dev, "%s: IC Reset\n", __func__); +/* + if (!info->reset_is_on_going) + schedule_delayed_work(&info->reset_work, msecs_to_jiffies(10)); +*/ + } + } + + if ((p_event_status->stype == FTS_EVENT_STATUSTYPE_INFORMATION) && + (p_event_status->status_id == FTS_INFO_WET_MODE)) { + info->wet_mode = p_event_status->status_data_1; + + input_info(true, &info->client->dev, "%s: WET MODE %s[%d]\n", + __func__, info->wet_mode == 0 ? "OFF" : "ON", + p_event_status->status_data_1); + + if (info->wet_mode) + info->wet_count++; + } + + if ((p_event_status->stype == FTS_EVENT_STATUSTYPE_INFORMATION) && + (p_event_status->status_id == FTS_INFO_NOISE_MODE)) { + info->touch_noise_status = (p_event_status->status_data_1 >> 4); + info->touch_noise_reason = (p_event_status->status_data_1 & 0x0F); + + input_info(true, &info->client->dev, "%s: NOISE MODE %s[%02X]\n", + __func__, info->touch_noise_status == 0 ? "OFF" : "ON", + p_event_status->status_data_1); + + if (info->touch_noise_status) + info->noise_count++; + } + + if ((p_event_status->stype == FTS_EVENT_STATUSTYPE_INFORMATION) && + (p_event_status->status_id == FTS_INFO_XENOSENSOR_DETECT)) { + info->xenosensor_detect = (p_event_status->status_data_5 & 0x80); + info->xenosensor_x = (p_event_status->status_data_1 << 4) | ((p_event_status->status_data_3 & 0xf0) >> 4); + info->xenosensor_y = (p_event_status->status_data_2 << 4) | (p_event_status->status_data_3 & 0x0f); + + input_info(true, &info->client->dev, "%s: XENOSENSOR DETECT [%d] (%d,%d)\n", + __func__, info->xenosensor_detect, info->xenosensor_x, info->xenosensor_y); + } + + if (p_event_status->stype == FTS_EVENT_STATUSTYPE_VENDORINFO) { + if (info->board->support_ear_detect) { + if (p_event_status->status_id == 0x6A) { + info->hover_event = p_event_status->status_data_1; + input_report_abs(info->input_dev_proximity, ABS_MT_CUSTOM, p_event_status->status_data_1); + input_sync(info->input_dev_proximity); + input_info(true, &info->client->dev, "%s: proximity: %d\n", __func__, p_event_status->status_data_1); + } + } + } + break; + + case FTS_COORDINATE_EVENT: + if (info->fts_power_state < FTS_POWER_STATE_ACTIVE) { + input_info(true, &info->client->dev, "%s: opmode is not normal\n", __func__); + break; + } + + p_event_coord = (struct fts_event_coordinate *) event_buff; + + TouchID = p_event_coord->tid; + if (TouchID >= FINGER_MAX) { + input_err(true, &info->client->dev, + "%s: tid(%d) is out of supported max finger number\n", + __func__, TouchID); + break; + } + + info->finger[TouchID].prev_ttype = info->finger[TouchID].ttype; + prev_action = info->finger[TouchID].action; + info->finger[TouchID].id = TouchID; + info->finger[TouchID].action = p_event_coord->tchsta; + info->finger[TouchID].x = (p_event_coord->x_11_4 << 4) | (p_event_coord->x_3_0); + info->finger[TouchID].y = (p_event_coord->y_11_4 << 4) | (p_event_coord->y_3_0); + info->finger[TouchID].z = p_event_coord->z & 0x3F; + info->finger[TouchID].ttype = p_event_coord->ttype_3_2 << 2 | + p_event_coord->ttype_1_0 << 0; + info->finger[TouchID].major = p_event_coord->major; + info->finger[TouchID].minor = p_event_coord->minor; + info->finger[TouchID].max_energy = p_event_coord->max_energy; + if (info->finger[TouchID].max_energy) { + info->finger[TouchID].max_energy_x = info->finger[TouchID].x; + info->finger[TouchID].max_energy_y = info->finger[TouchID].y; + } + + if (!info->finger[TouchID].palm && + info->finger[TouchID].ttype == FTS_EVENT_TOUCHTYPE_PALM) + info->finger[TouchID].palm_count++; + + info->finger[TouchID].palm = (info->finger[TouchID].ttype == FTS_EVENT_TOUCHTYPE_PALM); + info->finger[TouchID].left_event = p_event_coord->left_event; + + info->finger[TouchID].noise_level = p_event_coord->noise_level; + info->finger[TouchID].max_strength = max(info->finger[TouchID].max_strength, p_event_coord->max_strength); + info->finger[TouchID].hover_id_num = max(info->finger[TouchID].hover_id_num, (u8)p_event_coord->hover_id_num); + + if (info->finger[TouchID].z <= 0) + info->finger[TouchID].z = 1; + + if ((info->finger[TouchID].ttype == FTS_EVENT_TOUCHTYPE_NORMAL) || + (info->finger[TouchID].ttype == FTS_EVENT_TOUCHTYPE_PALM) || + (info->finger[TouchID].ttype == FTS_EVENT_TOUCHTYPE_WET) || + (info->finger[TouchID].ttype == FTS_EVENT_TOUCHTYPE_GLOVE)) { + + location_detect(info, location, info->finger[TouchID].x, info->finger[TouchID].y); + + if (info->finger[TouchID].action == FTS_COORDINATE_ACTION_RELEASE) { + input_mt_slot(info->input_dev, TouchID); + + if (info->board->support_mt_pressure) + input_report_abs(info->input_dev, ABS_MT_PRESSURE, 0); + + input_report_abs(info->input_dev, ABS_MT_CUSTOM, 0); + + input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 0); + + if (info->touch_count > 0) + info->touch_count--; + + if (info->touch_count == 0) { + input_report_key(info->input_dev, BTN_TOUCH, 0); + input_report_key(info->input_dev, BTN_TOOL_FINGER, 0); + info->check_multi = 0; + info->print_info_cnt_release = 0; + } + +#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) + input_info(true, &info->client->dev, + "[R] tID:%d loc:%s dd:%d,%d mc:%d tc:%d lx:%d ly:%d mx:%d my:%d p:%d nlvl:%d maxS:%d hid:%d\n", + TouchID, location, + info->finger[TouchID].x - info->finger[TouchID].p_x, + info->finger[TouchID].y - info->finger[TouchID].p_y, + info->finger[TouchID].mcount, info->touch_count, + info->finger[TouchID].x, info->finger[TouchID].y, + info->finger[TouchID].max_energy_x, info->finger[TouchID].max_energy_y, + info->finger[TouchID].palm_count, info->finger[TouchID].noise_level, + info->finger[TouchID].max_strength, info->finger[TouchID].hover_id_num); +#else + input_info(true, &info->client->dev, + "[R] tID:%d loc:%s dd:%d,%d mp:%d,%d mc:%d tc:%d p:%d nlvl:%d maxS:%d hid:%d\n", + TouchID, location, + info->finger[TouchID].x - info->finger[TouchID].p_x, + info->finger[TouchID].y - info->finger[TouchID].p_y, + info->finger[TouchID].max_energy_x - info->finger[TouchID].p_x, + info->finger[TouchID].max_energy_y - info->finger[TouchID].p_y, + info->finger[TouchID].mcount, info->touch_count, + info->finger[TouchID].palm_count, info->finger[TouchID].noise_level, + info->finger[TouchID].max_strength, info->finger[TouchID].hover_id_num); +#endif + + info->finger[TouchID].action = FTS_COORDINATE_ACTION_NONE; + info->finger[TouchID].mcount = 0; + info->finger[TouchID].palm_count = 0; + info->finger[TouchID].noise_level = 0; + info->finger[TouchID].max_strength = 0; + info->finger[TouchID].hover_id_num = 0; + + } else if (info->finger[TouchID].action == FTS_COORDINATE_ACTION_PRESS) { + + info->touch_count++; + info->all_finger_count++; + + info->finger[TouchID].p_x = info->finger[TouchID].x; + info->finger[TouchID].p_y = info->finger[TouchID].y; + + input_mt_slot(info->input_dev, TouchID); + input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 1); + input_report_key(info->input_dev, BTN_TOUCH, 1); + input_report_key(info->input_dev, BTN_TOOL_FINGER, 1); + + input_report_abs(info->input_dev, ABS_MT_POSITION_X, info->finger[TouchID].x); + input_report_abs(info->input_dev, ABS_MT_POSITION_Y, info->finger[TouchID].y); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MAJOR, + info->finger[TouchID].major); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MINOR, + info->finger[TouchID].minor); + + if (info->brush_mode) + input_report_abs(info->input_dev, ABS_MT_CUSTOM, + (info->finger[TouchID].max_energy << 16) | + (info->finger[TouchID].z << 1) | + info->finger[TouchID].palm); + else + input_report_abs(info->input_dev, ABS_MT_CUSTOM, + (info->finger[TouchID].max_energy << 16) | + (BRUSH_Z_DATA << 1) | + info->finger[TouchID].palm); + + if (info->board->support_mt_pressure) + input_report_abs(info->input_dev, ABS_MT_PRESSURE, + info->finger[TouchID].z); + + if ((info->touch_count > 4) && (info->check_multi == 0)) { + info->check_multi = 1; + info->multi_count++; + } + +#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) + input_info(true, &info->client->dev, + "[P] tID:%d.%d x:%d y:%d z:%d major:%d minor:%d loc:%s tc:%d type:%d p:%d nlvl:%d maxS:%d hid:%d\n", + TouchID, (info->input_dev->mt->trkid - 1) & TRKID_MAX, + info->finger[TouchID].x, info->finger[TouchID].y, + info->finger[TouchID].z, + info->finger[TouchID].major, info->finger[TouchID].minor, + location, info->touch_count, info->finger[TouchID].ttype, + info->finger[TouchID].palm_count, info->finger[TouchID].noise_level, + info->finger[TouchID].max_strength, info->finger[TouchID].hover_id_num); +#else + input_info(true, &info->client->dev, + "[P] tID:%d.%d z:%d major:%d minor:%d loc:%s tc:%d type:%d p:%d nlvl:%d maxS:%d hid:%d\n", + TouchID, (info->input_dev->mt->trkid - 1) & TRKID_MAX, + info->finger[TouchID].z, + info->finger[TouchID].major, info->finger[TouchID].minor, + location, info->touch_count, info->finger[TouchID].ttype, + info->finger[TouchID].palm_count, info->finger[TouchID].noise_level, + info->finger[TouchID].max_strength, info->finger[TouchID].hover_id_num); +#endif + } else if (info->finger[TouchID].action == FTS_COORDINATE_ACTION_MOVE) { + if (info->touch_count == 0) { + input_err(true, &info->client->dev, "%s: touch count 0\n", __func__); + fts_release_all_finger(info); + break; + } + + if (prev_action == FTS_COORDINATE_ACTION_NONE) { + input_err(true, &info->client->dev, + "%s: previous state is released but point is moved\n", + __func__); + break; + } + + input_mt_slot(info->input_dev, TouchID); + input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 1); + input_report_key(info->input_dev, BTN_TOUCH, 1); + input_report_key(info->input_dev, BTN_TOOL_FINGER, 1); + + input_report_abs(info->input_dev, ABS_MT_POSITION_X, info->finger[TouchID].x); + input_report_abs(info->input_dev, ABS_MT_POSITION_Y, info->finger[TouchID].y); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MAJOR, + info->finger[TouchID].major); + input_report_abs(info->input_dev, ABS_MT_TOUCH_MINOR, + info->finger[TouchID].minor); + + if (info->brush_mode) + input_report_abs(info->input_dev, ABS_MT_CUSTOM, + (info->finger[TouchID].max_energy << 16) | + (info->finger[TouchID].z << 1) | + info->finger[TouchID].palm); + else + input_report_abs(info->input_dev, ABS_MT_CUSTOM, + (info->finger[TouchID].max_energy << 16) | + (BRUSH_Z_DATA << 1) | + info->finger[TouchID].palm); + + if (info->board->support_mt_pressure) + input_report_abs(info->input_dev, ABS_MT_PRESSURE, + info->finger[TouchID].z); + + info->finger[TouchID].mcount++; + } else { + input_dbg(true, &info->client->dev, + "%s: do not support coordinate action(%d)\n", + __func__, info->finger[TouchID].action); + } + + + if (info->finger[TouchID].ttype != info->finger[TouchID].prev_ttype) { + input_info(true, &info->client->dev, "%s: tID:%d ttype(%c->%c) : %s\n", + __func__, info->finger[TouchID].id, + finger_mode[info->finger[TouchID].prev_ttype], + finger_mode[info->finger[TouchID].ttype], + info->finger[TouchID].action == FTS_COORDINATE_ACTION_PRESS ? "P" : + info->finger[TouchID].action == FTS_COORDINATE_ACTION_MOVE ? "M" : "R"); + } + } else { + input_dbg(true, &info->client->dev, + "%s: do not support coordinate type(%d)\n", + __func__, info->finger[TouchID].ttype); + } + + break; + case FTS_GESTURE_EVENT: + p_gesture_status = (struct fts_gesture_status *)event_buff; + input_info(true, &info->client->dev, "%s: [GESTURE] type:%X sf:%X id:%X | %X, %X, %X, %X\n", + __func__, p_gesture_status->stype, p_gesture_status->sf, p_gesture_status->gesture_id, + p_gesture_status->gesture_data_1, p_gesture_status->gesture_data_2, + p_gesture_status->gesture_data_3, p_gesture_status->gesture_data_4); + +#ifdef FTS_SUPPORT_SPONGELIB + if (p_gesture_status->sf == FTS_GESTURE_SAMSUNG_FEATURE) { + switch (p_gesture_status->stype) { + case FTS_SPONGE_EVENT_SWIPE_UP: + info->scrub_id = SPONGE_EVENT_TYPE_SPAY; + input_info(true, &info->client->dev, "%s: SPAY\n", __func__); + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 0); + break; + case FTS_SPONGE_EVENT_DOUBLETAP: + if (p_gesture_status->gesture_id == FTS_SPONGE_EVENT_GESTURE_ID_AOD) { + info->scrub_id = SPONGE_EVENT_TYPE_AOD_DOUBLETAB; + info->scrub_x = (p_gesture_status->gesture_data_1 << 4) | (p_gesture_status->gesture_data_3 >> 4); + info->scrub_y = (p_gesture_status->gesture_data_2 << 4) | (p_gesture_status->gesture_data_3 & 0x0F); + + input_info(true, &info->client->dev, "%s: AOD\n", __func__); + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 0); + } else if (p_gesture_status->gesture_id == FTS_SPONGE_EVENT_GESTURE_ID_DOUBLETAP_TO_WAKEUP) { + input_report_key(info->input_dev, KEY_WAKEUP, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, KEY_WAKEUP, 0); + input_info(true, &info->client->dev, "%s: DOUBLE TAP TO WAKEUP\n", __func__); + } + break; + case FTS_SPONGE_EVENT_SINGLETAP: + info->scrub_id = SPONGE_EVENT_TYPE_SINGLE_TAP; + info->scrub_x = (p_gesture_status->gesture_data_1 << 4) | (p_gesture_status->gesture_data_3 >> 4); + info->scrub_y = (p_gesture_status->gesture_data_2 << 4) | (p_gesture_status->gesture_data_3 & 0x0F); + + input_info(true, &info->client->dev, "%s: SINGLE TAP\n", __func__); + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 0); + break; +#ifdef CONFIG_TOUCHSCREEN_DUMP_MODE + case FTS_SPONGE_EVENT_DUMPFLUSH: + if (info->sponge_inf_dump) { + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + if (p_gesture_status->gesture_id == FTS_SPONGE_DUMP_0) + fts_sponge_dump_flush(info, FTS_SPONGE_DUMP_0); + if (p_gesture_status->gesture_id == FTS_SPONGE_DUMP_1) + fts_sponge_dump_flush(info, FTS_SPONGE_DUMP_1); + } else { + info->sponge_dump_delayed_flag = true; + info->sponge_dump_delayed_area = p_gesture_status->gesture_id; + } + } + break; +#endif + case FTS_SPONGE_EVENT_PRESS: + if (p_gesture_status->gesture_id == FTS_SPONGE_EVENT_GESTURE_ID_FOD_LONG || + p_gesture_status->gesture_id == FTS_SPONGE_EVENT_GESTURE_ID_FOD_NORMAL) { + info->scrub_id = SPONGE_EVENT_TYPE_FOD; + input_info(true, &info->client->dev, "%s: FOD %sPRESS\n", + __func__, p_gesture_status->gesture_id ? "" : "LONG"); + } else if (p_gesture_status->gesture_id == FTS_SPONGE_EVENT_GESTURE_ID_FOD_RELEASE) { + info->scrub_id = SPONGE_EVENT_TYPE_FOD_RELEASE; + input_info(true, &info->client->dev, "%s: FOD RELEASE\n", __func__); + } else if (p_gesture_status->gesture_id == FTS_SPONGE_EVENT_GESTURE_ID_FOD_OUT) { + info->scrub_id = SPONGE_EVENT_TYPE_FOD_OUT; + input_info(true, &info->client->dev, "%s: FOD OUT\n", __func__); + } else if (p_gesture_status->gesture_id == FTS_SPONGE_EVENT_GESTURE_ID_FOD_VI) { + if (info->lowpower_flag & FTS_MODE_PRESS) { + int ret; + + ret = fts_read_from_sponge(info, FTS_CMD_SPONGE_FOD_POSITION, info->fod_vi_data, info->fod_vi_size); + if (ret < 0) { + input_info(true, &info->client->dev, "%s: failed to read FOD VI: ret: %d\n", __func__, ret); + } else { + input_info(true, &info->client->dev, "%s: FOD VI\n", __func__); + } + } else { + input_info(true, &info->client->dev, "%s: FOD not enabled: 0x%X\n", __func__, info->lowpower_flag); + } + break; + } else { + input_info(true, &info->client->dev, "%s: invalid id %d\n", + __func__, p_gesture_status->gesture_id); + break; + } + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, KEY_BLACK_UI_GESTURE, 0); + break; + } + } +#endif + break; + case FTS_VENDOR_EVENT: // just print message for debugging + if (event_buff[1] == 0x01) { // echo event + input_info(true, &info->client->dev, + "%s: echo event %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + __func__, event_buff[0], event_buff[1], event_buff[2], event_buff[3], event_buff[4], event_buff[5], + event_buff[6], event_buff[7], event_buff[8], event_buff[9], event_buff[10], event_buff[11], + event_buff[12], event_buff[13], event_buff[14], event_buff[15]); + } else { + input_info(true, &info->client->dev, + "%s: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + __func__, event_buff[0], event_buff[1], event_buff[2], event_buff[3], event_buff[4], event_buff[5], + event_buff[6], event_buff[7], event_buff[8], event_buff[9], event_buff[10], event_buff[11], + event_buff[12], event_buff[13], event_buff[14], event_buff[15]); + } + break; + default: + input_info(true, &info->client->dev, + "%s: unknown event %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + __func__, event_buff[0], event_buff[1], event_buff[2], event_buff[3], event_buff[4], event_buff[5], + event_buff[6], event_buff[7], event_buff[8], event_buff[9], event_buff[10], event_buff[11], + event_buff[12], event_buff[13], event_buff[14], event_buff[15]); + break; + } + + EventNum++; + left_event_count--; + } while (left_event_count >= 0); + + input_sync(info->input_dev); + + if (info->touch_count == 0 && info->tsp_temp_data_skip) { + info->tsp_temp_data_skip = false; + fts_set_temp(info, false); + input_err(true, &info->client->dev, "%s: fts_set_temp, no touch\n", __func__); + } + +// fts_lfd_ctrl(info, info->touch_count); + + return 0; +} + +/* +static void fts_lfd_ctrl(struct fts_ts_info *info, int touch_count) +{ + if (info->lfd_ctrl_delay > 0) { + if (touch_count > 0) { + cancel_delayed_work_sync(&info->work_lfd_ctrl); + info->lfd_ctrl = FTS_LFD_CTRL_LOCK; + schedule_work(&info->work_lfd_ctrl.work); + } else { + cancel_delayed_work_sync(&info->work_lfd_ctrl); + info->lfd_ctrl = FTS_LFD_CTRL_UNLOCK; + schedule_delayed_work(&info->work_lfd_ctrl, msecs_to_jiffies(info->lfd_ctrl_delay)); + } + } +} +*/ +#ifdef FTS_SUPPORT_TA_MODE +static void fts_ta_cb(struct fts_callbacks *cb, int ta_status) +{ + struct fts_ts_info *info = + container_of(cb, struct fts_ts_info, callbacks); + + u8 regAdd[8] = {0}; + u8 data; + u8 wiredCharger; + + regAdd[0] = FTS_CMD_SET_GET_CHARGER_MODE; + fts_read_reg(info, ®Add[0], 1, &data, 1); + + if (ta_status == 0x01 || ta_status == 0x03) { + wiredCharger = data | FTS_BIT_CHARGER_MODE_WIRE_CHARGER; + + info->TA_Pluged = true; + input_info(true, &info->client->dev, + "%s: device_control : CHARGER CONNECTED, ta_status : %x\n", + __func__, ta_status); + } else { + wiredCharger = data & (~FTS_BIT_CHARGER_MODE_WIRE_CHARGER); + + info->TA_Pluged = false; + input_info(true, &info->client->dev, + "%s: device_control : CHARGER DISCONNECTED, ta_status : %x\n", + __func__, ta_status); + } + + regAdd[1] = wiredCharger; + fts_write_reg(info, ®Add[0], 2); + +} +#endif + +/** + * fts_interrupt_handler() + * + * Called by the kernel when an interrupt occurs (when the sensor + * asserts the attention irq). + * + * This function is the ISR thread and handles the acquisition + * and the reporting of finger data when the presence of fingers + * is detected. + */ +static irqreturn_t fts_interrupt_handler(int irq, void *handle) +{ + struct fts_ts_info *info = handle; + + int ret; + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + if (fts_filter_interrupt(info) == IRQ_HANDLED) { + ret = wait_for_completion_interruptible_timeout((&info->st_interrupt), + msecs_to_jiffies(10 * MSEC_PER_SEC)); + return IRQ_HANDLED; + } +#endif + + /* in LPM, waiting blsp block resume */ + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + input_dbg(true, &info->client->dev, "%s: run LPM interrupt handler\n", __func__); + + wake_lock_timeout(&info->wakelock, msecs_to_jiffies(500)); + /* waiting for blsp block resuming, if not occurs i2c error */ + ret = wait_for_completion_interruptible_timeout(&info->resume_done, msecs_to_jiffies(500)); + if (ret == 0) { + input_err(true, &info->client->dev, "%s: LPM: pm resume is not handled\n", __func__); + return IRQ_NONE; + } + + if (ret < 0) { + input_err(true, &info->client->dev, "%s: LPM: -ERESTARTSYS if interrupted, %d\n", __func__, ret); + return IRQ_NONE; + } + + input_info(true, &info->client->dev, "%s: run LPM interrupt handler, %d\n", __func__, jiffies_to_msecs(ret)); + /* run lpm interrupt handler */ + } + + mutex_lock(&info->eventlock); + + ret = fts_event_handler_type_b(info); + + mutex_unlock(&info->eventlock); + + return IRQ_HANDLED; +} + +int fts_irq_enable(struct fts_ts_info *info, + bool enable) +{ + int retval = 0; + + if (enable) { + if (info->irq_enabled) + return retval; + + retval = request_threaded_irq(info->irq, NULL, + fts_interrupt_handler, IRQF_TRIGGER_LOW | IRQF_ONESHOT, + FTS_TS_DRV_NAME, info); + if (retval < 0) { + input_err(true, &info->client->dev, + "%s: Failed to create irq thread %d\n", + __func__, retval); + return retval; + } + + info->irq_enabled = true; + } else { + if (info->irq_enabled) { + fts_interrupt_set(info, INT_DISABLE); + free_irq(info->irq, info); + info->irq_enabled = false; + } + } + + return retval; +} + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE +static int fts_notifier_call(struct notifier_block *n, + unsigned long data, void *v) +{ + struct fts_ts_info *info = container_of(n, struct fts_ts_info, nb); + + input_dbg(true, &info->client->dev, "%s: %lu\n", __func__, data); + + return 0; +} + +static void fts_switching_work(struct work_struct *work) +{ + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + switching_work.work); + + if (info == NULL) { + input_err(true, NULL, "%s: tsp info is null\n", __func__); + return; + } + + if (info->flip_status != info->flip_status_current) { + if (!info->info_work_done) { + input_err(true, &info->client->dev, "%s: info_work is not done yet\n", __func__); + info->change_flip_status = 1; + return; + } + info->change_flip_status = 0; + + mutex_lock(&info->switching_mutex); + info->flip_status = info->flip_status_current; + + if (info->flip_status == 0) { + /* open : main_tsp on */ + } else { + /* close : main_tsp off */ +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + fts_secure_touch_stop(info, 1); +#endif + } + + fts_chk_tsp_ic_status(info, FTS_STATE_CHK_POS_HALL); + + mutex_unlock(&info->switching_mutex); + } else if (info->board->support_flex_mode) { + input_info(true, &info->client->dev, "%s support_flex_mode\n", __func__); + mutex_lock(&info->switching_mutex); + fts_chk_tsp_ic_status(info, FTS_STATE_CHK_POS_SYSFS); + sec_input_notify(&info->nb, NOTIFIER_MAIN_TOUCH_ON, NULL); + mutex_unlock(&info->switching_mutex); + } +} + +#ifdef CONFIG_FOLDER_HALL +static int fts_hall_ic_notify(struct notifier_block *nb, + unsigned long flip_cover, void *v) +{ + struct fts_ts_info *info = container_of(nb, struct fts_ts_info, + hall_ic_nb); + + if (info == NULL) { + input_err(true, NULL, "%s: tsp info is null\n", __func__); + return 0; + } + + input_info(true, &info->client->dev, "%s: %s\n", __func__, + flip_cover ? "close" : "open"); + + cancel_delayed_work(&info->switching_work); + + info->flip_status_current = flip_cover; + + schedule_work(&info->switching_work.work); + + if (info->xenosensor_detect && info->flip_status_current) { + info->xenosensor_detect_count++; + info->xenosensor_detect_x = info->xenosensor_x; + info->xenosensor_detect_y = info->xenosensor_y; + time64_to_tm(ktime_get_real_seconds(), -sys_tz.tz_minuteswest * 60, &info->xenosensor_time); + input_info(true, &info->client->dev, "%s: xenosensor_detect_count %d\n", __func__, info->xenosensor_detect_count); + } + + return 0; +} +#endif +#endif + +#ifdef FTS_SUPPORT_TA_MODE +struct fts_callbacks *fts_charger_callbacks; +void tsp_charger_infom(bool en) +{ + pr_err("%s: %s %s: ta:%d\n", FTS_TS_DRV_NAME, SECLOG, __func__, en); + + if (fts_charger_callbacks && fts_charger_callbacks->inform_charger) + fts_charger_callbacks->inform_charger(fts_charger_callbacks, en); +} +static void fts_tsp_register_callback(void *cb) +{ + fts_charger_callbacks = cb; +} +#endif + +static int fts_power_ctrl(void *data, bool on) +{ + struct fts_ts_info *info = (struct fts_ts_info *)data; + const struct fts_i2c_platform_data *pdata = info->board; + struct device *dev = &info->client->dev; + static bool enabled; + static bool boot_on = true; + int retval = 0; + + if (enabled == on) + return retval; + + if (info->regulator_dvdd == NULL) { + info->regulator_dvdd = devm_regulator_get(&info->client->dev, "dvdd"); + if (IS_ERR_OR_NULL(info->regulator_dvdd)) { + input_err(true, dev, "%s: Failed to get regulator: dvdd\n", __func__); + goto out; + } + } + if (info->regulator_avdd == NULL) { + info->regulator_avdd = devm_regulator_get(&info->client->dev, "avdd"); + if (IS_ERR_OR_NULL(info->regulator_avdd)) { + input_err(true, dev, "%s: Failed to get regulator dvdd\n", __func__); + goto out; + } + } + if (on) { + if (!regulator_is_enabled(info->regulator_avdd) || boot_on) { + retval = regulator_enable(info->regulator_avdd); + if (retval) { + input_err(true, dev, "%s: Failed to enable avdd: %d\n", __func__, retval); + goto out; + } + } else { + input_err(true, dev, "%s: avdd is already enabled\n", __func__); + } + + fts_delay(1); + + if (!regulator_is_enabled(info->regulator_dvdd) || boot_on) { + retval = regulator_enable(info->regulator_dvdd); + if (retval) { + input_err(true, dev, "%s: Failed to enable vdd: %d\n", __func__, retval); + regulator_disable(info->regulator_avdd); + goto out; + } + } else { + input_err(true, dev, "%s: dvdd is already enabled\n", __func__); + } + + if (!IS_ERR_OR_NULL(pdata->pins_default)) { + retval = pinctrl_select_state(pdata->pinctrl, pdata->pins_default); + if (retval < 0) + input_err(true, dev, "%s: Failed to configure tsp_attn pin\n", __func__); + } + fts_delay(5); + } else { + if (regulator_is_enabled(info->regulator_dvdd)) { + retval = regulator_disable(info->regulator_dvdd); + if (retval) { + input_err(true, dev, "%s: Failed to disable dvdd: %d\n", __func__, retval); + goto out; + } + } else { + input_err(true, dev, "%s: dvdd is already disabled\n", __func__); + } + + if (regulator_is_enabled(info->regulator_avdd)) { + retval = regulator_disable(info->regulator_avdd); + if (retval) { + input_err(true, dev, "%s: Failed to disable avdd: %d\n", __func__, retval); + regulator_enable(info->regulator_dvdd); + goto out; + } + } else { + input_err(true, dev, "%s: avdd is already disabled\n", __func__); + } + + if (!IS_ERR_OR_NULL(pdata->pins_sleep)) { + retval = pinctrl_select_state(pdata->pinctrl, pdata->pins_sleep); + if (retval < 0) + input_err(true, dev, "%s: Failed to configure tsp_attn pin\n", __func__); + } + } + enabled = on; + + input_err(true, dev, "%s: %s: avdd:%s, dvdd:%s\n", __func__, on ? "on" : "off", + regulator_is_enabled(info->regulator_avdd) ? "on" : "off", + regulator_is_enabled(info->regulator_dvdd) ? "on" : "off"); + +out: +// regulator_put(regulator_dvdd); +// regulator_put(regulator_avdd); + + boot_on = false; + + return retval; +} + +static int fts_parse_dt(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct fts_i2c_platform_data *pdata = dev->platform_data; + struct device_node *np = dev->of_node; + u32 coords[2]; + u32 ic_match_value; + int retval = 0; + int lcdtype = 0; +#if defined(CONFIG_EXYNOS_DPU30) + int connected; +#endif + u32 px_zone[3] = { 0 }; + int count = 0, i; + + pdata->tsp_icid = of_get_named_gpio(np, "stm,tsp-icid_gpio", 0); + if (gpio_is_valid(pdata->tsp_icid)) { + input_info(true, dev, "%s: TSP_ICID : %d\n", __func__, gpio_get_value(pdata->tsp_icid)); + if (of_property_read_u32(np, "stm,icid_match_value", &ic_match_value)) { + input_err(true, dev, "%s: Failed to get icid match value\n", __func__); + return -EINVAL; + } + + input_err(true, dev, "%s: IC matched value : %d\n", __func__, ic_match_value); + + if (gpio_get_value(pdata->tsp_icid) != ic_match_value) { + input_err(true, dev, "%s: Do not match TSP_ICID\n", __func__); + return -EINVAL; + } + } else { + input_err(true, dev, "%s: Failed to get tsp-icid gpio\n", __func__); + } + + if (gpio_is_valid(pdata->tsp_icid)) { + retval = gpio_request(pdata->tsp_icid, "TSP_ICID"); + if (retval) + input_err(true, dev, "%s: Unable to request tsp_icid [%d]\n", __func__, pdata->tsp_icid); + } + + pdata->tsp_id = of_get_named_gpio(np, "stm,tsp-id_gpio", 0); + if (gpio_is_valid(pdata->tsp_id)) + input_info(true, dev, "%s: TSP_ID : %d\n", __func__, gpio_get_value(pdata->tsp_id)); + else + input_err(true, dev, "%s: Failed to get tsp-id gpio\n", __func__); + + if (gpio_is_valid(pdata->tsp_id)) { + retval = gpio_request(pdata->tsp_id, "TSP_ID"); + if (retval) + input_err(true, dev, "%s: Unable to request tsp_id [%d]\n", __func__, pdata->tsp_id); + } + + pdata->device_id = of_get_named_gpio(np, "stm,device_gpio", 0); + if (gpio_is_valid(pdata->device_id)) + input_info(true, dev, "%s: Device ID : %d\n", __func__, gpio_get_value(pdata->device_id)); + else + input_err(true, dev, "%s: skipped to get device-id gpio\n", __func__); + + pdata->irq_gpio = of_get_named_gpio(np, "stm,irq_gpio", 0); + if (gpio_is_valid(pdata->irq_gpio)) { + retval = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stm,tsp_int"); + if (retval) { + input_err(true, dev, "%s: Unable to request tsp_int [%d]\n", __func__, pdata->irq_gpio); + return -EINVAL; + } + } else { + input_err(true, dev, "%s: Failed to get irq gpio\n", __func__); + return -EINVAL; + } + client->irq = gpio_to_irq(pdata->irq_gpio); + + if (of_property_read_u32_array(np, "stm,max_coords", coords, 2)) { + input_err(true, dev, "%s: Failed to get max_coords property\n", __func__); + return -EINVAL; + } + pdata->max_x = coords[0]; + pdata->max_y = coords[1]; +/* + if (of_property_read_string(np, "stm,regulator_dvdd", &pdata->regulator_dvdd)) { + input_err(true, dev, "%s: Failed to get regulator_dvdd name property\n", __func__); + return -EINVAL; + } + + if (of_property_read_string(np, "stm,regulator_avdd", &pdata->regulator_avdd)) { + input_err(true, dev, "%s: Failed to get regulator_avdd name property\n", __func__); + return -EINVAL; + } +*/ + pdata->power = fts_power_ctrl; + + /* Optional parmeters(those values are not mandatory) + * do not return error value even if fail to get the value + */ + if (of_property_read_bool(np, "stm,support_gesture")) + pdata->support_sidegesture = true; + + pdata->support_dex = of_property_read_bool(np, "support_dex_mode"); + pdata->support_ear_detect = of_property_read_bool(np, "support_ear_detect"); + pdata->sync_reportrate_120 = of_property_read_bool(np, "sync-reportrate-120"); + pdata->support_open_short_test = of_property_read_bool(np, "support_open_short_test"); + pdata->support_mis_calibration_test = of_property_read_bool(np, "support_mis_calibration_test"); + pdata->support_sram_test = of_property_read_bool(np, "support_sram_test"); + pdata->support_hall_ic = of_property_read_bool(np, "support_hall_ic"); + pdata->support_flex_mode = of_property_read_bool(np, "support_flex_mode"); + + of_property_read_u32(np, "stm,bringup", &pdata->bringup); + + pdata->enable_settings_aot = of_property_read_bool(np, "stm,enable_settings_aot"); + + pdata->support_fod = of_property_read_bool(np, "stm,support_fod"); + pdata->hw_i2c_reset = of_property_read_bool(np, "stm,hw_i2c_reset"); + + pdata->support_hover = false; + pdata->support_glove = false; +#ifdef CONFIG_SEC_FACTORY + pdata->support_mt_pressure = true; +#endif +#ifdef FTS_SUPPORT_TA_MODE + pdata->register_cb = fts_tsp_register_callback; +#endif + + if (of_property_read_u32(np, "stm,device_num", &pdata->device_num)) + input_err(true, dev, "%s: Failed to get device_num property\n", __func__); + + pdata->chip_on_board = of_property_read_bool(np, "stm,chip_on_board"); +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + of_property_read_u32(np, "stm,ss_touch_num", &pdata->ss_touch_num); + input_info(true, dev, "%s: ss_touch_num:%d\n", __func__, pdata->ss_touch_num); +#endif +#if defined(CONFIG_DISPLAY_SAMSUNG) + lcdtype = get_lcd_attached("GET"); + if (lcdtype == 0xFFFFFF || (lcdtype != 0x805080 && lcdtype != 0x805081)) { + input_err(true, &client->dev, "%s: lcd is not attached %X\n", __func__, lcdtype); + if (!pdata->chip_on_board) + return -ENODEV; + } +#endif + +#if defined(CONFIG_EXYNOS_DPU30) + connected = get_lcd_info("connected"); + if (connected < 0) { + input_err(true, dev, "%s: Failed to get lcd info\n", __func__); + if (!pdata->chip_on_board) + return -EINVAL; + } + + if (!connected) { + input_err(true, &client->dev, "%s: lcd is disconnected\n", __func__); + if (!pdata->chip_on_board) + return -ENODEV; + } + + input_info(true, &client->dev, "%s: lcd is connected\n", __func__); + + lcdtype = get_lcd_info("id"); + if (lcdtype < 0 || (lcdtype != 0x805080 && lcdtype != 0x805081)) { + input_err(true, dev, "%s: Failed to get lcd info %X\n", __func__, lcdtype); + if (!pdata->chip_on_board) + return -EINVAL; + } +#endif + input_info(true, &client->dev, "%s: lcdtype 0x%08X\n", __func__, lcdtype); + + count = of_property_count_strings(np, "stm,firmware_name"); + if (count <= 0) { + pdata->firmware_name = NULL; + } else { + if (gpio_is_valid(pdata->tsp_id)) { + of_property_read_string_index(np, "stm,firmware_name", gpio_get_value(pdata->tsp_id), + &pdata->firmware_name); + } else { + u8 lcd_id_num = of_property_count_u32_elems(np, "stm,select_lcdid"); + + if ((lcd_id_num != count) || (lcd_id_num <= 0)) { + of_property_read_string_index(np, "stm,firmware_name", 0, &pdata->firmware_name); + } else { + u32 lcd_id[5]; + + of_property_read_u32_array(np, "stm,select_lcdid", lcd_id, lcd_id_num); + + for (i = 0; i < lcd_id_num; i++) { + if (lcd_id[i] == ((lcdtype >> 16) & 0xFF)) { + of_property_read_string_index(np, "stm,firmware_name", i, &pdata->firmware_name); + break; + } + } + if (!pdata->firmware_name) + pdata->bringup = 1; + else if (strlen(pdata->firmware_name) == 0) + pdata->bringup = 1; + } + } + } + + pdata->panel_revision = ((lcdtype >> 8) & 0xFF) >> 4; + + if (of_property_read_u32_array(np, "stm,area-size", px_zone, 3)) { + input_info(true, &client->dev, "%s: Failed to get zone's size\n", __func__); + pdata->area_indicator = 48; + pdata->area_navigation = 96; + pdata->area_edge = 60; + } else { + pdata->area_indicator = px_zone[0]; + pdata->area_navigation = px_zone[1]; + pdata->area_edge = px_zone[2]; + } + input_info(true, dev, "%s : zone's size - indicator:%d, navigation:%d, edge:%d\n", + __func__, pdata->area_indicator, pdata->area_navigation, pdata->area_edge); + + input_err(true, dev, + "%s: irq :%d, max[x,y]: [%d,%d], " + "panel_revision: %d, gesture: %d, device_num: %d, dex: %d, aot: %d%s\n", + __func__, pdata->irq_gpio, pdata->max_x, pdata->max_y, + pdata->panel_revision, + pdata->support_sidegesture, pdata->device_num, pdata->support_dex, pdata->enable_settings_aot, + pdata->chip_on_board ? ", COB type" : ""); + + return retval; +} + +#ifdef TCLM_CONCEPT +static void sec_tclm_parse_dt(struct i2c_client *client, struct sec_tclm_data *tdata) +{ + struct device *dev = &client->dev; + struct device_node *np = dev->of_node; + + if (of_property_read_u32(np, "stm,tclm_level", &tdata->tclm_level) < 0) { + tdata->tclm_level = 0; + input_err(true, dev, "%s: Failed to get tclm_level property\n", __func__); + } + + if (of_property_read_u32(np, "stm,afe_base", &tdata->afe_base) < 0) { + tdata->afe_base = 0; + input_err(true, dev, "%s: Failed to get afe_base property\n", __func__); + } + + tdata->support_tclm_test = of_property_read_bool(np, "support_tclm_test"); + + input_err(true, &client->dev, "%s: tclm_level %d, sec_afe_base %04X\n", __func__, tdata->tclm_level, tdata->afe_base); +} +#endif + +static int fts_setup_drv_data(struct i2c_client *client) +{ + int retval = 0; + struct fts_i2c_platform_data *pdata; + struct fts_ts_info *info; + struct sec_tclm_data *tdata = NULL; + + /* parse dt */ + if (client->dev.of_node) { + pdata = devm_kzalloc(&client->dev, + sizeof(struct fts_i2c_platform_data), GFP_KERNEL); + + if (!pdata) { + input_err(true, &client->dev, "%s: Failed to allocate platform data\n", __func__); + return -ENOMEM; + } + + client->dev.platform_data = pdata; + retval = fts_parse_dt(client); + if (retval) { + input_err(true, &client->dev, "%s: Failed to parse dt\n", __func__); + return retval; + } + + tdata = devm_kzalloc(&client->dev, + sizeof(struct sec_tclm_data), GFP_KERNEL); + if (!tdata) + return -ENOMEM; + +#ifdef TCLM_CONCEPT + sec_tclm_parse_dt(client, tdata); +#endif + } else { + pdata = client->dev.platform_data; + } + + if (!pdata) { + input_err(true, &client->dev, "%s: No platform data found\n", __func__); + return -EINVAL; + } + if (!pdata->power) { + input_err(true, &client->dev, "%s: No power contorl found\n", __func__); + return -EINVAL; + } + + pdata->pinctrl = devm_pinctrl_get(&client->dev); + if (IS_ERR(pdata->pinctrl)) { + input_err(true, &client->dev, "%s: could not get pinctrl\n", __func__); + return PTR_ERR(pdata->pinctrl); + } + + pdata->pins_default = pinctrl_lookup_state(pdata->pinctrl, "on_state"); + if (IS_ERR(pdata->pins_default)) + input_err(true, &client->dev, "%s: could not get default pinstate\n", __func__); + + pdata->pins_sleep = pinctrl_lookup_state(pdata->pinctrl, "off_state"); + if (IS_ERR(pdata->pins_sleep)) + input_err(true, &client->dev, "%s: could not get sleep pinstate\n", __func__); + + info = kzalloc(sizeof(struct fts_ts_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->client = client; + info->board = pdata; + info->irq = client->irq; + info->irq_enabled = false; + info->panel_revision = info->board->panel_revision; + info->stop_device = fts_stop_device; + info->start_device = fts_start_device; + info->fts_command = fts_command; + info->fts_read_reg = fts_read_reg; + info->fts_write_reg = fts_write_reg; + info->fts_systemreset = fts_systemreset; + info->fts_get_version_info = fts_get_version_info; + info->fts_get_sysinfo_data = fts_get_sysinfo_data; + info->fts_wait_for_ready = fts_wait_for_ready; +#ifdef FTS_SUPPORT_SPONGELIB + info->fts_read_from_sponge = fts_read_from_sponge; + info->fts_write_to_sponge = fts_write_to_sponge; +#endif + info->tdata = tdata; + if (!info->tdata) { + input_err(true, &client->dev, "%s: No tclm data found\n", __func__); + kfree(info); + return -EINVAL; + } + +#ifdef TCLM_CONCEPT + sec_tclm_initialize(info->tdata); + info->tdata->client = info->client; + info->tdata->tclm_read = fts_tclm_data_read; + info->tdata->tclm_write = fts_tclm_data_write; + info->tdata->tclm_execute_force_calibration = fts_tclm_execute_force_calibration; + info->tdata->tclm_parse_dt = sec_tclm_parse_dt; +#endif + +#ifdef USE_OPEN_DWORK + INIT_DELAYED_WORK(&info->open_work, fts_open_work); +#endif + INIT_DELAYED_WORK(&info->reset_work, fts_reset_work); + INIT_DELAYED_WORK(&info->work_read_info, fts_read_info_work); + INIT_DELAYED_WORK(&info->work_print_info, fts_print_info_work); +// INIT_DELAYED_WORK(&info->work_lfd_ctrl, fts_lfd_ctrl_work); + info->lfd_ctrl_delay = 500; + + if (pdata->hw_i2c_reset) + INIT_DELAYED_WORK(&info->fw_reset_work, fts_fw_reset_work); + + if (info->board->support_hover) + input_info(true, &info->client->dev, "%s: Support Hover Event\n", __func__); + else + input_info(true, &info->client->dev, "%s: Not support Hover Event\n", __func__); + + i2c_set_clientdata(client, info); + + if (pdata->get_ddi_type) { + info->ddi_type = pdata->get_ddi_type(); + input_info(true, &client->dev, "%s: DDI Type is %s[%d]\n", + __func__, info->ddi_type ? "MAGNA" : "SDC", info->ddi_type); + } + + return retval; +} + +static void fts_set_input_prop(struct fts_ts_info *info, struct input_dev *dev, u8 propbit) +{ + static char fts_ts_phys[64] = { 0 }; + + dev->dev.parent = &info->client->dev; + + snprintf(fts_ts_phys, sizeof(fts_ts_phys), "%s/input1", + dev->name); + dev->phys = fts_ts_phys; + dev->id.bustype = BUS_I2C; + + set_bit(EV_SYN, dev->evbit); + set_bit(EV_KEY, dev->evbit); + set_bit(EV_ABS, dev->evbit); + set_bit(propbit, dev->propbit); + set_bit(BTN_TOUCH, dev->keybit); + set_bit(BTN_TOOL_FINGER, dev->keybit); + set_bit(KEY_BLACK_UI_GESTURE, dev->keybit); + set_bit(KEY_WAKEUP, dev->keybit); + set_bit(KEY_INT_CANCEL, dev->keybit); + + if (info->board->support_sidegesture) { + set_bit(KEY_SIDE_GESTURE, dev->keybit); + set_bit(KEY_SIDE_GESTURE_RIGHT, dev->keybit); + set_bit(KEY_SIDE_GESTURE_LEFT, dev->keybit); + } + + input_set_abs_params(dev, ABS_MT_POSITION_X, + 0, info->board->max_x, 0, 0); + input_set_abs_params(dev, ABS_MT_POSITION_Y, + 0, info->board->max_y, 0, 0); +#ifdef CONFIG_SEC_FACTORY + input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); +#else + if (info->board->support_mt_pressure) + input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 10000, 0, 0); +#endif + + input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(dev, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); + input_set_abs_params(dev, ABS_MT_CUSTOM, 0, 0xFFFFFFFF, 0, 0); + + if (info->board->support_hover) + input_set_abs_params(dev, ABS_MT_DISTANCE, 0, 255, 0, 0); + + if (propbit == INPUT_PROP_POINTER) + input_mt_init_slots(dev, FINGER_MAX, INPUT_MT_POINTER); + else + input_mt_init_slots(dev, FINGER_MAX, INPUT_MT_DIRECT); + + input_set_drvdata(dev, info); +} + +static void fts_set_input_prop_proximity(struct fts_ts_info *info, struct input_dev *dev) +{ + char phys[64] = { 0 }; + + snprintf(phys, sizeof(phys), "%s/input1", dev->name); + dev->phys = phys; + dev->id.bustype = BUS_I2C; + dev->dev.parent = &info->client->dev; + + set_bit(EV_SYN, dev->evbit); + + input_set_abs_params(dev, ABS_MT_CUSTOM, 0, 0xFFFFFFFF, 0, 0); + + input_set_drvdata(dev, info); +} + +static int fts_probe(struct i2c_client *client, const struct i2c_device_id *idp) +{ + int retval; + struct fts_ts_info *info = NULL; + int i = 0; + + input_info(true, &client->dev, "%s: FTS Driver [70%s]\n", __func__, + FTS_TS_DRV_VERSION); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + input_err(true, &client->dev, "%s: FTS err = EIO!\n", __func__); + return -EIO; + } +#ifdef CONFIG_BATTERY_SAMSUNG + if (lpcharge == 1) { + input_err(true, &client->dev, "%s: Do not load driver due to : lpm %d\n", + __func__, lpcharge); + return -ENODEV; + } +#endif + /* Build up driver data */ + retval = fts_setup_drv_data(client); + if (retval < 0) { + input_err(true, &client->dev, "%s: Failed to set up driver data\n", __func__); + goto err_setup_drv_data; + } + + info = (struct fts_ts_info *)i2c_get_clientdata(client); + if (!info) { + input_err(true, &client->dev, "%s: Failed to get driver data\n", __func__); + retval = -ENODEV; + goto err_get_drv_data; + } + i2c_set_clientdata(client, info); + + info->probe_done = false; + + if (info->board->power) + info->board->power(info, true); + info->fts_power_state = FTS_POWER_STATE_ACTIVE; + + info->input_dev = input_allocate_device(); + if (!info->input_dev) { + input_err(true, &info->client->dev, "%s: Failed to alloc input_dev\n", __func__); + retval = -ENOMEM; + goto err_input_allocate_device; + } + + if (info->board->support_dex) { + info->input_dev_pad = input_allocate_device(); + if (!info->input_dev_pad) { + input_err(true, &info->client->dev, "%s: Failed to alloc input_dev\n", __func__); + retval = -ENOMEM; + goto err_input_pad_allocate_device; + } + } + + if (info->board->support_ear_detect) { + info->input_dev_proximity = input_allocate_device(); + if (!info->input_dev_proximity) { + input_err(true, &info->client->dev, "%s: Failed to alloc input_dev: proximity\n", __func__); + goto err_input_proximity_allocate_device; + } + } + + mutex_init(&info->device_mutex); + mutex_init(&info->i2c_mutex); + mutex_init(&info->irq_mutex); + mutex_init(&info->eventlock); + mutex_init(&info->status_mutex); + mutex_init(&info->wait_for); +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + mutex_init(&info->st_lock); +#endif + mutex_init(&info->sponge_mutex); + init_completion(&info->resume_done); + complete_all(&info->resume_done); + + retval = fts_init(info); + if (retval) { + input_err(true, &info->client->dev, "%s: fts_init fail!\n", __func__); + goto err_fts_init; + } + + fts_init_proc(info); + + mutex_lock(&info->device_mutex); + info->reinit_done = true; + mutex_unlock(&info->device_mutex); + + wake_lock_init(&info->wakelock, WAKE_LOCK_SUSPEND, "tsp_wakelock"); + + if (info->board->support_dex) { + info->input_dev_pad->name = "sec_touchpad"; + fts_set_input_prop(info, info->input_dev_pad, INPUT_PROP_POINTER); + } + + if (info->board->support_ear_detect) { + info->input_dev_proximity->name = "sec_touchproximity"; + fts_set_input_prop_proximity(info, info->input_dev_proximity); + } + + if (info->board->device_num == 0) + info->input_dev->name = "sec_touchscreen"; + else if (info->board->device_num == 2) + info->input_dev->name = "sec_touchscreen2"; + else + info->input_dev->name = "sec_touchscreen"; + fts_set_input_prop(info, info->input_dev, INPUT_PROP_DIRECT); +#ifdef USE_OPEN_CLOSE + info->input_dev->open = fts_input_open; + info->input_dev->close = fts_input_close; +#endif + info->input_dev_touch = info->input_dev; + + retval = input_register_device(info->input_dev); + if (retval) { + input_err(true, &info->client->dev, "%s: input_register_device fail!\n", __func__); + goto err_register_input; + } + if (info->board->support_dex) { + retval = input_register_device(info->input_dev_pad); + if (retval) { + input_err(true, &info->client->dev, "%s: input_register_device fail!\n", __func__); + goto err_register_input_pad; + } + } + + if (info->board->support_ear_detect) { + retval = input_register_device(info->input_dev_proximity); + if (retval) { + input_err(true, &info->client->dev, "%s: Unable to register %s input device\n", + __func__, info->input_dev_proximity->name); + goto err_register_input_dev_proximity; + } + } + + for (i = 0; i < FINGER_MAX; i++) { + info->finger[i].action = FTS_COORDINATE_ACTION_NONE; + info->finger[i].mcount = 0; + } + + retval = fts_irq_enable(info, true); + if (retval < 0) { + input_err(true, &info->client->dev, + "%s: Failed to enable attention interrupt\n", + __func__); + goto err_enable_irq; + } + +#ifdef FTS_SUPPORT_TA_MODE + info->register_cb = info->board->register_cb; + + info->callbacks.inform_charger = fts_ta_cb; + if (info->register_cb) + info->register_cb(&info->callbacks); +#endif + +#ifdef SEC_TSP_FACTORY_TEST +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + retval = sec_cmd_init(&info->sec, ft_commands, + ARRAY_SIZE(ft_commands), SEC_CLASS_DEVT_TSP1); +#else + retval = sec_cmd_init(&info->sec, ft_commands, + ARRAY_SIZE(ft_commands), SEC_CLASS_DEVT_TSP); +#endif + if (retval < 0) { + input_err(true, &info->client->dev, + "%s: Failed to sec_cmd_init\n", __func__); + retval = -ENODEV; + goto err_sec_cmd; + } + + retval = sysfs_create_group(&info->sec.fac_dev->kobj, + &sec_touch_factory_attr_group); + if (retval < 0) { + input_err(true, &info->client->dev, "%s: Failed to create sysfs group\n", __func__); + goto err_sysfs; + } + + retval = sysfs_create_link(&info->sec.fac_dev->kobj, + &info->input_dev->dev.kobj, "input"); + if (retval < 0) { + input_err(true, &info->client->dev, + "%s: Failed to create link\n", __func__); + goto err_input_link; + } +#endif + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + for (i = 0; i < (int)ARRAY_SIZE(attrs); i++) { + retval = sysfs_create_file(&info->input_dev->dev.kobj, + &attrs[i].attr); + if (retval < 0) { + input_err(true, &info->client->dev, + "%s: Failed to create sysfs attributes\n", + __func__); + } + } + + fts_secure_touch_init(info); +#endif + + device_init_wakeup(&client->dev, true); + +#ifdef FTS_SUPPORT_SPONGELIB + fts_check_custom_library(info); +#endif + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + mutex_init(&info->switching_mutex); + INIT_DELAYED_WORK(&info->switching_work, fts_switching_work); + + sec_input_register_notify(&info->nb, fts_notifier_call, 1); + + info->flip_status = -1; + info->flip_status_current = FTS_STATUS_UNFOLDING; // default : 0 unfolding +#ifdef CONFIG_FOLDER_HALL + /* Hall IC notify priority -> ftn -> register */ + info->hall_ic_nb.priority = 1; + info->hall_ic_nb.notifier_call = fts_hall_ic_notify; + if (info->board->support_hall_ic) { + hall_ic_register_notify(&info->hall_ic_nb); + input_info(true, &info->client->dev, "%s: hall ic register\n", __func__); + } +#endif +#endif + + schedule_delayed_work(&info->work_read_info, msecs_to_jiffies(100)); + info->info_work_done = true; + +#if defined(CONFIG_TOUCHSCREEN_DUMP_MODE) +#if defined(CONFIG_TOUCHSCREEN_DUAL_FOLDABLE) + tsp_callbacks[FTS_STATUS_UNFOLDING].inform_dump = tsp_dump; +#else + dump_callbacks.inform_dump = tsp_dump; +#endif + INIT_DELAYED_WORK(&info->debug_work, dump_tsp_rawdata); + p_debug_work = &info->debug_work; +#endif +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + info->ss_drv = sec_secure_touch_register(info, info->board->ss_touch_num, &info->input_dev->dev.kobj); +#endif + + info->psy = power_supply_get_by_name("battery"); + if (!info->psy) + input_err(true, &info->client->dev, "%s: Cannot find power supply\n", __func__); + + info->probe_done = true; + input_err(true, &info->client->dev, "%s: done\n", __func__); + input_log_fix(); + + return 0; + +#ifdef SEC_TSP_FACTORY_TEST + //sysfs_remove_link(&info->sec.fac_dev->kobj, "input"); +err_input_link: + sysfs_remove_group(&info->sec.fac_dev->kobj, + &sec_touch_factory_attr_group); +err_sysfs: +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + sec_cmd_exit(&info->sec, SEC_CLASS_DEVT_TSP1); +#else + sec_cmd_exit(&info->sec, SEC_CLASS_DEVT_TSP); +#endif +err_sec_cmd: +#endif + if (info->irq_enabled) + fts_irq_enable(info, false); +err_enable_irq: + if (info->board->support_ear_detect) { + input_unregister_device(info->input_dev_proximity); + info->input_dev_proximity = NULL; + } +err_register_input_dev_proximity: + if (info->board->support_dex) { + input_unregister_device(info->input_dev_pad); + info->input_dev_pad = NULL; + } +err_register_input_pad: + input_unregister_device(info->input_dev); + info->input_dev = NULL; + info->input_dev_touch = NULL; +err_register_input: + wake_lock_destroy(&info->wakelock); + +#ifdef SEC_TSP_FACTORY_TEST + kfree(info->ito_result); + kfree(info->cx_data); + kfree(info->pFrame); +#endif +err_fts_init: +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + mutex_destroy(&info->st_lock); +#endif + mutex_destroy(&info->device_mutex); + mutex_destroy(&info->i2c_mutex); + mutex_destroy(&info->status_mutex); + if (info->board->support_ear_detect) { + if (info->input_dev_proximity) + input_free_device(info->input_dev_proximity); + } +err_input_proximity_allocate_device: + if (info->board->support_dex) { + if (info->input_dev_pad) + input_free_device(info->input_dev_pad); + } +err_input_pad_allocate_device: + if (info->input_dev) + input_free_device(info->input_dev); +err_input_allocate_device: + if (info->board->power) + info->board->power(info, false); + if (gpio_is_valid(info->board->irq_gpio)) + gpio_free(info->board->irq_gpio); + + g_fts_info = NULL; + kfree(info); +err_get_drv_data: +err_setup_drv_data: + input_err(true, &client->dev, "%s: failed(%d)\n", __func__, retval); + input_log_fix(); + return retval; +} + +static int fts_remove(struct i2c_client *client) +{ + struct fts_ts_info *info = i2c_get_clientdata(client); +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + int i = 0; +#endif + + input_info(true, &info->client->dev, "%s\n", __func__); + info->shutdown_is_on_going = true; + + disable_irq_nosync(info->client->irq); + free_irq(info->client->irq, info); + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + cancel_delayed_work_sync(&info->switching_work); +#ifdef CONFIG_FOLDER_HALL + hall_ic_unregister_notify(&info->hall_ic_nb); +#endif +#endif + + if (info->board->hw_i2c_reset) + cancel_delayed_work_sync(&info->fw_reset_work); + cancel_delayed_work_sync(&info->work_print_info); + cancel_delayed_work_sync(&info->work_read_info); + cancel_delayed_work_sync(&info->reset_work); +// cancel_delayed_work_sync(&info->work_lfd_ctrl); + + wake_lock_destroy(&info->wakelock); + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + for (i = 0; i < (int)ARRAY_SIZE(attrs); i++) { + sysfs_remove_file(&info->input_dev->dev.kobj, + &attrs[i].attr); + } +#endif + +#ifdef SEC_TSP_FACTORY_TEST + sysfs_remove_link(&info->sec.fac_dev->kobj, "input"); + sysfs_remove_group(&info->sec.fac_dev->kobj, + &sec_touch_factory_attr_group); +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + sec_cmd_exit(&info->sec, SEC_CLASS_DEVT_TSP1); +#else + sec_cmd_exit(&info->sec, SEC_CLASS_DEVT_TSP); +#endif + + kfree(info->ito_result); + kfree(info->cx_data); + kfree(info->pFrame); +#endif + + if (info->board->support_dex) { + input_mt_destroy_slots(info->input_dev_pad); + input_unregister_device(info->input_dev_pad); + } + info->input_dev_pad = NULL; + + info->input_dev = info->input_dev_touch; + input_mt_destroy_slots(info->input_dev); + input_unregister_device(info->input_dev); + info->input_dev = NULL; + info->input_dev_touch = NULL; + + if (info->board->power) + info->board->power(info, false); + + g_fts_info = NULL; + kfree(info); + + return 0; +} + +#ifdef USE_OPEN_CLOSE +#ifdef USE_OPEN_DWORK +static void fts_open_work(struct work_struct *work) +{ + int retval; + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + open_work.work); + + input_info(true, &info->client->dev, "%s\n", __func__); + + retval = fts_start_device(info); + if (retval < 0) + input_err(true, &info->client->dev, + "%s: Failed to start device\n", __func__); +} +#endif + +static int fts_input_open(struct input_dev *dev) +{ + struct fts_ts_info *info = input_get_drvdata(dev); + int retval; + + if (!info->probe_done) { + input_dbg(true, &info->client->dev, "%s: not probe\n", __func__); + goto out; + } + if (!info->info_work_done) { + input_err(true, &info->client->dev, "%s: not finished info work\n", __func__); + goto out; + } + + input_dbg(false, &info->client->dev, "%s\n", __func__); + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + fts_secure_touch_stop(info, 1); +#endif + mutex_lock(&info->device_mutex); +#ifdef USE_OPEN_DWORK + schedule_delayed_work(&info->open_work, + msecs_to_jiffies(TOUCH_OPEN_DWORK_TIME)); +#else +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + cancel_delayed_work_sync(&info->switching_work); + mutex_lock(&info->switching_mutex); +#endif + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + retval = fts_start_device(info); + if (retval < 0) { + input_err(true, &info->client->dev, + "%s: Failed to start device\n", __func__); +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + mutex_unlock(&info->switching_mutex); +#endif + mutex_unlock(&info->device_mutex); + goto out; + } + } else { /* FTS_POWER_STATE_LOWPOWER */ + fts_set_lowpowermode(info, TO_TOUCH_MODE); + } + + info->fts_power_state = FTS_POWER_STATE_ACTIVE; + fts_set_hsync_scanmode(info, FTS_CMD_NPM_SYNC_SCAN); + + if (info->fix_active_mode) + fts_fix_active_mode(info, true); +#endif + + fts_set_temp(info, true); + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + mutex_unlock(&info->switching_mutex); +#endif + mutex_unlock(&info->device_mutex); + +out: + cancel_delayed_work(&info->work_print_info); + info->print_info_cnt_open = 0; + info->print_info_cnt_release = 0; + schedule_work(&info->work_print_info.work); + info->flip_status_prev = info->flip_status_current; + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + if (!info->board->support_hall_ic || info->board->support_flex_mode) + sec_input_notify(&info->nb, NOTIFIER_MAIN_TOUCH_ON, NULL); +#endif + return 0; +} + +static void fts_input_close(struct input_dev *dev) +{ + struct fts_ts_info *info = input_get_drvdata(dev); + + if (!info->probe_done || info->shutdown_is_on_going) { + input_dbg(false, &info->client->dev, "%s: not probe\n", __func__); + return; + } + if (!info->info_work_done) { + input_err(true, &info->client->dev, "%s: not finished info work\n", __func__); + return; + } + + input_dbg(false, &info->client->dev, "%s\n", __func__); + + if (info->touch_aging_mode) { + info->touch_aging_mode = false; + fts_reinit(info, false); + } + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + fts_secure_touch_stop(info, 1); +#endif + mutex_lock(&info->device_mutex); + +#ifdef TCLM_CONCEPT + sec_tclm_debug_info(info->tdata); +#endif + +#ifdef USE_OPEN_DWORK + cancel_delayed_work(&info->open_work); +#endif + cancel_delayed_work(&info->reset_work); + cancel_delayed_work(&info->work_print_info); + fts_print_info(info); + + if (info->flip_status_prev != info->flip_status_current || info->prox_power_off) { + input_report_key(info->input_dev, KEY_INT_CANCEL, 1); + input_sync(info->input_dev); + input_report_key(info->input_dev, KEY_INT_CANCEL, 0); + input_sync(info->input_dev); + } + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + cancel_delayed_work_sync(&info->switching_work); + mutex_lock(&info->switching_mutex); +#endif + if (info->flip_status_current || info->rear_selfie_mode) { + fts_stop_device(info); + } else { + if (info->lowpower_flag || info->ed_enable || info->pocket_mode) { + if (info->fix_active_mode) + fts_fix_active_mode(info, false); + fts_set_lowpowermode(info, TO_LOWPOWER_MODE); + } else { + fts_stop_device(info); + } + } +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + mutex_unlock(&info->switching_mutex); +#endif + info->prox_power_off = 0; + info->fw_corruption = false; + + mutex_unlock(&info->device_mutex); + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + if (!info->board->support_hall_ic) + sec_input_notify(&info->nb, NOTIFIER_MAIN_TOUCH_OFF, NULL); +#endif +} +#endif + +#if 0 //def CONFIG_SEC_FACTORY +static void fts_reinit_fac(struct fts_ts_info *info) +{ + u8 regAdd[3] = {0}; + + info->touch_count = 0; + + fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + info->scan_mode = FTS_SCAN_MODE_DEFAULT; + + fts_set_scanmode(info, info->scan_mode); + + if (info->flip_enable) + fts_set_cover_type(info, true); + +#ifdef CONFIG_GLOVE_TOUCH + /* enable glove touch when flip cover is closed */ + if (info->glove_enabled) { + info->touch_functions = info->touch_functions | FTS_TOUCHTYPE_BIT_GLOVE; + regAdd[0] = FTS_CMD_SET_GET_TOUCHTYPE; + regAdd[1] = (u8)(info->touch_functions & 0xFF); + regAdd[2] = (u8)(info->touch_functions >> 8); + fts_write_reg(info, ®Add[0], 3); + } +#endif + fts_command(info, FTS_CMD_FORCE_CALIBRATION, true); + + input_info(true, &info->client->dev, "%s\n", __func__); +} +#endif + +void fts_reinit(struct fts_ts_info *info, bool delay) +{ + u8 regAdd[3] = {0}; +#ifdef FTS_SUPPORT_TA_MODE + u8 data; + u8 wiredCharger; +#endif + u8 retry = 3; + int rc = 0; + + if (delay) { + rc = fts_wait_for_ready(info); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: Failed to wait for ready\n", __func__); + goto out; + } + rc = fts_read_chip_id(info); + if (rc < 0) { + input_err(true, &info->client->dev, "%s: Failed to read chip id\n", __func__); + goto out; + } + } + + do { + rc = fts_systemreset(info, 0); + if (rc < 0) + fts_reset(info, 20); + else + break; + } while (--retry); + + if (retry == 0) { + input_err(true, &info->client->dev, "%s: Failed to system reset\n", __func__); + goto out; + } + +#if defined(FTS_SUPPORT_SPONGELIB) && defined(CONFIG_SEC_FACTORY) + if (info->use_sponge) + fts_disable_sponge(info); +#endif + + fts_command(info, FTS_CMD_CLEAR_ALL_EVENT, true); + + info->touch_functions = FTS_TOUCHTYPE_DEFAULT_ENABLE; + + if (info->flip_enable) + fts_set_cover_type(info, true); + +#ifdef CONFIG_GLOVE_TOUCH + if (info->glove_enabled) + info->touch_functions = (info->touch_functions | FTS_TOUCHTYPE_BIT_GLOVE); +#endif + + regAdd[0] = FTS_CMD_SET_GET_TOUCHTYPE; + regAdd[1] = (u8)(info->touch_functions & 0xFF); + regAdd[2] = (u8)(info->touch_functions >> 8); + fts_write_reg(info, ®Add[0], 3); + +#ifdef FTS_SUPPORT_TA_MODE + regAdd[0] = FTS_CMD_SET_GET_CHARGER_MODE; + + if (info->TA_Pluged) { + fts_read_reg(info, ®Add[0], 1, &data, 1); + wiredCharger = data | FTS_BIT_CHARGER_MODE_WIRE_CHARGER; + regAdd[1] = wiredCharger; + fts_write_reg(info, ®Add[0], 2); + } +#endif + + /* need to add new command (dex mode ~ touchable area) */ + fts_set_external_noise_mode(info, EXT_NOISE_MODE_MAX); + + fts_set_fod_rect(info); + + if (info->brush_mode) { + u8 regAdd[3] = {FTS_CMD_SET_FUNCTION_ONOFF, FTS_FUNCTION_ENABLE_BRUSH_MODE, info->brush_mode}; + + input_info(true, &info->client->dev, "%s: set brush mode\n", __func__); + if (fts_write_reg(info, regAdd, 3) < 0) + input_err(true, &info->client->dev, "%s: brush_enable failed\n", __func__); + } + + if (info->touchable_area) { + u8 regAdd[3] = {FTS_CMD_SET_FUNCTION_ONOFF, FTS_FUNCTION_SET_TOUCHABLE_AREA, info->touchable_area}; + + input_info(true, &info->client->dev, "%s: set 16:9 mode\n", __func__); + if (fts_write_reg(info, regAdd, 3) < 0) + input_err(true, &info->client->dev, "%s: set_touchable_area failed\n", __func__); + } + + /* because edge and dead zone will recover soon */ +#if defined(CONFIG_TOUCHSCREEN_DUAL_FOLDABLE) + fts_set_grip_type(info, GRIP_ALL_DATA); +#else + fts_set_grip_type(info, ONLY_EDGE_HANDLER); +#endif + + if (info->board->support_ear_detect) { + + if (info->ed_enable) { + regAdd[0] = FTS_CMD_SET_EAR_DETECT; + regAdd[1] = info->ed_enable; + + rc = fts_write_reg(info, regAdd, 2); + input_info(true, &info->client->dev, "%s: set ear detect %s, rc = %d\n", + __func__, info->ed_enable ? "enable" : "disable", rc); + } + + if (info->pocket_mode) { + regAdd[0] = FTS_CMD_SET_POCKET_MODE; + regAdd[1] = info->pocket_mode; + + rc = fts_write_reg(info, regAdd, 2); + input_info(true, &info->client->dev, "%s: set pocket mode %s, rc = %d\n", + __func__, info->pocket_mode ? "enable" : "disable", rc); + } + } + + fts_delay(50); + +out: + info->touch_count = 0; + +#if defined(CONFIG_TOUCHSCREEN_DUAL_FOLDABLE) && defined(CONFIG_SEC_FACTORY) + if (info->flip_status_current == FTS_STATUS_FOLDING) + fts_set_hsync_scanmode(info, FTS_CMD_LPM_ASYNC_SCAN); +#endif + fts_set_scanmode(info, info->scan_mode); +} + +void fts_locked_release_all_finger(struct fts_ts_info *info) +{ + mutex_lock(&info->eventlock); + fts_release_all_finger(info); + mutex_unlock(&info->eventlock); +}; + +void fts_release_all_finger(struct fts_ts_info *info) +{ + int i; + + for (i = 0; i < FINGER_MAX; i++) { + input_mt_slot(info->input_dev, i); + + if (info->board->support_mt_pressure) + input_report_abs(info->input_dev, ABS_MT_PRESSURE, 0); + + input_report_abs(info->input_dev, ABS_MT_CUSTOM, 0); + + input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 0); + + if ((info->finger[i].action == FTS_COORDINATE_ACTION_PRESS) || + (info->finger[i].action == FTS_COORDINATE_ACTION_MOVE)) { + input_info(true, &info->client->dev, + "[RA] tID:%d mc:%d tc:%d\n", + i, info->finger[i].mcount, info->touch_count); + } + + info->finger[i].action = FTS_COORDINATE_ACTION_NONE; + info->finger[i].mcount = 0; + info->finger[i].palm_count = 0; + info->finger[i].noise_level = 0; + info->finger[i].max_strength = 0; + info->finger[i].hover_id_num = 0; + } + + info->touch_count = 0; + + input_report_key(info->input_dev, BTN_TOUCH, 0); + input_report_key(info->input_dev, BTN_TOOL_FINGER, 0); + + if (info->board->support_sidegesture) { + input_report_key(info->input_dev, KEY_SIDE_GESTURE, 0); + input_report_key(info->input_dev, KEY_SIDE_GESTURE_RIGHT, 0); + input_report_key(info->input_dev, KEY_SIDE_GESTURE_LEFT, 0); + } + + if (info->board->support_ear_detect) { + input_report_abs(info->input_dev_proximity, ABS_MT_CUSTOM, 0xFF); + input_sync(info->input_dev_proximity); + } + + input_sync(info->input_dev); + + info->check_multi = 0; + +// cancel_delayed_work_sync(&info->work_lfd_ctrl); +// info->lfd_ctrl = FTS_LFD_CTRL_UNLOCK; +// schedule_work(&info->work_lfd_ctrl.work); +} + +#ifdef CONFIG_TOUCHSCREEN_DUMP_MODE +static void dump_tsp_rawdata(struct work_struct *work) +{ + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + debug_work.work); + + if (info->rawdata_read_lock == 1) { + input_err(true, &info->client->dev, "%s: ignored ## already checking..\n", __func__); + return; + } + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: ignored ## IC is power off\n", __func__); + return; + } + + fts_run_rawdata_read_all(info); +} + +static void tsp_dump(void) +{ +#ifdef CONFIG_BATTERY_SAMSUNG + if (lpcharge) + return; +#endif + if (!p_debug_work) + return; + pr_err("%s: %s %s: start\n", FTS_TS_DRV_NAME, SECLOG, __func__); + schedule_delayed_work(p_debug_work, msecs_to_jiffies(100)); +} + +static void fts_sponge_dump_flush(struct fts_ts_info *info, int dump_area) +{ + int i, ret; + unsigned char *sec_spg_dat; + u16 addr; + + input_info(true, &info->client->dev, "%s: ++\n", __func__); + + sec_spg_dat = vmalloc(FTS_MAX_SPONGE_DUMP_BUFFER); + if (!sec_spg_dat) { + input_err(true, &info->client->dev, "%s : Failed!!\n", __func__); + return; + } + memset(sec_spg_dat, 0, FTS_MAX_SPONGE_DUMP_BUFFER); + + input_info(true, &info->client->dev, "%s: dump area=%d\n", __func__, dump_area); + + /* check dump area */ + if (dump_area == 0) + addr = FTS_CMD_SPONGE_LP_DUMP_EVENT; + else + addr = info->sponge_dump_border; + + if ((info->sponge_dump_event * info->sponge_dump_format) > FTS_MAX_SPONGE_DUMP_BUFFER) { + input_err(true, &info->client->dev, "%s: wrong sponge dump read size (%d)\n", + __func__, info->sponge_dump_event * info->sponge_dump_format); + vfree(sec_spg_dat); + return; + } + + /* dump all events at once */ + ret = fts_read_from_sponge(info, addr, sec_spg_dat, info->sponge_dump_event * info->sponge_dump_format); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Failed to read sponge\n", __func__); + vfree(sec_spg_dat); + return; + } + + for (i = 0 ; i < info->sponge_dump_event ; i++) { + int e_offset = i * info->sponge_dump_format; + char buff[30] = {0, }; + u16 edata[5]; + + edata[0] = (sec_spg_dat[1 + e_offset] & 0xFF) << 8 | (sec_spg_dat[0 + e_offset] & 0xFF); + edata[1] = (sec_spg_dat[3 + e_offset] & 0xFF) << 8 | (sec_spg_dat[2 + e_offset] & 0xFF); + edata[2] = (sec_spg_dat[5 + e_offset] & 0xFF) << 8 | (sec_spg_dat[4 + e_offset] & 0xFF); + edata[3] = (sec_spg_dat[7 + e_offset] & 0xFF) << 8 | (sec_spg_dat[6 + e_offset] & 0xFF); + edata[4] = (sec_spg_dat[9 + e_offset] & 0xFF) << 8 | (sec_spg_dat[8 + e_offset] & 0xFF); + + if (edata[0] || edata[1] || edata[2] || edata[3] || edata[4]) { + snprintf(buff, sizeof(buff), "%03d: %04x%04x%04x%04x%04x\n", + i + (info->sponge_dump_event * dump_area), + edata[0], edata[1], edata[2], edata[3], edata[4]); + sec_tsp_sponge_log(buff); + } + } + + vfree(sec_spg_dat); + input_info(true, &info->client->dev, "%s: --\n", __func__); +} +#endif + +static void fts_reset(struct fts_ts_info *info, unsigned int ms) +{ + input_info(true, &info->client->dev, "%s: Recover IC, discharge time:%d\n", __func__, ms); + + fts_interrupt_set(info, INT_DISABLE); + + if (info->board->power) + info->board->power(info, false); + + fts_delay(ms); + + if (info->board->power) + info->board->power(info, true); + + fts_delay(5); + + fts_interrupt_set(info, INT_ENABLE); +} + +static void fts_reset_work(struct work_struct *work) +{ + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + reset_work.work); + + if (info->debug_string & FTS_DEBUG_SEND_UEVENT) + sec_cmd_send_event_to_user(&info->sec, NULL, "RESULT=RESET"); + +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + if (atomic_read(&info->st_enabled)) { + input_err(true, &info->client->dev, "%s: secure touch enabled\n", + __func__); + return; + } +#endif + + input_info(true, &info->client->dev, "%s: Call Power-Off to recover IC\n", __func__); + info->reset_is_on_going = true; + + wake_lock(&info->wakelock); + + fts_stop_device(info); + + msleep(100); /* Delay to discharge the IC from ESD or On-state.*/ + if (fts_start_device(info) < 0) + input_err(true, &info->client->dev, "%s: Failed to start device\n", __func__); + + if (info->input_dev_touch->disabled) { + u8 data[8] = { 0 }; + + input_err(true, &info->client->dev, "%s: call input_close[0x%X]\n", __func__, info->lowpower_flag); + + if (info->lowpower_flag) { + if (info->fix_active_mode) + fts_fix_active_mode(info, false); + + fts_set_lowpowermode(info, TO_LOWPOWER_MODE); + + if ((info->lowpower_flag & FTS_MODE_AOD) && info->use_sponge) { + int i; + + for (i = 0; i < 4; i++) { + data[i * 2] = info->rect_data[i] & 0xFF; + data[i * 2 + 1] = (info->rect_data[i] >> 8) & 0xFF; + } +#ifdef FTS_SUPPORT_SPONGELIB + info->fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_AOD_RECT, + data, sizeof(data)); +#endif + } + } else { + fts_stop_device(info); + } + } + fts_set_press_property(info); + fts_set_fod_finger_merge(info); + + info->reset_is_on_going = false; + wake_unlock(&info->wakelock); +} + +static void fts_read_info_work(struct work_struct *work) +{ + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + work_read_info.work); + int ret; + + input_info(true, &info->client->dev, "%s\n", __func__); +#ifdef TCLM_CONCEPT + ret = sec_tclm_check_cal_case(info->tdata); + input_info(true, &info->client->dev, "%s: sec_tclm_check_cal_case ret: %d\n", __func__, ret); +#endif + + ret = fts_get_tsp_test_result(info); + if (ret < 0) + input_err(true, &info->client->dev, "%s: failed to get result\n", + __func__); + input_raw_info_d(true, &info->client->dev, "%s: fac test result %02X\n", + __func__, info->test_result.data[0]); + + fts_run_rawdata_read_all(info); + + input_info(true, &info->client->dev, "%s: read cm data in tsp ic\n", __func__); + fts_get_cmoffset_dump(info, info->cmoffset_sdc_proc, OFFSET_FW_SDC); + fts_get_cmoffset_dump(info, info->cmoffset_sub_proc, OFFSET_FW_SUB); + fts_get_cmoffset_dump(info, info->cmoffset_main_proc, OFFSET_FW_MAIN); + + info->info_work_done = true; + + if (info->shutdown_is_on_going) { + input_info(true, &info->client->dev, "%s done, do not run work\n", __func__); + return; + } + + schedule_work(&info->work_print_info.work); + +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + if (info->change_flip_status) { + input_info(true, &info->client->dev, "%s: re-try switching after reading info\n", __func__); + schedule_work(&info->switching_work.work); + } +#endif + /* sec_touchscreen is opened by KGSL(handler registered) in probe time + * so, + */ +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + if (!info->board->support_hall_ic) + sec_input_notify(&info->nb, NOTIFIER_MAIN_TOUCH_ON, NULL); +#endif + input_info(true, &info->client->dev, "%s done\n", __func__); + +} + +static void fts_fw_reset_work(struct work_struct *work) +{ + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + fw_reset_work.work); + u8 data[3]; + int ret; + + if (info->reset_is_on_going) { + input_err(true, &info->client->dev, "%s: reset is on going, attempt 3 sec after\n", __func__); + schedule_delayed_work(&info->fw_reset_work, msecs_to_jiffies(3000)); + return; + } + + data[0] = 0xC1; + data[1] = 0x13; + data[2] = info->fw_reset_cmd; + + ret = fts_write_reg(info, &data[0], 3); + if (ret < 0) { + input_err(true, &info->client->dev, "%s: Failed to write command: %d\n", __func__, data[2]); + } else { + input_err(true, &info->client->dev, "%s: send fw reset enable command: %d\n", __func__, data[2]); + } + if (info->fw_reset_cmd == 0x01) { + schedule_delayed_work(&info->fw_reset_work, msecs_to_jiffies(3000)); + } +} + +/* limit LFD during touch + * LFD LOCK : limit to Display LFD mode + */ +/* +static void fts_lfd_ctrl_work(struct work_struct *work) +{ + struct fts_ts_info *info = container_of(work, struct fts_ts_info, + work_lfd_ctrl.work); + struct sec_input_notify_data data; + + data.dual_policy = MAIN_TOUCHSCREEN; + + if (info->lfd_ctrl == info->lfd_ctrl_prev) + return; + + if (info->lfd_ctrl == FTS_LFD_CTRL_LOCK) { + sec_input_notify(&info->nb, NOTIFIER_LCD_VRR_LFD_LOCK_REQUEST, &data); + } else if (info->lfd_ctrl == FTS_LFD_CTRL_UNLOCK) { + sec_input_notify(&info->nb, NOTIFIER_LCD_VRR_LFD_LOCK_RELEASE, &data); + } else { + input_err(true, &info->client->dev, "%s: not work\n", __func__); + } + info->lfd_ctrl_prev = info->lfd_ctrl; +} +*/ + +void fts_chk_tsp_ic_status(struct fts_ts_info *info, int call_pos) +{ + mutex_lock(&info->status_mutex); + + input_info(true, &info->client->dev, + "%s: START: pos[%d] power_state[0x%X] lowpower_flag[0x%X] %sfolding\n", + __func__, call_pos, info->fts_power_state, info->lowpower_flag, + info->flip_status_current ? "" : "un"); + + if (call_pos == FTS_STATE_CHK_POS_OPEN) { + input_dbg(true, &info->client->dev, "%s: OPEN : Nothing\n", __func__); + + } else if (call_pos == FTS_STATE_CHK_POS_CLOSE) { + input_dbg(true, &info->client->dev, "%s: CLOSE: Nothing\n", __func__); + + } else if (call_pos == FTS_STATE_CHK_POS_HALL) { + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER && info->flip_status_current == FTS_STATUS_FOLDING) { + input_info(true, &info->client->dev, "%s: HALL : TSP IC LP => IC OFF\n", __func__); + fts_stop_device(info); + + } else { + input_info(true, &info->client->dev, "%s: HALL : Nothing\n", __func__); + } + } else if (call_pos == FTS_STATE_CHK_POS_SYSFS) { + if (info->rear_selfie_mode) { + if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER) { + input_info(true, &info->client->dev, "%s: SYSFS: Rear Selfie mode => TSP IC OFF\n", + __func__); + fts_stop_device(info); + } else { + input_info(true, &info->client->dev, "%s: SYSFS: Rear Selfie mode nothing!\n", __func__); + } + } else if (info->flip_status_current == FTS_STATUS_UNFOLDING) { + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN && info->lowpower_flag) { + input_info(true, &info->client->dev, "%s: SYSFS: TSP IC OFF => LP mode[0x%X]\n", + __func__, info->lowpower_flag); + fts_start_device(info); + fts_set_lowpowermode(info, TO_LOWPOWER_MODE); + + } else if (info->fts_power_state == FTS_POWER_STATE_LOWPOWER && info->lowpower_flag == 0) { + input_info(true, &info->client->dev, "%s: SYSFS: LP mode [0x0] => TSP IC OFF\n", + __func__); + fts_stop_device(info); + } else { + input_info(true, &info->client->dev, "%s: SYSFS: set lowpower_flag again[0x%X]\n", + __func__, info->lowpower_flag); + info->fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_MODE, + &info->lowpower_flag, sizeof(info->lowpower_flag)); + } + } else { + input_info(true, &info->client->dev, "%s: SYSFS: folding nothing[0x%X]\n", __func__, info->lowpower_flag); + } + } else { + input_info(true, &info->client->dev, "%s: ETC : nothing!\n", __func__); + } + + input_info(true, &info->client->dev, "%s: END : pos[%d] power_state[0x%X] lowpower_flag[0x%X]\n", + __func__, call_pos, info->fts_power_state, info->lowpower_flag); + + mutex_unlock(&info->status_mutex); +} + +/* optional reg : SEC_TS_CMD_LPM_AOD_OFF_ON(0x9B) */ +/* 0 : Async base scan (default on lp mode) */ +/* 1 : sync base scan */ +int fts_set_hsync_scanmode(struct fts_ts_info *info, u8 mode) +{ + int ret = 0; + u8 regAdd[2] = {FTS_CMD_SET_LPM_AOD_OFF_ON, 0}; + + input_info(true, &info->client->dev, "%s: mode:%x\n", __func__, mode); + regAdd[1] = mode; + + ret = fts_write_reg(info, ®Add[0], 2); + if (ret <= 0) + input_err(true, &info->client->dev, "%s: Failed to send command: %x/%x", + __func__, regAdd[0], regAdd[1]); + return ret; +} + +void fts_set_utc_sponge(struct fts_ts_info *info) +{ + struct timeval current_time; + u8 data[4]; + + do_gettimeofday(¤t_time); + data[0] = (u8)(current_time.tv_sec >> 0 & 0xFF); + data[1] = (u8)(current_time.tv_sec >> 8 & 0xFF); + data[2] = (u8)(current_time.tv_sec >> 16 & 0xFF); + data[3] = (u8)(current_time.tv_sec >> 24 & 0xFF); + + fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_UTC, data, sizeof(data)); +} + +int fts_set_lowpowermode(struct fts_ts_info *info, u8 mode) +{ + int ret = 0; + u8 d_lowpower_flag; + + input_info(true, &info->client->dev, "%s: %s(%X)\n", __func__, + mode == TO_LOWPOWER_MODE ? "ENTER" : "EXIT", info->lowpower_flag); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: power off error!\n", __func__); + goto out; + } + + if (mode == TO_LOWPOWER_MODE) { + if (device_may_wakeup(&info->client->dev)) + enable_irq_wake(info->irq); + + if (info->read_ito) + fts_panel_ito_test(info, OPEN_SHORT_CRACK_TEST); + info->read_ito = false; + + fts_set_opmode(info, FTS_OPMODE_LOWPOWER); + info->fts_power_state = FTS_POWER_STATE_LOWPOWER; + + fts_locked_release_all_finger(info); + +#ifdef FTS_SUPPORT_SPONGELIB + if (info->use_sponge) { + fts_set_utc_sponge(info); +#ifdef CONFIG_TOUCHSCREEN_DUMP_MODE + if (info->sponge_inf_dump) { + if (info->sponge_dump_delayed_flag) { + fts_sponge_dump_flush(info, info->sponge_dump_delayed_area); + info->sponge_dump_delayed_flag = false; + input_info(true, &info->client->dev, "%s : Sponge dump flush delayed work have proceed\n", __func__); + } + } +#endif + if (info->prox_power_off) + d_lowpower_flag = info->lowpower_flag & ~FTS_MODE_DOUBLETAP_WAKEUP; + else + d_lowpower_flag = info->lowpower_flag; + + info->fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_MODE, + &d_lowpower_flag, sizeof(d_lowpower_flag)); + } +#endif + + } else { + ret = fts_set_opmode(info, FTS_OPMODE_NORMAL); + if (ret < 0) { + info->reinit_done = false; + fts_reinit(info, false); + info->reinit_done = true; + } + + info->fts_power_state = FTS_POWER_STATE_ACTIVE; + + if (device_may_wakeup(&info->client->dev)) + disable_irq_wake(info->irq); + + info->lp_dump_readmore = 1; + } +out: + + return 0; +} + + +static int fts_stop_device(struct fts_ts_info *info) +{ + input_info(true, &info->client->dev, "%s\n", __func__); + + if (info->fts_power_state == FTS_POWER_STATE_POWERDOWN) { + input_err(true, &info->client->dev, "%s: already power off\n", __func__); + goto out; + } +#ifdef FTS_SUPPORT_SPONGELIB +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + if (info->sec.fac_dev) + get_lp_dump(info->sec.fac_dev, NULL, NULL); +#endif +#endif + if (info->board->hw_i2c_reset) + cancel_delayed_work_sync(&info->fw_reset_work); + + fts_command(info, FTS_CMD_SENSE_OFF, false); + fts_interrupt_set(info, INT_DISABLE); + fts_release_all_finger(info); + + info->hover_enabled = false; + info->hover_ready = false; + info->touch_noise_status = 0; + info->touch_noise_reason = 0; + info->wet_mode = 0; + info->fts_power_state = FTS_POWER_STATE_POWERDOWN; + + if (info->board->power) + info->board->power(info, false); +out: + + return 0; +} + +static int fts_start_device(struct fts_ts_info *info) +{ + input_info(true, &info->client->dev, "%s%s\n", + __func__, info->fts_power_state ? ": exit low power mode" : ""); + + if (info->fts_power_state == FTS_POWER_STATE_ACTIVE) { + input_err(true, &info->client->dev, "%s: already power on\n", __func__); + goto out; + } + + fts_release_all_finger(info); + + if (info->board->power) + info->board->power(info, true); + + fts_delay(20); + + info->reinit_done = false; + info->fts_power_state = FTS_POWER_STATE_ACTIVE; + fts_reinit(info, false);//true); + info->reinit_done = true; + + if (info->board->support_ear_detect) { + u8 data[2]; + int ret; + + if (info->ed_enable) { + data[0] = FTS_CMD_SET_EAR_DETECT; + data[1] = info->ed_enable; + + ret = fts_write_reg(info, data, 2); + input_info(true, &info->client->dev, "%s: set ear detect %s, ret = %d\n", + __func__, info->ed_enable ? "enable" : "disable", ret); + } + + if (info->pocket_mode) { + data[0] = FTS_CMD_SET_POCKET_MODE; + data[1] = info->pocket_mode; + + ret = fts_write_reg(info, data, 2); + input_info(true, &info->client->dev, "%s: set pocket mode %s, ret = %d\n", + __func__, info->pocket_mode ? "enable" : "disable", ret); + } + } + +#ifdef FTS_SUPPORT_SPONGELIB +#ifndef CONFIG_SEC_FACTORY + if (info->lowpower_flag) +#endif + info->fts_write_to_sponge(info, FTS_CMD_SPONGE_OFFSET_MODE, + &info->lowpower_flag, sizeof(info->lowpower_flag)); +#endif + +out: + fts_wirelesscharger_mode(info); + + return 0; +} + +static void fts_shutdown(struct i2c_client *client) +{ + struct fts_ts_info *info = i2c_get_clientdata(client); + + input_info(true, &info->client->dev, "%s\n", __func__); + + fts_remove(client); +} + +#ifdef CONFIG_PM +static int fts_pm_suspend(struct device *dev) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + input_dbg(true, &info->client->dev, "%s\n", __func__); + +#if 0//def USE_OPEN_CLOSE + if (info->input_dev) { + int retval = mutex_lock_interruptible(&info->input_dev->mutex); + + if (retval) { + input_err(true, &info->client->dev, + "%s : mutex error\n", __func__); + goto out; + } + + if (!info->input_dev->disabled) { + info->input_dev->disabled = true; + if (info->input_dev->users && info->input_dev->close) { + input_err(true, &info->client->dev, + "%s called without input_close\n", + __func__); + info->input_dev->close(info->input_dev); + } + info->input_dev->users = 0; + } + + mutex_unlock(&info->input_dev->mutex); + } +out: +#endif + reinit_completion(&info->resume_done); + + return 0; +} + +static int fts_pm_resume(struct device *dev) +{ + struct fts_ts_info *info = dev_get_drvdata(dev); + + input_dbg(true, &info->client->dev, "%s\n", __func__); + + complete_all(&info->resume_done); + + return 0; +} +#endif + +#if (!defined(CONFIG_PM)) && !defined(USE_OPEN_CLOSE) +static int fts_suspend(struct i2c_client *client, pm_message_t mesg) +{ + struct fts_ts_info *info = i2c_get_clientdata(client); + + input_dbg(true, &info->client->dev, "%s\n", __func__); + + if (info->lowpower_flag) { + fts_set_lowpowermode(info, TO_LOWPOWER_MODE); + } else { + fts_stop_device(info); + } + return 0; +} + +static int fts_resume(struct i2c_client *client) +{ + + struct fts_ts_info *info = i2c_get_clientdata(client); + + input_dbg(true, &info->client->dev, "%s\n", __func__); + + if (info->lowpower_flag) { + fts_set_lowpowermode(info, TO_TOUCH_MODE); + } else { + fts_start_device(info); + } + + return 0; +} +#endif + +static const struct i2c_device_id fts_device_id[] = { + {FTS_TS_DRV_NAME, 0}, + {} +}; + +#ifdef CONFIG_PM +static const struct dev_pm_ops fts_dev_pm_ops = { + .suspend = fts_pm_suspend, + .resume = fts_pm_resume, +}; +#endif + +#ifdef CONFIG_OF +static const struct of_device_id fts_match_table[] = { + {.compatible = "stm,fts_touch",}, + {}, +}; +#else +#define fts_match_table NULL +#endif + +static struct i2c_driver fts_i2c_driver = { + .driver = { + .name = FTS_TS_DRV_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = fts_match_table, +#endif +#ifdef CONFIG_PM + .pm = &fts_dev_pm_ops, +#endif + }, + .probe = fts_probe, + .remove = fts_remove, + .shutdown = fts_shutdown, +#if (!defined(CONFIG_PM)) && !defined(USE_OPEN_CLOSE) + .suspend = fts_suspend, + .resume = fts_resume, +#endif + .id_table = fts_device_id, +}; + +static int __init fts_driver_init(void) +{ + pr_info("[sec_input] %s\n", __func__); + + return i2c_add_driver(&fts_i2c_driver); +} + +static void __exit fts_driver_exit(void) +{ + i2c_del_driver(&fts_i2c_driver); +} + +MODULE_DESCRIPTION("STMicroelectronics MultiTouch IC Driver"); +MODULE_AUTHOR("STMicroelectronics, Inc."); +MODULE_LICENSE("GPL v2"); + +module_init(fts_driver_init); +module_exit(fts_driver_exit); diff --git a/drivers/input/touchscreen/stm/fts5cu56a/fts_ts.h b/drivers/input/touchscreen/stm/fts5cu56a/fts_ts.h new file mode 100644 index 000000000..e3eaf5ca1 --- /dev/null +++ b/drivers/input/touchscreen/stm/fts5cu56a/fts_ts.h @@ -0,0 +1,1092 @@ +#ifndef _LINUX_FTS_TS_H_ +#define _LINUX_FTS_TS_H_ + +#include +#include +#include +#include +#include +#include + +#define TSP_TYPE_BUILTIN_FW 0 +#define TSP_TYPE_EXTERNAL_FW 1 +#define TSP_TYPE_EXTERNAL_FW_SIGNED 2 +#define TSP_TYPE_SPU_FW_SIGNED 3 + +#define TSP_PATH_EXTERNAL_FW "/sdcard/Firmware/TSP/tsp.bin" +#define TSP_PATH_EXTERNAL_FW_SIGNED "/sdcard/Firmware/TSP/tsp_signed.bin" +#define TSP_PATH_SPU_FW_SIGNED "/spu/TSP/ffu_tsp.bin" + +#if defined(CONFIG_FOLDER_HALL) && defined(CONFIG_TOUCHSCREEN_DUAL_FOLDABLE) +#include +#endif +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE +#define input_raw_info_d(mode, dev, fmt, ...) input_raw_info(MAIN_TOUCH, dev, fmt, ## __VA_ARGS__) +#else +#define input_raw_info_d(mode, dev, fmt, ...) input_raw_info(mode, dev, fmt, ## __VA_ARGS__) +#endif + +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH +#include +#endif + +#define FTS_SUPPORT_SPONGELIB +#define USE_OPEN_CLOSE +#define SEC_TSP_FACTORY_TEST +#define CONFIG_GLOVE_TOUCH + +#include +#ifdef CONFIG_INPUT_TOUCHSCREEN_TCLMV2 +#define TCLM_CONCEPT +#endif + +#define USE_POR_AFTER_I2C_RETRY + +#define BRUSH_Z_DATA 63 /* for ArtCanvas */ + +#undef FTS_SUPPORT_TA_MODE +#undef USE_OPEN_DWORK + +#ifdef USE_OPEN_DWORK +#define TOUCH_OPEN_DWORK_TIME 10 +#endif +#define TOUCH_PRINT_INFO_DWORK_TIME 30000 /* 30s */ + +#define FIRMWARE_IC "fts_ic" +#define FTS_MAX_FW_PATH 64 +#define FTS_TS_DRV_NAME "fts_touch" +#define FTS_TS_DRV_VERSION "0100" + +#define FTS_TS_I2C_RETRY_CNT 3 + +/* + * fts1b: ID0: 0x39 + * fts9c: ID0: 0x50 + * fts5c: ID0: 0x48 + */ +#define FTS_ID0 0x48 +#define FTS_ID1 0x36 + +#define FTS_FIFO_MAX 31 +#define FTS_EVENT_SIZE 16 +#define FTS_VERSION_SIZE 9 + +#define PRESSURE_MIN 0 +#define PRESSURE_MAX 127 +#define FINGER_MAX 10 +#define AREA_MIN PRESSURE_MIN +#define AREA_MAX PRESSURE_MAX + +#define INT_ENABLE 1 +#define INT_DISABLE 0 + +#define FTS_CMD_SPONGE_ACCESS 0x0000 + +/* COMMANDS */ +#define FTS_CMD_SENSE_ON 0x10 +#define FTS_CMD_SENSE_OFF 0x11 +#define FTS_CMD_SW_RESET 0x12 +#define FTS_CMD_FORCE_CALIBRATION 0x13 +#define FTS_CMD_FACTORY_PANELCALIBRATION 0x14 + +#define FTS_READ_GPIO_STATUS 0x20 +#define FTS_READ_FIRMWARE_INTEGRITY 0x21 +#define FTS_READ_DEVICE_ID 0x22 +#define FTS_READ_PANEL_INFO 0x23 +#define FTS_READ_FW_VERSION 0x24 + +#define FTS_CMD_SET_GET_TOUCHTYPE 0x30 +#define FTS_CMD_SET_GET_OPMODE 0x31 +#define FTS_CMD_SET_GET_CHARGER_MODE 0x32 +#define FTS_CMD_SET_GET_NOISE_MODE 0x33 +#define FTS_CMD_SET_GET_REPORT_RATE 0x34 +#define FTS_CMD_SET_GET_TOUCH_MODE_FOR_THRESHOLD 0x35 +#define FTS_CMD_SET_GET_TOUCH_THRESHOLD 0x36 +#define FTS_CMD_SET_GET_KEY_THRESHOLD 0x37 +#define FTS_CMD_SET_GET_COVERTYPE 0x38 +#define FTS_CMD_WRITE_WAKEUP_GESTURE 0x39 +#define FTS_CMD_WRITE_COORDINATE_FILTER 0x3A +#define FTS_CMD_SET_FOD_FINGER_MERGE 0x3B +#define FTS_CMD_SET_EAR_DETECT 0x41 +#define FTS_CMD_SET_PROX_POWER_OFF 0x42 +#define FTS_CMD_SET_POCKET_MODE 0x42 + +#define FTS_READ_ONE_EVENT 0x60 +#define FTS_READ_ALL_EVENT 0x61 +#define FTS_CMD_CLEAR_ALL_EVENT 0x62 + +#define FTS_CMD_SENSITIVITY_MODE 0x70 +#define FTS_READ_SENSITIVITY_VALUE 0x72 +#define FTS_CMD_RUN_SRAM_TEST 0x78 + +#define FTS_CMD_SET_LPM_AOD_OFF_ON 0x9B + +#define FTS_CMD_LPM_ASYNC_SCAN 0x00 +#define FTS_CMD_LPM_SYNC_SCAN 0x01 +#define FTS_CMD_NPM_SYNC_SCAN 0x01 + +#define FTS_CMD_SET_FUNCTION_ONOFF 0xC1 + +/* FTS SPONGE COMMAND */ +#define FTS_CMD_SPONGE_DUMP_FLUSH 0x01 +#define FTS_CMD_SPONGE_READ_WRITE_CMD 0xAA +#define FTS_CMD_SPONGE_NOTIFY_CMD 0xC0 + +#define FTS_CMD_SPONGE_OFFSET_MODE 0x00 +#define FTS_CMD_SPONGE_OFFSET_AOD_RECT 0x02 +#define FTS_CMD_SPONGE_OFFSET_UTC 0x10 +#define FTS_CMD_SPONGE_PRESS_PROPERTY 0x14 +#define FTS_CMD_SPONGE_FOD_INFO 0x15 +#define FTS_CMD_SPONGE_FOD_POSITION 0x19 +#define FTS_CMD_SPONGE_FOD_RECT 0x4B +#define FTS_CMD_SPONGE_LP_DUMP 0xF0 +#define FTS_CMD_SPONGE_LP_DUMP_CUR_IDX 0xF2 +#define FTS_CMD_SPONGE_LP_DUMP_EVENT 0xF4 + +/* First byte of ONE EVENT */ +#define FTS_EVENT_PASS_REPORT 0x03 +#define FTS_EVENT_STATUS_REPORT 0x43 +#define FTS_EVENT_JITTER_RESULT 0x49 +#define FTS_EVENT_ERROR_REPORT 0xF3 + +/* Test Event */ +#define FTS_EVENT_JITTER_MUTUAL_TEST 0x01 +#define FTS_EVENT_JITTER_SELF_TEST 0x02 + +#define FTS_EVENT_JITTER_MUTUAL_MAX 0x01 +#define FTS_EVENT_JITTER_MUTUAL_MIN 0x02 +#define FTS_EVENT_JITTER_MUTUAL_AVG 0x03 +#define FTS_EVENT_JITTER_SELF_TX_P2P 0x05 +#define FTS_EVENT_JITTER_SELF_RX_P2P 0x06 + +#define FTS_EVENT_SRAM_TEST_RESULT 0xD0 + +/* Status Event */ +#define FTS_COORDINATE_EVENT 0 +#define FTS_STATUS_EVENT 1 +#define FTS_GESTURE_EVENT 2 +#define FTS_VENDOR_EVENT 3 + +#define FTS_GESTURE_CODE_SPAY 0x00 +#define FTS_GESTURE_CODE_DOUBLE_TAP 0x01 + +#define FTS_COORDINATE_ACTION_NONE 0 +#define FTS_COORDINATE_ACTION_PRESS 1 +#define FTS_COORDINATE_ACTION_MOVE 2 +#define FTS_COORDINATE_ACTION_RELEASE 3 + +#define FTS_EVENT_TOUCHTYPE_NORMAL 0 +#define FTS_EVENT_TOUCHTYPE_HOVER 1 +#define FTS_EVENT_TOUCHTYPE_FLIPCOVER 2 +#define FTS_EVENT_TOUCHTYPE_GLOVE 3 +#define FTS_EVENT_TOUCHTYPE_STYLUS 4 +#define FTS_EVENT_TOUCHTYPE_PALM 5 +#define FTS_EVENT_TOUCHTYPE_WET 6 +#define FTS_EVENT_TOUCHTYPE_PROXIMITY 7 +#define FTS_EVENT_TOUCHTYPE_JIG 8 + +/* Status - ERROR event */ +#define FTS_EVENT_STATUSTYPE_CMDDRIVEN 0 +#define FTS_EVENT_STATUSTYPE_ERROR 1 +#define FTS_EVENT_STATUSTYPE_INFORMATION 2 +#define FTS_EVENT_STATUSTYPE_USERINPUT 3 +#define FTS_EVENT_STATUSTYPE_VENDORINFO 7 + +#define FTS_ERR_EVNET_CORE_ERR 0x00 +#define FTS_ERR_EVENT_QUEUE_FULL 0x01 +#define FTS_ERR_EVENT_ESD 0x02 + +/* Status - Information report */ +#define FTS_INFO_READY_STATUS 0x00 +#define FTS_INFO_WET_MODE 0x01 +#define FTS_INFO_NOISE_MODE 0x02 +#define FTS_INFO_XENOSENSOR_DETECT 0x04 + +// Scan mode for A0 command +#define FTS_SCAN_MODE_SCAN_OFF 0 +#define FTS_SCAN_MODE_MS_SS_SCAN (1 << 0) +#define FTS_SCAN_MODE_KEY_SCAN (1 << 1) +#define FTS_SCAN_MODE_HOVER_SCAN (1 << 2) +#define FTS_SCAN_MODE_FORCE_TOUCH_SCAN (1 << 4) +#define FTS_SCAN_MODE_DEFAULT FTS_SCAN_MODE_MS_SS_SCAN + + +/* Control Command */ + +// For 0x30 command - touch type +#define FTS_TOUCHTYPE_BIT_TOUCH (1 << 0) +#define FTS_TOUCHTYPE_BIT_HOVER (1 << 1) +#define FTS_TOUCHTYPE_BIT_COVER (1 << 2) +#define FTS_TOUCHTYPE_BIT_GLOVE (1 << 3) +#define FTS_TOUCHTYPE_BIT_STYLUS (1 << 4) +#define FTS_TOUCHTYPE_BIT_PALM (1 << 5) +#define FTS_TOUCHTYPE_BIT_WET (1 << 6) +#define FTS_TOUCHTYPE_BIT_PROXIMITY (1 << 7) +#define FTS_TOUCHTYPE_DEFAULT_ENABLE (FTS_TOUCHTYPE_BIT_TOUCH | FTS_TOUCHTYPE_BIT_PALM | FTS_TOUCHTYPE_BIT_WET) + +// For 0x31 command - touch operation mode +#define FTS_OPMODE_NORMAL 0 +#define FTS_OPMODE_LOWPOWER 1 + +// For 0x32 command - charger mode +#define FTS_BIT_CHARGER_MODE_NORMAL 0 +#define FTS_BIT_CHARGER_MODE_WIRE_CHARGER 1 +#define FTS_BIT_CHARGER_MODE_WIRELESS_CHARGER 2 +#define FTS_BIT_CHARGER_MODE_WIRELESS_BATTERY_PACK 3 + +// For 0xC1 command - on/off function +#define FTS_FUNCTION_ENABLE_SIP_MODE 0x00 +#define FTS_FUNCTION_SET_MONITOR_NOISE_MODE 0x01 +#define FTS_FUNCTION_ENABLE_BRUSH_MODE 0x02 +#define FTS_FUNCTION_ENABLE_DEAD_ZONE 0x04 /* *#0*# */ +#define FTS_FUNCTION_ENABLE_SPONGE_LIB 0x05 +#define FTS_FUNCTION_EDGE_AREA 0x07 /* used for grip cmd */ +#define FTS_FUNCTION_DEAD_ZONE 0x08 /* used for grip cmd */ +#define FTS_FUNCTION_LANDSCAPE_MODE 0x09 /* used for grip cmd */ +#define FTS_FUNCTION_LANDSCAPE_TOP_BOTTOM 0x0A /* used for grip cmd */ +#define FTS_FUNCTION_EDGE_HANDLER 0x0C /* used for grip cmd */ +#define FTS_FUNCTION_ENABLE_VSYNC 0x0D +#define FTS_FUNCTION_SET_TOUCHABLE_AREA 0x0F +#define FTS_FUNCTION_SET_NOTE_MODE 0x10 +#define FTS_FUNCTION_SET_GAME_MODE 0x11 + +/* FTS DEBUG FLAG */ +#define FTS_DEBUG_PRINT_I2C_READ_CMD 0x04 +#define FTS_DEBUG_PRINT_I2C_WRITE_CMD 0x08 +#define FTS_DEBUG_SEND_UEVENT 0x80 + +#define FTS_RETRY_COUNT 10 +#define FTS_DELAY_NVWRITE 50 + +/* gesture SF */ +#define FTS_GESTURE_SAMSUNG_FEATURE 1 + +/* gesture type */ +#define FTS_SPONGE_EVENT_SWIPE_UP 0 +#define FTS_SPONGE_EVENT_DOUBLETAP 1 +#define FTS_SPONGE_EVENT_PRESS 3 +#define FTS_SPONGE_EVENT_SINGLETAP 4 +#define FTS_SPONGE_EVENT_DUMPFLUSH 5 + +/* gesture ID */ +#define FTS_SPONGE_EVENT_GESTURE_ID_AOD 0 +#define FTS_SPONGE_EVENT_GESTURE_ID_DOUBLETAP_TO_WAKEUP 1 +#define FTS_SPONGE_EVENT_GESTURE_ID_FOD_LONG 0 +#define FTS_SPONGE_EVENT_GESTURE_ID_FOD_NORMAL 1 +#define FTS_SPONGE_EVENT_GESTURE_ID_FOD_RELEASE 2 +#define FTS_SPONGE_EVENT_GESTURE_ID_FOD_OUT 3 +#define FTS_SPONGE_EVENT_GESTURE_ID_FOD_VI 4 + +/* SEC_TS_DUMP_ID */ +#define FTS_SPONGE_DUMP_0 0x00 +#define FTS_SPONGE_DUMP_1 0x01 + +#define FTS_ENABLE 1 +#define FTS_DISABLE 0 + +#define FTS_SPONGE_LP_DUMP_LENGTH 70 +#define FTS_SPONGE_LP_DUMP_DATA_FORMAT_10_LEN 12 /* addr 2, data 10, */ +#define FTS_SPONGE_LP_DUMP_DATA_FORMAT_8_LEN 10 /* addr 2, data 8 */ + +/* sponge mode */ +#define FTS_MODE_SPAY (1 << 1) +#define FTS_MODE_AOD (1 << 2) +#define FTS_MODE_SINGLETAP (1 << 3) +#define FTS_MODE_PRESS (1 << 4) +#define FTS_MODE_DOUBLETAP_WAKEUP (1 << 5) + +typedef enum { + SPONGE_EVENT_TYPE_SPAY = 0x04, + SPONGE_EVENT_TYPE_SINGLE_TAP = 0x08, + SPONGE_EVENT_TYPE_AOD_PRESS = 0x09, + SPONGE_EVENT_TYPE_AOD_LONGPRESS = 0x0A, + SPONGE_EVENT_TYPE_AOD_DOUBLETAB = 0x0B, + SPONGE_EVENT_TYPE_FOD = 0x0F, + SPONGE_EVENT_TYPE_FOD_RELEASE = 0x10, + SPONGE_EVENT_TYPE_FOD_OUT = 0x11, +} SPONGE_EVENT_TYPE; + +/*SPONGE library parameters*/ +#define FTS_MAX_SPONGE_DUMP_BUFFER 512 +#define FTS_SPONGE_DUMP_EVENT_MASK 0x7F +#define FTS_SPONGE_DUMP_INF_MASK 0x80 +#define FTS_SPONGE_DUMP_INF_SHIFT 7 + +#define FTS_MAX_X_RESOLUTION 4096 +#define FTS_MAX_Y_RESOLUTION 4096 +#define FTS_MAX_NUM_FORCE 50 /* Number of TX CH */ +#define FTS_MAX_NUM_SENSE 50 /* Number of RX CH */ + +#define FTS_LFD_CTRL_LOCK 1 +#define FTS_LFD_CTRL_UNLOCK 2 + +#define FTS_TS_LOCATION_DETECT_SIZE 6 + +#define FTS_STATUS_UNFOLDING 0x00 +#define FTS_STATUS_FOLDING 0x01 + +#ifdef FTS_SUPPORT_TA_MODE +extern struct fts_callbacks *fts_charger_callbacks; +struct fts_callbacks { + void (*inform_charger)(struct fts_callbacks *, int); +}; +#endif + +enum external_noise_mode { + EXT_NOISE_MODE_NONE = 0, + EXT_NOISE_MODE_MONITOR = 1, /* for dex mode */ + EXT_NOISE_MODE_MAX, /* add new mode above this line */ +}; + +enum fts_error_return { + FTS_NOT_ERROR = 0, + FTS_I2C_ERROR, + FTS_ERROR_INVALID_CHIP_ID, + FTS_ERROR_INVALID_CHIP_VERSION_ID, + FTS_ERROR_INVALID_SW_VERSION, + FTS_ERROR_EVENT_ID, + FTS_ERROR_FW_CORRUPTION, + FTS_ERROR_TIMEOUT, + FTS_ERROR_TIMEOUT_ZERO, + FTS_ERROR_FW_UPDATE_FAIL, + FTS_ERROR_BROKEN_OSC_TRIM, +}; + +enum fts_fw_update_status { + FTS_NOT_UPDATE = 10, + FTS_NEED_FW_UPDATE, + FTS_NEED_CALIBRATION_ONLY, + FTS_NEED_FW_UPDATE_N_CALIBRATION, +}; + +struct fts_sponge_information { + u8 sponge_use; // 0 : don't use, 1 : use + u16 sponge_ver; + u16 sponge_model_number; + u16 sponge_model_name_size; + u8 sponge_model_name[32]; +} __packed; + +enum grip_write_mode { + G_NONE = 0, + G_SET_EDGE_HANDLER = 1, + G_SET_EDGE_ZONE = 2, + G_SET_NORMAL_MODE = 4, + G_SET_LANDSCAPE_MODE = 8, + G_CLR_LANDSCAPE_MODE = 16, +}; +enum grip_set_data { + ONLY_EDGE_HANDLER = 0, + GRIP_ALL_DATA = 1, +}; + +/** + * struct fts_finger - Represents fingers. + * @ state: finger status (Event ID). + * @ mcount: moving counter for debug. + */ +struct fts_finger { + u8 id; + u8 prev_ttype; + u8 ttype; + u8 action; + u16 x; + u16 y; + u16 p_x; + u16 p_y; + u8 z; + u8 hover_flag; + u8 glove_flag; + u8 touch_height; + u16 mcount; + u8 major; + u8 minor; + bool palm; + int palm_count; + u8 left_event; + u8 max_energy; + u16 max_energy_x; + u16 max_energy_y; + u8 noise_level; + u8 max_strength; + u8 hover_id_num; +}; + +enum switch_system_mode { + TO_TOUCH_MODE = 0, + TO_LOWPOWER_MODE = 1, +}; + +enum tsp_power_mode { + FTS_POWER_STATE_POWERDOWN = 0, + FTS_POWER_STATE_LOWPOWER, + FTS_POWER_STATE_ACTIVE, +// FTS_POWER_STATE_SLEEP, +}; + +enum tsp_status_call_pos { + FTS_STATE_CHK_POS_OPEN = 0, + FTS_STATE_CHK_POS_CLOSE, + FTS_STATE_CHK_POS_HALL, + FTS_STATE_CHK_POS_SYSFS, +}; + +enum fts_cover_id { + FTS_FLIP_WALLET = 0, + FTS_VIEW_COVER, + FTS_COVER_NOTHING1, + FTS_VIEW_WIRELESS, + FTS_COVER_NOTHING2, + FTS_CHARGER_COVER, + FTS_VIEW_WALLET, + FTS_LED_COVER, + FTS_CLEAR_FLIP_COVER, + FTS_QWERTY_KEYBOARD_EUR, + FTS_QWERTY_KEYBOARD_KOR, + FTS_CLEAR_SIDE_VIEW_COVER = 15, + FTS_MINI_SVIEW_WALLET_COVER = 16, + FTS_MONTBLANC_COVER = 100, +}; + +enum fts_config_value_feature { + FTS_CFG_NONE = 0, + FTS_CFG_APWR = 1, + FTS_CFG_AUTO_TUNE_PROTECTION = 2, +}; + +enum { + SPECIAL_EVENT_TYPE_SPAY = 0x04, + SPECIAL_EVENT_TYPE_AOD = 0x08, + SPECIAL_EVENT_TYPE_AOD_PRESS = 0x09, + SPECIAL_EVENT_TYPE_AOD_LONGPRESS = 0x0A, + SPECIAL_EVENT_TYPE_AOD_DOUBLETAB = 0x0B, +}; + +enum fts_system_information_address { + FTS_SI_CONFIG_CHECKSUM = 0x58, /* 4 bytes */ + FTS_SI_OSC_TRIM_INFO = 0x60, /* 4 bytes */ +}; + +enum fts_ito_test_mode { + OPEN_TEST = 0, // trx_open_test 1,1 + SHORT_TEST, // trx_open_test 1,2 + MICRO_OPEN_TEST, // trx_open_test 2 + MICRO_SHORT_TEST, // trx_open_test 3 + OPEN_SHORT_CRACK_TEST, + SAVE_MISCAL_REF_RAW, +}; + +enum fts_ito_test_result { + ITO_PASS = 0, + ITO_FAIL, + ITO_FAIL_OPEN, + ITO_FAIL_SHORT, + ITO_FAIL_MICRO_OPEN, + ITO_FAIL_MICRO_SHORT, +}; + +/* FTS_OFFSET_SIGNUTRE */ +#define FTS_OFFSET_SIGNATURE 0x59525446 +#define FTS_CM2_SIGNATURE 0x324D5446 +#define FTS_CM3_SIGNATURE 0x334D5446 +#define FTS_FAIL_HIST_SIGNATURE 0x53484646 + +enum fts_miscal_test_result { + MISCAL_PASS = 0, + MISCAL_FAIL, +}; + +#define UEVENT_OPEN_SHORT_PASS 1 +#define UEVENT_OPEN_SHORT_FAIL 2 + +/* ---------------------------------------- + * write 0xE4 [ 11 | 10 | 01 | 00 ] + * MSB <-------------------> LSB + * read 0xE4 + * mapping sequnce : LSB -> MSB + * struct sec_ts_test_result { + * * assy : front + OCTA assay + * * module : only OCTA + * union { + * struct { + * u8 assy_count:2; -> 00 + * u8 assy_result:2; -> 01 + * u8 module_count:2; -> 10 + * u8 module_result:2; -> 11 + * } __attribute__ ((packed)); + * u8 data[1]; + * }; + *}; + * ---------------------------------------- + */ +struct fts_ts_test_result { + union { + struct { + u8 assy_count:2; + u8 assy_result:2; + u8 module_count:2; + u8 module_result:2; + } __packed; + u8 data[1]; + }; +}; + +#define TEST_OCTA_MODULE 1 +#define TEST_OCTA_ASSAY 2 + +#define TEST_OCTA_NONE 0 +#define TEST_OCTA_FAIL 1 +#define TEST_OCTA_PASS 2 + +#define SEC_OFFSET_SIGNATURE 0x59525446 + +enum offset_fac_position { + OFFSET_FAC_NOSAVE = 0, // FW index 0 + OFFSET_FAC_SUB = 1, // FW Index 2 + OFFSET_FAC_MAIN = 2, // FW Index 3 + OFFSET_FAC_SVC = 3, // FW Index 4 +}; + +enum offset_fw_position { + OFFSET_FW_NOSAVE = 0, + OFFSET_FW_SDC = 1, + OFFSET_FW_SUB = 2, + OFFSET_FW_MAIN = 3, + OFFSET_FW_SVC = 4, +}; + +enum offset_fac_data_type { + OFFSET_FAC_DATA_NO = 0, + OFFSET_FAC_DATA_CM = 1, + OFFSET_FAC_DATA_CM2 = 2, + OFFSET_FAC_DATA_CM3 = 3, +// OFFSET_FAC_DATA_SELF_FAIL = 7, +}; + +#define FTS_ITO_RESULT_PRINT_SIZE 1024 + +struct fts_sec_panel_test_result { + u8 flag; + u8 num_of_test; + u16 max_of_tx_gap; + u16 max_of_rx_gap; + u8 tx_of_txmax_gap; + u8 rx_of_txmax_gap; + u8 tx_of_rxmax_gap; + u8 rx_of_rxmax_gap; +} __packed; + +struct fts_sdc_panel_test_result { + u16 max_of_tx_gap; + u16 max_of_rx_gap; + u8 tx_of_txmax_gap; + u8 rx_of_txmax_gap; + u8 tx_of_rxmax_gap; + u8 rx_of_rxmax_gap; +} __packed; + +/* 16 byte */ +struct fts_event_coordinate { + u8 eid:2; + u8 tid:4; + u8 tchsta:2; + u8 x_11_4; + u8 y_11_4; + u8 y_3_0:4; + u8 x_3_0:4; + u8 major; + u8 minor; + u8 z:6; + u8 ttype_3_2:2; + u8 left_event:5; + u8 max_energy:1; + u8 ttype_1_0:2; + u8 noise_level; + u8 max_strength; + u8 hover_id_num:4; + u8 reserved_10:4; + u8 reserved_11; + u8 reserved_12; + u8 reserved_13; + u8 reserved_14; + u8 reserved_15; +} __packed; + + +/* 16 byte */ +struct fts_event_status { + u8 eid:2; + u8 stype:4; + u8 sf:2; + u8 status_id; + u8 status_data_1; + u8 status_data_2; + u8 status_data_3; + u8 status_data_4; + u8 status_data_5; + u8 left_event_4_0:5; + u8 max_energy:1; + u8 reserved:2; + u8 reserved_8; + u8 reserved_9; + u8 reserved_10; + u8 reserved_11; + u8 reserved_12; + u8 reserved_13; + u8 reserved_14; + u8 reserved_15; +} __packed; + +/* 34 byte */ +struct fts_selftest_fail_hist { + u32 tsp_signature; + u32 tsp_fw_version; + u16 fail_cnt; + u16 exec_parm; + u32 test_result; + u8 fail_data[18]; +} __attribute__ ((packed)); + +/* 16 byte */ +struct fts_gesture_status { + u8 eid:2; + u8 stype:4; + u8 sf:2; + u8 gesture_id; + u8 gesture_data_1; + u8 gesture_data_2; + u8 gesture_data_3; + u8 gesture_data_4; + u8 reserved_6; + u8 left_event_4_0:5; + u8 max_energy:1; + u8 reserved_7:2; + u8 reserved_8; + u8 reserved_9; + u8 reserved_10; + u8 reserved_11; + u8 reserved_12; + u8 reserved_13; + u8 reserved_14; + u8 reserved_15; +} __packed; + +struct FTS_SyncFrameHeader { + u8 header; // 0 + u8 host_data_mem_id; // 1 + u16 cnt; // 2~3 + u8 dbg_frm_len; // 4 + u8 ms_force_len; // 5 + u8 ms_sense_len; // 6 + u8 ss_force_len; // 7 + u8 ss_sense_len; // 8 + u8 key_len; // 9 + u16 reserved1; // 10~11 + u32 reserved2; // 12~15 +} __packed; + +struct stm_ts_snr_result_cmd { + s16 status; + s16 point; + s16 average; +} __packed; + +struct tsp_snr_result_of_point { + s16 max; + s16 min; + s16 average; + s16 nontouch_peak_noise; + s16 touch_peak_noise; + s16 snr1; + s16 snr2; +} __packed; + +struct stm_ts_snr_result { + s16 status; + s16 reserved[6]; + struct tsp_snr_result_of_point result[9]; +} __packed; + +struct fts_i2c_platform_data { + bool support_hover; + bool support_glove; + bool support_mt_pressure; + bool support_sidegesture; + bool support_dex; + bool support_open_short_test; + bool support_mis_calibration_test; + bool support_sram_test; + bool support_ear_detect; + bool sync_reportrate_120; + bool enable_settings_aot; + bool support_hall_ic; + bool support_flex_mode; + bool support_fod; + bool hw_i2c_reset; + int max_x; + int max_y; + u8 panel_revision; /* to identify panel info */ + const char *firmware_name; + const char *regulator_dvdd; + const char *regulator_avdd; + + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; + + int (*power)(void *data, bool on); + void (*register_cb)(void *); + void (*enable_sync)(bool on); + u8 (*get_ddi_type)(void); /* to indentify ddi type */ + + int tsp_icid; /* IC Vendor */ + int tsp_id; /* Panel Vendor */ + int device_id; /* Device id */ + + int irq_gpio; /* Interrupt GPIO */ + unsigned int irq_type; + u32 device_num; + + int gpio_scl; + int gpio_sda; + + int bringup; + + bool chip_on_board; +#ifdef CONFIG_INPUT_SEC_SECURE_TOUCH + int ss_touch_num; +#endif + u32 area_indicator; + u32 area_navigation; + u32 area_edge; +}; + +struct fts_ts_info { + struct i2c_client *client; + struct input_dev *input_dev; + struct input_dev *input_dev_pad; + struct input_dev *input_dev_touch; + struct input_dev *input_dev_proximity; + + int irq; + bool irq_enabled; + struct fts_i2c_platform_data *board; +#ifdef FTS_SUPPORT_TA_MODE + void (*register_cb)(void *); + struct fts_callbacks callbacks; +#endif + struct mutex lock; + bool probe_done; +#ifdef SEC_TSP_FACTORY_TEST + struct sec_cmd_data sec; + int SenseChannelLength; + int ForceChannelLength; + short *pFrame; + u8 miscal_result; + u8 *cx_data; + u8 *ito_result; +#endif + struct fts_ts_test_result test_result; + u8 disassemble_count; + u8 fac_nv; + + struct regulator *regulator_dvdd; + struct regulator *regulator_avdd; + + struct sec_tclm_data *tdata; + bool is_cal_done; + + bool fw_corruption; + bool hover_ready; + bool hover_enabled; + bool glove_enabled; + bool flip_enable; + bool mainscr_disable; + unsigned int cover_type; + u8 cover_cmd; + u8 external_noise_mode; + u8 brush_mode; + u8 touchable_area; + + int ICXResolution; + int ICYResolution; + + volatile u8 touch_noise_status; + u8 touch_noise_reason; + + u8 touch_opmode; + u16 touch_functions; + u8 charger_mode; + + u8 scan_mode; + + u8 lowpower_flag; + bool deepsleep_mode; + bool wet_mode; + bool xenosensor_detect; + unsigned int xenosensor_detect_count; /* noise mode count */ + struct tm xenosensor_time; + u16 xenosensor_x; + u16 xenosensor_y; + u16 xenosensor_detect_x; + u16 xenosensor_detect_y; + volatile int fts_power_state; + int wakeful_edge_side; + struct completion resume_done; + struct wake_lock wakelock; + +#ifdef FTS_SUPPORT_TA_MODE + bool TA_Pluged; +#endif + + unsigned int noise_count; /* noise mode count */ + + int touch_count; + struct fts_finger finger[FINGER_MAX]; + + int retry_hover_enable_after_wakeup; + + int fw_version_of_ic; /* firmware version of IC */ + int fw_version_of_bin; /* firmware version of binary */ + int config_version_of_ic; /* Config release data from IC */ + int config_version_of_bin; /* Config release data from IC */ + u16 fw_main_version_of_ic; /* firmware main version of IC */ + u16 fw_main_version_of_bin; /* firmware main version of binary */ + u8 project_id_of_ic; + u8 project_id_of_bin; + u8 ic_name_of_ic; + u8 ic_name_of_bin; + u8 module_version_of_ic; + u8 module_version_of_bin; + int panel_revision; /* Octa panel revision */ + int tspid_val; + int tspid2_val; + + struct notifier_block nb; + int flip_status_current; + int flip_status_prev; +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE + int flip_status; + int change_flip_status; + struct mutex switching_mutex; + struct delayed_work switching_work; +#ifdef CONFIG_FOLDER_HALL + struct notifier_block hall_ic_nb; +#endif +#endif +#ifdef USE_OPEN_DWORK + struct delayed_work open_work; +#endif + struct delayed_work work_read_nv; + + struct delayed_work work_print_info; + u32 print_info_cnt_open; + u32 print_info_cnt_release; + + unsigned int debug_string; + struct delayed_work reset_work; + struct delayed_work work_read_info; + struct delayed_work debug_work; + bool rawdata_read_lock; + volatile bool reset_is_on_going; + volatile bool shutdown_is_on_going; + + struct delayed_work work_lfd_ctrl; + char lfd_ctrl; + char lfd_ctrl_prev; + int lfd_ctrl_delay; + + struct delayed_work fw_reset_work; + u8 fw_reset_cmd; + + bool use_sponge; + unsigned int scrub_id; + unsigned int scrub_x; + unsigned int scrub_y; + + u8 press_prop; + int fod_x; + int fod_y; + int fod_vi_size; + u8 *fod_vi_data; + +#if defined(CONFIG_INPUT_SEC_SECURE_TOUCH) + atomic_t st_enabled; + atomic_t st_pending_irqs; + struct completion st_powerdown; + struct completion st_interrupt; + struct sec_touch_driver *ss_drv; + struct mutex st_lock; +#endif + struct mutex i2c_mutex; + struct mutex irq_mutex; + struct mutex device_mutex; + struct mutex eventlock; + struct mutex status_mutex; + struct mutex wait_for; + struct mutex sponge_mutex; + bool reinit_done; + bool info_work_done; + + u8 ddi_type; + + const char *firmware_name; + + u8 grip_edgehandler_direction; + int grip_edgehandler_start_y; + int grip_edgehandler_end_y; + u16 grip_edge_range; + u8 grip_deadzone_up_x; + u8 grip_deadzone_dn_x; + int grip_deadzone_y; + u8 grip_landscape_mode; + int grip_landscape_edge; + u16 grip_landscape_deadzone; + u16 grip_landscape_top_deadzone; + u16 grip_landscape_bottom_deadzone; + u16 grip_landscape_top_gripzone; + u16 grip_landscape_bottom_gripzone; + + u16 rect_data[4]; + u16 fod_rect_data[4]; + u8 ito_test[4]; + u8 check_multi; + bool read_ito; + unsigned int multi_count; + unsigned int wet_count; + unsigned int comm_err_count; + unsigned int checksum_result; + unsigned int all_finger_count; + unsigned int all_aod_tap_count; + unsigned int all_spay_count; + + u8 factory_position; + int proc_cmoffset_size; + int proc_cmoffset_all_size; + char *cmoffset_sdc_proc; + char *cmoffset_sub_proc; + char *cmoffset_main_proc; + char *cmoffset_all_proc; + + bool sponge_inf_dump; + u8 sponge_dump_format; + u8 sponge_dump_event; + u8 sponge_dump_border_msb; + u8 sponge_dump_border_lsb; + bool sponge_dump_delayed_flag; + u8 sponge_dump_delayed_area; + u16 sponge_dump_border; + + unsigned char *lp_dump; + int lp_dump_index; + int lp_dump_readmore; + + int prox_power_off; + bool rear_selfie_mode; + + u8 ed_enable; + u8 hover_event; + + u8 pocket_mode; + + /* thermistor */ + union power_supply_propval psy_value; + struct power_supply *psy; + u8 tsp_temp_data; + bool tsp_temp_data_skip; + + bool fix_active_mode; + bool touch_aging_mode; + int sensitivity_mode; + + u8 sip_mode; + + bool rawcap_lock; + int rawcap_max; + int rawcap_max_tx; + int rawcap_max_rx; + int rawcap_min; + int rawcap_min_tx; + int rawcap_min_rx; + + int (*stop_device)(struct fts_ts_info *info); + int (*start_device)(struct fts_ts_info *info); + + int (*fts_write_reg)(struct fts_ts_info *info, u8 *reg, u16 num_com); + int (*fts_read_reg)(struct fts_ts_info *info, u8 *reg, int cnum, u8 *buf, int num); + int (*fts_systemreset)(struct fts_ts_info *info, unsigned int msec); + int (*fts_wait_for_ready)(struct fts_ts_info *info); + void (*fts_command)(struct fts_ts_info *info, u8 cmd, bool checkEcho); + int (*fts_get_version_info)(struct fts_ts_info *info); + int (*fts_get_sysinfo_data)(struct fts_ts_info *info, u8 sysinfo_addr, u8 read_cnt, u8 *data); + +#ifdef FTS_SUPPORT_SPONGELIB + int (*fts_read_from_sponge)(struct fts_ts_info *info, u16 offset, u8 *data, int length); + int (*fts_write_to_sponge)(struct fts_ts_info *info, u16 offset, u8 *data, int length); +#endif +}; + +int fts_fw_update_on_probe(struct fts_ts_info *info); +int fts_fw_update_on_hidden_menu(struct fts_ts_info *info, int update_type); +void fts_reinit(struct fts_ts_info *info, bool delay); +int fts_execute_autotune(struct fts_ts_info *info, bool IsSaving); +int fts_fw_wait_for_event(struct fts_ts_info *info, u8 *result, u8 result_cnt); +int fts_fw_wait_for_echo_event(struct fts_ts_info *info, u8 *cmd, u8 cmd_cnt, int delay); +int fts_irq_enable(struct fts_ts_info *info, bool enable); +int fts_set_calibration_information(struct fts_ts_info *info, u8 count, u16 version); +void fts_checking_miscal(struct fts_ts_info *info); +int fts_get_tsp_test_result(struct fts_ts_info *info); +void fts_interrupt_set(struct fts_ts_info *info, int enable); +void fts_release_all_finger(struct fts_ts_info *info); +void fts_delay(unsigned int ms); +int fts_set_opmode(struct fts_ts_info *info, u8 mode); +int fts_set_scanmode(struct fts_ts_info *info, u8 scan_mode); +int fts_osc_trim_recovery(struct fts_ts_info *info); + +#ifdef TCLM_CONCEPT +int fts_tclm_data_read(struct i2c_client *client, int address); +int fts_tclm_data_write(struct i2c_client *client, int address); +int fts_tclm_execute_force_calibration(struct i2c_client *client, int cal_mode); +#endif +int set_nvm_data(struct fts_ts_info *info, u8 type, u8 *buf); +int get_nvm_data(struct fts_ts_info *info, int type, u8 *nvdata); + +int fts_panel_ito_test(struct fts_ts_info *info, int testmode); +void fts_chk_tsp_ic_status(struct fts_ts_info *info, int call_pos); +int fts_set_lowpowermode(struct fts_ts_info *info, u8 mode); +int fts_set_hsync_scanmode(struct fts_ts_info *info, u8 mode); +int fts_set_external_noise_mode(struct fts_ts_info *info, u8 mode); +int fts_fix_active_mode(struct fts_ts_info *info, bool enable); +#ifdef FTS_SUPPORT_SPONGELIB +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE +ssize_t get_lp_dump(struct device *dev, struct device_attribute *attr, char *buf); +#endif +int fts_check_custom_library(struct fts_ts_info *info); +#endif + +#ifndef CONFIG_SEC_SYSFS +extern struct class *sec_class; +#endif +#ifdef CONFIG_BATTERY_SAMSUNG +extern unsigned int lpcharge; +#endif +#if defined(CONFIG_DISPLAY_SAMSUNG) +extern int get_lcd_attached(char *mode); +#endif +#if defined(CONFIG_EXYNOS_DPU30) +extern int get_lcd_info(char *arg); +#endif + +extern void fts_set_grip_data_to_ic(struct fts_ts_info *info, u8 flag); +extern void fts_set_grip_type(struct fts_ts_info *info, u8 set_type); +void fts_run_rawdata_read_all(struct fts_ts_info *info); + +#ifdef CONFIG_TOUCHSCREEN_DUMP_MODE +#ifdef CONFIG_TOUCHSCREEN_DUAL_FOLDABLE +extern struct tsp_dump_callbacks *tsp_callbacks; +#else +extern struct tsp_dump_callbacks dump_callbacks; +#endif +#endif + +#endif /* _LINUX_FTS_TS_H_ */ diff --git a/drivers/input/touchscreen/stm/fts9cu80f_b/fts_sec.c b/drivers/input/touchscreen/stm/fts9cu80f_b/fts_sec.c index dedba394c..94298e116 100755 --- a/drivers/input/touchscreen/stm/fts9cu80f_b/fts_sec.c +++ b/drivers/input/touchscreen/stm/fts9cu80f_b/fts_sec.c @@ -6468,6 +6468,10 @@ static void spay_enable(void *device_data) else info->lowpower_flag &= ~FTS_MODE_SPAY; + mutex_lock(&info->device_mutex); + fts_chk_tsp_ic_status(info, FTS_STATE_CHK_POS_SYSFS); + mutex_unlock(&info->device_mutex); + snprintf(buff, sizeof(buff), "OK"); sec->cmd_state = SEC_CMD_STATUS_OK; sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); @@ -6490,6 +6494,10 @@ static void aot_enable(void *device_data) else info->lowpower_flag &= ~FTS_MODE_DOUBLETAP_WAKEUP; + mutex_lock(&info->device_mutex); + fts_chk_tsp_ic_status(info, FTS_STATE_CHK_POS_SYSFS); + mutex_unlock(&info->device_mutex); + snprintf(buff, sizeof(buff), "OK"); sec->cmd_state = SEC_CMD_STATUS_OK; sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); @@ -6510,6 +6518,10 @@ static void aod_enable(void *device_data) else info->lowpower_flag &= ~FTS_MODE_AOD; + mutex_lock(&info->device_mutex); + fts_chk_tsp_ic_status(info, FTS_STATE_CHK_POS_SYSFS); + mutex_unlock(&info->device_mutex); + snprintf(buff, sizeof(buff), "OK"); sec->cmd_state = SEC_CMD_STATUS_OK; sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); @@ -6530,6 +6542,10 @@ static void singletap_enable(void *device_data) else info->lowpower_flag &= ~FTS_MODE_SINGLETAP; + mutex_lock(&info->device_mutex); + fts_chk_tsp_ic_status(info, FTS_STATE_CHK_POS_SYSFS); + mutex_unlock(&info->device_mutex); + snprintf(buff, sizeof(buff), "OK"); sec->cmd_state = SEC_CMD_STATUS_OK; sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); diff --git a/drivers/input/touchscreen/zinitix/zt7650/zinitix_ts.c b/drivers/input/touchscreen/zinitix/zt7650/zinitix_ts.c index a893c5579..ba1bc9c89 100755 --- a/drivers/input/touchscreen/zinitix/zt7650/zinitix_ts.c +++ b/drivers/input/touchscreen/zinitix/zt7650/zinitix_ts.c @@ -943,6 +943,11 @@ static inline s32 read_data(struct i2c_client *client, return length; I2C_ERROR: + if (info->work_state == PROBE) { + input_err(true, &client->dev, + "%s work state is PROBE.\n", __func__); + return ret; + } if (info->work_state == ESD_TIMER) { input_err(true, &client->dev, "%s reset work queue be working.\n", __func__); @@ -1011,6 +1016,11 @@ static inline s32 write_data(struct i2c_client *client, mutex_unlock(&info->i2c_mutex); return length; I2C_ERROR: + if (info->work_state == PROBE) { + input_err(true, &client->dev, + "%s work state is PROBE.\n", __func__); + return ret; + } if (info->work_state == ESD_TIMER) { input_err(true, &client->dev, "%s reset work queue be working.\n", __func__); @@ -1083,6 +1093,11 @@ static inline s32 write_cmd(struct i2c_client *client, u16 reg) return I2C_SUCCESS; I2C_ERROR: + if (info->work_state == PROBE) { + input_err(true, &client->dev, + "%s work state is PROBE.\n", __func__); + return ret; + } if (info->work_state == ESD_TIMER) { input_err(true, &client->dev, "%s reset work queue be working.\n", __func__); @@ -1160,6 +1175,11 @@ static inline s32 read_raw_data(struct i2c_client *client, return length; I2C_ERROR: + if (info->work_state == PROBE) { + input_err(true, &client->dev, + "%s work state is PROBE.\n", __func__); + return ret; + } if (info->work_state == ESD_TIMER) { input_err(true, &client->dev, "%s reset work be working.\n", __func__); @@ -3690,7 +3710,6 @@ static irqreturn_t zt_touch_work(int irq, void *data) static int zt_ts_open(struct input_dev *dev) { struct zt_ts_info *info = misc_info; - u8 prev_work_state; int ret = 0; if (info == NULL) @@ -3720,14 +3739,13 @@ static int zt_ts_open(struct input_dev *dev) if (info->sleep_mode) { mutex_lock(&info->work_lock); - prev_work_state = info->work_state; info->work_state = SLEEP_MODE_OUT; info->sleep_mode = 0; input_info(true, &info->client->dev, "%s, wake up\n", __func__); write_cmd(info->client, ZT_WAKEUP_CMD); write_reg(info->client, ZT_OPTIONAL_SETTING, info->m_optional_mode.optional_mode); - info->work_state = prev_work_state; + info->work_state = NOTHING; mutex_unlock(&info->work_lock); #if ESD_TIMER_INTERVAL @@ -9775,8 +9793,8 @@ static int zt_ts_probe(struct i2c_client *client, #ifdef CONFIG_DISPLAY_SAMSUNG lcdtype = get_lcd_attached("GET"); - if (lcdtype == 0xFFFFFF) { - input_err(true, &client->dev, "%s: lcd is not attached\n", __func__); + if (lcdtype == 0xFFFFFF || ((lcdtype >> 8) != 0x8000)) { + input_err(true, &client->dev, "%s: lcd is not attached %X\n", __func__, lcdtype); return -ENODEV; } #endif @@ -9796,8 +9814,8 @@ static int zt_ts_probe(struct i2c_client *client, input_info(true, &client->dev, "%s: lcd is connected\n", __func__); lcdtype = get_lcd_info("id"); - if (lcdtype < 0) { - input_err(true, &client->dev, "%s: Failed to get lcd info\n", __func__); + if (lcdtype < 0 || ((lcdtype >> 8) != 0x8000)) { + input_err(true, &client->dev, "%s: Failed to get lcd info %X\n", __func__, lcdtype); return -EINVAL; } #endif @@ -9867,6 +9885,10 @@ static int zt_ts_probe(struct i2c_client *client, mutex_init(&info->i2c_mutex); mutex_init(&info->sponge_mutex); mutex_init(&info->power_init); +#if ESD_TIMER_INTERVAL + mutex_init(&info->lock); + INIT_WORK(&info->tmr_work, ts_tmr_work); +#endif info->input_dev = input_allocate_device(); if (!info->input_dev) { @@ -9917,8 +9939,6 @@ static int zt_ts_probe(struct i2c_client *client, misc_info = info; #if ESD_TIMER_INTERVAL - mutex_init(&info->lock); - INIT_WORK(&info->tmr_work, ts_tmr_work); esd_tmr_workqueue = create_singlethread_workqueue("esd_tmr_workqueue"); diff --git a/drivers/input/wacom/wacom_i2c.c b/drivers/input/wacom/wacom_i2c.c index bc8078aa3..a50edb25e 100644 --- a/drivers/input/wacom/wacom_i2c.c +++ b/drivers/input/wacom/wacom_i2c.c @@ -1104,13 +1104,11 @@ static void wacom_i2c_cover_handler(struct wacom_i2c *wac_i2c, char *data) change_status = (data[3] >> 7) & 0x01; - if (wac_i2c->flip_state != change_status) { - input_info(true, &wac_i2c->client->dev, "%s: cover status %d\n", __func__, change_status); - input_report_switch(wac_i2c->input_dev, - SW_FLIP, change_status); - input_sync(wac_i2c->input_dev); - wac_i2c->flip_state = change_status; - } + input_info(true, &wac_i2c->client->dev, "%s: cover status %d\n", __func__, change_status); + input_report_switch(wac_i2c->input_dev, + SW_FLIP, change_status); + input_sync(wac_i2c->input_dev); + wac_i2c->flip_state = change_status; } static void wacom_i2c_noti_handler(struct wacom_i2c *wac_i2c, char *data) @@ -1667,9 +1665,10 @@ static void pen_insert_work(struct work_struct *work) { struct wacom_i2c *wac_i2c = container_of(work, struct wacom_i2c, pen_insert_dwork.work); + char data; + int ret = 0; #if !WACOM_SEC_FACTORY - int ret = 0; if (wac_i2c->pdata->support_garage_open_test) { ret = wacom_open_test(wac_i2c, WACOM_GARAGE_TEST); @@ -1709,6 +1708,15 @@ static void pen_insert_work(struct work_struct *work) input_info(true, &wac_i2c->client->dev, "%s : pen is %s\n", __func__, (wac_i2c->function_result & EPEN_EVENT_PEN_OUT) ? "OUT" : "IN"); + + /* occur cover status event*/ + if (wac_i2c->pdata->support_cover_detection) { + data = COM_KBDCOVER_CHECK_STATUS; + ret = wacom_i2c_send(wac_i2c, &data, 1); + if (ret < 0) { + input_err(true, &wac_i2c->client->dev, "%s: failed to send cover status event %d\n", __func__, ret); + } + } } static void init_pen_insert(struct wacom_i2c *wac_i2c) diff --git a/drivers/input/wacom/wacom_reg.h b/drivers/input/wacom/wacom_reg.h index 09884bd75..e0244d4f4 100755 --- a/drivers/input/wacom/wacom_reg.h +++ b/drivers/input/wacom/wacom_reg.h @@ -17,6 +17,8 @@ #define COM_BOOKCOVER_COMPENSATION 0x81 #define COM_KBDCOVER_COMPENSATION 0x82 +#define COM_KBDCOVER_CHECK_STATUS 0x88 + /* elec test*/ #define COM_ASYNC_VSYNC 0X28 #define COM_SYNC_VSYNC 0X29 diff --git a/drivers/kunit/strerror-test.c b/drivers/kunit/strerror-test.c index 5965c514b..47abe3a85 100644 --- a/drivers/kunit/strerror-test.c +++ b/drivers/kunit/strerror-test.c @@ -13,8 +13,8 @@ static void test_strerror_returns_null_for_unknown_errors(struct test *test) { - EXPECT_NULL(test, strerror(-1)); - EXPECT_NULL(test, strerror(MAX_ERRNO + 1)); + EXPECT_NULL(test, strerror_str(-1)); + EXPECT_NULL(test, strerror_str(MAX_ERRNO + 1)); } static void test_strerror_r_returns_null_if_buflen_is_zero(struct test *test) @@ -27,7 +27,7 @@ static void test_strerror_returns_string(struct test *test) const char *err; char buf[64]; - err = strerror(EAGAIN); + err = strerror_str(EAGAIN); ASSERT_NOT_NULL(test, err); EXPECT_STREQ(test, err, "EAGAIN"); diff --git a/drivers/kunit/strerror.c b/drivers/kunit/strerror.c index c373b34ad..76aea258f 100644 --- a/drivers/kunit/strerror.c +++ b/drivers/kunit/strerror.c @@ -151,21 +151,16 @@ static const char * const errmap[] = { MAKE_ERROR(EHWPOISON) }; -//#pragma GCC diagnostic push -//#pragma GCC diagnostic ignored "-Wincompatible-library-redeclaration" - -const char *strerror(int errno) +const char *strerror_str(int errno) { if (errno < 0 || errno >= ARRAY_SIZE(errmap)) return NULL; return errmap[errno]; } -//#pragma GCC diagnostic pop - const char *strerror_r(int errno, char *buf, size_t buflen) { - const char *err = strerror(errno); + const char *err = strerror_str(errno); if (!buflen) return NULL; diff --git a/drivers/leds/leds-rt8547.c b/drivers/leds/leds-rt8547.c index f52e02f17..671b26bd8 100644 --- a/drivers/leds/leds-rt8547.c +++ b/drivers/leds/leds-rt8547.c @@ -149,7 +149,6 @@ ssize_t rt8547_led_store(struct device *dev, sysfs_flash_op = true; global_rt8547data->mode_status = RT8547_ENABLE_TORCH_MODE; spin_lock_irqsave(&global_rt8547data->int_lock, flags); - rt8547_led_write_data(RT8547_ADDR_HIDDEN_SETTING, RT8547_HIDDEN_LVP_DISABLE); rt8547_led_write_data(RT8547_ADDR_LVP_SETTING, RT8547_3V); if (value == 100) { pr_info("%s: sysfs flash value %d\n", __func__, value); @@ -247,7 +246,6 @@ int64_t rt8547_led_mode_ctrl(int state, int value) pr_info("%s: Pre Flash ON E(%d)\n", __func__, state); global_rt8547data->mode_status = RT8547_ENABLE_PRE_FLASH_MODE; spin_lock_irqsave(&global_rt8547data->int_lock, flags); - rt8547_led_write_data(RT8547_ADDR_HIDDEN_SETTING, RT8547_HIDDEN_LVP_DISABLE); rt8547_led_write_data(RT8547_ADDR_LVP_SETTING, global_rt8547data->LVP_Voltage); rt8547_led_write_data(RT8547_ADDR_CURRENT_SETTING, global_rt8547data->pre_current_value|RT8547_TORCH_SELECT); @@ -264,7 +262,6 @@ int64_t rt8547_led_mode_ctrl(int state, int value) spin_lock_irqsave(&global_rt8547data->int_lock, flags); if(value == 0) { - rt8547_led_write_data(RT8547_ADDR_HIDDEN_SETTING, RT8547_HIDDEN_LVP_DISABLE); rt8547_led_write_data(RT8547_ADDR_LVP_SETTING, global_rt8547data->LVP_Voltage); rt8547_led_write_data(RT8547_ADDR_CURRENT_SETTING, global_rt8547data->torch_current_value|RT8547_TORCH_SELECT); @@ -273,7 +270,6 @@ int64_t rt8547_led_mode_ctrl(int state, int value) } else { - rt8547_led_write_data(RT8547_ADDR_HIDDEN_SETTING, RT8547_HIDDEN_LVP_DISABLE); rt8547_led_write_data(RT8547_ADDR_LVP_SETTING, global_rt8547data->LVP_Voltage); rt8547_led_write_data(RT8547_ADDR_CURRENT_SETTING, value|RT8547_TORCH_SELECT); rt8547_led_write_data(RT8547_ADDR_FLASH_CURRENT_LEVEL_TIMEOUT_SETTING, @@ -291,15 +287,12 @@ int64_t rt8547_led_mode_ctrl(int state, int value) spin_lock_irqsave(&global_rt8547data->int_lock, flags); if(value == 0) { - rt8547_led_write_data(RT8547_ADDR_HIDDEN_SETTING, RT8547_HIDDEN_LVP_DISABLE); rt8547_led_write_data(RT8547_ADDR_LVP_SETTING, global_rt8547data->LVP_Voltage); // LVP setting rt8547_led_write_data(RT8547_ADDR_CURRENT_SETTING, RT8547_STROBE_SELECT); // Strobe select rt8547_led_write_data(RT8547_ADDR_FLASH_CURRENT_LEVEL_TIMEOUT_SETTING, (RT8547_TIMEOUT_CURRENT_400mA << 5) | global_rt8547data->flash_current_value); } - else { - rt8547_led_write_data(RT8547_ADDR_HIDDEN_SETTING, RT8547_HIDDEN_LVP_DISABLE); rt8547_led_write_data(RT8547_ADDR_LVP_SETTING, global_rt8547data->LVP_Voltage); // LVP setting rt8547_led_write_data(RT8547_ADDR_CURRENT_SETTING, RT8547_STROBE_SELECT); // Strobe select rt8547_led_write_data(RT8547_ADDR_FLASH_CURRENT_LEVEL_TIMEOUT_SETTING, @@ -355,7 +348,6 @@ int32_t rt8547_led_set_torch(int curr) LED_INFO("RT8547-FLICKERTEST ON E(%d)\n", curr); spin_lock_irqsave(&global_rt8547data->int_lock, flags); - rt8547_led_write_data(RT8547_ADDR_HIDDEN_SETTING, RT8547_HIDDEN_LVP_DISABLE); rt8547_led_write_data(RT8547_ADDR_LVP_SETTING, global_rt8547data->LVP_Voltage); rt8547_led_write_data(RT8547_ADDR_CURRENT_SETTING, curr|RT8547_TORCH_SELECT); diff --git a/drivers/md/alta_bigdata.c b/drivers/md/alta_bigdata.c index 3ecfc49f9..617c8d542 100644 --- a/drivers/md/alta_bigdata.c +++ b/drivers/md/alta_bigdata.c @@ -4,12 +4,15 @@ #include #include #include -#include -#include +#include +#include #include "dm-verity-debug.h" #define ALTA_BUF_SIZE 4096 + +static DEFINE_SPINLOCK(alta_lock); + char* alta_buf; size_t * alta_offset,alta_size; @@ -98,9 +101,10 @@ ssize_t alta_bigdata_read(struct file *filep, char __user *buf, size_t size, lof size_t proc_offset = 0; char* proc_buf = kzalloc(ALTA_BUF_SIZE, GFP_KERNEL); - if(!proc_buf) - return -ENOMEM; + if (!proc_buf) + return -ENOMEM; + spin_lock(&alta_lock); set_print_buf(proc_buf,&proc_offset,ALTA_BUF_SIZE); /* Print DMV info */ @@ -112,6 +116,7 @@ ssize_t alta_bigdata_read(struct file *filep, char __user *buf, size_t size, lof show_dmv_ctr_list(); show_fc_blks_list(); } + spin_unlock(&alta_lock); ret = simple_read_from_buffer(buf, size, offset, proc_buf, proc_offset); kfree(proc_buf); diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 34dc77e2b..682374b83 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -3995,54 +3995,60 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp) int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req, struct qseecom_send_modfd_listener_resp *lstnr_resp, - struct qseecom_dev_handle *data, int i) + struct qseecom_dev_handle *data, int i, size_t size) { + char *curr_field = NULL; + char *temp_field = NULL; + int j = 0; if ((data->type != QSEECOM_LISTENER_SERVICE) && (req->ifd_data[i].fd > 0)) { - if ((req->cmd_req_len < sizeof(uint32_t)) || + if ((req->cmd_req_len < size) || (req->ifd_data[i].cmd_buf_offset > - req->cmd_req_len - sizeof(uint32_t))) { + req->cmd_req_len - size)) { pr_err("Invalid offset (req len) 0x%x\n", req->ifd_data[i].cmd_buf_offset); return -EINVAL; } - } else if ((data->type == QSEECOM_LISTENER_SERVICE) && - (lstnr_resp->ifd_data[i].fd > 0)) { - if ((lstnr_resp->resp_len < sizeof(uint32_t)) || - (lstnr_resp->ifd_data[i].cmd_buf_offset > - lstnr_resp->resp_len - sizeof(uint32_t))) { - pr_err("Invalid offset (lstnr resp len) 0x%x\n", - lstnr_resp->ifd_data[i].cmd_buf_offset); - return -EINVAL; - } - } - return 0; -} - -static int __boundary_checks_offset_64(struct qseecom_send_modfd_cmd_req *req, - struct qseecom_send_modfd_listener_resp *lstnr_resp, - struct qseecom_dev_handle *data, int i) -{ - if ((data->type != QSEECOM_LISTENER_SERVICE) && - (req->ifd_data[i].fd > 0)) { - if ((req->cmd_req_len < sizeof(uint64_t)) || - (req->ifd_data[i].cmd_buf_offset > - req->cmd_req_len - sizeof(uint64_t))) { - pr_err("Invalid offset (req len) 0x%x\n", + curr_field = (char *) (req->cmd_req_buf + req->ifd_data[i].cmd_buf_offset); - return -EINVAL; + for (j = 0; j < MAX_ION_FD; j++) { + if ((req->ifd_data[j].fd > 0) && i != j) { + temp_field = (char *) (req->cmd_req_buf + + req->ifd_data[j].cmd_buf_offset); + if (temp_field >= curr_field && temp_field < + (curr_field + size)) { + pr_err("Invalid field offset 0x%x\n", + req->ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } } } else if ((data->type == QSEECOM_LISTENER_SERVICE) && (lstnr_resp->ifd_data[i].fd > 0)) { - if ((lstnr_resp->resp_len < sizeof(uint64_t)) || + if ((lstnr_resp->resp_len < size) || (lstnr_resp->ifd_data[i].cmd_buf_offset > - lstnr_resp->resp_len - sizeof(uint64_t))) { + lstnr_resp->resp_len - size)) { pr_err("Invalid offset (lstnr resp len) 0x%x\n", lstnr_resp->ifd_data[i].cmd_buf_offset); return -EINVAL; } + + curr_field = (char *) (lstnr_resp->resp_buf_ptr + + lstnr_resp->ifd_data[i].cmd_buf_offset); + for (j = 0; j < MAX_ION_FD; j++) { + if ((lstnr_resp->ifd_data[j].fd > 0) && i != j) { + temp_field = (char *) lstnr_resp->resp_buf_ptr + + lstnr_resp->ifd_data[j].cmd_buf_offset; + if (temp_field >= curr_field && temp_field < + (curr_field + size)) { + pr_err("Invalid lstnr field offset 0x%x\n", + lstnr_resp->ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } + } } return 0; } @@ -4117,8 +4123,10 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, if (sg_ptr->nents == 1) { uint32_t *update; - if (__boundary_checks_offset(req, lstnr_resp, data, i)) + if (__boundary_checks_offset(req, lstnr_resp, data, i, + sizeof(uint32_t))) goto err; + if ((data->type == QSEECOM_CLIENT_APP && (data->client.app_arch == ELFCLASS32 || data->client.app_arch == ELFCLASS64)) || @@ -4149,30 +4157,10 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, struct qseecom_sg_entry *update; int j = 0; - if ((data->type != QSEECOM_LISTENER_SERVICE) && - (req->ifd_data[i].fd > 0)) { - - if ((req->cmd_req_len < - SG_ENTRY_SZ * sg_ptr->nents) || - (req->ifd_data[i].cmd_buf_offset > - (req->cmd_req_len - - SG_ENTRY_SZ * sg_ptr->nents))) { - pr_err("Invalid offset = 0x%x\n", - req->ifd_data[i].cmd_buf_offset); - goto err; - } - - } else if ((data->type == QSEECOM_LISTENER_SERVICE) && - (lstnr_resp->ifd_data[i].fd > 0)) { + if (__boundary_checks_offset(req, lstnr_resp, data, i, + (SG_ENTRY_SZ * sg_ptr->nents))) + goto err; - if ((lstnr_resp->resp_len < - SG_ENTRY_SZ * sg_ptr->nents) || - (lstnr_resp->ifd_data[i].cmd_buf_offset > - (lstnr_resp->resp_len - - SG_ENTRY_SZ * sg_ptr->nents))) { - goto err; - } - } if ((data->type == QSEECOM_CLIENT_APP && (data->client.app_arch == ELFCLASS32 || data->client.app_arch == ELFCLASS64)) || @@ -4392,9 +4380,10 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, if (sg_ptr->nents == 1) { uint64_t *update_64bit; - if (__boundary_checks_offset_64(req, lstnr_resp, - data, i)) + if (__boundary_checks_offset(req, lstnr_resp, data, i, + sizeof(uint64_t))) goto err; + /* 64bit app uses 64bit address */ update_64bit = (uint64_t *) field; *update_64bit = cleanup ? 0 : @@ -4404,30 +4393,9 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, struct qseecom_sg_entry_64bit *update_64bit; int j = 0; - if ((data->type != QSEECOM_LISTENER_SERVICE) && - (req->ifd_data[i].fd > 0)) { - - if ((req->cmd_req_len < - SG_ENTRY_SZ_64BIT * sg_ptr->nents) || - (req->ifd_data[i].cmd_buf_offset > - (req->cmd_req_len - - SG_ENTRY_SZ_64BIT * sg_ptr->nents))) { - pr_err("Invalid offset = 0x%x\n", - req->ifd_data[i].cmd_buf_offset); - goto err; - } - - } else if ((data->type == QSEECOM_LISTENER_SERVICE) && - (lstnr_resp->ifd_data[i].fd > 0)) { - - if ((lstnr_resp->resp_len < - SG_ENTRY_SZ_64BIT * sg_ptr->nents) || - (lstnr_resp->ifd_data[i].cmd_buf_offset > - (lstnr_resp->resp_len - - SG_ENTRY_SZ_64BIT * sg_ptr->nents))) { - goto err; - } - } + if (__boundary_checks_offset(req, lstnr_resp, data, i, + (SG_ENTRY_SZ_64BIT * sg_ptr->nents))) + goto err; /* 64bit app uses 64bit address */ update_64bit = (struct qseecom_sg_entry_64bit *)field; for (j = 0; j < sg_ptr->nents; j++) { diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 01e466996..c9e25397b 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1698,6 +1698,7 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, struct mmc_blk_request *brq = &mqrq->brq; struct request *req = mmc_queue_req_to_req(mqrq); bool do_rel_wr, do_data_tag; + bool read_dir = (rq_data_dir(req) == READ); /* * Reliable writes are used to implement Forced Unit Access and @@ -1771,6 +1772,10 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, MMC_DATA_READ : MMC_DATA_WRITE, brq->data.blocks); } + if (mq->use_cqe) { + if (read_dir || req->cmd_flags & REQ_SYNC) + brq->data.flags |= MMC_DATA_PRIO; + } if (do_rel_wr) { mmc_apply_rel_rw(brq, card, req); diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index f684061c0..1bf057b3f 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -400,12 +400,13 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card) INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); if (mmc_card_sd(card)) { - /* decrease max # of requests to 32. The goal of this tunning is + /* decrease max # of requests to 32. The goal of this tuning is * reducing the time for draining elevator when elevator_switch * function is called. It is effective for slow external sdcard. */ mq->queue->nr_requests = BLKDEV_MAX_RQ / 8; - if (mq->queue->nr_requests < 32) mq->queue->nr_requests = 32; + if (mq->queue->nr_requests < 32) + mq->queue->nr_requests = 32; #ifdef CONFIG_LARGE_DIRTY_BUFFER /* apply more throttle on external sdcard */ mq->queue->backing_dev_info->capabilities |= BDI_CAP_STRICTLIMIT; @@ -538,7 +539,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq) #ifdef CONFIG_LARGE_DIRTY_BUFFER /* Restore bdi min/max ratio before device removal */ - /* Should proceed before blk_cleanup_queue */ bdi_set_min_ratio(q->backing_dev_info, 0); bdi_set_max_ratio(q->backing_dev_info, 100); #endif diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c index 6070393a8..b7f3ab9a1 100644 --- a/drivers/mmc/host/cqhci.c +++ b/drivers/mmc/host/cqhci.c @@ -280,7 +280,7 @@ static void __cqhci_enable(struct cqhci_host *cq_host) cqcfg |= CQHCI_TASK_DESC_SZ; if (cqhci_host_is_crypto_supported(cq_host)) { - cqhci_crypto_enable(cq_host); +// cqhci_crypto_enable(cq_host); cqcfg |= CQHCI_ICE_ENABLE; /* For SDHC v5.0 onwards, ICE 3.0 specific registers are added * in CQ register space, due to which few CQ registers are @@ -324,8 +324,8 @@ static void __cqhci_disable(struct cqhci_host *cq_host) { u32 cqcfg; - if (cqhci_host_is_crypto_supported(cq_host)) - cqhci_crypto_disable(cq_host); +// if (cqhci_host_is_crypto_supported(cq_host)) +// cqhci_crypto_disable(cq_host); cqcfg = cqhci_readl(cq_host, CQHCI_CFG); cqcfg &= ~CQHCI_ENABLE; @@ -371,6 +371,8 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) err = cqhci_host_alloc_tdl(cq_host); if (err) return err; + if (cqhci_host_is_crypto_supported(cq_host)) + cqhci_crypto_enable(cq_host); __cqhci_enable(cq_host); @@ -428,6 +430,8 @@ static void cqhci_disable(struct mmc_host *mmc) return; cqhci_off(mmc); + if (cqhci_host_is_crypto_supported(cq_host)) + cqhci_crypto_disable(cq_host); __cqhci_disable(cq_host); diff --git a/drivers/motor/cs40l2x-private.h b/drivers/motor/cs40l2x-private.h index d194b8a16..2c836677f 100644 --- a/drivers/motor/cs40l2x-private.h +++ b/drivers/motor/cs40l2x-private.h @@ -602,6 +602,9 @@ #define CS40L2X_TRIG_HIBER_MASK 0x00000001 #define CS40L2X_TRIG_HIBER_SHIFT 0 +#define CS40L2X_UPDT_WKCTL_MASK 0x00000100 +#define CS40L2X_UPDT_WKCTL_SHIFT 8 + #define CS40L2X_WKSRC_POL_MASK 0x0000000F #define CS40L2X_WKSRC_POL_SHIFT 0 #define CS40L2X_WKSRC_POL_GPIO1 1 @@ -616,6 +619,9 @@ #define CS40L2X_WKSRC_EN_GPIO4 4 #define CS40L2X_WKSRC_EN_SDA 8 +#define CS40L2X_WR_PEND_STS_MASK 0x2 +#define CS40L2X_WR_PEND_STS_SHIFT 1 + #define CS40L2X_PLL_REFCLK_EN_MASK 0x00000010 #define CS40L2X_PLL_REFCLK_EN_SHIFT 4 diff --git a/drivers/motor/cs40l2x.c b/drivers/motor/cs40l2x.c index a682ac88d..ee4942b54 100644 --- a/drivers/motor/cs40l2x.c +++ b/drivers/motor/cs40l2x.c @@ -466,7 +466,16 @@ static void set_cp_trigger_index_for_dig_scale(struct cs40l2x_private *cs40l2x) case 23: case 24: case 25: - case 31 ... 70: + case 31 ... 64: + case 71: + case 72: + case 75: + case 76: + case 81: + case 88: + case 89: + case 90: + case 92: short_duration = 1; break; default: @@ -1102,99 +1111,144 @@ static ssize_t cs40l2x_cp_trigger_q_sub_show(struct device *dev, return ret; } -static int cs40l2x_hiber_cmd_send(struct cs40l2x_private *cs40l2x, - unsigned int hiber_cmd) +static int cs40l2x_wait_for_pwrmgt_sts(struct cs40l2x_private *cs40l2x) { - struct regmap *regmap = cs40l2x->regmap; + unsigned int sts; + int i, ret; + + for (i = 0; i < CS40L2X_STATUS_RETRIES; i++) { + ret = regmap_read(cs40l2x->regmap, CS40L2X_PWRMGT_STS, &sts); + if (ret) + dev_err(cs40l2x->dev, + "Failed to read PWRMGT_STS: %d\n", ret); + else if (!(sts & CS40L2X_WR_PEND_STS_MASK)) + return 0; + } + + dev_err(cs40l2x->dev, "Timed out reading PWRMGT_STS\n"); + return -ETIMEDOUT; +} + +static int cs40l2x_apply_hibernate_errata(struct cs40l2x_private *cs40l2x) +{ + int ret; + + dev_warn(cs40l2x->dev, "Retry hibernate\n"); + + cs40l2x_wait_for_pwrmgt_sts(cs40l2x); + + ret = regmap_write(cs40l2x->regmap, CS40L2X_WAKESRC_CTL, + (CS40L2X_WKSRC_EN_SDA << CS40L2X_WKSRC_EN_SHIFT) | + (CS40L2X_WKSRC_POL_SDA << CS40L2X_WKSRC_POL_SHIFT)); + if (ret) + dev_err(cs40l2x->dev, "Failed to set WAKESRC: %d\n", ret); + + cs40l2x_wait_for_pwrmgt_sts(cs40l2x); + + ret = regmap_write(cs40l2x->regmap, CS40L2X_WAKESRC_CTL, + CS40L2X_UPDT_WKCTL_MASK | + (CS40L2X_WKSRC_EN_SDA << CS40L2X_WKSRC_EN_SHIFT) | + (CS40L2X_WKSRC_POL_SDA << CS40L2X_WKSRC_POL_SHIFT)); + if (ret) + dev_err(cs40l2x->dev, "Failed to enable WAKESRC: %d\n", ret); + + cs40l2x_wait_for_pwrmgt_sts(cs40l2x); + + /* + * This write may force the device into hibernation before the ACK is + * returned, so ignore the return value. + */ + regmap_write(cs40l2x->regmap, CS40L2X_PWRMGT_CTL, + (1 << CS40L2X_MEM_RDY_SHIFT) | + (1 << CS40L2X_TRIG_HIBER_SHIFT)); + + return 0; +} + +static int cs40l2x_wake_from_hibernate(struct cs40l2x_private *cs40l2x) +{ + unsigned int pwr_reg = cs40l2x_dsp_reg(cs40l2x, "POWERSTATE", + CS40L2X_XM_UNPACKED_TYPE, + cs40l2x->fw_desc->id); unsigned int val; - int ret, i, j; + int ret, i; - switch (hiber_cmd) { - case CS40L2X_POWERCONTROL_NONE: - case CS40L2X_POWERCONTROL_FRC_STDBY: - return cs40l2x_ack_write(cs40l2x, - CS40L2X_MBOX_POWERCONTROL, hiber_cmd, + dev_dbg(cs40l2x->dev, "Attempt wake from hibernate\n"); + + ret = cs40l2x_ack_write(cs40l2x, CS40L2X_MBOX_POWERCONTROL, + CS40L2X_POWERCONTROL_WAKEUP, CS40L2X_POWERCONTROL_NONE); + if (ret) { + if (ret == -ETIME) + cs40l2x_apply_hibernate_errata(cs40l2x); - case CS40L2X_POWERCONTROL_HIBERNATE: - /* - * control port is unavailable immediately after - * this write, so don't poll for acknowledgment - */ - return regmap_write(regmap, - CS40L2X_MBOX_POWERCONTROL, hiber_cmd); + return ret; + } - case CS40L2X_POWERCONTROL_WAKEUP: - for (i = 0; i < CS40L2X_WAKEUP_RETRIES; i++) { - /* - * the first several transactions are expected to be - * NAK'd, so retry multiple times in rapid succession - */ - ret = regmap_write(regmap, - CS40L2X_MBOX_POWERCONTROL, hiber_cmd); - if (ret) { - usleep_range(1000, 1100); - continue; - } + for (i = 0; i < CS40L2X_STATUS_RETRIES; i++) { + ret = regmap_read(cs40l2x->regmap, pwr_reg, &val); + if (ret) { + dev_err(cs40l2x->dev, "Failed to read POWERSTATE: %d\n", + ret); + return ret; + } - /* - * verify the previous firmware ID remains intact and - * brute-force a dummy hibernation cycle if otherwise - */ - for (j = 0; j < CS40L2X_STATUS_RETRIES; j++) { - usleep_range(5000, 5100); + dev_dbg(cs40l2x->dev, "Read POWERSTATE: %d\n", val); - ret = regmap_read(regmap, - CS40L2X_XM_FW_ID, &val); - if (ret) - return ret; + switch (val) { + case CS40L2X_POWERSTATE_ACTIVE: + case CS40L2X_POWERSTATE_STANDBY: + dev_dbg(cs40l2x->dev, "Woke from hibernate\n"); + return 0; + case CS40L2X_POWERSTATE_HIBERNATE: + break; + default: + dev_err(cs40l2x->dev, "Invalid POWERSTATE: %x\n", val); + break; + } - if (val == cs40l2x->fw_desc->id) - break; - } - if (j < CS40L2X_STATUS_RETRIES) - break; + usleep_range(5000, 5100); + } - dev_warn(cs40l2x->dev, - "Unexpected firmware ID: 0x%06X\n", - val); + dev_err(cs40l2x->dev, "Timed out waiting for POWERSTATE: %d\n", val); - /* - * this write may force the device into hibernation - * before the ACK is returned, so ignore the return - * value - */ - regmap_write(regmap, CS40L2X_PWRMGT_CTL, - (1 << CS40L2X_MEM_RDY_SHIFT) | - (1 << CS40L2X_TRIG_HIBER_SHIFT)); + cs40l2x_apply_hibernate_errata(cs40l2x); - usleep_range(1000, 1100); - } - if (i == CS40L2X_WAKEUP_RETRIES) - return -EIO; + return -ETIMEDOUT; +} - for (i = 0; i < CS40L2X_STATUS_RETRIES; i++) { - ret = regmap_read(regmap, - cs40l2x_dsp_reg(cs40l2x, "POWERSTATE", - CS40L2X_XM_UNPACKED_TYPE, - cs40l2x->fw_desc->id), - &val); - if (ret) - return ret; +static int cs40l2x_hiber_cmd_send(struct cs40l2x_private *cs40l2x, + unsigned int hiber_cmd) +{ + int i; + + switch (hiber_cmd) { + case CS40L2X_POWERCONTROL_NONE: + case CS40L2X_POWERCONTROL_FRC_STDBY: + return cs40l2x_ack_write(cs40l2x, CS40L2X_MBOX_POWERCONTROL, + hiber_cmd, CS40L2X_POWERCONTROL_NONE); + + case CS40L2X_POWERCONTROL_HIBERNATE: + /* + * The control port is unavailable immediately after this write, + * so don't poll for acknowledgment. + */ + return regmap_write(cs40l2x->regmap, CS40L2X_MBOX_POWERCONTROL, + hiber_cmd); - switch (val) { - case CS40L2X_POWERSTATE_ACTIVE: - case CS40L2X_POWERSTATE_STANDBY: + case CS40L2X_POWERCONTROL_WAKEUP: + /* + * The first several transactions are expected to be NAK'd, so + * retry multiple times in rapid succession. + */ + for (i = 0; i < CS40L2X_WAKEUP_RETRIES; i++) { + if (!cs40l2x_wake_from_hibernate(cs40l2x)) return 0; - case CS40L2X_POWERSTATE_HIBERNATE: - break; - default: - return -EINVAL; - } - usleep_range(5000, 5100); + usleep_range(1000, 1100); } - return -ETIME; + + return -ETIMEDOUT; default: return -EINVAL; @@ -4610,15 +4664,8 @@ static void cs40l2x_vibe_mode_worker(struct work_struct *work) unsigned int val; int ret; - if (cs40l2x->devid != CS40L2X_DEVID_L25A) - return; - mutex_lock(&cs40l2x->lock); - if (cs40l2x->vibe_mode == CS40L2X_VIBE_MODE_HAPTIC - && cs40l2x->asp_enable == CS40L2X_ASP_DISABLED) - goto err_mutex; - ret = regmap_read(regmap, cs40l2x_dsp_reg(cs40l2x, "STATUS", CS40L2X_XM_UNPACKED_TYPE, CS40L2X_ALGO_ID_VIBE), &val); if (ret) { @@ -4685,28 +4732,37 @@ static void cs40l2x_vibe_mode_worker(struct work_struct *work) } cs40l2x->vibe_mode = CS40L2X_VIBE_MODE_HAPTIC; - if (cs40l2x->vibe_state != CS40L2X_VIBE_STATE_RUNNING) - cs40l2x_wl_relax(cs40l2x); - } else if (cs40l2x->vibe_mode == CS40L2X_VIBE_MODE_HAPTIC && - cs40l2x->a2h_enable) { - ret = regmap_update_bits(regmap, CS40L2X_PWR_CTRL3, - CS40L2X_CLASSH_EN_MASK, - 1 << CS40L2X_CLASSH_EN_SHIFT); - if (ret) + if (cs40l2x->pbq_state != CS40L2X_PBQ_STATE_IDLE) goto err_mutex; - ret = regmap_write(regmap, CS40L2X_DSP_VIRT1_MBOX_5, - CS40L2X_A2H_I2S_START); - if (ret) + cs40l2x->vibe_state = CS40L2X_VIBE_STATE_STOPPED; + cs40l2x_wl_relax(cs40l2x); + } else { + /* haptic-mode teardown */ + if (cs40l2x->vibe_state == CS40L2X_VIBE_STATE_STOPPED + || cs40l2x->pbq_state != CS40L2X_PBQ_STATE_IDLE) goto err_mutex; + + if (cs40l2x->amp_gnd_stby) { + ret = regmap_write(regmap, + CS40L2X_SPK_FORCE_TST_1, + CS40L2X_FORCE_SPK_GND); + if (ret) { + dev_err(dev, + "Failed to ground amplifier outputs\n"); + goto err_mutex; + } + } + + cs40l2x->vibe_state = CS40L2X_VIBE_STATE_STOPPED; + cs40l2x_wl_relax(cs40l2x); } ret = cs40l2x_enable_classh(cs40l2x); if (ret) goto err_mutex; - err_mutex: mutex_unlock(&cs40l2x->lock); } @@ -4905,36 +4961,6 @@ static void cs40l2x_vibe_pbq_worker(struct work_struct *work) switch (cs40l2x->pbq_state) { case CS40L2X_PBQ_STATE_IDLE: - if (cs40l2x->vibe_state == CS40L2X_VIBE_STATE_STOPPED) - goto err_mutex; - - ret = regmap_read(regmap, - cs40l2x_dsp_reg(cs40l2x, "STATUS", - CS40L2X_XM_UNPACKED_TYPE, - CS40L2X_ALGO_ID_VIBE), - &val); - if (ret) { - dev_err(dev, "Failed to capture playback status\n"); - goto err_mutex; - } - - if (val != CS40L2X_STATUS_IDLE) - goto err_mutex; - - if (cs40l2x->amp_gnd_stby) { - ret = regmap_write(regmap, - CS40L2X_SPK_FORCE_TST_1, - CS40L2X_FORCE_SPK_GND); - if (ret) { - dev_err(dev, - "Failed to ground amplifier outputs\n"); - goto err_mutex; - } - } - - cs40l2x->vibe_state = CS40L2X_VIBE_STATE_STOPPED; - if (cs40l2x->vibe_mode != CS40L2X_VIBE_MODE_AUDIO) - cs40l2x_wl_relax(cs40l2x); goto err_mutex; case CS40L2X_PBQ_STATE_PLAYING: @@ -9456,7 +9482,6 @@ static int cs40l2x_i2c_remove(struct i2c_client *i2c_client) static int __maybe_unused cs40l2x_suspend(struct device *dev) { struct cs40l2x_private *cs40l2x = dev_get_drvdata(dev); - struct i2c_client *i2c_client = to_i2c_client(dev); int ret = 0; dev_info(dev, "Entering cs40l2x_suspend...\n"); @@ -9467,9 +9492,6 @@ static int __maybe_unused cs40l2x_suspend(struct device *dev) return ret; } #endif - - disable_irq(i2c_client->irq); - mutex_lock(&cs40l2x->lock); if (cs40l2x->pdata.gpio1_mode == CS40L2X_GPIO1_MODE_AUTO @@ -9503,7 +9525,6 @@ static int __maybe_unused cs40l2x_suspend(struct device *dev) static int __maybe_unused cs40l2x_resume(struct device *dev) { struct cs40l2x_private *cs40l2x = dev_get_drvdata(dev); - struct i2c_client *i2c_client = to_i2c_client(dev); int ret = 0; #ifdef CONFIG_CS40L2X_SAMSUNG_FEATURE @@ -9539,8 +9560,6 @@ static int __maybe_unused cs40l2x_resume(struct device *dev) err_mutex: mutex_unlock(&cs40l2x->lock); - enable_irq(i2c_client->irq); - return ret; } diff --git a/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs.h b/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs.h index 99ca7e449..5c28537fa 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs.h +++ b/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -106,6 +106,7 @@ struct rmnet_shs_cfg_s { u8 dl_ind_state; u8 map_mask; u8 map_len; + u8 ff_flag; }; @@ -178,6 +179,8 @@ enum rmnet_shs_flush_reason_e { RMNET_SHS_FLUSH_WQ_FB_FLUSH, RMNET_SHS_FLUSH_WQ_CORE_FLUSH, RMNET_SHS_FLUSH_PSH_PKT_FLUSH, + RMNET_SHS_FLUSH_WQ_FB_FF_FLUSH, + RMNET_SHS_FLUSH_Z_QUEUE_FLUSH, RMNET_SHS_FLUSH_MAX_REASON }; diff --git a/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs_main.c b/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs_main.c index b08070ef0..85251f42d 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs_main.c +++ b/drivers/net/ethernet/qualcomm/rmnet/shs/rmnet_shs_main.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -83,6 +83,18 @@ unsigned int rmnet_shs_byte_store_limit __read_mostly = 271800 * 80; module_param(rmnet_shs_byte_store_limit, uint, 0644); MODULE_PARM_DESC(rmnet_shs_byte_store_limit, "Maximum byte module will park"); +unsigned int rmnet_shs_in_count = 0; +module_param(rmnet_shs_in_count, uint, 0644); +MODULE_PARM_DESC(rmnet_shs_in_count, "SKb in count"); + +unsigned int rmnet_shs_out_count = 0; +module_param(rmnet_shs_out_count, uint, 0644); +MODULE_PARM_DESC(rmnet_shs_out_count, "SKb out count"); + +unsigned int rmnet_shs_wq_fb_limit = 10; +module_param(rmnet_shs_wq_fb_limit, uint, 0644); +MODULE_PARM_DESC(rmnet_shs_wq_fb_limit, "Final fb timer"); + unsigned int rmnet_shs_pkts_store_limit __read_mostly = 2100 * 8; module_param(rmnet_shs_pkts_store_limit, uint, 0644); MODULE_PARM_DESC(rmnet_shs_pkts_store_limit, "Maximum pkts module will park"); @@ -371,6 +383,8 @@ static void rmnet_shs_deliver_skb(struct sk_buff *skb) struct rmnet_priv *priv; struct napi_struct *napi; + rmnet_shs_out_count++; + SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START, 0xDEF, 0xDEF, 0xDEF, 0xDEF, skb, NULL); @@ -393,6 +407,7 @@ static void rmnet_shs_deliver_skb_wq(struct sk_buff *skb) SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START, 0xDEF, 0xDEF, 0xDEF, 0xDEF, skb, NULL); + rmnet_shs_out_count++; priv = netdev_priv(skb->dev); gro_cells_receive(&priv->gro_cells, skb); @@ -461,6 +476,7 @@ static void rmnet_shs_deliver_skb_segmented(struct sk_buff *in_skb, SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START, 0x1, 0xDEF, 0xDEF, 0xDEF, in_skb, NULL); + rmnet_shs_out_count++; segs = rmnet_shs_skb_partial_segment(in_skb, segs_per_skb); if (segs == NULL) { @@ -823,6 +839,7 @@ int rmnet_shs_node_can_flush_pkts(struct rmnet_shs_skbn_s *node, u8 force_flush) int new_cpu; struct rmnet_shs_cpu_node_s *cpun; u8 map = rmnet_shs_cfg.map_mask; + u32 old_cpu_qlen; cpu_map_index = rmnet_shs_get_hash_map_idx_to_stamp(node); do { @@ -849,9 +866,9 @@ int rmnet_shs_node_can_flush_pkts(struct rmnet_shs_skbn_s *node, u8 force_flush) cur_cpu_qhead = rmnet_shs_get_cpu_qhead(node->map_cpu); node_qhead = node->queue_head; cpu_num = node->map_cpu; + old_cpu_qlen = GET_PQUEUE(cpu_num).qlen + GET_IQUEUE(cpu_num).qlen; - if ((cur_cpu_qhead >= node_qhead) || - (force_flush)) { + if ((cur_cpu_qhead >= node_qhead) || force_flush || (!old_cpu_qlen && ++rmnet_shs_flush_reason[RMNET_SHS_FLUSH_Z_QUEUE_FLUSH])) { if (rmnet_shs_switch_cores) { /* Move the amount parked to other core's count @@ -893,6 +910,7 @@ int rmnet_shs_node_can_flush_pkts(struct rmnet_shs_skbn_s *node, u8 force_flush) cpun = &rmnet_shs_cpu_node_tbl[node->map_cpu]; rmnet_shs_update_cpu_proc_q_all_cpus(); node->queue_head = cpun->qhead; + rmnet_shs_cpu_node_move(node, &cpun->node_list_id, cpu_num); @@ -1282,7 +1300,7 @@ void rmnet_shs_flush_lock_table(u8 flsh, u8 ctxt) if ((rmnet_shs_cfg.num_bytes_parked <= 0) || (rmnet_shs_cfg.num_pkts_parked <= 0)) { - + rmnet_shs_cfg.ff_flag = 0; rmnet_shs_cfg.num_bytes_parked = 0; rmnet_shs_cfg.num_pkts_parked = 0; rmnet_shs_cfg.is_pkt_parked = 0; @@ -1291,9 +1309,7 @@ void rmnet_shs_flush_lock_table(u8 flsh, u8 ctxt) if (hrtimer_active(&rmnet_shs_cfg.hrtimer_shs)) hrtimer_cancel(&rmnet_shs_cfg.hrtimer_shs); } - } - } void rmnet_shs_flush_table(u8 flsh, u8 ctxt) @@ -1315,6 +1331,12 @@ void rmnet_shs_flush_table(u8 flsh, u8 ctxt) hrtimer_start(&rmnet_shs_cfg.hrtimer_shs, ns_to_ktime(rmnet_shs_timeout * NS_IN_MS), HRTIMER_MODE_REL); + if (rmnet_shs_fall_back_timer && + rmnet_shs_cfg.num_bytes_parked && + rmnet_shs_cfg.num_pkts_parked){ + rmnet_shs_cfg.ff_flag++; + } + } rmnet_shs_flush_reason[RMNET_SHS_FLUSH_WQ_FB_FLUSH]++; } @@ -1390,23 +1412,27 @@ void rmnet_shs_chain_to_skb_list(struct sk_buff *skb, */ static void rmnet_flush_buffered(struct work_struct *work) { - u8 is_force_flush = 0; SHS_TRACE_HIGH(RMNET_SHS_FLUSH, - RMNET_SHS_FLUSH_DELAY_WQ_START, is_force_flush, + RMNET_SHS_FLUSH_DELAY_WQ_START, rmnet_shs_cfg.ff_flag, rmnet_shs_cfg.force_flush_state, 0xDEF, 0xDEF, NULL, NULL); if (rmnet_shs_cfg.num_pkts_parked && rmnet_shs_cfg.force_flush_state == RMNET_SHS_FLUSH_ON) { local_bh_disable(); - rmnet_shs_flush_table(is_force_flush, + if (rmnet_shs_cfg.ff_flag >= rmnet_shs_wq_fb_limit) { + rmnet_shs_flush_reason[RMNET_SHS_FLUSH_WQ_FB_FF_FLUSH]++; + + } + rmnet_shs_flush_table(rmnet_shs_cfg.ff_flag >= rmnet_shs_wq_fb_limit, RMNET_WQ_CTXT); + local_bh_enable(); } SHS_TRACE_HIGH(RMNET_SHS_FLUSH, RMNET_SHS_FLUSH_DELAY_WQ_END, - is_force_flush, 0xDEF, 0xDEF, 0xDEF, NULL, NULL); + rmnet_shs_cfg.ff_flag, 0xDEF, 0xDEF, 0xDEF, NULL, NULL); } /* Invoked when the flushing timer has expired. * Upon first expiry, we set the flag that will trigger force flushing of all @@ -1743,12 +1769,14 @@ void rmnet_shs_assign(struct sk_buff *skb, struct rmnet_port *port) u8 is_shs_reqd = 0; struct rmnet_shs_cpu_node_s *cpu_node_tbl_p; + rmnet_shs_in_count++; + /*deliver non TCP/UDP packets right away*/ if (!rmnet_shs_is_skb_stamping_reqd(skb)) { + rmnet_shs_deliver_skb(skb); return; } - if ((unlikely(!map)) || !rmnet_shs_cfg.rmnet_shs_init_complete) { rmnet_shs_deliver_skb(skb); SHS_TRACE_ERR(RMNET_SHS_ASSIGN, diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/Kconfig b/drivers/net/wireless/broadcom/bcmdhd_101_16/Kconfig index 6822c096c..2e05dc437 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/Kconfig +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/Kconfig @@ -1,5 +1,5 @@ # -# Copyright (C) 2020, Broadcom. +# Copyright (C) 2021, Broadcom. # # Unless you and Broadcom execute a separate written software license # agreement governing use of this software, this software is licensed to you @@ -281,3 +281,17 @@ config WLAN_SOFTAP_HE_ENABLE default n ---help--- Support BCM4375 SoftAP HE Feature + +config WLAN_ANQP_RMAC_BACKPORTED + bool "Support backported kernel ANQP Random MAC Feature" + depends on BROADCOM_WIFI + default n + ---help--- + Support backported kernel ANQP Random MAC Feature + +config WLAN_MERLOT + bool "Merlot" + depends on BCM43013 + default n + ---help--- + Support Merlot diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/Makefile b/drivers/net/wireless/broadcom/bcmdhd_101_16/Makefile index 2a27680aa..b462791da 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/Makefile +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2020, Broadcom. +# Copyright (C) 2021, Broadcom. # # Unless you and Broadcom execute a separate written software license # agreement governing use of this software, this software is licensed to you @@ -67,6 +67,9 @@ endif DHDCFLAGS += -DCUSTOM_MAX_KSO_ATTEMPTS=64 # Enable atomic pktget by default DHDCFLAGS += -DDHD_USE_ATOMIC_PKTGET + # Enable Firmware Coredump + DHDCFLAGS += -DDHD_FW_COREDUMP + DHDCFLAGS += -DDHD_DUMP_FILE_WRITE_FROM_KERNEL endif ##################### @@ -213,7 +216,8 @@ DHDCFLAGS += -DDEBUG_SETROAMMODE # Enable Roam time thresh DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000 DHDCFLAGS += -DENABLE_MAX_DTIM_IN_SUSPEND -DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925 +DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=517 +DHDCFLAGS += -DCUSTOM_SUSPEND_BCN_LI_DTIM=1 DHDCFLAGS += -DDISABLE_DTIM_IN_SUSPEND # SoftAP @@ -249,6 +253,9 @@ DHDCFLAGS += -DSUPPORT_SET_TID DHDCFLAGS += -DROAMEXP_SUPPORT DHDCFLAGS += -DCUSTOM_BSSID_BLACKLIST_NUM=0 DHDCFLAGS += -DCUSTOM_SSID_WHITELIST_NUM=0 +# For cleanup KEEP_ALIVE +DHDCFLAGS += -DDHD_CLEANUP_KEEP_ALIVE + # Extended HANG event with reason codes DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON # Override HANG detect on MFG Test @@ -355,6 +362,12 @@ ifeq ($(CONFIG_WLAN_VENDOR_DUMP_ENABLE),y) DHDCFLAGS := $(filter-out -DDHD_DUMP_FILE_WRITE_FROM_KERNEL ,$(DHDCFLAGS)) endif +ifeq ($(CONFIG_WLAN_ANQP_RMAC_BACKPORTED),y) + DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_ANQP_RMAC +endif +# CONTROL_LOGTRACE=1 to print as EL +DHDCFLAGS += -DCUSTOM_CONTROL_LOGTRACE=1 + ############################## # Android Platform Definition ############################## @@ -411,12 +424,10 @@ DHDCFLAGS += -DCUSTOM_COUNTRY_CODE_XZ DHDCFLAGS += -DWL_SCHED_SCAN # Enable the Linux Firmware API for Andorid R OS -ifeq ($(BUS_IFACE_PCIE),y) DHDCFLAGS += -DDHD_LINUX_STD_FW_API DHDCFLAGS += -DDHD_FW_NAME="\"bcmdhd_sta.bin\"" DHDCFLAGS += -DDHD_NVRAM_NAME="\"nvram.txt\"" DHDCFLAGS += -DDHD_CLM_NAME="\"bcmdhd_clm.blob\"" -endif # GN4 platform still disabled Lollipop features ifeq ($(filter y,$(CONFIG_MACH_UNIVERSAL5433) $(CONFIG_ARCH_APQ8084)),y) @@ -530,6 +541,10 @@ ifeq ($(filter y,$(CONFIG_SOC_EXYNOS9820) $(CONFIG_SOC_EXYNOS9830) \ # AXI error logging DHDCFLAGS += -DDNGL_AXI_ERROR_LOGGING #DHDCFLAGS += -DDHD_USE_WQ_FOR_DNGL_AXI_ERROR +endif +# Host wakeup gpio debug +ifeq ($(CONFIG_SOC_EXYNOS2100),y) + DHDCFLAGS += -DPRINT_WAKEUP_GPIO_STATUS endif DHDCFLAGS += -DUSE_DMA_LOCK DHDCFLAGS += -DDHD_MAP_LOGGING @@ -594,8 +609,6 @@ endif # LOGTRACE_EVENT DHDCFLAGS += -DSHOW_LOGTRACE DHDCFLAGS += -DLOGTRACE_FROM_FILE -# CONTROL_LOGTRACE=1 to print as EL - DHDCFLAGS += -DCUSTOM_CONTROL_LOGTRACE=1 # Higher rate beacon transmission at softAP DHDCFLAGS += -DSUPPORT_AP_HIGHER_BEACONRATE # Enhanced radio power save with NOA at softAP @@ -691,6 +704,8 @@ endif # Basic types and constants relating to 802.11ax DHDCFLAGS += -DWL11AX +# Advertise HE capabilities + DHDCFLAGS += -DWL_CAP_HE # For Samsung factory mode only ifeq ($(CONFIG_SEC_FACTORY),y) # Detect NON DMA M2M corruption @@ -807,6 +822,10 @@ ifeq ($(filter y,$(CONFIG_SOC_EXYNOS9820) $(CONFIG_SOC_EXYNOS9830) \ # AXI error logging DHDCFLAGS += -DDNGL_AXI_ERROR_LOGGING #DHDCFLAGS += -DDHD_USE_WQ_FOR_DNGL_AXI_ERROR +endif +# Host wakeup gpio debug +ifeq ($(CONFIG_SOC_EXYNOS2100),y) + DHDCFLAGS += -DPRINT_WAKEUP_GPIO_STATUS endif DHDCFLAGS += -DUSE_DMA_LOCK DHDCFLAGS += -DDHD_MAP_LOGGING @@ -868,8 +887,6 @@ endif # LOGTRACE_EVENT DHDCFLAGS += -DSHOW_LOGTRACE DHDCFLAGS += -DLOGTRACE_FROM_FILE -# CONTROL_LOGTRACE=1 to print as EL - DHDCFLAGS += -DCUSTOM_CONTROL_LOGTRACE=1 # Higher rate beacon transmission at softAP DHDCFLAGS += -DSUPPORT_AP_HIGHER_BEACONRATE # Enhanced radio power save with NOA at softAP @@ -968,6 +985,8 @@ endif # Basic types and constants relating to 802.11ax DHDCFLAGS += -DWL11AX +# Advertise HE capabilities + DHDCFLAGS += -DWL_CAP_HE # Support Know HDM feature DHDCFLAGS += -DDHD_SUPPORT_HDM # For Samsung factory mode only @@ -1040,6 +1059,8 @@ ifneq ($(CONFIG_BCM4361),) # Customer ocl disabe DHDCFLAGS += -DCUSTOM_SET_OCLOFF DHDCFLAGS += -DCUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE +# Channel Utilization + DHDCFLAGS += -DWL_GET_CU # OCE/MBO DHDCFLAGS += -DWL_MBO DHDCFLAGS += -DWL_OCE @@ -1054,6 +1075,8 @@ DHDCFLAGS += -DWL_FILS_ROAM_OFFLD endif # ADDTS DHDCFLAGS += -DWL_CAC_TS +# FAKEAP + DHDCFLAGS += -DWL_BCNRECV # tput enhancement for PCIE ifeq ($(BUS_IFACE_PCIE),y) DHDCFLAGS += -DCUSTOM_TCPACK_SUPP_RATIO=15 @@ -1200,6 +1223,8 @@ ifeq ($(CONFIG_BCM4361),y) endif # Latency critical data DHDCFLAGS += -DSUPPORT_LATENCY_CRITICAL_DATA +# Silent roam + DHDCFLAGS += -DCONFIG_SILENT_ROAM endif ifneq ($(CONFIG_BCM4359),) @@ -1675,9 +1700,6 @@ ifeq ($(CONFIG_BCM43013),y) DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC DRIVER_TYPE = y endif - DHDCFLAGS += -DDHD_FW_COREDUMP - DHDCFLAGS += -DDHD_DUMP_FILE_WRITE_FROM_KERNEL - DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON DHDCFLAGS += -DDHD_LOG_DUMP DHDCFLAGS += -DDHD_LOG_PRINT_RATE_LIMIT # HANG simulation @@ -1693,6 +1715,7 @@ endif DHDCFLAGS += -DDISCARD_UDPNETBIOS_FLTR # Use single nvram file DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE + DHDCFLAGS += -DIFACE_HANG_FORCE_DEV_CLOSE ifeq ($(CONFIG_NOBLESSE),y) DHDCFLAGS += -USUPPORT_P2P_GO_PS DHDCFLAGS += -UP2P_LISTEN_OFFLOADING @@ -1704,7 +1727,6 @@ ifeq ($(CONFIG_NOBLESSE),y) DHDCFLAGS += -DENABLE_WAKEUP_PKT_DUMP DHDCFLAGS += -DWL_CFGVENDOR_SEND_HANG_EVENT DHDCFLAGS += -DNOT_SUPPORT_EXT_TRAP_INFO - DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON DHDCFLAGS += -DDHD_DUMP_MNGR DHDCFLAGS += -UDHD_COMMON_DUMP_PATH DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/opt/usr/data/network/\"" @@ -1712,15 +1734,28 @@ ifeq ($(CONFIG_NOBLESSE),y) DHDCFLAGS += -DDHD_PM_OVERRIDE DHDCFLAGS += -DP2P_IF_STATE_EVENT_CTRL endif +ifeq ($(CONFIG_WLAN_MERLOT),y) + DHDCFLAGS += -USUPPORT_P2P_GO_PS + DHDCFLAGS += -UP2P_LISTEN_OFFLOADING + DHDCFLAGS += -DUSE_INITIAL_2G_SCAN + DHDCFLAGS += -DENABLE_WAKEUP_PKT_DUMP + DHDCFLAGS += -DWL_CFGVENDOR_SEND_HANG_EVENT + DHDCFLAGS += -DNOT_SUPPORT_EXT_TRAP_INFO + DHDCFLAGS += -DDHD_DUMP_MNGR + DHDCFLAGS += -DTSQ_MULTIPLIER=10 + DHDCFLAGS += -DDHD_PM_OVERRIDE + DHDCFLAGS += -DP2P_IF_STATE_EVENT_CTRL +# Update Tx/Rx rate info + DHDCFLAGS += -DWL_RATE_INFO +ifeq ($(CONFIG_BCMDHD_PREALLOC_MEMDUMP),y) + DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP +endif +endif + DHDCFLAGS += -UWL_6G_BAND # Remove common feature for 43013 DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS)) DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS)) endif - -ifneq ($(CONFIG_BCM43013),) - # band lock : auto=0, 5G=1, 2G=2 - DHDCFLAGS += -DBANDLOCK=2 -endif endif # chipset supported SDIO only ifeq ($(DRIVER_TYPE),y) @@ -1814,6 +1849,13 @@ ifeq ($(CONFIG_ARCH_LAHAINA),y) DHDCFLAGS += -Wno-date-time DHDCFLAGS += -Wno-sometimes-uninitialized endif +ifeq ($(CONFIG_SOC_EXYNOS9110),y) + DHDCFLAGS += -Wno-unused-const-variable +endif +ifeq ($(CONFIG_SOC_S5E5515),y) + DHDCFLAGS += -Wno-date-time + DHDCFLAGS += -Wno-unused-const-variable +endif # DTS Support ifeq ($(CONFIG_OF),y) @@ -1894,6 +1936,9 @@ ifeq ($(CONFIG_SOC_EXYNOS9110),y) DHDCFLAGS += -DDHD_OF_SUPPORT DHDCFLAGS += -Wno-date-time endif +ifeq ($(CONFIG_SOC_S5E5515),y) +DHDCFLAGS += -DDHD_OF_SUPPORT +endif endif #CONFIG_OF ifneq ($(CONFIG_ARCH_TEGRA),) diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/aiutils.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/aiutils.c index 3d533b6d6..5f3604da4 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/aiutils.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/aiutils.c @@ -2,7 +2,7 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_app_utils.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_app_utils.c index 62d050739..f51cdddca 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_app_utils.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_app_utils.c @@ -3,7 +3,7 @@ * Contents are wifi-specific, used by any kernel or app-level * software that might want wifi things as it grows. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_l2_filter.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_l2_filter.c index 749e813d6..035dfe883 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_l2_filter.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcm_l2_filter.c @@ -1,7 +1,7 @@ /* * L2 Filter handling functions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmbloom.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmbloom.c index 7660c882b..f97d61a97 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmbloom.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmbloom.c @@ -1,7 +1,7 @@ /* * Bloom filter support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmevent.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmevent.c index 6499b69f9..f0e470ae4 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmevent.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmevent.c @@ -1,7 +1,7 @@ /* * bcmevent read-only data shared by kernel or app layers * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh.c index c9be656b7..fa34a656a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh.c @@ -2,7 +2,7 @@ * BCMSDH interface glue * implement bcmsdh API for SDIOH driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_linux.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_linux.c index 1e26ff6a9..33de96384 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_linux.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_linux.c @@ -1,7 +1,7 @@ /* * SDIO access interface for drivers - linux specific (pci only) * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc.c index 5f84817e8..7e445f908 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc.c @@ -1,7 +1,7 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc_linux.c index 307371c6a..ab79e6c5a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc_linux.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdh_sdmmc_linux.c @@ -1,7 +1,7 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdstd.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdstd.h index aa6a67c49..568cf31f5 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdstd.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmsdstd.h @@ -1,7 +1,7 @@ /* * 'Standard' SDIO HOST CONTROLLER driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmstdlib_s.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmstdlib_s.c index f029f0150..c926ddc89 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmstdlib_s.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmstdlib_s.c @@ -1,7 +1,7 @@ /* * Broadcom Secure Standard Library. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmutils.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmutils.c index b34795344..239a0bf90 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmutils.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmutils.c @@ -1,7 +1,7 @@ /* * Driver O/S-independent utility routines * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmwifi_channels.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmwifi_channels.c index bf4e148ae..4454af49f 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmwifi_channels.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmwifi_channels.c @@ -3,7 +3,7 @@ * Contents are wifi-specific, used by any kernel or app-level * software that might want wifi things as it grows. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmxtlv.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmxtlv.c index ddc6351ce..b37e45e8c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmxtlv.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/bcmxtlv.c @@ -1,7 +1,7 @@ /* * Driver O/S-independent utility routines * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd.h index 39ad579f8..0b993b543 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd.h @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -538,7 +538,8 @@ enum dhd_dongledump_type { DUMP_TYPE_INBAND_DEVICE_WAKE_FAILURE = 30, DUMP_TYPE_PKTID_POOL_DEPLETED = 31, DUMP_TYPE_ESCAN_SYNCID_MISMATCH = 32, - DUMP_TYPE_INVALID_SHINFO_NRFRAGS = 33 + DUMP_TYPE_INVALID_SHINFO_NRFRAGS = 33, + DUMP_TYPE_P2P_DISC_BUSY = 34 }; enum dhd_hang_reason { @@ -563,12 +564,14 @@ enum dhd_hang_reason { HANG_REASON_ESCAN_SYNCID_MISMATCH = 0x8013, HANG_REASON_SCAN_TIMEOUT = 0x8014, HANG_REASON_SCAN_TIMEOUT_SCHED_ERROR = 0x8015, + HANG_REASON_P2P_DISC_BUSY = 0x8016, HANG_REASON_PCIE_LINK_DOWN_RC_DETECT = 0x8805, HANG_REASON_INVALID_EVENT_OR_DATA = 0x8806, HANG_REASON_UNKNOWN = 0x8807, HANG_REASON_PCIE_LINK_DOWN_EP_DETECT = 0x8808, HANG_REASON_PCIE_CTO_DETECT = 0x8809, - HANG_REASON_MAX = 0x880A + HANG_REASON_DONGLE_TRAP_HC_DD_RX_DMA_STALL = 0x880A, + HANG_REASON_MAX = 0x880B }; #define WLC_E_DEAUTH_MAX_REASON 0x0FFF @@ -811,7 +814,9 @@ typedef enum { LOG_DUMP_SECTION_RING, LOG_DUMP_SECTION_STATUS, LOG_DUMP_SECTION_RTT, - LOG_DUMP_SECTION_BCM_TRACE + LOG_DUMP_SECTION_BCM_TRACE, + LOG_DUMP_SECTION_PKTID_MAP_LOG, + LOG_DUMP_SECTION_PKTID_UNMAP_LOG } log_dump_section_type_t; /* Each section in the debug_dump log file shall begin with a header */ @@ -1163,6 +1168,7 @@ typedef struct dhd_pub { bool is_bt_recovery_required; #endif bool smmu_fault_occurred; /* flag to indicate SMMU Fault */ + bool p2p_disc_busy_occurred; /* * Add any new variables to track Bus errors above * this line. Also ensure that the variable is @@ -1461,6 +1467,9 @@ typedef struct dhd_pub { #ifdef DHD_STATUS_LOGGING void *statlog; #endif /* DHD_STATUS_LOGGING */ +#ifdef DHD_MAP_PKTID_LOGGING + bool enable_pktid_log_dump; +#endif /* DHD_MAP_PKTID_LOGGING */ #ifdef DHD_DB0TS bool db0ts_capable; #endif /* DHD_DB0TS */ @@ -1521,6 +1530,7 @@ typedef struct dhd_pub { #ifdef DHD_GRO_ENABLE_HOST_CTRL bool permitted_gro; #endif /* DHD_GRO_ENABLE_HOST_CTRL */ + bool stop_in_progress; } dhd_pub_t; #if defined(__linux__) @@ -2177,6 +2187,7 @@ extern int dhd_keep_alive_onoff(dhd_pub_t *dhd); #endif /* KEEP_ALIVE */ #if defined(DHD_FW_COREDUMP) +extern bool dhd_memdump_is_scheduled(dhd_pub_t *dhdp); void dhd_schedule_memdump(dhd_pub_t *dhdp, uint8 *buf, uint32 size); #endif /* DHD_FW_COREDUMP */ @@ -2241,6 +2252,7 @@ extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd, int *dtim_period, int *bc #else extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd); #endif /* OEM_ANDROID && BCMPCIE */ +extern int dhd_set_suspend_bcn_li_dtim(dhd_pub_t *dhd, bool set_suspend); extern bool dhd_support_sta_mode(dhd_pub_t *dhd); extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size); @@ -3483,6 +3495,14 @@ extern int dhd_print_status_log_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, void *fp, uint32 len, void *pos); extern uint32 dhd_get_status_log_len(void *ndev, dhd_pub_t *dhdp); #endif /* DHD_STATUS_LOGGING */ +#ifdef DHD_MAP_PKTID_LOGGING +extern uint32 dhd_pktid_buf_len(dhd_pub_t *dhd, bool is_map); +extern int dhd_print_pktid_map_log_data(void *dev, dhd_pub_t *dhdp, + const void *user_buf, void *fp, uint32 len, void *pos, bool is_map); +extern int dhd_write_pktid_log_dump(dhd_pub_t *dhdp, const void *user_buf, + void *fp, uint32 len, unsigned long *pos, bool is_map); +extern uint32 dhd_get_pktid_map_logging_len(void *ndev, dhd_pub_t *dhdp, bool is_map); +#endif /* DHD_MAP_PKTID_LOGGING */ int dhd_print_ecntrs_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, void *fp, uint32 len, void *pos); int dhd_print_rtt_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, @@ -3661,6 +3681,7 @@ extern void dhd_dump_file_manage_enqueue(dhd_pub_t *dhd, char *dump_path, char * #if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) int dhd_throttle_p2p_interface_event(void *handle, bool onoff); +void dhd_reset_p2p_interface_event(void *handle); #endif /* !PCIE_FULL_DONGLE & P2P_IF_STATE_EVENT_CTRL */ #ifdef DNGL_AXI_ERROR_LOGGING diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.c index c3aecaf1e..62c31daa5 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.c @@ -1,7 +1,7 @@ /* * Bit packing and Base64 utils for EWP * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.h index 74bebf3f1..12813ea1a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bitpack.h @@ -1,7 +1,7 @@ /* * Bit packing and Base64 utils for EWP * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bus.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bus.h index 5676dddc7..ea2e73603 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bus.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_bus.h @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cdc.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cdc.c index 48bd3ebdb..b83cc7a8d 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cdc.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cdc.c @@ -1,7 +1,7 @@ /* * DHD Protocol Module for CDC and BDC. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.c index af86a2d6c..fdc5ea4dc 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.c @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -52,6 +52,10 @@ static int dhd_dongle_up = FALSE; #include #include +#if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) +#include +#endif /* !PCIE_FULL_DONGLE & P2P_IF_STATE_EVENT_CTRL */ + static s32 wl_dongle_up(struct net_device *ndev); static s32 wl_dongle_down(struct net_device *ndev); @@ -94,6 +98,10 @@ s32 dhd_cfg80211_set_p2p_info(struct bcm_cfg80211 *cfg, int val) dhd->op_mode |= val; WL_ERR(("Set : op_mode=0x%04x\n", dhd->op_mode)); +#if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) + dhd_reset_p2p_interface_event(dhd); +#endif /* !PCIE_FULL_DONGLE & P2P_IF_STATE_EVENT_CTRL */ + return 0; } diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.h index 1abf42b7d..ed6f026d7 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_cfg80211.h @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_common.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_common.c index c01d2ab52..a147df814 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_common.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_common.c @@ -1,7 +1,7 @@ /* * Broadcom Dongle Host Driver (DHD), common DHD core. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -441,17 +441,13 @@ dhd_query_bus_erros(dhd_pub_t *dhdp) { bool ret = FALSE; - if (dhdp->dongle_reset) { - DHD_ERROR_RLMT(("%s: Dongle Reset occurred, cannot proceed\n", - __FUNCTION__)); - ret = TRUE; - } - if (dhdp->dongle_trap_occured) { DHD_ERROR_RLMT(("%s: FW TRAP has occurred, cannot proceed\n", __FUNCTION__)); ret = TRUE; - dhdp->hang_reason = HANG_REASON_DONGLE_TRAP; + if (dhdp->hang_reason == 0) { + dhdp->hang_reason = HANG_REASON_DONGLE_TRAP; + } dhd_os_send_hang_message(dhdp); } @@ -503,6 +499,12 @@ dhd_query_bus_erros(dhd_pub_t *dhdp) ret = TRUE; } + if (dhdp->p2p_disc_busy_occurred) { + DHD_ERROR_RLMT(("%s: p2p_disc_busy_occurred, cannot proceed\n", + __FUNCTION__)); + ret = TRUE; + } + #ifdef DNGL_AXI_ERROR_LOGGING if (dhdp->axi_error) { DHD_ERROR_RLMT(("%s: AXI error occurred, cannot proceed\n", @@ -550,6 +552,7 @@ dhd_clear_bus_errors(dhd_pub_t *dhdp) dhdp->iface_op_failed = FALSE; dhdp->scan_timeout_occurred = FALSE; dhdp->scan_busy_occurred = FALSE; + dhdp->p2p_disc_busy_occurred = FALSE; } #ifdef DHD_SSSR_DUMP @@ -6341,10 +6344,11 @@ int dhd_get_download_buffer(dhd_pub_t *dhd, char *file_path, download_type_t com *length = fw->size; goto err; } - *buffer = MALLOCZ(dhd->osh, fw->size); + *buffer = VMALLOCZ(dhd->osh, fw->size); if (*buffer == NULL) { DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, (int)fw->size)); + ret = BCME_NOMEM; goto err; } *length = fw->size; @@ -6390,11 +6394,11 @@ int dhd_get_download_buffer(dhd_pub_t *dhd, char *file_path, download_type_t com goto err; } } - buf = MALLOCZ(dhd->osh, file_len); if (buf == NULL) { DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, file_len)); + ret = BCME_NOMEM; goto err; } @@ -6556,7 +6560,7 @@ int dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) { char *clm_blob_path; - int len; + int len = 0, memblock_len = 0; char *memblock = NULL; int err = BCME_OK; char iovbuf[WLC_IOCTL_SMLEN]; @@ -6585,17 +6589,21 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) #if defined(DHD_LINUX_STD_FW_API) DHD_ERROR(("Clmblob file : %s\n", clm_blob_path)); len = MAX_CLM_BUF_SIZE; - dhd_get_download_buffer(dhd, clm_blob_path, CLM_BLOB, &memblock, &len); + err = dhd_get_download_buffer(dhd, clm_blob_path, CLM_BLOB, &memblock, &len); +#ifdef DHD_LINUX_STD_FW_API + memblock_len = len; +#else + memblock_len = MAX_CLM_BUF_SIZE; +#endif /* DHD_LINUX_STD_FW_API */ #else memblock = dhd_os_open_image1(dhd, (char *)clm_blob_path); len = dhd_os_get_image_size(memblock); + BCM_REFERENCE(memblock_len); #endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */ if (memblock == NULL) { #if defined(DHD_BLOB_EXISTENCE_CHECK) - if (dhd->is_blob) { - err = BCME_ERROR; - } else { + if (!dhd->is_blob) { status = dhd_check_current_clm_data(dhd); if (status == TRUE) { err = BCME_OK; @@ -6673,7 +6681,7 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) #if !defined(DHD_LINUX_STD_FW_API) dhd_os_close_image1(dhd, memblock); #else - dhd_free_download_buffer(dhd, memblock, MAX_CLM_BUF_SIZE); + dhd_free_download_buffer(dhd, memblock, memblock_len); #endif /* LINUX || linux */ } @@ -6682,7 +6690,11 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path) void dhd_free_download_buffer(dhd_pub_t *dhd, void *buffer, int length) { +#if defined(DHD_LINUX_STD_FW_API) + VMFREE(dhd->osh, buffer, length); +#else MFREE(dhd->osh, buffer, length); +#endif /* DHD_LINUX_STD_FW_API */ } #ifdef SHOW_LOGTRACE @@ -9282,6 +9294,9 @@ dhd_convert_memdump_type_to_str(uint32 type, char *buf, size_t buf_len, int subs case DUMP_TYPE_INVALID_SHINFO_NRFRAGS: type_str = "INVALID_SHINFO_NRFRAGS"; break; + case DUMP_TYPE_P2P_DISC_BUSY: + type_str = "P2P_DISC_BUSY"; + break; default: type_str = "Unknown_type"; break; diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_cis.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_cis.c index f1a2d4fad..0d00cbfe1 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_cis.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_cis.c @@ -2,7 +2,7 @@ * Process CIS information from OTP for customer platform * (Handle the MAC address and module information) * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_exynos.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_exynos.c index c9b962f50..2a07a55c4 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_exynos.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_exynos.c @@ -1,7 +1,7 @@ /* * Platform Dependent file for Samsung Exynos * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -72,9 +72,10 @@ #endif /* CONFIG_SEC_SYSFS */ #endif /* BCMDHD_MODULAR */ -#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) +#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) || \ + defined(CONFIG_WLAN_MERLOT) #define PINCTL_DELAY 150 -#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */ +#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE || CONFIG_WLAN_MERLOT */ #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM extern void dhd_exit_wlan_mem(void); @@ -90,9 +91,10 @@ static int wlan_host_wake_irq = 0; static unsigned int wlan_host_wake_up = -1; #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */ -#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) +#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) || \ + defined(CONFIG_WLAN_MERLOT) extern struct device *mmc_dev_for_wlan; -#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */ +#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE || CONFIG_WLAN_MERLOT */ #ifdef CONFIG_BCMDHD_PCIE extern int pcie_ch_num; @@ -100,28 +102,31 @@ extern int exynos_pcie_pm_resume(int); extern void exynos_pcie_pm_suspend(int); #endif /* CONFIG_BCMDHD_PCIE */ -#if defined(CONFIG_SOC_EXYNOS7870) || defined(CONFIG_SOC_EXYNOS9110) +#if defined(CONFIG_SOC_EXYNOS7870) || defined(CONFIG_SOC_EXYNOS9110) || \ + defined(CONFIG_SOC_S5E5515) extern struct mmc_host *wlan_mmc; extern void mmc_ctrl_power(struct mmc_host *host, bool onoff); -#endif /* SOC_EXYNOS7870 || CONFIG_SOC_EXYNOS9110 */ +#endif /* SOC_EXYNOS7870 || CONFIG_SOC_EXYNOS9110 || CONFIG_SOC_S5E5515 */ static int dhd_wlan_power(int onoff) { -#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) +#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) || \ + defined(CONFIG_WLAN_MERLOT) struct pinctrl *pinctrl = NULL; -#endif /* CONFIG_MACH_A7LTE || ONFIG_NOBLESSE */ +#endif /* CONFIG_MACH_A7LTE || ONFIG_NOBLESSE || CONFIG_WLAN_MERLOT */ printk(KERN_INFO"%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off"); -#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) +#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) || \ + defined(CONFIG_WLAN_MERLOT) if (onoff) { pinctrl = devm_pinctrl_get_select(mmc_dev_for_wlan, "sdio_wifi_on"); if (IS_ERR(pinctrl)) printk(KERN_INFO "%s WLAN SDIO GPIO control error\n", __FUNCTION__); msleep(PINCTL_DELAY); } -#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */ +#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE || CONFIG_WLAN_MERLOT */ if (gpio_direction_output(wlan_pwr_on, onoff)) { printk(KERN_ERR "%s failed to control WLAN_REG_ON to %s\n", @@ -129,18 +134,20 @@ dhd_wlan_power(int onoff) return -EIO; } -#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) +#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE) || \ + defined(CONFIG_WLAN_MERLOT) if (!onoff) { pinctrl = devm_pinctrl_get_select(mmc_dev_for_wlan, "sdio_wifi_off"); if (IS_ERR(pinctrl)) printk(KERN_INFO "%s WLAN SDIO GPIO control error\n", __FUNCTION__); } -#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */ +#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE || CONFIG_WLAN_MERLOT */ -#if defined(CONFIG_SOC_EXYNOS7870) || defined(CONFIG_SOC_EXYNOS9110) +#if defined(CONFIG_SOC_EXYNOS7870) || defined(CONFIG_SOC_EXYNOS9110) || \ + defined(CONFIG_SOC_S5E5515) if (wlan_mmc) mmc_ctrl_power(wlan_mmc, onoff); -#endif /* SOC_EXYNOS7870 || CONFIG_SOC_EXYNOS9110 */ +#endif /* SOC_EXYNOS7870 || CONFIG_SOC_EXYNOS9110 || CONFIG_SOC_S5E5515 */ return 0; } @@ -252,6 +259,13 @@ dhd_get_wlan_oob_gpio(void) gpio_get_value(wlan_host_wake_up) : -1; } EXPORT_SYMBOL(dhd_get_wlan_oob_gpio); +int +dhd_get_wlan_oob_gpio_number(void) +{ + return gpio_is_valid(wlan_host_wake_up) ? + wlan_host_wake_up : -1; +} +EXPORT_SYMBOL(dhd_get_wlan_oob_gpio_number); #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE && CONFIG_BCMDHD_GET_OOB_STATE */ struct resource dhd_wlan_resources = { diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_gpio.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_gpio.c index 0e52368c5..78c4506ad 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_gpio.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_gpio.c @@ -1,7 +1,7 @@ /* * Customer code to add GPIO control during WLAN start/stop * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_memprealloc.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_memprealloc.c index f43d7e336..35def1b5e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_memprealloc.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_memprealloc.c @@ -1,7 +1,7 @@ /* * Platform Dependent file for usage of Preallocted Memory * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_msm.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_msm.c index 58864c0f8..9762a29d9 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_msm.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_msm.c @@ -1,7 +1,7 @@ /* * Platform Dependent file for Qualcomm MSM/APQ * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -188,6 +188,14 @@ dhd_get_wlan_oob_gpio(void) gpio_get_value(wlan_host_wake_up) : -1; } EXPORT_SYMBOL(dhd_get_wlan_oob_gpio); +int +dhd_get_wlan_oob_gpio_number(void) +{ + return gpio_is_valid(wlan_host_wake_up) ? + wlan_host_wake_up : -1; +} +EXPORT_SYMBOL(dhd_get_wlan_oob_gpio_number); + #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE && CONFIG_BCMDHD_GET_OOB_STATE */ struct resource dhd_wlan_resources = { diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_sec.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_sec.c index 8345078fd..24f909553 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_sec.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_custom_sec.c @@ -1,7 +1,7 @@ /* * Customer HW 4 dependant file * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -778,7 +778,8 @@ uint32 sec_save_wlinfo(char *firm_ver, char *dhd_ver, char *nvram_p, char *clm_v DHD_ERROR(("[WIFI_SEC] %s: Nvarm File open failed.\n", __FUNCTION__)); return -1; } else { - ret = dhd_kernel_read_compat(nvfp, nvfp->f_pos, temp_buf, sizeof(temp_buf)); + ret = dhd_kernel_read_compat(nvfp, nvfp->f_pos, temp_buf, + sizeof(temp_buf)-1); dhd_filp_close(nvfp, NULL); } #else diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg.h index 202cd93e7..0f0217fef 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg.h @@ -1,7 +1,7 @@ /* * Debug/trace/assert driver definitions for Dongle Host Driver. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -56,6 +56,9 @@ extern void dhd_log_dump_write(int type, char *binary_data, #define RTT_LOG_HDR "\n-------------------- RTT log --------------------------\n" #define BCM_TRACE_LOG_HDR "\n-------------------- BCM Trace log --------------------------\n" #define COOKIE_LOG_HDR "\n-------------------- Cookie List ----------------------------\n" +#define DHD_PKTID_MAP_LOG_HDR "\n---------------- PKTID MAP log -----------------------\n" +#define DHD_PKTID_UNMAP_LOG_HDR "\n------------------ PKTID UNMAP log -----------------------\n" +#define PKTID_LOG_DUMP_FMT "\nIndex(Current=%d) Timestamp Pktaddr(PA) Pktid Size\n" #endif /* DHD_LOG_DUMP */ #if defined(DHD_DEBUG) diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.c index 8b39867e0..feef011eb 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.c @@ -1,7 +1,7 @@ /* * DHD debug ring API and structures - implementation * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.h index 8bce77026..6162508c7 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_dbg_ring.h @@ -1,7 +1,7 @@ /* * DHD debug ring header file - interface * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.c index 94bd95772..502aa7cfe 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.c @@ -1,7 +1,7 @@ /* * DHD debugability support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -959,7 +959,7 @@ dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data, DHD_ERROR(("%s logset: %d max: %d out of range queried: %d\n", __FUNCTION__, logset, event_log_max_sets, event_log_max_sets_queried)); #ifdef DHD_FW_COREDUMP - if (event_log_max_sets_queried) { + if (event_log_max_sets_queried && !dhd_memdump_is_scheduled(dhdp)) { DHD_ERROR(("%s: collect socram for DUMP_TYPE_LOGSET_BEYOND_RANGE\n", __FUNCTION__)); dhdp->memdump_type = DUMP_TYPE_LOGSET_BEYOND_RANGE; @@ -1435,9 +1435,18 @@ __dhd_dbg_map_tx_status_to_pkt_fate(uint16 status) case WLFC_CTL_PKTFLAG_EXPIRED: pkt_fate = TX_PKT_FATE_FW_DROP_EXPTIME; break; + case WLFC_CTL_PKTFLAG_DROPPED: + pkt_fate = TX_PKT_FATE_DRV_DROP_OTHER; + break; case WLFC_CTL_PKTFLAG_MKTFREE: pkt_fate = TX_PKT_FATE_FW_PKT_FREE; break; + case WLFC_CTL_PKTFLAG_MAX_SUP_RETR: + pkt_fate = TX_PKT_FATE_FW_MAX_SUP_RETR; + break; + case WLFC_CTL_PKTFLAG_FORCED_EXPIRED: + pkt_fate = TX_PKT_FATE_FW_FORCED_EXPIRED; + break; default: pkt_fate = TX_PKT_FATE_FW_DROP_OTHER; break; @@ -1937,6 +1946,19 @@ dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp) } \ } while (0); +static wifi_tx_packet_fate +__dhd_dbg_convert_fate(wifi_tx_packet_fate fate) +{ + wifi_tx_packet_fate new_fate = fate; + + /* To prevent SIG-ABORT, packet_fate > TX_PKT_FATE_DRV_DROP_OTHER */ + if (fate > TX_PKT_FATE_DRV_DROP_OTHER) { + new_fate = TX_PKT_FATE_FW_DROP_OTHER; + } + + return new_fate; +} + int dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, uint16 req_count, uint16 *resp_count) @@ -1983,7 +2005,12 @@ dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, compat_wifi_tx_report_t *comp_ptr = compat_ptr((uintptr_t) cptr); compat_dhd_dbg_pkt_info_t compat_tx_pkt; __dhd_dbg_dump_tx_pkt_info(dhdp, tx_pkt, count); - __COPY_TO_USER(&comp_ptr->fate, &tx_pkt->fate, sizeof(tx_pkt->fate)); + /* fate convert asscording to wifi_logger.h */ + { + wifi_tx_packet_fate new_fate = tx_pkt->fate; + new_fate = __dhd_dbg_convert_fate(new_fate); + __COPY_TO_USER(&comp_ptr->fate, &new_fate, sizeof(new_fate)); + } compat_tx_pkt.payload_type = tx_pkt->info.payload_type; compat_tx_pkt.pkt_len = tx_pkt->info.pkt_len; @@ -2006,7 +2033,12 @@ dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, ptr = (wifi_tx_report_t *)user_buf; while ((count < pkt_count) && tx_pkt && ptr) { __dhd_dbg_dump_tx_pkt_info(dhdp, tx_pkt, count); - __COPY_TO_USER(&ptr->fate, &tx_pkt->fate, sizeof(tx_pkt->fate)); + /* fate convert asscording to wifi_logger.h */ + { + wifi_tx_packet_fate new_fate = tx_pkt->fate; + new_fate = __dhd_dbg_convert_fate(new_fate); + __COPY_TO_USER(&ptr->fate, &new_fate, sizeof(new_fate)); + } __COPY_TO_USER(&ptr->frame_inf.payload_type, &tx_pkt->info.payload_type, OFFSETOF(dhd_dbg_pkt_info_t, pkt_hash)); @@ -2073,7 +2105,6 @@ dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf, compat_dhd_dbg_pkt_info_t compat_rx_pkt; __dhd_dbg_dump_rx_pkt_info(dhdp, rx_pkt, count); __COPY_TO_USER(&comp_ptr->fate, &rx_pkt->fate, sizeof(rx_pkt->fate)); - compat_rx_pkt.payload_type = rx_pkt->info.payload_type; compat_rx_pkt.pkt_len = rx_pkt->info.pkt_len; compat_rx_pkt.driver_ts = rx_pkt->info.driver_ts; @@ -2095,7 +2126,6 @@ dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf, ptr = (wifi_rx_report_t *)user_buf; while ((count < pkt_count) && rx_pkt && ptr) { __dhd_dbg_dump_rx_pkt_info(dhdp, rx_pkt, count); - __COPY_TO_USER(&ptr->fate, &rx_pkt->fate, sizeof(rx_pkt->fate)); __COPY_TO_USER(&ptr->frame_inf.payload_type, &rx_pkt->info.payload_type, diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.h index 3a1272a0f..491f0725a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug.h @@ -1,7 +1,7 @@ /* * DHD debugability header file * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -407,6 +407,12 @@ typedef enum { /* Packet free by firmware. */ TX_PKT_FATE_FW_PKT_FREE, + /* Firmware dropped the frame after suppress retries reached max */ + TX_PKT_FATE_FW_MAX_SUP_RETR, + + /* Firmware forced packet lifetime expiry */ + TX_PKT_FATE_FW_FORCED_EXPIRED, + } wifi_tx_packet_fate; typedef enum { diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug_linux.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug_linux.c index 0298d4512..98977a0de 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug_linux.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_debug_linux.c @@ -1,7 +1,7 @@ /* * DHD debugability Linux os layer * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.c index 0a8a2e707..8da3d4e8c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.c @@ -1,7 +1,7 @@ /* * Wifi dongle status Filter and Report * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.h index a39da3bd7..9e9d380b3 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_event_log_filter.h @@ -1,7 +1,7 @@ /* * Wifi dongle status Filter and Report * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.c index cf1e05452..a84edf3f4 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.c @@ -4,7 +4,7 @@ * Flow rings are transmit traffic (=propagating towards antenna) related entities * * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.h index 436e42376..e016b913f 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_flowring.h @@ -6,7 +6,7 @@ * Provides type definitions and function prototypes used to create, delete and manage flow rings at * high level. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.c index 9bd9f760f..86009c4ff 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.c @@ -1,7 +1,7 @@ /* * IP Packet Parser Module. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.h index 483279fe2..a95a38965 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_ip.h @@ -3,7 +3,7 @@ * * Provides type definitions and function prototypes used to parse ip packet. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.c index b51fdc406..1f1da4271 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.c @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface. * Basically selected code segments from usb-cdc.c and usb-rndis.c * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -112,11 +112,11 @@ #include #endif -#ifdef CONFIG_ARCH_EXYNOS +#if defined(CONFIG_ARCH_EXYNOS) && !defined(CONFIG_SOC_S5E5515) #ifndef SUPPORT_EXYNOS7420 #include #endif /* SUPPORT_EXYNOS7420 */ -#endif /* CONFIG_ARCH_EXYNOS */ +#endif /* defined(CONFIG_ARCH_EXYNOS) && !defined(CONFIG_SOC_S5E5515) */ #ifdef DHD_L2_FILTER #include @@ -948,9 +948,11 @@ static int dhd_pm_callback(struct notifier_block *nfb, unsigned long action, voi } #endif /* defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS) */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ + KERNEL_VERSION(2, 6, 39)) dhd_mmc_suspend = suspend; smp_mb(); - +#endif return ret; } @@ -1010,6 +1012,15 @@ struct dhd_if * dhd_get_ifp(dhd_pub_t *dhdp, uint32 ifidx) return dhdp->info->iflist[ifidx]; } +#define CHK_BUF_ENOUGH_AND_UPDATE_LEN(func, srclen, buflen, bufpos, ret) \ + if ((buflen <= bufpos) || ((buflen - bufpos) < srclen)) { \ + ret = BCME_BUFTOOSHORT; \ + DHD_ERROR(("%s, check buffer (%d/%d/%d/%d)\n", \ + func, srclen, buflen, bufpos, buflen - bufpos)); \ + return ret; \ + } \ + buflen = srclen + bufpos; \ + #ifdef PCIE_FULL_DONGLE /** Dummy objects are defined with state representing bad|down. @@ -1684,8 +1695,10 @@ dhd_enable_packet_filter(int value, dhd_pub_t *dhd) int i; DHD_ERROR(("%s: enter, value = %d\n", __FUNCTION__, value)); - if ((dhd->op_mode & DHD_FLAG_HOSTAP_MODE) && value) { - DHD_ERROR(("%s: DHD_FLAG_HOSTAP_MODE\n", __FUNCTION__)); + if ((dhd->op_mode & + (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_P2P_GO_MODE)) && + value) { + DHD_ERROR(("%s: DHD_FLAG_HOSTAP_MODE or DHD_FLAG_P2P_GO_MODE\n", __FUNCTION__)); return; } /* 1 - Enable packet filter, only allow unicast packet to send up */ @@ -1801,7 +1814,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) int power_mode = PM_MAX; #endif /* SUPPORT_PM2_ONLY */ /* wl_pkt_filter_enable_t enable_parm; */ - int bcn_li_dtim = 0; /* Default bcn_li_dtim in resume mode is 0 */ int ret = 0; #ifdef DHD_USE_EARLYSUSPEND #ifdef CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND @@ -1810,9 +1822,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) #ifndef ENABLE_FW_ROAM_SUSPEND uint roamvar = 1; #endif /* ENABLE_FW_ROAM_SUSPEND */ -#ifdef ENABLE_BCN_LI_BCN_WAKEUP - int bcn_li_bcn = 1; -#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ uint nd_ra_filter = 0; #ifdef ENABLE_IPMCAST_FILTER int ipmcast_l2filter; @@ -1837,13 +1846,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) /* CUSTOM_BCN_TIMEOUT_IN_SUSPEND in suspend, otherwise CUSTOM_BCN_TIMEOUT */ int bcn_timeout = CUSTOM_BCN_TIMEOUT; #endif /* DHD_BCN_TIMEOUT_IN_SUSPEND && DHD_USE_EARLYSUSPEND */ -#if defined(BCMPCIE) - int lpas = 0; - int dtim_period = 0; - int bcn_interval = 0; - int bcn_to_dly = 0; -#endif /* OEM_ANDROID && BCMPCIE */ + BCM_REFERENCE(ret); if (!dhd) return -ENODEV; @@ -1886,7 +1890,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) dhd_arp_offload_enable(dhd, TRUE); } #endif /* ARP_OFFLOAD_SUPPORT */ - #ifdef PASS_ALL_MCAST_PKTS allmulti = 0; for (i = 0; i < DHD_MAX_IFS; i++) { @@ -1906,66 +1909,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) * each third DTIM for better power savings. Note that * one side effect is a chance to miss BC/MC packet. */ -#ifdef WLTDLS - /* Do not set bcn_li_ditm on WFD mode */ - if (dhd->tdls_mode) { - bcn_li_dtim = 0; - } else -#endif /* WLTDLS */ -#if defined(BCMPCIE) - bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd, &dtim_period, - &bcn_interval); - ret = dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim, - sizeof(bcn_li_dtim), NULL, 0, TRUE); - if (ret < 0) { - DHD_ERROR(("%s bcn_li_dtim failed %d\n", - __FUNCTION__, ret)); - } - if ((bcn_li_dtim * dtim_period * bcn_interval) >= - MIN_DTIM_FOR_ROAM_THRES_EXTEND) { - /* - * Increase max roaming threshold from 2 secs to 8 secs - * the real roam threshold is MIN(max_roam_threshold, - * bcn_timeout/2) - */ - lpas = 1; - ret = dhd_iovar(dhd, 0, "lpas", (char *)&lpas, sizeof(lpas), - NULL, 0, TRUE); - if (ret < 0) { - if (ret == BCME_UNSUPPORTED) { - DHD_ERROR(("%s lpas, UNSUPPORTED\n", - __FUNCTION__)); - } else { - DHD_ERROR(("%s set lpas failed %d\n", - __FUNCTION__, ret)); - } - } - bcn_to_dly = 1; - /* - * if bcn_to_dly is 1, the real roam threshold is - * MIN(max_roam_threshold, bcn_timeout -1); - * notify link down event after roaming procedure complete - * if we hit bcn_timeout while we are in roaming progress. - */ - ret = dhd_iovar(dhd, 0, "bcn_to_dly", (char *)&bcn_to_dly, - sizeof(bcn_to_dly), NULL, 0, TRUE); - if (ret < 0) { - if (ret == BCME_UNSUPPORTED) { - DHD_ERROR(("%s bcn_to_dly, UNSUPPORTED\n", - __FUNCTION__)); - } else { - DHD_ERROR(("%s set bcn_to_dly failed %d\n", - __FUNCTION__, ret)); - } - } - } -#else - bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd); - if (dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim, - sizeof(bcn_li_dtim), NULL, 0, TRUE) < 0) - DHD_ERROR(("%s: set dtim failed\n", __FUNCTION__)); -#endif /* OEM_ANDROID && BCMPCIE */ - + dhd_set_suspend_bcn_li_dtim(dhd, TRUE); #ifdef DHD_USE_EARLYSUSPEND #ifdef DHD_BCN_TIMEOUT_IN_SUSPEND bcn_timeout = CUSTOM_BCN_TIMEOUT_IN_SUSPEND; @@ -1997,16 +1941,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) ROAMOFF_DBG_SAVE(dhd_linux_get_primary_netdev(dhd), SET_ROAM_DHD_SUSPEND, roamvar); #endif /* ENABLE_FW_ROAM_SUSPEND */ -#ifdef ENABLE_BCN_LI_BCN_WAKEUP - if (bcn_li_dtim) { - bcn_li_bcn = 0; - } - ret = dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn, - sizeof(bcn_li_bcn), NULL, 0, TRUE); - if (ret < 0) { - DHD_ERROR(("%s bcn_li_bcn failed %d\n", __FUNCTION__, ret)); - } -#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ #if defined(WL_CFG80211) && defined(WL_BCNRECV) ret = wl_android_bcnrecv_suspend(dhd_linux_get_primary_netdev(dhd)); if (ret != BCME_OK) { @@ -2132,43 +2066,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) } } #endif /* PASS_ALL_MCAST_PKTS */ -#if defined(BCMPCIE) - /* restore pre-suspend setting */ - ret = dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim, - sizeof(bcn_li_dtim), NULL, 0, TRUE); - if (ret < 0) { - DHD_ERROR(("%s:bcn_li_ditm failed:%d\n", - __FUNCTION__, ret)); - } - ret = dhd_iovar(dhd, 0, "lpas", (char *)&lpas, sizeof(lpas), NULL, - 0, TRUE); - if (ret < 0) { - if (ret == BCME_UNSUPPORTED) { - DHD_ERROR(("%s lpas, UNSUPPORTED\n", __FUNCTION__)); - } else { - DHD_ERROR(("%s set lpas failed %d\n", - __FUNCTION__, ret)); - } - } - ret = dhd_iovar(dhd, 0, "bcn_to_dly", (char *)&bcn_to_dly, - sizeof(bcn_to_dly), NULL, 0, TRUE); - if (ret < 0) { - if (ret == BCME_UNSUPPORTED) { - DHD_ERROR(("%s bcn_to_dly UNSUPPORTED\n", - __FUNCTION__)); - } else { - DHD_ERROR(("%s set bcn_to_dly failed %d\n", - __FUNCTION__, ret)); - } - } -#else /* restore pre-suspend setting for dtim_skip */ - ret = dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim, - sizeof(bcn_li_dtim), NULL, 0, TRUE); - if (ret < 0) { - DHD_ERROR(("%s:bcn_li_ditm fail:%d\n", __FUNCTION__, ret)); - } -#endif /* OEM_ANDROID && BCMPCIE */ + dhd_set_suspend_bcn_li_dtim(dhd, FALSE); #ifdef DHD_USE_EARLYSUSPEND #ifdef DHD_BCN_TIMEOUT_IN_SUSPEND bcn_timeout = CUSTOM_BCN_TIMEOUT; @@ -2200,14 +2099,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) ROAMOFF_DBG_SAVE(dhd_linux_get_primary_netdev(dhd), SET_ROAM_DHD_SUSPEND, roamvar); #endif /* ENABLE_FW_ROAM_SUSPEND */ -#ifdef ENABLE_BCN_LI_BCN_WAKEUP - ret = dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn, - sizeof(bcn_li_bcn), NULL, 0, TRUE); - if (ret < 0) { - DHD_ERROR(("%s: bcn_li_bcn failed:%d\n", - __FUNCTION__, ret)); - } -#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ #ifdef NDO_CONFIG_SUPPORT if (dhd->ndo_enable) { /* Disable ND offload on resume */ @@ -4077,6 +3968,24 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) #endif /* SHOW_LOGTRACE */ continue; } + + eh = (struct ether_header *)PKTDATA(dhdp->osh, pktbuf); + + /* Check if dhd_stop is in progress */ + if (dhdp->stop_in_progress) { + DHD_ERROR_RLMT(("%s: dhd_stop in progress ignore received packet\n", + __FUNCTION__)); + if (ntoh16(eh->ether_type) == ETHER_TYPE_BRCM) { +#ifdef DHD_USE_STATIC_CTRLBUF + PKTFREE_STATIC(dhdp->osh, pktbuf, FALSE); +#else + PKTFREE(dhdp->osh, pktbuf, FALSE); +#endif /* DHD_USE_STATIC_CTRLBUF */ + } else { + PKTCFREE(dhdp->osh, pktbuf, FALSE); + } + continue; + } #ifdef DHD_WAKE_STATUS pkt_wake = dhd_bus_get_bus_wake(dhdp); wcp = dhd_bus_get_wakecount(dhdp); @@ -4086,7 +3995,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) } #endif /* DHD_WAKE_STATUS */ - eh = (struct ether_header *)PKTDATA(dhdp->osh, pktbuf); if (dhd->pub.tput_data.tput_test_running && dhd->pub.tput_data.direction == TPUT_DIR_RX && ntoh16(eh->ether_type) == ETHER_TYPE_IP) { @@ -4333,6 +4241,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) len, NULL, NULL, FALSE, pkt_wake, TRUE); #if defined(DHD_WAKE_STATUS) && defined(DHD_WAKEPKT_DUMP) if (pkt_wake) { + DHD_ERROR(("##### dhdpcie_host_wake caused by packets\n")); dhd_prhex("[wakepkt_dump]", (char*)dump_data, MIN(len, 64), DHD_ERROR_VAL); DHD_ERROR(("config check in_suspend: %d ", dhdp->in_suspend)); #ifdef ARP_OFFLOAD_SUPPORT @@ -4359,10 +4268,10 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) #ifdef ENABLE_WAKEUP_PKT_DUMP if (dhd_mmc_wake) { DHD_INFO(("wake_pkt %s(%d)\n", __FUNCTION__, __LINE__)); - if (DHD_INFO_ON()) { - prhex("wake_pkt", (char*) eth, MIN(len, 48)); - } + prhex("wake_pkt", (char*) eth, MIN(len, 48)); update_wake_pkt_info(skb); + DHD_ERROR(("wake_pkt %s(%d), raw_info=0x%016llx\n", + __FUNCTION__, __LINE__, temp_raw)); #ifdef CONFIG_IRQ_HISTORY add_irq_history(0, "WIFI"); #endif @@ -4762,6 +4671,9 @@ dhd_watchdog_thread(void *data) min(msecs_to_jiffies(dhd_watchdog_ms), time_lapse)); } DHD_GENERAL_UNLOCK(&dhd->pub, flags); +#if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) + dhd_throttle_p2p_interface_event(dhd, true); +#endif /* !PCIE_FULL_DONGLE & P2P_IF_STATE_EVENT_CTRL */ } #ifdef BCMPCIE DHD_OS_WD_WAKE_UNLOCK(&dhd->pub); @@ -6404,6 +6316,11 @@ dhd_stop(struct net_device *net) dhd->pub.d3ackcnt_timeout = 0; #endif /* BCMPCIE */ + /* Synchronize between the stop and rx path */ + dhd->pub.stop_in_progress = true; + OSL_SMP_WMB(); + dhd_os_busbusy_wait_negation(&dhd->pub, &dhd->pub.dhd_bus_busy_state); + mutex_lock(&dhd->pub.ndev_op_sync); if (dhd->pub.up == 0) { goto exit; @@ -6629,6 +6546,8 @@ dhd_stop(struct net_device *net) dhd_ctrl_tcp_limit_output_bytes(0); #endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */ mutex_unlock(&dhd->pub.ndev_op_sync); + /* Clear stop in progress flag */ + dhd->pub.stop_in_progress = false; DHD_ERROR(("%s: EXIT\n", __FUNCTION__)); return 0; } @@ -6743,21 +6662,6 @@ dhd_open(struct net_device *net) DHD_OS_WAKE_LOCK_INIT(dhd); dhd->dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT; } - -#ifdef SHOW_LOGTRACE - skb_queue_head_init(&dhd->evt_trace_queue); - - if (!(dhd->dhd_state & DHD_ATTACH_LOGTRACE_INIT)) { - ret = dhd_init_logstrs_array(dhd->pub.osh, &dhd->event_data); - if (ret == BCME_OK) { - dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data, - st_str_file_path, map_file_path); - dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data, - rom_st_str_file_path, rom_map_file_path); - dhd->dhd_state |= DHD_ATTACH_LOGTRACE_INIT; - } - } -#endif /* SHOW_LOGTRACE */ } #if defined(MULTIPLE_SUPPLICANT) @@ -6784,6 +6688,7 @@ dhd_open(struct net_device *net) dhd->pub.iface_op_failed = 0; dhd->pub.scan_timeout_occurred = 0; dhd->pub.scan_busy_occurred = 0; + dhd->pub.p2p_disc_busy_occurred = 0; dhd->pub.smmu_fault_occurred = 0; #ifdef DHD_LOSSLESS_ROAMING dhd->pub.dequeue_prec_map = ALLPRIO; @@ -6791,6 +6696,24 @@ dhd_open(struct net_device *net) #ifdef DHD_GRO_ENABLE_HOST_CTRL dhd->pub.permitted_gro = TRUE; #endif /* DHD_GRO_ENABLE_HOST_CTRL */ + +#ifdef SHOW_LOGTRACE + if (!dhd_download_fw_on_driverload) { + skb_queue_head_init(&dhd->evt_trace_queue); + + if (!(dhd->dhd_state & DHD_ATTACH_LOGTRACE_INIT)) { + ret = dhd_init_logstrs_array(dhd->pub.osh, &dhd->event_data); + if (ret == BCME_OK) { + dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data, + st_str_file_path, map_file_path); + dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data, + rom_st_str_file_path, rom_map_file_path); + dhd->dhd_state |= DHD_ATTACH_LOGTRACE_INIT; + } + } + } +#endif /* SHOW_LOGTRACE */ + #if !defined(WL_CFG80211) /* * Force start if ifconfig_up gets called before START command @@ -7766,6 +7689,12 @@ dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock) if (ifp->net != NULL) { DHD_ERROR(("deleting interface '%s' idx %d\n", ifp->net->name, ifp->idx)); +#if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) + if (wl_cfgp2p_vif_created(wl_get_cfg(ifp->net))) { + dhd_reset_p2p_interface_event(dhdpub); + } +#endif /* !PCIE_FULL_DONGLE & P2P_IF_STATE_EVENT_CTRL */ + DHD_GENERAL_LOCK(dhdpub, flags); ifp->del_in_progress = true; DHD_GENERAL_UNLOCK(dhdpub, flags); @@ -9295,11 +9224,15 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd->pub.iface_op_failed = 0; dhd->pub.scan_timeout_occurred = 0; dhd->pub.scan_busy_occurred = 0; + dhd->pub.p2p_disc_busy_occurred = 0; /* Retain BH induced errors and clear induced error during initialize */ if (dhd->pub.dhd_induce_error) { dhd->pub.dhd_induce_bh_error = dhd->pub.dhd_induce_error; } dhd->pub.dhd_induce_error = DHD_INDUCE_ERROR_CLEAR; +#ifdef DHD_MAP_PKTID_LOGGING + dhd->pub.enable_pktid_log_dump = FALSE; +#endif /* DHD_MAP_PKTID_LOGGING */ dhd->pub.tput_test_done = FALSE; /* try to download image and nvram to the dongle */ @@ -11303,6 +11236,7 @@ dhd_legacy_preinit_ioctls(dhd_pub_t *dhd) dhd->info->rxthread_enabled = TRUE; #endif +#ifndef CONFIG_WLAN_MERLOT #if defined(CUSTOM_COUNTRY_CODE_XZ) /* Set initial country code to XZ */ strlcpy(dhd->dhd_cspec.country_abbrev, "XZ", WLC_CNTRY_BUF_SZ); @@ -11316,6 +11250,7 @@ dhd_legacy_preinit_ioctls(dhd_pub_t *dhd) if (ret < 0) DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__)); } +#endif /* CONFIG_WLAN_MERLOT */ /* Set Listen Interval */ ret = dhd_iovar(dhd, 0, "assoc_listen", (char *)&listen_interval, sizeof(listen_interval), @@ -12328,6 +12263,21 @@ dhd_legacy_preinit_ioctls(dhd_pub_t *dhd) dhd_ecounter_configure(dhd, TRUE); } +#ifdef CONFIG_WLAN_MERLOT + /* Set initial country code to XZ */ + strlcpy(dhd->dhd_cspec.country_abbrev, "XZ", WLC_CNTRY_BUF_SZ); + strlcpy(dhd->dhd_cspec.ccode, "XZ", WLC_CNTRY_BUF_SZ); + DHD_INFO(("%s: Set initial country code to XZ(World Wide Safe)\n", __FUNCTION__)); + /* Set Country code */ + if (dhd->dhd_cspec.ccode[0] != 0) { + ret = dhd_iovar(dhd, 0, "country", (char *)&dhd->dhd_cspec, sizeof(wl_country_t), + NULL, 0, TRUE); + if (ret < 0) { + DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__)); + } + } +#endif /* CONFIG_WLAN_MERLOT */ + #ifdef CONFIG_SILENT_ROAM dhd->sroam_turn_on = TRUE; dhd->sroamed = FALSE; @@ -14089,8 +14039,16 @@ dhd_os_runtimepm_timer(void *bus, uint tick) int dhd_os_get_img_fwreq(const struct firmware **fw, char *file_path) { - return request_firmware(fw, file_path, - dhd_bus_to_dev(g_dhd_pub->bus)); + int ret = BCME_ERROR; + + ret = request_firmware(fw, file_path, dhd_bus_to_dev(g_dhd_pub->bus)); + if (ret < 0) { + DHD_ERROR(("%s: request_firmware err: %d\n", __FUNCTION__, ret)); + /* convert to BCME_NOTFOUND error for error handling */ + ret = BCME_NOTFOUND; + } + + return ret; } void @@ -14562,6 +14520,13 @@ dhd_net_bus_devreset(struct net_device *dev, uint8 flag) dhd->pub.iface_op_failed = 0; dhd->pub.scan_timeout_occurred = 0; dhd->pub.scan_busy_occurred = 0; + dhd->pub.p2p_disc_busy_occurred = 0; + } + + if ((ret == BCME_NOMEM) || (ret == BCME_NOTFOUND)) { + DHD_ERROR(("%s: skip collect dump in case of BCME_NOMEM or BCME_NOTFOUND\n", + __FUNCTION__)); + return BCME_ERROR; } if (ret) { @@ -14620,19 +14585,27 @@ int net_os_set_suspend(struct net_device *dev, int val, int force) int net_os_set_suspend_bcn_li_dtim(struct net_device *dev, int val) { dhd_info_t *dhd = DHD_DEV_INFO(dev); + dhd_pub_t *dhdp = &dhd->pub; if (dhd) { DHD_ERROR(("%s: Set bcn_li_dtim in suspend %d\n", __FUNCTION__, val)); dhd->pub.suspend_bcn_li_dtim = val; + } else { + return BCME_ERROR; } - return 0; + if (dhdp->in_suspend) { + dhd_set_suspend_bcn_li_dtim(dhdp, TRUE); + } + + return BCME_OK; } int net_os_set_max_dtim_enable(struct net_device *dev, int val) { dhd_info_t *dhd = DHD_DEV_INFO(dev); + dhd_pub_t *dhdp = &dhd->pub; if (dhd) { DHD_ERROR(("%s: use MAX bcn_li_dtim in suspend %s\n", @@ -14643,16 +14616,21 @@ int net_os_set_max_dtim_enable(struct net_device *dev, int val) dhd->pub.max_dtim_enable = FALSE; } } else { - return -1; + return BCME_ERROR; } - return 0; + if (dhdp->in_suspend) { + dhd_set_suspend_bcn_li_dtim(dhdp, TRUE); + } + + return BCME_OK; } #ifdef DISABLE_DTIM_IN_SUSPEND int net_os_set_disable_dtim_in_suspend(struct net_device *dev, int val) { dhd_info_t *dhd = DHD_DEV_INFO(dev); + dhd_pub_t *dhdp = &dhd->pub; if (dhd) { DHD_ERROR(("%s: Disable bcn_li_dtim in suspend %s\n", @@ -14666,10 +14644,88 @@ int net_os_set_disable_dtim_in_suspend(struct net_device *dev, int val) return BCME_ERROR; } + if (dhdp->in_suspend) { + dhd_set_suspend_bcn_li_dtim(dhdp, TRUE); + } + return BCME_OK; } #endif /* DISABLE_DTIM_IN_SUSPEND */ +int +dhd_set_suspend_bcn_li_dtim(dhd_pub_t *dhd, bool set_suspend) +{ + int ret = BCME_OK; + int bcn_li_dtim = 0; /* Default bcn_li_dtim in resume mode is 0 */ +#if defined(BCMPCIE) + int lpas = 0; + int dtim_period = 0; + int bcn_interval = 0; + int bcn_to_dly = 0; +#endif /* OEM_ANDROID && BCMPCIE */ +#ifdef ENABLE_BCN_LI_BCN_WAKEUP + int bcn_li_bcn = 1; +#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ + + if (set_suspend) { +#ifdef WLTDLS + /* Do not set bcn_li_ditm on WFD mode */ + if (dhd->tdls_mode) { + return 0; + } +#endif /* WLTDLS */ +#if defined(BCMPCIE) + bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd, &dtim_period, &bcn_interval); + if ((bcn_li_dtim * dtim_period * bcn_interval) >= MIN_DTIM_FOR_ROAM_THRES_EXTEND) { + /* + * Increase max roaming threshold from 2 secs to 8 secs + * the real roam threshold is MIN(max_roam_threshold, + * bcn_timeout/2) + */ + lpas = 1; + bcn_to_dly = 1; + /* + * if bcn_to_dly is 1, the real roam threshold is + * MIN(max_roam_threshold, bcn_timeout -1); + * notify link down event after roaming procedure complete + * if we hit bcn_timeout while we are in roaming progress. + */ + } +#else + bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd); +#endif /* OEM_ANDROID && BCMPCIE */ + } + + ret = dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim, sizeof(bcn_li_dtim), + NULL, 0, TRUE); + if (ret < 0) { + DHD_ERROR(("%s set bcn_li_ditm failed %d\n", __FUNCTION__, ret)); + } +#if defined(BCMPCIE) + ret = dhd_iovar(dhd, 0, "lpas", (char *)&lpas, sizeof(lpas), NULL, 0, TRUE); + if (ret < 0) { + DHD_ERROR(("%s set lpas failed %d\n", __FUNCTION__, ret)); + } + ret = dhd_iovar(dhd, 0, "bcn_to_dly", (char *)&bcn_to_dly, sizeof(bcn_to_dly), + NULL, 0, TRUE); + if (ret < 0) { + DHD_ERROR(("%s set bcn_to_dly failed %d\n", __FUNCTION__, ret)); + } +#endif /* OEM_ANDROID && BCMPCIE */ +#ifdef ENABLE_BCN_LI_BCN_WAKEUP + if (bcn_li_dtim) { + bcn_li_bcn = 0; + } + ret = dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn, sizeof(bcn_li_bcn), + NULL, 0, TRUE); + if (ret < 0) { + DHD_ERROR(("%s set bcn_li_bcn failed %d\n", __FUNCTION__, ret)); + } +#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ + + return 0; +} + #ifdef PKT_FILTER_SUPPORT int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num) { @@ -17991,6 +18047,11 @@ dhd_log_flush(dhd_pub_t *dhdp, log_dump_type_t *type) #endif /* DHD_LOG_DUMP */ #ifdef DHD_FW_COREDUMP +bool dhd_memdump_is_scheduled(dhd_pub_t *dhdp) +{ + return dhdp->info->scheduled_memdump; +} + void dhd_schedule_memdump(dhd_pub_t *dhdp, uint8 *buf, uint32 size) { dhd_dump_t *dump = NULL; @@ -18471,6 +18532,7 @@ dhd_sssr_dump_dig_buf_before(void *dev, const void *user_buf, uint32 len) uint dig_buf_size = 0; dig_buf_size = dhd_sssr_dig_buf_size(dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, dig_buf_size, len, 0, ret); if (dhdp->sssr_dig_buf_before && (dhdp->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) { ret = dhd_export_debug_data((char *)dhdp->sssr_dig_buf_before, @@ -18486,6 +18548,9 @@ dhd_sssr_dump_d11_buf_before(void *dev, const void *user_buf, uint32 len, int co dhd_pub_t *dhdp = &dhd_info->pub; int pos = 0, ret = BCME_ERROR; + uint32 length = dhd_sssr_mac_buf_size(dhdp, core); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, 0, ret); + if (dhdp->sssr_d11_before[core] && dhdp->sssr_d11_outofreset[core] && (dhdp->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) { @@ -18505,6 +18570,7 @@ dhd_sssr_dump_dig_buf_after(void *dev, const void *user_buf, uint32 len) uint dig_buf_size = 0; dig_buf_size = dhd_sssr_dig_buf_size(dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, dig_buf_size, len, 0, ret); if (dhdp->sssr_dig_buf_after) { ret = dhd_export_debug_data((char *)dhdp->sssr_dig_buf_after, @@ -18520,6 +18586,9 @@ dhd_sssr_dump_d11_buf_after(void *dev, const void *user_buf, uint32 len, int cor dhd_pub_t *dhdp = &dhd_info->pub; int pos = 0, ret = BCME_ERROR; + uint32 length = dhd_sssr_mac_buf_size(dhdp, core); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, 0, ret); + if (dhdp->sssr_d11_after[core] && dhdp->sssr_d11_outofreset[core]) { ret = dhd_export_debug_data((char *)dhdp->sssr_d11_after[core], @@ -18763,8 +18832,8 @@ void dhd_schedule_log_dump(dhd_pub_t *dhdp, void *type) static void dhd_print_buf_addr(dhd_pub_t *dhdp, char *name, void *buf, unsigned int size) { - if ((dhdp->memdump_enabled == DUMP_MEMONLY) || - (dhdp->memdump_enabled == DUMP_MEMFILE_BUGON) || + if (((dhdp->memdump_enabled > DUMP_DISABLED) && + (dhdp->memdump_enabled < DUMP_MEMFILE_MAX)) || (dhdp->memdump_type == DUMP_TYPE_SMMU_FAULT) || #ifdef DHD_DETECT_CONSECUTIVE_MFG_HANG (dhdp->op_mode & DHD_FLAG_MFG_MODE && @@ -19197,6 +19266,10 @@ dhd_get_dld_log_dump(void *dev, dhd_pub_t *dhdp, const void *user_buf, DHD_ERROR(("%s: ENTER \n", __FUNCTION__)); + if (!fp) { + uint32 length = dhd_get_dld_len(type); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } dhd_init_sec_hdr(&sec_hdr); /* write the section header first */ @@ -19318,6 +19391,11 @@ dhd_print_time_str(const void *user_buf, void *fp, uint32 len, void *pos) snprintf(time_str, sizeof(time_str), "\n\n ========== LOG DUMP TAKEN AT : %s =========\n", ts); + if (!fp) { + uint32 length = dhd_get_time_str_len(); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } + /* write the timestamp hdr to the file first */ ret = dhd_export_debug_data(time_str, fp, user_buf, strlen(time_str), pos); if (ret < 0) { @@ -19343,6 +19421,10 @@ dhd_print_health_chk_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, if (!dhdp) return BCME_ERROR; + if (!fp) { + uint32 length = dhd_get_health_chk_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } dhd_init_sec_hdr(&sec_hdr); if (dhdp->memdump_type == DUMP_TYPE_DONGLE_HOST_EVENT) { @@ -19388,6 +19470,10 @@ dhd_print_ext_trap_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, if (!dhdp) return BCME_ERROR; + if (!fp) { + uint32 length = dhd_get_ext_trap_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } dhd_init_sec_hdr(&sec_hdr); /* append extended trap data to the file in case of traps */ @@ -19434,6 +19520,11 @@ dhd_print_dump_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, if (!dhdp) return BCME_ERROR; + if (!fp) { + uint32 length = dhd_get_dhd_dump_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } + dhd_init_sec_hdr(&sec_hdr); ret = dhd_export_debug_data(DHD_DUMP_LOG_HDR, fp, user_buf, strlen(DHD_DUMP_LOG_HDR), pos); @@ -19475,6 +19566,11 @@ dhd_print_cookie_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, if (!dhdp) return BCME_ERROR; + if (!fp) { + uint32 length = dhd_get_cookie_log_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } + if (dhdp->logdump_cookie && dhd_logdump_cookie_count(dhdp) > 0) { ret = dhd_log_dump_cookie_to_file(dhdp, fp, user_buf, (unsigned long *)pos); } @@ -19499,6 +19595,10 @@ dhd_print_flowring_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, if (!dhdp) return BCME_ERROR; + if (!fp) { + uint32 length = dhd_get_flowring_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } dhd_init_sec_hdr(&sec_hdr); remain_len = dhd_dump(dhdp, (char *)dhdp->concise_dbg_buf, CONCISE_DUMP_BUFLEN); @@ -19548,6 +19648,10 @@ dhd_print_ecntrs_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, if (!dhdp) return BCME_ERROR; + if (!fp) { + uint32 length = dhd_get_ecntrs_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } dhd_init_sec_hdr(&sec_hdr); if (logdump_ecntr_enable && @@ -19578,6 +19682,10 @@ dhd_print_rtt_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, if (!dhdp) return BCME_ERROR; + if (!fp) { + uint32 length = dhd_get_rtt_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } dhd_init_sec_hdr(&sec_hdr); if (logdump_rtt_enable && dhdp->rtt_dbg_ring) { @@ -19595,6 +19703,7 @@ dhd_print_status_log_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, void *fp, uint32 len, void *pos) { dhd_info_t *dhd_info; + int ret = BCME_OK; if (dev) { dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev); @@ -19605,6 +19714,11 @@ dhd_print_status_log_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, return BCME_ERROR; } + if (!fp) { + uint32 length = dhd_get_status_log_len(dev, dhdp); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } + return dhd_statlog_write_logdump(dhdp, user_buf, fp, len, pos); } @@ -20031,6 +20145,50 @@ dhd_get_rtt_len(void *ndev, dhd_pub_t *dhdp) } #endif /* EWP_RTT_LOGGING */ +#ifdef DHD_MAP_PKTID_LOGGING +uint32 +dhd_get_pktid_map_logging_len(void *ndev, dhd_pub_t *dhdp, bool is_map) +{ + dhd_info_t *dhd_info; + log_dump_section_hdr_t sec_hdr; + uint32 length = 0; + + if (ndev) { + dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev); + dhdp = &dhd_info->pub; + } + + if (!dhdp || !dhdp->enable_pktid_log_dump) + return length; + + length = dhd_pktid_buf_len(dhdp, is_map) + sizeof(sec_hdr); + return length; +} + +int +dhd_print_pktid_map_log_data(void *dev, dhd_pub_t *dhdp, const void *user_buf, + void *fp, uint32 len, void *pos, bool is_map) +{ + dhd_info_t *dhd_info; + int ret = BCME_OK; + + if (dev) { + dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev); + dhdp = &dhd_info->pub; + } + + if (!dhdp) { + return BCME_ERROR; + } + + if (!fp) { + uint32 length = dhd_get_pktid_map_logging_len(dev, dhdp, is_map); + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, *(int*)pos, ret); + } + return dhd_write_pktid_log_dump(dhdp, user_buf, fp, len, pos, is_map); +} +#endif /* DHD_MAP_PKTID_LOGGING */ + int dhd_os_get_version(struct net_device *dev, bool dhd_ver, char **buf, uint32 size) { @@ -20060,11 +20218,15 @@ dhd_os_get_pktlog_dump(void *dev, const void *user_buf, uint32 len) int ret = BCME_OK; dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); dhd_pub_t *dhdp = &dhd->pub; + uint32 length = dhd_os_get_pktlog_dump_size(dev); + if (user_buf == NULL) { DHD_ERROR(("%s(): user buffer is NULL\n", __FUNCTION__)); return BCME_ERROR; } + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, 0, ret); + ret = dhd_pktlog_dump_write_memory(dhdp, user_buf, len); if (ret < 0) { DHD_ERROR(("%s(): fail to dump pktlog, err = %d\n", __FUNCTION__, ret)); @@ -20104,11 +20266,14 @@ dhd_os_get_axi_error_dump(void *dev, const void *user_buf, uint32 len) dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); dhd_pub_t *dhdp = &dhd->pub; loff_t pos = 0; + uint32 length = dhd_os_get_axi_error_dump_size(dev); if (user_buf == NULL) { DHD_ERROR(("%s(): user buffer is NULL\n", __FUNCTION__)); return BCME_ERROR; } + CHK_BUF_ENOUGH_AND_UPDATE_LEN(__FUNCTION__, length, len, 0, ret); + ret = dhd_export_debug_data((char *)dhdp->axi_err_dump, NULL, user_buf, sizeof(dhd_axi_error_dump_t), &pos); @@ -23396,6 +23561,12 @@ dhd_cto_recovery_handler(void *handle, void *event_info, u8 event) void dhd_schedule_cto_recovery(dhd_pub_t *dhdp) { + if (dhdp->up == FALSE) { + DHD_ERROR(("%s : skip scheduling cto because dhd is not up\n", + __FUNCTION__)); + return; + } + DHD_ERROR(("%s: scheduling cto recovery.. \n", __FUNCTION__)); dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, NULL, DHD_WQ_WORK_CTO_RECOVERY, @@ -23683,9 +23854,56 @@ static void dhd_p2p_interface_event_ctrl_fn(struct work_struct * work) } } -static bool dhd_is_p2p_connected(dhd_info_t *dhd) +#define P2P_NOA_CONTINUOUS 255 +static bool dhd_is_noa_enabled(dhd_pub_t *dhd_pub, int ifidx) +{ + int iov_len = 0; + char iovbuf[128]; + wl_p2p_sched_t dongle_noa[2]; + wl_p2p_sched_t *noa; + int rc; + + if (dhd_pub == NULL) { + return false; + } + + iov_len = bcm_mkiovar("p2p_noa", (char *)dongle_noa, + sizeof(dongle_noa), iovbuf, sizeof(iovbuf)); + if (!iov_len) { + DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n", + __FUNCTION__, sizeof(iovbuf))); + return false; + } + + rc = dhd_wl_ioctl_cmd(dhd_pub, WLC_GET_VAR, iovbuf, iov_len, FALSE, ifidx); + + if (rc) { + DHD_ERROR(("%s: failed to get p2p_noa info, retcode = %d\n", + __FUNCTION__, rc)); + + return false; + } + + noa = (wl_p2p_sched_t *)iovbuf; + DHD_INFO(("%s, ifidx=%d noa type=%d, st=%d, interval=%d, dur=%d, cnt=%d\n", + __FUNCTION__, ifidx, noa->type, noa->desc[0].start, + noa->desc[0].interval, noa->desc[0].duration, noa->desc[0].count)); + + if ((noa->type == WL_P2P_SCHED_TYPE_ABS) && + (noa->desc[0].duration != 0) && (noa->desc[0].count == P2P_NOA_CONTINUOUS)) { + return true; + } + + return false; +} + +static bool dhd_is_p2pgc_noa(dhd_info_t *dhd) { dhd_pub_t *dhdp; + struct net_device *dev; + int idx, p2p_idx = -1; + bool p2pgc_connected = FALSE; + int connected_cnt = 0; if (dhd == NULL) { return false; @@ -23697,7 +23915,29 @@ static bool dhd_is_p2p_connected(dhd_info_t *dhd) return false; } - return true; + for (idx = 0; idx < DHD_MAX_IFS; idx++) { + if (dhd->iflist[idx] != NULL) { + dev = dhd->iflist[idx]->net; + /* check if connected */ + if (wl_get_drv_status(wl_get_cfg(dev), CONNECTED, dev)) { + connected_cnt++; + if (dev->ieee80211_ptr && + dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) { + p2pgc_connected = true; + p2p_idx = idx; + } + } + } + } + + /* check if only p2p is connected */ + if (p2pgc_connected && (connected_cnt == 1)) { + if (dhd_is_noa_enabled(dhdp, p2p_idx)) { + return true; + } + } + + return false; } #define NO_TX_DURATION 5000 @@ -23707,23 +23947,24 @@ static bool dhd_is_p2p_connected(dhd_info_t *dhd) int dhd_throttle_p2p_interface_event(void *handle, bool onoff) { dhd_info_t *dhd = handle; - uint32 cur, diff; - - if (!dhd_is_p2p_connected(dhd)) { - return 0; - } - cur = OSL_SYSUPTIME(); - - DHD_INFO(("%s, onoff=%d, tx_time=%u, cur=%u p2p_close=%d\n", - __FUNCTION__, onoff, dhd->last_tx_time, cur, dhd-> p2p_if_event_close)); if (onoff) { /* on */ + uint32 cur, diff; - if (dhd->p2p_if_event_close) + if (dhd->p2p_if_event_close) { return 0; + } + + cur = OSL_SYSUPTIME(); + DHD_INFO(("%s, onoff=%d, tx_time=%u, cur=%u p2p_close=%d\n", + __FUNCTION__, onoff, dhd->last_tx_time, cur, dhd-> p2p_if_event_close)); diff = TIME_DIFF(cur, dhd->last_tx_time); if ((dhd->last_tx_time != 0) && (diff > NO_TX_DURATION)) { + if (!dhd_is_p2pgc_noa(dhd)) { + return 0; + } + dhd->p2p_if_event_close = true; schedule_work(&dhd->p2p_interface_event_ctrl_work); } @@ -23740,6 +23981,20 @@ int dhd_throttle_p2p_interface_event(void *handle, bool onoff) return 0; } + +void dhd_reset_p2p_interface_event(void *handle) +{ + dhd_pub_t *dhdp = handle; + + dhdp->info->p2p_if_event_close = false; + dhdp->info->last_tx_time = 0; + + if (dhd_wlfc_ctrl_if_state_event(dhdp, false)) { + DHD_ERROR(("%s, iface event open failure\n", __FUNCTION__)); + } else { + DHD_ERROR(("%s, iface event open success\n", __FUNCTION__)); + } +} #endif /* !PCIE_FULL_DONGLE & P2P_IF_STATE_EVENT_CTRL */ #if defined(WLAN_ACCEL_BOOT) int diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.h index 32598d68f..458d7638c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux.h @@ -1,7 +1,7 @@ /* * DHD Linux header file (dhd_linux exports for cfg80211 and other components) * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_exportfs.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_exportfs.c index f7e50f93b..b4775b0db 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_exportfs.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_exportfs.c @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface * Basically selected code segments from usb-cdc.c and usb-rndis.c * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -1151,8 +1151,8 @@ set_proptx(struct dhd_info *dev, const char *buf, size_t count) } proptx = onoff; - DHD_ERROR(("[WIFI_SEC] %s: FRAMEBURST On/Off from sysfs = %u\n", - __FUNCTION__, txbf)); + DHD_ERROR(("[WIFI_SEC] %s: proptx from sysfs = %u\n", + __FUNCTION__, proptx)); return count; } diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_lb.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_lb.c index 5fe709bbf..315a96c2d 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_lb.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_lb.c @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface * Basically selected code segments from usb-cdc.c and usb-rndis.c * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -166,8 +166,22 @@ void dhd_select_cpu_candidacy(dhd_info_t *dhd) * cpumask_next returns >= nr_cpu_ids */ tx_cpu = cpumask_next(napi_cpu, dhd->cpumask_primary_new); - if (tx_cpu >= nr_cpu_ids) - tx_cpu = 0; + if (tx_cpu >= nr_cpu_ids) { + /* If no CPU is available for tx processing in primary CPUs, + * choose the same CPU with net_tx_cpu + * in case net_tx_cpu is in primary CPUs. + */ + cpumask_and(dhd->cpumask_primary_new, dhd->cpumask_primary, + dhd->cpumask_curr_avail); + + if (cpumask_test_cpu(net_tx_cpu, dhd->cpumask_primary_new)) { + tx_cpu = net_tx_cpu; + DHD_INFO(("%s If no CPU is for tx cpu, use net_tx_cpu %d\n", + __FUNCTION__, net_tx_cpu)); + } else { + tx_cpu = 0; + } + } } DHD_INFO(("%s After primary CPU check napi_cpu %d tx_cpu %d\n", @@ -212,6 +226,13 @@ void dhd_select_cpu_candidacy(dhd_info_t *dhd) ASSERT(napi_cpu < nr_cpu_ids); ASSERT(tx_cpu < nr_cpu_ids); + if (!cpu_online(napi_cpu)) { + napi_cpu = 0; + } + if (!cpu_online(tx_cpu)) { + tx_cpu = 0; + } + atomic_set(&dhd->rx_napi_cpu, napi_cpu); atomic_set(&dhd->tx_cpu, tx_cpu); diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.c index eaa10be90..0c046e56c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.c @@ -1,7 +1,7 @@ /* * Packet dump helper functions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -167,15 +167,17 @@ static const char pkt_cnt_msg[][20] = { #endif /* DHD_PKTDUMP_ROAM */ static const char tx_pktfate[][30] = { - "TX_PKT_FATE_ACKED", /* 0: WLFC_CTL_PKTFLAG_DISCARD */ - "TX_PKT_FATE_FW_QUEUED", /* 1: WLFC_CTL_PKTFLAG_D11SUPPRESS */ - "TX_PKT_FATE_FW_QUEUED", /* 2: WLFC_CTL_PKTFLAG_WLSUPPRESS */ - "TX_PKT_FATE_FW_DROP_INVALID", /* 3: WLFC_CTL_PKTFLAG_TOSSED_BYWLC */ - "TX_PKT_FATE_SENT", /* 4: WLFC_CTL_PKTFLAG_DISCARD_NOACK */ - "TX_PKT_FATE_FW_DROP_OTHER", /* 5: WLFC_CTL_PKTFLAG_SUPPRESS_ACKED */ - "TX_PKT_FATE_FW_DROP_EXPTIME", /* 6: WLFC_CTL_PKTFLAG_EXPIRED */ - "TX_PKT_FATE_FW_DROP_OTHER", /* 7: WLFC_CTL_PKTFLAG_DROPPED */ - "TX_PKT_FATE_FW_PKT_FREE", /* 8: WLFC_CTL_PKTFLAG_MKTFREE */ + "TX_PKT_FATE_ACKED", /* 0: WLFC_CTL_PKTFLAG_DISCARD */ + "TX_PKT_FATE_FW_D11SUPPRESS", /* 1: WLFC_CTL_PKTFLAG_D11SUPPRESS */ + "TX_PKT_FATE_FW_WLSUPPRESS", /* 2: WLFC_CTL_PKTFLAG_WLSUPPRESS */ + "TX_PKT_FATE_FW_TOSSED_BYWLC", /* 3: WLFC_CTL_PKTFLAG_TOSSED_BYWLC */ + "TX_PKT_FATE_SENT_NOACK", /* 4: WLFC_CTL_PKTFLAG_DISCARD_NOACK */ + "TX_PKT_FATE_FW_SUPPRESS_ACKED", /* 5: WLFC_CTL_PKTFLAG_SUPPRESS_ACKED */ + "TX_PKT_FATE_FW_DROP_EXPTIME", /* 6: WLFC_CTL_PKTFLAG_EXPIRED */ + "TX_PKT_FATE_FW_DROP_OTHER", /* 7: WLFC_CTL_PKTFLAG_DROPPED */ + "TX_PKT_FATE_FW_PKT_FREE", /* 8: WLFC_CTL_PKTFLAG_MKTFREE */ + "TX_PKT_FATE_FW_MAX_SUP_RETR", /* 9: WLFC_CTL_PKTFLAG_MAX_SUP_RETR */ + "TX_PKT_FATE_FW_FORCED_EXPIRED" /* 10: WLFC_CTL_PKTFLAG_FORCED_EXPIRED */ }; #define DBGREPLAY " Replay Counter: %02x%02x%02x%02x%02x%02x%02x%02x" @@ -189,8 +191,8 @@ static const char tx_pktfate[][30] = { ((const eapol_key_hdr_t *)(key))->replay[7] #define TXFATE_FMT " TX_PKTHASH:0x%X TX_PKT_FATE:%s" #define TX_PKTHASH(pkthash) ((pkthash) ? (*pkthash) : (0)) -#define TX_FATE_STR(fate) (((*fate) <= (WLFC_CTL_PKTFLAG_MKTFREE)) ? \ - (tx_pktfate[(*fate)]) : "TX_PKT_FATE_FW_DROP_OTHER") +#define TX_FATE_STR(fate) (((*fate) <= (WLFC_CTL_PKTFLAG_FORCED_EXPIRED)) ? \ + (tx_pktfate[(*fate)]) : "TX_PKT_FATE_UNKNOWN") #define TX_FATE(fate) ((fate) ? (TX_FATE_STR(fate)) : "N/A") #define TX_FATE_ACKED(fate) ((fate) ? ((*fate) == (WLFC_CTL_PKTFLAG_DISCARD)) : (0)) diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.h index ae3b85a10..a850e4233 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_pktdump.h @@ -1,7 +1,7 @@ /* * Header file for the Packet dump helper functions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_platdev.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_platdev.c index 836be9cd1..7108ec4fa 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_platdev.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_platdev.c @@ -1,7 +1,7 @@ /* * Linux platform device for DHD WLAN adapter * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_priv.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_priv.h index 2d5ec215a..0a5797a32 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_priv.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_priv.h @@ -1,7 +1,7 @@ /* * DHD Linux header file - contains private structure definition of the Linux specific layer * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -485,7 +485,8 @@ extern uint fis_enab; (defined(CONFIG_SOC_EXYNOS9820) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 187))) \ || (defined(CONFIG_ARCH_MSM) && (((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 170)) && \ (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))) || (LINUX_VERSION_CODE >= \ - KERNEL_VERSION(4, 19, 110)))) + KERNEL_VERSION(4, 19, 110)))) || ((defined(CONFIG_SOC_EXYNOS9110) || \ + defined(CONFIG_SOC_S5E5515)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 151))) #define WAKELOCK_BACKPORT #endif /* WAKELOCK_BACKPORT */ diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sched.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sched.c index 40cb7852a..c93423d27 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sched.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sched.c @@ -1,7 +1,7 @@ /* * Expose some of the kernel scheduler routines * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sock_qos.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sock_qos.h index 04bab4be0..f37cc030f 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sock_qos.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_sock_qos.h @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes to call into * DHD's QOS on Socket Flow module. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.c index f94db884b..4e0570072 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.c @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), * Linux-specific network interface for transmit(tx) path * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -113,11 +113,11 @@ #include #endif -#ifdef CONFIG_ARCH_EXYNOS +#if defined(CONFIG_ARCH_EXYNOS) && !defined(CONFIG_SOC_S5E5515) #ifndef SUPPORT_EXYNOS7420 #include #endif /* SUPPORT_EXYNOS7420 */ -#endif /* CONFIG_ARCH_EXYNOS */ +#endif /* defined(CONFIG_ARCH_EXYNOS) && !defined(CONFIG_SOC_S5E5515) */ #ifdef DHD_L2_FILTER #include @@ -561,8 +561,10 @@ BCMFASTPATH(dhd_start_xmit)(struct sk_buff *skb, struct net_device *net) __FUNCTION__, dhd->pub.busstate, dhd->pub.dhd_bus_busy_state)); DHD_BUS_BUSY_CLEAR_IN_TX(&dhd->pub); #ifdef PCIE_FULL_DONGLE - /* Stop tx queues if suspend is in progress */ - if (DHD_BUS_CHECK_ANY_SUSPEND_IN_PROGRESS(&dhd->pub)) { + /* Stop tx queues if suspend is in progress or suspended */ + if (DHD_BUS_CHECK_ANY_SUSPEND_IN_PROGRESS(&dhd->pub) || + (dhd->pub.busstate == DHD_BUS_SUSPEND && + !DHD_BUS_BUSY_CHECK_RESUME_IN_PROGRESS(&dhd->pub))) { dhd_bus_stop_queue(dhd->pub.bus); } #endif /* PCIE_FULL_DONGLE */ @@ -772,6 +774,11 @@ BCMFASTPATH(dhd_start_xmit)(struct sk_buff *skb, struct net_device *net) static void __dhd_txflowcontrol(dhd_pub_t *dhdp, struct net_device *net, bool state) { + + if (net->reg_state != NETREG_REGISTERED) { + return; + } + if (state == ON) { if (!netif_queue_stopped(net)) { DHD_ERROR(("%s: Stop Netif Queue\n", __FUNCTION__)); diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.h index 92aa5458c..242cc1e9a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_tx.h @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), * Linux-specific network interface for transmit(tx) path * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.c index 72d307844..3370a4708 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.c @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), Generic work queue framework * Generic interface to handle dhd deferred work events * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.h index 2a5f2cdf9..2e9d316ee 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_linux_wq.h @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), Generic work queue framework * Generic interface to handle dhd deferred work events * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.c index 4f4765fad..c9c91dc8a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.c @@ -1,7 +1,7 @@ /* * DHD debugability support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.h index 7a81b61ef..349f56750 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_mschdbg.h @@ -1,7 +1,7 @@ /* * DHD debugability header file * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_msgbuf.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_msgbuf.c index 7fc1bdf0e..0ec9d3365 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_msgbuf.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_msgbuf.c @@ -3,7 +3,7 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -914,6 +914,13 @@ dhd_prot_check_pending_ctrl_cmpls(dhd_pub_t *dhd) bool ret; dhd_bus_cmn_readshared(dhd->bus, &tcm_wr, RING_WR_UPD, ring->idx); + + if (tcm_wr > ring->max_items) { + DHD_ERROR(("%s(): ring %p, ring->name %s, tcm_wr %d ring->max_items %d\n", + __FUNCTION__, ring, ring->name, tcm_wr, ring->max_items)); + return FALSE; + } + host_rd = ring->rd; /* Consider the ring as processed if host rd and tcm wr are same */ ret = (host_rd != tcm_wr) ? TRUE : FALSE; @@ -1644,6 +1651,13 @@ typedef struct dhd_pktid_log { typedef void * dhd_pktid_log_handle_t; /* opaque handle to pktid log */ #define MAX_PKTID_LOG (2048) +/* + * index timestamp pktaddr(pa) pktid size + * index(4) + timestamp (<= 12) + pa (<=12) + pktid (4) + size(4) + space x 4 + 2 (lf) + * ex) 1 22531185990 0x91fc38010 1017 8192 + */ +#define PKTID_LOG_STR_SZ 48u +#define MAX_PKTID_LOG_BUF_SZ MAX_PKTID_LOG * PKTID_LOG_STR_SZ #define DHD_PKTID_LOG_ITEM_SZ (sizeof(dhd_pktid_log_item_t)) #define DHD_PKTID_LOG_SZ(items) (uint32)((sizeof(dhd_pktid_log_t)) + \ ((DHD_PKTID_LOG_ITEM_SZ) * (items))) @@ -1724,6 +1738,8 @@ dhd_pktid_logging_dump(dhd_pub_t *dhd) return; } + dhd->enable_pktid_log_dump = TRUE; + map_log = (dhd_pktid_log_t *)(prot->pktid_dma_map); unmap_log = (dhd_pktid_log_t *)(prot->pktid_dma_unmap); OSL_GET_LOCALTIME(&ts_sec, &ts_usec); @@ -1740,6 +1756,103 @@ dhd_pktid_logging_dump(dhd_pub_t *dhd) (uint32)(DHD_PKTID_LOG_ITEM_SZ * unmap_log->items))); } } + +uint32 +dhd_pktid_buf_len(dhd_pub_t *dhd, bool is_map) +{ + dhd_prot_t *prot = dhd->prot; + dhd_pktid_log_t *pktlog_buf; + uint32 len = 0; + + if (is_map == TRUE) { + pktlog_buf = (dhd_pktid_log_t *)(prot->pktid_dma_map); + len += strlen(DHD_PKTID_MAP_LOG_HDR); + } else { + pktlog_buf = (dhd_pktid_log_t *)(prot->pktid_dma_unmap); + len += strlen(DHD_PKTID_UNMAP_LOG_HDR); + } + + /* Adding Format string + LineFeed */ + len += strlen(PKTID_LOG_DUMP_FMT) + 2; + len += (uint32)PKTID_LOG_STR_SZ * pktlog_buf->items; + return len; +} + +int +dhd_write_pktid_log_dump(dhd_pub_t *dhdp, const void *user_buf, + void *fp, uint32 len, unsigned long *pos, bool is_map) +{ + dhd_prot_t *prot = dhdp->prot; + dhd_pktid_log_t *log_buf; + log_dump_section_hdr_t sec_hdr; + char *buf; + uint32 buflen = 0, remain_len = 0; + unsigned long long addr = 0; + int i = 0; + int ret = BCME_OK; + + if (prot == NULL) { + DHD_ERROR(("%s: prot is NULL\n", __FUNCTION__)); + return BCME_ERROR; + } + + buf = (char *)VMALLOCZ(dhdp->osh, MAX_PKTID_LOG_BUF_SZ); + remain_len = buflen = MAX_PKTID_LOG_BUF_SZ; + + dhd_init_sec_hdr(&sec_hdr); + sec_hdr.magic = LOG_DUMP_MAGIC; + + if (is_map) { + log_buf = prot->pktid_dma_map; + ret = dhd_export_debug_data(DHD_PKTID_MAP_LOG_HDR, fp, user_buf, + strlen(DHD_PKTID_MAP_LOG_HDR), pos); + if (ret < 0) { + DHD_ERROR(("%s : PKTID_MAP_LOG_HDR write error\n", + __FUNCTION__)); + goto exit; + } + sec_hdr.type = LOG_DUMP_SECTION_PKTID_MAP_LOG; + } else { + log_buf = prot->pktid_dma_unmap; + ret = dhd_export_debug_data(DHD_PKTID_UNMAP_LOG_HDR, fp, user_buf, + strlen(DHD_PKTID_UNMAP_LOG_HDR), pos); + if (ret < 0) { + DHD_ERROR(("%s : PKTID_UNMAP_LOG_HDR write error\n", + __FUNCTION__)); + goto exit; + } + sec_hdr.type = LOG_DUMP_SECTION_PKTID_UNMAP_LOG; + } + + remain_len -= scnprintf(&buf[buflen - remain_len], remain_len, + PKTID_LOG_DUMP_FMT, log_buf->index); + + for (i = 0; i < log_buf->items; i++) { +#ifdef BCMDMA64OSL + PHYSADDRTOULONG(log_buf->map[i].pa, addr); +#else + addr = PHYSADDRLO(log_buf->map[i].pa); +#endif /* BCMDMA64OSL */ + remain_len -= scnprintf(&buf[buflen - remain_len], remain_len, + "%4u %12llu 0x%llx %4u %4u\n", + i, log_buf->map[i].ts_nsec, addr, + log_buf->map[i].pktid, log_buf->map[i].size); + } + remain_len -= scnprintf(&buf[buflen - remain_len], remain_len, "\n"); + + sec_hdr.timestamp = local_clock(); + sec_hdr.length = buflen - remain_len; + + ret = dhd_export_debug_data((char *)&sec_hdr, NULL, user_buf, sizeof(sec_hdr), pos); + ret = dhd_export_debug_data(buf, NULL, user_buf, sec_hdr.length, pos); + +exit: + if (buf) { + VMFREE(dhdp->osh, buf, buflen); + } + + return ret; +} #endif /* DHD_MAP_PKTID_LOGGING */ /* +----------------- End of DHD_MAP_PKTID_LOGGING -----------------------+ */ @@ -4534,8 +4647,13 @@ BCMFASTPATH(dhd_prot_rxbuf_post)(dhd_pub_t *dhd, uint16 count, bool use_rsv_pkti dhd->rx_pktgetfail++; DHD_ERROR(("%s:%d: PKTGET for rxbuf failed, rx_pktget_fail :%lu\n", __FUNCTION__, __LINE__, dhd->rx_pktgetfail)); + /* Try to get pkt from Rx reserve pool if monitor mode is not enabled as + * the buffer size for monitor mode is larger(4k) than normal rx pkt(1920) + */ #if defined(WL_MONITOR) - if (!dhd_monitor_enabled(dhd, 0)) + if (dhd_monitor_enabled(dhd, 0)) { + break; + } else #endif /* WL_MONITOR */ { #ifdef RX_PKT_POOL @@ -5240,7 +5358,7 @@ BCMFASTPATH(dhd_prot_process_msgbuf_infocpl)(dhd_pub_t *dhd, uint bound) #ifdef EWP_EDL bool -dhd_prot_process_msgbuf_edl(dhd_pub_t *dhd) +dhd_prot_process_msgbuf_edl(dhd_pub_t *dhd, uint32 *edl_itmes) { dhd_prot_t *prot = dhd->prot; msgbuf_ring_t *ring = prot->d2hring_edl; @@ -5286,6 +5404,7 @@ dhd_prot_process_msgbuf_edl(dhd_pub_t *dhd) depth = ring->max_items; /* check for avail space, in number of ring items */ items = READ_AVAIL_SPACE(ring->wr, rd, depth); + *edl_itmes = items; if (items == 0) { /* no work items in edl ring */ return FALSE; @@ -7800,7 +7919,7 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf) uint32 intstatus = si_corereg(dhd->bus->sih, dhd->bus->sih->buscoreidx, dhd->bus->pcie_mailbox_int, 0, 0); int host_irq_disbled = dhdpcie_irq_disabled(dhd->bus); - if ((intstatus != (uint32)-1) && + if ((intstatus) && (intstatus != (uint32)-1) && (timeleft == 0) && (!dhd_query_bus_erros(dhd))) { DHD_ERROR(("%s: resumed on timeout for IOVAR happened. intstatus=%x" " host_irq_disabled=%d\n", @@ -10776,12 +10895,66 @@ copy_hang_info_etd_base64(dhd_pub_t *dhd, char *dest, int *bytes_written, int *c } #endif /* DHD_EWPR_VER2 */ +int +get_ext_trap_hc_module_id(dhd_pub_t *dhd) +{ + uint32 *ext_data = dhd->extended_trap_data; + hnd_ext_trap_hdr_t *hdr; + bcm_tlv_t *tlv; + bcm_xtlv_t *wl_hc; + bcm_dngl_socramind_t *socramind_ptr; + bcm_dngl_healthcheck_t *dngl_hc; + uint16 tag; + int ret = BCME_ERROR; + + /* First word is original trap_data */ + ext_data++; + + /* Followed by the extended trap data header */ + hdr = (hnd_ext_trap_hdr_t *)ext_data; + + tlv = bcm_parse_tlvs(hdr->data, hdr->len, TAG_TRAP_HC_DATA); + if (tlv) { + socramind_ptr = (bcm_dngl_socramind_t *)((uint8 *)tlv->data); + tag = ltoh32(socramind_ptr->tag); + + switch (tag) { + case SOCRAM_IND_TAG_HEALTH_CHECK: + dngl_hc = (bcm_dngl_healthcheck_t *)((uint8 *)socramind_ptr->value); + switch (ltoh32(dngl_hc->top_module_tag)) { + case HCHK_SW_ENTITY_WL_PRIMARY: + case HCHK_SW_ENTITY_WL_SECONDARY: + wl_hc = (bcm_xtlv_t*)((uint8 *)dngl_hc->value); + + if (ltoh32(dngl_hc->top_module_len) + < sizeof(bcm_xtlv_t)) { + DHD_ERROR(("WL SW HC Wrong length:%d\n", + ltoh32(dngl_hc->top_module_len))); + return BCME_ERROR; + } + DHD_ERROR(("WL SW HC type %d len %d\n", + ltoh16(wl_hc->id), ltoh16(wl_hc->len))); + ret = ltoh16(wl_hc->id); + break; + default: + break; + } + break; + default: + break; + } + } + + return ret; +} + void copy_hang_info_trap(dhd_pub_t *dhd) { trap_t tr; int bytes_written; int trap_subtype = 0; + int ext_trap_hc_module_id; if (!dhd || !dhd->hang_info) { DHD_ERROR(("%s dhd=%p hang_info=%p\n", __FUNCTION__, @@ -10802,6 +10975,19 @@ copy_hang_info_trap(dhd_pub_t *dhd) hang_info_trap_tbl[HANG_INFO_TRAP_T_REASON_IDX].offset = HANG_REASON_DONGLE_TRAP; hang_info_trap_tbl[HANG_INFO_TRAP_T_SUBTYPE_IDX].offset = trap_subtype; + if (trap_subtype == TAG_TRAP_HC_DATA) { + DHD_ERROR(("trap_subtype is TAG_TRAP_HC_DATA\n")); + ext_trap_hc_module_id = get_ext_trap_hc_module_id(dhd); + if (ext_trap_hc_module_id != BCME_ERROR) { + if (ext_trap_hc_module_id == WL_HC_DD_RX_DMA_STALL) { + hang_info_trap_tbl[HANG_INFO_TRAP_T_REASON_IDX].offset = + HANG_REASON_DONGLE_TRAP_HC_DD_RX_DMA_STALL; + dhd->hang_reason = HANG_REASON_DONGLE_TRAP_HC_DD_RX_DMA_STALL; + DHD_ERROR(("HC_DD_RX_DMA_STALL raises HC trap\n")); + } + } + } + bytes_written = 0; dhd->hang_info_cnt = 0; get_debug_dump_time(dhd->debug_dump_time_hang_str); diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.c index fec5c2c87..9d424b271 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.c @@ -1,7 +1,7 @@ /* * DHD Bus Module for PCIE * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -250,7 +250,9 @@ static void dhd_bus_idle_scan(dhd_bus_t *bus); #ifdef EXYNOS_PCIE_DEBUG extern void exynos_pcie_register_dump(int ch_num); #endif /* EXYNOS_PCIE_DEBUG */ - +#ifdef PRINT_WAKEUP_GPIO_STATUS +extern void exynos_pin_dbg_show(unsigned int pin, const char* str); +#endif /* PRINT_WAKEUP_GPIO_STATUS */ #if defined(DHD_H2D_LOG_TIME_SYNC) static void dhdpci_bus_rte_log_time_sync_poll(dhd_bus_t *bus); #endif /* DHD_H2D_LOG_TIME_SYNC */ @@ -1085,6 +1087,21 @@ dhdpcie_cto_recovery_handler(dhd_pub_t *dhd) dhd_bus_t *bus = dhd->bus; int ret; + if (dhd->up == FALSE) { + DHD_ERROR(("%s : dhd is not up\n", __FUNCTION__)); + return; + } + + if (bus->is_linkdown) { + DHD_ERROR(("%s: link is down\n", __FUNCTION__)); + return; + } + + if (bus->sih == NULL) { + DHD_ERROR(("%s: The address of sih is invalid\n", __FUNCTION__)); + return; + } + /* Disable PCIe Runtime PM to avoid D3_ACK timeout. */ DHD_DISABLE_RUNTIME_PM(dhd); @@ -3068,7 +3085,7 @@ static int dhdpcie_download_nvram(struct dhd_bus *bus) { int bcmerror = BCME_ERROR; - uint len; + uint len, memblock_len = 0; char * memblock = NULL; char *bufp; char *pnv_path; @@ -3081,14 +3098,15 @@ dhdpcie_download_nvram(struct dhd_bus *bus) /* First try UEFI */ len = MAX_NVRAMBUF_SIZE; - dhd_get_download_buffer(bus->dhd, NULL, NVRAM, &memblock, (int *)&len); + bcmerror = dhd_get_download_buffer(bus->dhd, NULL, NVRAM, &memblock, (int *)&len); /* If UEFI empty, then read from file system */ if ((len <= 0) || (memblock == NULL)) { if (nvram_file_exists) { len = MAX_NVRAMBUF_SIZE; - dhd_get_download_buffer(bus->dhd, pnv_path, NVRAM, &memblock, (int *)&len); + bcmerror = dhd_get_download_buffer(bus->dhd, pnv_path, NVRAM, &memblock, + (int *)&len); if ((len <= 0 || len > MAX_NVRAMBUF_SIZE)) { goto err; } @@ -3100,6 +3118,11 @@ dhdpcie_download_nvram(struct dhd_bus *bus) } else { nvram_uefi_exists = TRUE; } +#ifdef DHD_LINUX_STD_FW_API + memblock_len = len; +#else + memblock_len = MAX_NVRAMBUF_SIZE; +#endif /* DHD_LINUX_STD_FW_API */ DHD_ERROR(("%s: dhd_get_download_buffer len %d\n", __FUNCTION__, len)); @@ -3141,7 +3164,7 @@ dhdpcie_download_nvram(struct dhd_bus *bus) if (local_alloc) { MFREE(bus->dhd->osh, memblock, MAX_NVRAMBUF_SIZE); } else { - dhd_free_download_buffer(bus->dhd, memblock, MAX_NVRAMBUF_SIZE); + dhd_free_download_buffer(bus->dhd, memblock, memblock_len); } } @@ -3177,7 +3200,7 @@ _dhdpcie_download_firmware(struct dhd_bus *bus) /* External image takes precedence if specified */ if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) { - if (dhdpcie_download_code_file(bus, bus->fw_path)) { + if ((bcmerror = dhdpcie_download_code_file(bus, bus->fw_path))) { DHD_ERROR(("%s:%d dongle image file download failed\n", __FUNCTION__, __LINE__)); goto err; @@ -3198,7 +3221,7 @@ _dhdpcie_download_firmware(struct dhd_bus *bus) /* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */ /* External nvram takes precedence if specified */ - if (dhdpcie_download_nvram(bus)) { + if ((bcmerror = dhdpcie_download_nvram(bus))) { DHD_ERROR(("%s:%d dongle nvram file download failed\n", __FUNCTION__, __LINE__)); goto err; } @@ -3783,6 +3806,8 @@ dhdpcie_mem_dump(dhd_bus_t *bus) case DUMP_TYPE_ESCAN_SYNCID_MISMATCH: /* intentional fall through */ case DUMP_TYPE_INVALID_SHINFO_NRFRAGS: + /* intentional fall through */ + case DUMP_TYPE_P2P_DISC_BUSY: if (dhdp->db7_trap.fw_db7w_trap) { /* Set fw_db7w_trap_inprogress here and clear from DPC */ dhdp->db7_trap.fw_db7w_trap_inprogress = TRUE; @@ -7059,7 +7084,7 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state) uint32 intstatus = si_corereg(bus->sih, bus->sih->buscoreidx, bus->pcie_mailbox_int, 0, 0); int host_irq_disabled = dhdpcie_irq_disabled(bus); - if ((intstatus != (uint32)-1) && + if ((intstatus) && (intstatus != (uint32)-1) && (timeleft == 0) && (!dhd_query_bus_erros(bus->dhd))) { DHD_ERROR(("%s: resumed on timeout for D3 ack. intstatus=%x" " host_irq_disabled=%d\n", @@ -10241,6 +10266,9 @@ static bool dhdpci_bus_read_frames(dhd_bus_t *bus) { bool more = FALSE; +#if defined(EWP_EDL) + uint32 edl_itmes = 0; +#endif /* EWP_EDL */ /* First check if there a FW trap */ if ((bus->api.fw_rev >= PCIE_SHARED_VERSION_6) && @@ -10301,7 +10329,7 @@ dhdpci_bus_read_frames(dhd_bus_t *bus) } #ifdef EWP_EDL else { - more |= dhd_prot_process_msgbuf_edl(bus->dhd); + more |= dhd_prot_process_msgbuf_edl(bus->dhd, &edl_itmes); bus->last_process_edl_time = OSL_LOCALTIME_NS(); } #endif /* EWP_EDL */ @@ -10361,6 +10389,13 @@ dhdpci_bus_read_frames(dhd_bus_t *bus) #if defined(DHD_H2D_LOG_TIME_SYNC) dhdpci_bus_rte_log_time_sync_poll(bus); #endif /* DHD_H2D_LOG_TIME_SYNC */ + +#if defined(EWP_EDL) && defined(DHD_WAKE_STATUS) + if ((edl_itmes > 0) && (bcmpcie_get_edl_wake(bus) > 0)) { + DHD_ERROR(("##### dhdpcie_host_wake caused by Event Logs, edl_itmes %d\n", + edl_itmes)); + } +#endif /* EWP_EDL && DHD_WAKE_STATUS */ return more; } @@ -13815,6 +13850,9 @@ dhd_pcie_intr_count_dump(dhd_pub_t *dhd) DHD_ERROR(("oob_irq_enabled=%d oob_gpio_level=%d\n", dhdpcie_get_oob_irq_status(bus), dhdpcie_get_oob_irq_level())); +#ifdef PRINT_WAKEUP_GPIO_STATUS + exynos_pin_dbg_show(dhdpcie_get_oob_gpio_number(), "gpa0"); +#endif /* PRINT_WAKEUP_GPIO_STATUS */ #endif /* BCMPCIE_OOB_HOST_WAKE */ DHD_ERROR(("dpc_return_busdown_count=%lu non_ours_irq_count=%lu\n", bus->dpc_return_busdown_count, bus->non_ours_irq_count)); diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.h index 41b6e2921..6dd0ed8e8 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie.h @@ -1,7 +1,7 @@ /* * Linux DHD Bus Module for PCIE * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -736,6 +736,9 @@ extern void dhdpcie_oob_intr_set(dhd_bus_t *bus, bool enable); extern int dhdpcie_get_oob_irq_num(struct dhd_bus *bus); extern int dhdpcie_get_oob_irq_status(struct dhd_bus *bus); extern int dhdpcie_get_oob_irq_level(void); +#ifdef PRINT_WAKEUP_GPIO_STATUS +extern int dhdpcie_get_oob_gpio_number(void); +#endif /* PRINT_WAKEUP_GPIO_STATUS */ #endif /* BCMPCIE_OOB_HOST_WAKE */ #if defined(PCIE_INB_DW) extern void dhd_bus_doorbell_timeout_reset(struct dhd_bus *bus); @@ -852,6 +855,9 @@ extern int dhdpcie_send_mb_data(dhd_bus_t *bus, uint32 h2d_mb_data); #ifdef DHD_WAKE_STATUS int bcmpcie_get_total_wake(struct dhd_bus *bus); int bcmpcie_set_get_wake(struct dhd_bus *bus, int flag); +#if defined(EWP_EDL) +int bcmpcie_get_edl_wake(struct dhd_bus *bus); +#endif /* EWP_EDL */ #endif /* DHD_WAKE_STATUS */ #ifdef DHD_MMIO_TRACE extern void dhd_dump_bus_mmio_trace(dhd_bus_t *bus, struct bcmstrbuf *strbuf); diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie_linux.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie_linux.c index 5dd2878ea..cb4a05ba2 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie_linux.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pcie_linux.c @@ -1,7 +1,7 @@ /* * Linux DHD Bus Module for PCIE * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -123,6 +123,9 @@ typedef struct dhdpcie_info unsigned int total_wake_count; int pkt_wake; int wake_irq; +#if defined(EWP_EDL) + int edl_wake; +#endif /* EWP_EDL */ #endif /* DHD_WAKE_STATUS */ #ifdef USE_SMMU_ARCH_MSM void *smmu_cxt; @@ -720,6 +723,14 @@ static int dhdpcie_pm_resume(struct device *dev) dhd_os_busbusy_wake(bus->dhd); DHD_GENERAL_UNLOCK(bus->dhd, flags); +#if defined(CUSTOMER_HW4_DEBUG) + if (ret == BCME_OK) { + uint32 pm_dur = 0; + dhd_iovar(bus->dhd, 0, "pm_dur", NULL, 0, (char *)&pm_dur, sizeof(pm_dur), FALSE); + DHD_ERROR(("%s: PM duration(%d)\n", __FUNCTION__, pm_dur)); + } +#endif /* CUSTOMER_HW4_DEBUG */ + return ret; } @@ -1092,10 +1103,26 @@ int bcmpcie_set_get_wake(struct dhd_bus *bus, int flag) ret = pch->pkt_wake; pch->total_wake_count += flag; pch->pkt_wake = flag; - +#if defined(EWP_EDL) + pch->edl_wake = flag; +#endif /* EWP_EDL */ DHD_PKT_WAKE_UNLOCK(&pch->pkt_wake_lock, flags); return ret; } + +#if defined(EWP_EDL) +int +bcmpcie_get_edl_wake(struct dhd_bus *bus) +{ + int ret; + dhdpcie_info_t *pch = pci_get_drvdata(bus->dev); + + ret = pch->edl_wake; + pch->edl_wake = 0; + + return ret; +} +#endif /* EWP_EDL */ #endif /* DHD_WAKE_STATUS */ static int dhdpcie_resume_dev(struct pci_dev *dev) @@ -2562,6 +2589,9 @@ dhdpcie_bus_request_irq(struct dhd_bus *bus) #ifdef BCMPCIE_OOB_HOST_WAKE #ifdef CONFIG_BCMDHD_GET_OOB_STATE extern int dhd_get_wlan_oob_gpio(void); +#ifdef PRINT_WAKEUP_GPIO_STATUS +extern int dhd_get_wlan_oob_gpio_number(void); +#endif /* PRINT_WAKEUP_GPIO_STATUS */ #endif /* CONFIG_BCMDHD_GET_OOB_STATE */ int dhdpcie_get_oob_irq_level(void) @@ -2575,7 +2605,16 @@ int dhdpcie_get_oob_irq_level(void) #endif /* CONFIG_BCMDHD_GET_OOB_STATE */ return gpio_level; } - +#ifdef PRINT_WAKEUP_GPIO_STATUS +int dhdpcie_get_oob_gpio_number(void) +{ + int gpio_number = BCME_UNSUPPORTED; +#ifdef CONFIG_BCMDHD_GET_OOB_STATE + gpio_number = dhd_get_wlan_oob_gpio_number(); +#endif /* CONFIG_BCMDHD_GET_OOB_STATE */ + return gpio_number; +} +#endif /* PRINT_WAKEUP_GPIO_STATUS */ int dhdpcie_get_oob_irq_status(struct dhd_bus *bus) { dhdpcie_info_t *pch; diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.c index 0e607263a..5254033c1 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.c @@ -1,7 +1,7 @@ /* * DHD debugability packet logging support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -370,6 +370,14 @@ dhd_pktlog_ring_add_pkts(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pktid rem_nsec = do_div(ts_nsec, NSEC_PER_SEC); pkts->info.pkt = PKTDUP(dhdp->osh, pkt); + /* + * skb clone can be NULL, but pktlog feature assume it alway can be cloned + * The dummy pkt info will be added in the list to fit pktcount & list items + * and handled in the dhd_pktlog_dump_write() with ignoring info.pkt + */ + if (pkts->info.pkt == NULL) { + DHD_ERROR(("%s : skb clone returns NULL \n", __FUNCTION__)); + } pkts->info.pkt_len = PKTLEN(dhdp->osh, pkt); pkts->info.driver_ts_sec = (uint32)ts_nsec; pkts->info.driver_ts_usec = (uint32)(rem_nsec/NSEC_PER_USEC); @@ -1150,6 +1158,11 @@ dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32 break; } + if (report_ptr->info.pkt == NULL) { + DHD_ERROR(("%s : pkt isn't located skip it\n", __FUNCTION__)); + continue; + } + ret = dhd_export_debug_data((char*)&report_ptr->info.driver_ts_sec, file, user_buf, sizeof(report_ptr->info.driver_ts_sec), &pos); len += sizeof(report_ptr->info.driver_ts_sec); diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.h index 4c04d6518..628097b5e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pktlog.h @@ -1,7 +1,7 @@ /* * DHD debugability packet logging header file * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.c index 501dc921b..405702bde 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.c @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD) * Prefered Network Offload and Wi-Fi Location Service(WLS) code. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.h index 4b1568688..25d677d40 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_pno.h @@ -2,7 +2,7 @@ * Header file of Broadcom Dongle Host Driver (DHD) * Prefered Network Offload code and Wi-Fi Location Service(WLS) code. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_proto.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_proto.h index d162d193c..63bf37b54 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_proto.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_proto.h @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -201,7 +201,7 @@ extern void dhd_prot_dma_indx_free(dhd_pub_t *dhd); #ifdef EWP_EDL int dhd_prot_init_edl_rings(dhd_pub_t *dhd); -bool dhd_prot_process_msgbuf_edl(dhd_pub_t *dhd); +bool dhd_prot_process_msgbuf_edl(dhd_pub_t *dhd, uint32 *edl_itmes); int dhd_prot_process_edl_complete(dhd_pub_t *dhd, void *evt_decode_data); #endif /* EWP_EDL */ diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_qos_algo.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_qos_algo.h index 368d1207e..6d87312dd 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_qos_algo.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_qos_algo.h @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes for the QOS Algorithm * Note that this algorithm is a platform independent layer * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.c index 5e5d0bf5f..c0e046715 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.c @@ -1,7 +1,7 @@ /* * Broadcom Dongle Host Driver (DHD), RTT * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -4943,19 +4943,13 @@ dhd_rtt_deinit(dhd_pub_t *dhd) DHD_RTT_MEM(("dhd_rtt_deinit: ENTER\n")); #ifdef WL_NAN - if (delayed_work_pending(&rtt_status->rtt_retry_timer)) { - cancel_delayed_work_sync(&rtt_status->rtt_retry_timer); - } + cancel_delayed_work_sync(&rtt_status->rtt_retry_timer); #endif /* WL_NAN */ - if (work_pending(&rtt_status->work)) { - cancel_work_sync(&rtt_status->work); - rtt_status->rtt_sched = FALSE; - } + cancel_work_sync(&rtt_status->work); + rtt_status->rtt_sched = FALSE; - if (delayed_work_pending(&rtt_status->proxd_timeout)) { - cancel_delayed_work_sync(&rtt_status->proxd_timeout); - } + cancel_delayed_work_sync(&rtt_status->proxd_timeout); /* * Cleanup attempt is required, diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.h index a7b02a00d..d96245b97 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_rtt.h @@ -1,7 +1,7 @@ /* * Broadcom Dongle Host Driver (DHD), RTT * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sdio.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sdio.c index be37ab8ca..49ac8b398 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sdio.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sdio.c @@ -1,7 +1,7 @@ /* * DHD Bus Module for SDIO * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -1871,7 +1871,7 @@ dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) } } else { err = dhdsdio_clk_devsleep_iovar(bus, FALSE /* wake */); -#ifdef BT_OVER_SDIO +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) if (err < 0) { struct net_device *net = NULL; dhd_pub_t *dhd = bus->dhd; @@ -1885,7 +1885,7 @@ dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) DHD_ERROR(("<< WIFI HANG Fail because net is NULL\n")); } } -#endif /* BT_OVER_SDIO */ +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) && OEM_ANDROID */ } if (err == 0) { @@ -8422,8 +8422,13 @@ dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); ret = _dhdsdio_download_firmware(bus); - +#ifdef BCM43013_CHIP + if (ret < 0) { + dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); + } +#else /* BCM43013_CHIP */ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); +#endif /* BCM43013_CHIP */ DHD_OS_WAKE_UNLOCK(bus->dhd); return ret; @@ -8728,6 +8733,72 @@ void dhd_bus_unreg_sdio_notify(void) } #endif /* defined(BCMLXSDMMC) */ +#ifdef DHD_LINUX_STD_FW_API +static int +dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) +{ + int bcmerror = BCME_ERROR; + int offset = 0; + int len = 0; + bool store_reset; + int offset_end = bus->ramsize; + const struct firmware *fw = NULL; + int buf_offset = 0, residual_len = 0; + + DHD_ERROR(("%s: download firmware %s\n", __FUNCTION__, pfw_path)); + + /* check if CR4/CA7 */ + store_reset = (si_setcore(bus->sih, ARMCR4_CORE_ID, 0) || + si_setcore(bus->sih, ARMCA7_CORE_ID, 0)); + + bcmerror = dhd_os_get_img_fwreq(&fw, bus->fw_path); + if (bcmerror < 0) { + DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", + bcmerror)); + goto err; + } + DHD_ERROR(("dhd_os_get_img(Request Firmware API) success\n")); + residual_len = fw->size; + while (residual_len) { + len = MIN(residual_len, MEMBLOCK); + + /* if address is 0, store the reset instruction to be written in 0 */ + if (store_reset) { + ASSERT(offset == 0); + bus->resetinstr = *(((uint32*)fw->data + buf_offset)); + /* Add start of RAM address to the address given by user */ + offset += bus->dongle_ram_base; + offset_end += offset; + store_reset = FALSE; + } + + bcmerror = dhdsdio_membytes(bus, TRUE, offset, + (uint8 *)fw->data + buf_offset, len); + if (bcmerror) { + DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", + __FUNCTION__, bcmerror, MEMBLOCK, offset)); + goto err; + } + offset += MEMBLOCK; + + if (offset >= offset_end) { + DHD_ERROR(("%s: invalid address access to %x (offset end: %x)\n", + __FUNCTION__, offset, offset_end)); + bcmerror = BCME_ERROR; + goto err; + } + residual_len -= len; + buf_offset += len; + } +err: + if (fw) { + dhd_os_close_img_fwreq(fw); + } + return bcmerror; +} /* dhdpcie_download_code_file */ + +#else + static int dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) { @@ -8815,6 +8886,7 @@ dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) return bcmerror; } +#endif /* DHD_LINUX_STD_FW_API */ #ifdef DHD_UCODE_DOWNLOAD /* Currently supported only for the chips in which ucode RAM is AXI addressable */ @@ -8946,6 +9018,94 @@ dhd_bus_ucode_download(struct dhd_bus *bus) #endif /* DHD_UCODE_DOWNLOAD */ +#ifdef DHD_LINUX_STD_FW_API +#ifdef CUSTOMER_HW4_DEBUG +#define MIN_NVRAMVARS_SIZE 128 +#endif /* CUSTOMER_HW4_DEBUG */ + +static int +dhdsdio_download_nvram(struct dhd_bus *bus) +{ + int bcmerror = -1; + uint len; + char * memblock = NULL; + char *bufp; + char *pnv_path; + bool nvram_file_exists; + bool nvram_uefi_exists = FALSE; + bool local_alloc = FALSE; + + pnv_path = bus->nv_path; + + nvram_file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0')); + + len = MAX_NVRAMBUF_SIZE; + dhd_get_download_buffer(bus->dhd, NULL, NVRAM, &memblock, (int *)&len); + + /* If UEFI empty, then read from file system */ + if ((len <= 0) || (memblock == NULL)) { + + if (nvram_file_exists) { + len = MAX_NVRAMBUF_SIZE; + dhd_get_download_buffer(bus->dhd, pnv_path, NVRAM, &memblock, (int *)&len); + if ((len <= 0 || len > MAX_NVRAMBUF_SIZE)) { + goto err; + } + } + else { + /* For SROM OTP no external file or UEFI required */ + bcmerror = BCME_OK; + } + } else { + nvram_uefi_exists = TRUE; + } + + if (len > 0 && len < MAX_NVRAMBUF_SIZE && memblock != NULL) { + bufp = (char *) memblock; + + { + bufp[len-1] = 0; + if (nvram_uefi_exists || nvram_file_exists) { + len = process_nvram_vars(bufp, len); + } + } + +#ifdef CUSTOMER_HW4_DEBUG + if (len < MIN_NVRAMVARS_SIZE) { + DHD_ERROR(("%s: invalid nvram size in process_nvram_vars \n", + __FUNCTION__)); + bcmerror = BCME_ERROR; + goto err; + } +#endif /* CUSTOMER_HW4_DEBUG */ + + if (len % 4) { + len += 4 - (len % 4); + } + bufp += len; + *bufp++ = 0; + if (len) + bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1); + if (bcmerror) { + DHD_ERROR(("%s: error downloading vars: %d\n", + __FUNCTION__, bcmerror)); + } + } + +err: + if (memblock) { + if (local_alloc) { + MFREE(bus->dhd->osh, memblock, MAX_NVRAMBUF_SIZE); + } else { + dhd_free_download_buffer(bus->dhd, memblock, MAX_NVRAMBUF_SIZE); + } + } + + return bcmerror; +} + +#else + static int dhdsdio_download_nvram(struct dhd_bus *bus) { @@ -9005,6 +9165,7 @@ dhdsdio_download_nvram(struct dhd_bus *bus) return bcmerror; } +#endif /* DHD_LINUX_STD_FW_API */ static int _dhdsdio_download_firmware(struct dhd_bus *bus) diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sec_feature.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sec_feature.h index 4da9fe444..6ae4102d2 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sec_feature.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_sec_feature.h @@ -1,7 +1,7 @@ /* * Customer HW 4 dependant file * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.c index f6decff72..b43b72058 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.c @@ -1,7 +1,7 @@ /* * DHD debugability: Status Information Logging support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.h index c6dc5cf5b..dd3152d15 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_statlog.h @@ -1,7 +1,7 @@ /* * DHD debugability: Header file for the Status Information Logging * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.c index 168448b69..9e6dacda3 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.c @@ -1,7 +1,7 @@ /* * DHD PROP_TXSTATUS Module. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -2425,7 +2425,9 @@ _dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len, } } #if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) - { + /* Gc only */ + if ((entry->iftype == WLC_E_IF_ROLE_P2P_CLIENT) && + (entry->state == WLFC_STATE_OPEN)) { uint8 value_buf[1]; value_buf[0] = (uint8)DHD_PKTTAG_IF(PKTTAG(pktbuf)); @@ -2813,9 +2815,6 @@ _dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type) table[if_id].state = WLFC_STATE_CLOSE; /* WLFC_DBGMESG(("INTERFACE[%d] CLOSE\n", if_id)); */ } -#if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) - dhd_throttle_p2p_interface_event(dhd->info, true); -#endif /* !PCIE_FULL_DONGLE && P2P_IF_STATE_EVENT_CTRL */ return BCME_OK; } } @@ -3019,6 +3018,7 @@ int dhd_wlfc_ctrl_if_state_event(dhd_pub_t *dhd, bool block) { uint32 tlv = 0; + uint32 prev_tlv; int ret = BCME_OK; if (!dhd->wlfc_enabled) @@ -3030,12 +3030,14 @@ dhd_wlfc_ctrl_if_state_event(dhd_pub_t *dhd, bool block) goto error; } + prev_tlv = tlv; if (block) { tlv &= ~WLFC_FLAGS_XONXOFF_SIGNALS; } else { tlv |= WLFC_FLAGS_XONXOFF_SIGNALS; } + DHD_ERROR(("%s, prev_tlv =0x%08x, tlv = 0x%08x\n", __FUNCTION__, prev_tlv, tlv)); ret = dhd_wl_ioctl_set_intiovar(dhd, "tlv", tlv, WLC_SET_VAR, TRUE, 0); if (unlikely(ret)) { DHD_ERROR(("%s, failed to get tlv ret =%d\n", __FUNCTION__, ret)); @@ -3565,14 +3567,21 @@ dhd_wlfc_commit_packets(dhd_pub_t *dhdp, f_commitpkt_t fcommit, void* commit_ctx if (pktbuf) { int ac = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); ASSERT(ac <= AC_COUNT); - DHD_PKTTAG_WLFCPKT_SET(PKTTAG(pktbuf), 1); - /* en-queue the packets to respective queue. */ - rc = _dhd_wlfc_enque_delayq(ctx, pktbuf, ac); - if (rc) { - _dhd_wlfc_prec_drop(ctx->dhdp, (ac << 1), pktbuf, FALSE); + if (ac <= AC_COUNT) { + DHD_PKTTAG_WLFCPKT_SET(PKTTAG(pktbuf), 1); + /* en-queue the packets to respective queue. */ + rc = _dhd_wlfc_enque_delayq(ctx, pktbuf, ac); + if (rc) { + _dhd_wlfc_prec_drop(ctx->dhdp, (ac << 1), pktbuf, FALSE); + } else { + ctx->stats.pktin++; + ctx->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(pktbuf))][ac]++; + } } else { - ctx->stats.pktin++; - ctx->pkt_cnt_in_drv[DHD_PKTTAG_IF(PKTTAG(pktbuf))][ac]++; + DHD_ERROR(("Error: %s():%d, unsupported ac:%d\n", + __FUNCTION__, __LINE__, ac)); + rc = WLFC_UNSUPPORTED; + goto exit; } } @@ -4683,20 +4692,27 @@ int dhd_wlfc_set_rxpkt_chk(dhd_pub_t *dhd, int val) int dhd_txpkt_log_and_dump(dhd_pub_t *dhdp, void* pkt, uint16 *pktfate_status) { uint32 pktid; - uint32 pktlen = PKTLEN(dhdp->osh, pkt); - uint8 *pktdata = PKTDATA(dhdp->osh, pkt); + uint32 pktlen; + uint8 *pktdata; #ifdef BDC struct bdc_header *bdch; uint32 bdc_len; #endif /* BDC */ - uint8 ifidx = DHD_PKTTAG_IF(PKTTAG(pkt)); - uint8 hcnt = WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(pkt))); - uint8 fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pkt)); + uint8 ifidx; + uint8 hcnt; + uint8 fifo_id; - if (!pkt) { + if (pkt == NULL || dhdp == NULL) { DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__)); return BCME_BADARG; } + + pktlen = PKTLEN(dhdp->osh, pkt); + pktdata = PKTDATA(dhdp->osh, pkt); + ifidx = DHD_PKTTAG_IF(PKTTAG(pkt)); + hcnt = WL_TXSTATUS_GET_FREERUNCTR(DHD_PKTTAG_H2DTAG(PKTTAG(pkt))); + fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pkt)); + pktid = (ifidx << DHD_PKTID_IF_SHIFT) | (fifo_id << DHD_PKTID_FIFO_SHIFT) | hcnt; #ifdef BDC bdch = (struct bdc_header *)pktdata; diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.h index d8a767469..5325ab7b6 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/dhd_wlfc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -28,7 +28,7 @@ #define KERNEL_THREAD_RETURN_TYPE int -typedef int (*f_commitpkt_t)(void* ctx, void* p); +typedef int (*f_commitpkt_t)(struct dhd_bus *bus, void* p); typedef bool (*f_processpkt_t)(void* p, void* arg); #define WLFC_UNSUPPORTED -9999 diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.c index e49c3351b..36fe007fd 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.c @@ -2,7 +2,7 @@ * IE/TLV fragmentation/defragmentation support for * Broadcom 802.11bang Networking Device Driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.h index e14edd96f..c5127abc0 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/frag.h @@ -2,7 +2,7 @@ * IE/TLV (de)fragmentation declarations/definitions for * Broadcom 802.11abgn Networking Device Driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktpool.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktpool.c index 183e5305c..872a97b87 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktpool.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktpool.c @@ -1,7 +1,7 @@ /* * HND generic packet pool operation primitives * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktq.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktq.c index 276476998..ac51498fd 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktq.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/hnd_pktq.c @@ -1,7 +1,7 @@ /* * HND generic pktq operation primitives * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/hndpmu.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/hndpmu.c index 17da1ddfe..951722136 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/hndpmu.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/hndpmu.c @@ -2,7 +2,7 @@ * Misc utility routines for accessing PMU corerev specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11.h index 344954036..da3b6b106 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11.h @@ -1,7 +1,7 @@ /* * Fundamental types and constants relating to 802.11 * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11ax.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11ax.h index 49c5e4812..d64bb2812 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11ax.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11ax.h @@ -2,7 +2,7 @@ * Basic types and constants relating to 802.11ax/HE STA * This is a portion of 802.11ax definition. The rest are in 802.11.h. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11s.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11s.h index 49e89a798..a2c6b5b05 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11s.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.11s.h @@ -1,7 +1,7 @@ /* * Fundamental types and constants relating to 802.11s Mesh * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.1d.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.1d.h index a05bb2800..f9416ab60 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.1d.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.1d.h @@ -1,7 +1,7 @@ /* * Fundamental types and constants relating to 802.1D * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.3.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.3.h index af9de3841..8ee0002c5 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.3.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/802.3.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to 802.3 * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/aidmp.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/aidmp.h index 8df3b866a..b791559d3 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/aidmp.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/aidmp.h @@ -1,7 +1,7 @@ /* * Broadcom AMBA Interconnect definitions. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_l2_filter.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_l2_filter.h index d594285fc..e67ecdfc5 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_l2_filter.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_l2_filter.h @@ -1,7 +1,7 @@ /* * L2 Filter handling functions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_mpool_pub.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_mpool_pub.h index 76c4ce8a7..0f5498996 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_mpool_pub.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_mpool_pub.h @@ -35,7 +35,7 @@ * and instrumentation on top of the heap, without modifying the heap * allocation implementation. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_ring.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_ring.h index 0a4543234..6b64cd036 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_ring.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcm_ring.h @@ -6,7 +6,7 @@ * * NOTE: A ring of size N, may only hold N-1 elements. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmarp.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmarp.h index 2e6d92de5..a010fcefe 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmarp.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmarp.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to ARP Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmbloom.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmbloom.h index dabfb2645..1744a65ff 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmbloom.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmbloom.h @@ -1,7 +1,7 @@ /* * Bloom filter support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmcdc.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmcdc.h index cc03c7a05..5d05089d1 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmcdc.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmcdc.h @@ -4,7 +4,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdefs.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdefs.h index 2f3757455..a8acf15c8 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdefs.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdefs.h @@ -1,7 +1,7 @@ /* * Misc system wide definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs.h index 965f733b1..56083d160 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs.h @@ -1,7 +1,7 @@ /* * Broadcom device-specific manifest constants. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs_legacy.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs_legacy.h index dda37c557..8edf4d50a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs_legacy.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdevs_legacy.h @@ -1,7 +1,7 @@ /* * Broadcom device-specific manifest constants used by DHD, but deprecated in firmware. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdhcp.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdhcp.h index 0051ebff9..b4aed133c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdhcp.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmdhcp.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to DHCP Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmendian.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmendian.h index 5985cd3f6..cad9c43e0 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmendian.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmendian.h @@ -1,7 +1,7 @@ /* * Byte order utilities * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmerror.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmerror.h index f569c8d0c..9c93ff486 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmerror.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmerror.h @@ -1,7 +1,7 @@ /* * Common header file for all error codes. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmeth.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmeth.h index f43343759..a9c3e0594 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmeth.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmeth.h @@ -1,7 +1,7 @@ /* * Broadcom Ethernettype protocol definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmevent.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmevent.h index 579dba286..1720031bc 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmevent.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmevent.h @@ -3,7 +3,7 @@ * * Dependencies: bcmeth.h * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmicmp.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmicmp.h index 31e809afb..9ca3eed2f 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmicmp.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmicmp.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to ICMP Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmiov.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmiov.h index 6419a27ce..7814b4545 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmiov.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmiov.h @@ -4,7 +4,7 @@ * To be used in firmware and host apps or dhd - reducing code size, * duplication, and maintenance overhead. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmip.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmip.h index 898a231f6..0d3e2969c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmip.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmip.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to IP Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmipv6.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmipv6.h index df5ecd249..6529ac3b0 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmipv6.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmipv6.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to Neighbor Discovery Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmmsgbuf.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmmsgbuf.h index 62abda246..32edb6ec5 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmmsgbuf.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmmsgbuf.h @@ -4,7 +4,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmpcie.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmpcie.h index 7f3fce73c..c436ac862 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmpcie.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmpcie.h @@ -3,7 +3,7 @@ * Software-specific definitions shared between device and host side * Explains the shared area between host and dongle * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmproto.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmproto.h index 2770caff2..1444f25a1 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmproto.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmproto.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to IP Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmrand.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmrand.h index 3bebca68d..6cde11f10 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmrand.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmrand.h @@ -1,7 +1,7 @@ /* * bcmrand.h. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdbus.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdbus.h index ce32a92f1..cc526c32a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdbus.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdbus.h @@ -2,7 +2,7 @@ * Definitions for API from sdio common code (bcmsdh) to individual * host controller drivers. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh.h index bf21ee844..f7d96b418 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh.h @@ -3,7 +3,7 @@ * export functions to client drivers * abstract OS and BUS specific details of SDIO * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh_sdmmc.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh_sdmmc.h index e84f0cb95..0fcefe43a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh_sdmmc.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdh_sdmmc.h @@ -1,7 +1,7 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdpcm.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdpcm.h index 66aa2829b..649098d02 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdpcm.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmsdpcm.h @@ -2,7 +2,7 @@ * Broadcom SDIO/PCMCIA * Software-specific definitions shared between device and host side * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmstdlib_s.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmstdlib_s.h index 19e8c7dac..14d5a5718 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmstdlib_s.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmstdlib_s.h @@ -1,7 +1,7 @@ /* * Broadcom Secure Standard Library. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtcp.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtcp.h index 3e580a274..b8c4bc436 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtcp.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtcp.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to TCP Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtlv.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtlv.h index 78710b6a8..fed176fc2 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtlv.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmtlv.h @@ -1,7 +1,7 @@ /* * TLV and XTLV support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmudp.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmudp.h index 5a5113d6e..9058563d1 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmudp.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmudp.h @@ -1,7 +1,7 @@ /* * Fundamental constants relating to UDP Protocol * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmutils.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmutils.h index 0a0b506f8..982ecb16b 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmutils.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmutils.h @@ -1,7 +1,7 @@ /* * Misc useful os-independent macros and functions. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_channels.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_channels.h index 103fbac30..75a9c2b44 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_channels.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_channels.h @@ -3,7 +3,7 @@ * This header file housing the define and function prototype use by * both the wl driver, tools & Apps. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rates.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rates.h index bce527b60..406683a45 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rates.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rates.h @@ -1,7 +1,7 @@ /* * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rspec.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rspec.h index b4fc7657c..b0d500804 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rspec.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/bcmwifi_rspec.h @@ -1,7 +1,7 @@ /* * Common OS-independent driver header for rate management. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/brcm_nl80211.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/brcm_nl80211.h index 2a9e99782..5719324d5 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/brcm_nl80211.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/brcm_nl80211.h @@ -1,7 +1,7 @@ /* * Definitions for nl80211 vendor command/event access to host driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhd_daemon.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhd_daemon.h index d0cb12d37..c60a6f616 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhd_daemon.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhd_daemon.h @@ -1,7 +1,7 @@ /* * Header file for DHD daemon to handle timeouts * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhdioctl.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhdioctl.h index 42ca1971d..4540db3a3 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhdioctl.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dhdioctl.h @@ -5,7 +5,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dngl_stats.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dngl_stats.h index 79bc72064..bc658c751 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dngl_stats.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dngl_stats.h @@ -2,7 +2,7 @@ * Common stats definitions for clients of dongle * ports * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglevent.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglevent.h index e26fec6d6..cd976180f 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglevent.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglevent.h @@ -3,7 +3,7 @@ * * Dependencies: bcmeth.h * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglioctl.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglioctl.h index a18c716ed..9213dd01a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglioctl.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/dnglioctl.h @@ -1,7 +1,7 @@ /* * HND Run Time Environment ioctl. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eap.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eap.h index cfd9e580b..92d176d77 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eap.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eap.h @@ -4,7 +4,7 @@ * See * RFC 2284: PPP Extensible Authentication Protocol (EAP) * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eapol.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eapol.h index 84b8b26c0..50b855365 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eapol.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/eapol.h @@ -5,7 +5,7 @@ * IEEE Std 802.1X-2001 * IEEE 802.1X RADIUS Usage Guidelines * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/epivers.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/epivers.h index a0e8a6bdc..f0d04da57 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/epivers.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/epivers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -27,25 +27,25 @@ #define EPI_MINOR_VERSION 16 -#define EPI_RC_NUMBER 48 +#define EPI_RC_NUMBER 78 -#define EPI_INCREMENTAL_NUMBER 5 +#define EPI_INCREMENTAL_NUMBER 0 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 101, 16, 48, 5 +#define EPI_VERSION 101, 16, 78, 0 -#define EPI_VERSION_NUM 0x65103005 +#define EPI_VERSION_NUM 0x65104e00 -#define EPI_VERSION_DEV 101.16.48 +#define EPI_VERSION_DEV 101.16.78 /* Driver Version String, ASCII, 32 chars max */ #if defined (WLTEST) -#define EPI_VERSION_STR "101.16.48.5 (wlan=r909387 WLTEST)" +#define EPI_VERSION_STR "101.16.78 (wlan=r931097 WLTEST)" #elif (defined (BCMDBG_ASSERT) && !defined (BCMDBG_ASSERT_DISABLED)) -#define EPI_VERSION_STR "101.16.48.5 (wlan=r909387 ASSRT)" +#define EPI_VERSION_STR "101.16.78 (wlan=r931097 ASSRT)" #else -#define EPI_VERSION_STR "101.16.48.5 (wlan=r909387)" +#define EPI_VERSION_STR "101.16.78 (wlan=r931097)" #endif /* BCMINTERNAL */ #endif /* _epivers_h_ */ diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/etd.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/etd.h index 013037bde..ad1399b4c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/etd.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/etd.h @@ -1,7 +1,7 @@ /* * Extended Trap data component interface file. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/ethernet.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/ethernet.h index c5867f9b8..8ef9e7e08 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/ethernet.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/ethernet.h @@ -1,7 +1,7 @@ /* * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log.h index 2bbe4037e..16226fe4e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log.h @@ -1,7 +1,7 @@ /* * EVENT_LOG system definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_payload.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_payload.h index 4485fcc8f..b5edd9157 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_payload.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_payload.h @@ -4,7 +4,7 @@ * This file describes the payloads of event log entries that are data buffers * rather than formatted string entries. The contents are generally XTLVs. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_set.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_set.h index 5e098d87b..6ced7dae9 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_set.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_set.h @@ -1,7 +1,7 @@ /* * EVENT_LOG system definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_tag.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_tag.h index ea0700c30..ac0947cec 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_tag.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_log_tag.h @@ -1,7 +1,7 @@ /* * EVENT_LOG system definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_trace.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_trace.h index 3be93c633..606bf0437 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_trace.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/event_trace.h @@ -1,7 +1,7 @@ /* * Trace log blocks sent over HBUS * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/fils.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/fils.h index 1797abfa6..b4eeacb32 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/fils.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/fils.h @@ -1,7 +1,7 @@ /* * Fundamental types and constants relating to FILS AUTHENTICATION * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_armtrap.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_armtrap.h index ca4185146..e70b129c2 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_armtrap.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_armtrap.h @@ -1,7 +1,7 @@ /* * HND arm trap handling. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_cons.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_cons.h index eb5245803..f53d18e9c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_cons.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_cons.h @@ -1,7 +1,7 @@ /* * Console support for RTE - for host use only. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_debug.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_debug.h index 5a24e6644..40c2e7e87 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_debug.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_debug.h @@ -1,7 +1,7 @@ /* * HND Run Time Environment debug info area * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktpool.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktpool.h index ce241e802..586f35339 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktpool.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktpool.h @@ -1,7 +1,7 @@ /* * HND generic packet pool operation primitives * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktq.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktq.h index 375ebd871..be39bc57e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktq.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_pktq.h @@ -1,7 +1,7 @@ /* * HND generic pktq operation primitives * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_trap.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_trap.h index eded5da4d..622c3729b 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_trap.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hnd_trap.h @@ -1,7 +1,7 @@ /* * HND Trap handling. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndchipc.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndchipc.h index 26e53b3d6..5fc9cdb93 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndchipc.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndchipc.h @@ -1,7 +1,7 @@ /* * HND SiliconBackplane chipcommon support - OS independent. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndlhl.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndlhl.h index e2068a3e5..6e80fff78 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndlhl.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndlhl.h @@ -1,7 +1,7 @@ /* * HND SiliconBackplane PMU support. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndoobr.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndoobr.h index 351b2fa89..c53fc3f9d 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndoobr.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndoobr.h @@ -1,7 +1,7 @@ /* * HND OOBR interface header * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndpmu.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndpmu.h index e41bc14e7..e41e83e07 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndpmu.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndpmu.h @@ -1,7 +1,7 @@ /* * HND SiliconBackplane PMU support. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndsoc.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndsoc.h index 3811b9638..7a4d0c0bc 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndsoc.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/hndsoc.h @@ -1,7 +1,7 @@ /* * Broadcom HND chip & on-chip-interconnect-related definitions. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_osl.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_osl.h index f69ebd9c3..40e34cd97 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_osl.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_osl.h @@ -1,7 +1,7 @@ /* * Linux OS Independent Layer * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_pkt.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_pkt.h index 42dbdb298..c03161c42 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_pkt.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linux_pkt.h @@ -1,7 +1,7 @@ /* * Linux Packet (skb) interface * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linuxver.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linuxver.h index 8d32af7e4..bd4986624 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linuxver.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/linuxver.h @@ -2,7 +2,7 @@ * Linux-specific abstractions to gain some independence from linux kernel versions. * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/lpflags.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/lpflags.h index f284bbb59..98897504b 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/lpflags.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/lpflags.h @@ -1,7 +1,7 @@ /* * Chip related low power flags * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/mbo.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/mbo.h index 14bd92b17..41ab6251e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/mbo.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/mbo.h @@ -1,7 +1,7 @@ /* * Fundamental types and constants relating to WFA MBO * (Multiband Operation) - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/msgtrace.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/msgtrace.h index f564999d0..9fc7ae1b6 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/msgtrace.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/msgtrace.h @@ -1,7 +1,7 @@ /* * Trace messages sent over HBUS * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/nan.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/nan.h index dbbb8eef5..52b6fa48c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/nan.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/nan.h @@ -2,7 +2,7 @@ * Fundamental types and constants relating to WFA NAN * (Neighbor Awareness Networking) * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl.h index b5918be75..a55b3beea 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl.h @@ -1,7 +1,7 @@ /* * OS Abstraction Layer * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_decl.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_decl.h index a86805a5a..16adf43cc 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_decl.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_decl.h @@ -1,7 +1,7 @@ /* * osl forward declarations * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_ext.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_ext.h index 460bc3a23..6a04c2b3c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_ext.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/osl_ext.h @@ -2,7 +2,7 @@ * OS Abstraction Layer Extension - the APIs defined by the "extension" API * are only supported by a subset of all operating systems. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/p2p.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/p2p.h index 727fe969c..17a2505a2 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/p2p.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/p2p.h @@ -1,7 +1,7 @@ /* * Fundamental types and constants relating to WFA P2P (aka WiFi Direct) * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_end.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_end.h index 18a07c423..8f57273c5 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_end.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_end.h @@ -15,7 +15,7 @@ * #include * * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_start.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_start.h index 820e30b2b..855bc495f 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_start.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/packed_section_start.h @@ -15,7 +15,7 @@ * #include * * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcicfg.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcicfg.h index a2147ab3f..e4cac5e36 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcicfg.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcicfg.h @@ -1,7 +1,7 @@ /* * pcicfg.h: PCI configuration constants and structures. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcie_core.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcie_core.h index 7e3447946..4b0e2c12e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcie_core.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/pcie_core.h @@ -1,7 +1,7 @@ /* * BCM43XX PCIE core hardware definitions. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbchipc.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbchipc.h index f92959bf0..933a2b8e8 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbchipc.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbchipc.h @@ -5,7 +5,7 @@ * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer, * GPIO interface, extbus, and support for serial and parallel flashes. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbconfig.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbconfig.h index 283eb0e9e..d8786d0ff 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbconfig.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbconfig.h @@ -1,7 +1,7 @@ /* * Broadcom SiliconBackplane hardware register definitions. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbgci.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbgci.h index 0b265b611..fec5d46f9 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbgci.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbgci.h @@ -1,7 +1,7 @@ /* * SiliconBackplane GCI core hardware definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhndarm.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhndarm.h index fe0d28eec..92d7600ee 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhndarm.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhndarm.h @@ -1,7 +1,7 @@ /* * Broadcom SiliconBackplane ARM definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhnddma.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhnddma.h index bf7f3baa4..8e7bca0f0 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhnddma.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbhnddma.h @@ -2,7 +2,7 @@ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface * This supports the following chips: BCM42xx, 44xx, 47xx . * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbpcmcia.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbpcmcia.h index 77f65f4b2..87d6d09ab 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbpcmcia.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbpcmcia.h @@ -1,7 +1,7 @@ /* * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdio.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdio.h index 0a2c2271f..2e6ac1090 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdio.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdio.h @@ -4,7 +4,7 @@ * * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdpcmdev.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdpcmdev.h index 603702af5..bdb59b627 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdpcmdev.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsdpcmdev.h @@ -2,7 +2,7 @@ * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific * device core support * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsocram.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsocram.h index f8d6b0d90..97eaa6f27 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsocram.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsocram.h @@ -1,7 +1,7 @@ /* * BCM47XX Sonics SiliconBackplane embedded ram core * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsysmem.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsysmem.h index 0783e4ba0..77147faac 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsysmem.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sbsysmem.h @@ -1,7 +1,7 @@ /* * SiliconBackplane System Memory core * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdio.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdio.h index b9959293b..4bb72a9ed 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdio.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdio.h @@ -2,7 +2,7 @@ * SDIO spec header file * Protocol and standard (common) device definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdioh.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdioh.h index 805f0611d..f1e81813c 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdioh.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdioh.h @@ -2,7 +2,7 @@ * SDIO Host Controller Spec header file * Register map and definitions for the Standard Host Controller * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdiovar.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdiovar.h index f97a8ee2f..90cfbc1d9 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdiovar.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/sdiovar.h @@ -2,7 +2,7 @@ * Structure used by apps whose drivers access SDIO drivers. * Pulled out separately so dhdu and wlu can both use it. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/siutils.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/siutils.h index c8c02baf8..3ffccefe3 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/siutils.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/siutils.h @@ -2,7 +2,7 @@ * Misc utility routines for accessing the SOC Interconnects * of Broadcom HNBU chips. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/typedefs.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/typedefs.h index 871b511da..e803a1b60 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/typedefs.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/typedefs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/vlan.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/vlan.h index bbf5e5080..e4c33e928 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/vlan.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/vlan.h @@ -1,7 +1,7 @@ /* * 802.1Q VLAN protocol definitions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bam.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bam.h index 2c7d59c98..98d126f52 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bam.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bam.h @@ -1,7 +1,7 @@ /* * Bad AP Manager for ADPS * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bigdata.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bigdata.h index bdd40196c..a30f66f2b 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bigdata.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wl_bigdata.h @@ -1,7 +1,7 @@ /* * Bigdata logging and report. None EWP and Hang event. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wldev_common.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wldev_common.h index 006a3f644..39a350793 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wldev_common.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wldev_common.h @@ -1,7 +1,7 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlfc_proto.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlfc_proto.h index b2ade30b0..6a3f4a857 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlfc_proto.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlfc_proto.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl.h index f37fbbd9d..adaf872b7 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl.h @@ -6,7 +6,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_defs.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_defs.h index 3a1100f02..13ed84aa7 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_defs.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_defs.h @@ -4,7 +4,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_utils.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_utils.h index b419d1709..93b369c22 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_utils.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wlioctl_utils.h @@ -1,7 +1,7 @@ /* * Custom OID/ioctl related helper functions. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wpa.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wpa.h index 331cbbbe7..c9c7cb2a7 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wpa.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/include/wpa.h @@ -1,7 +1,7 @@ /* * Fundamental types and constants relating to WPA * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl.c index 55e5231c2..d48a2ad38 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl.c @@ -1,7 +1,7 @@ /* * Linux OS Independent Layer * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl_priv.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl_priv.h index cac352411..60c568100 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl_priv.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_osl_priv.h @@ -1,7 +1,7 @@ /* * Private header file for Linux OS Independent Layer * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_pkt.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_pkt.c index 640dc37d3..11f0ae169 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_pkt.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/linux_pkt.c @@ -1,7 +1,7 @@ /* * Linux Packet (skb) interface * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/pcie_core.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/pcie_core.c index b1473ac80..8482df303 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/pcie_core.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/pcie_core.c @@ -3,7 +3,7 @@ * Contains PCIe related functions that are shared between different driver models (e.g. firmware * builds, DHD builds, BMAC builds), in order to avoid code duplication. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/sbutils.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/sbutils.c index 80e74c571..066e4c8a1 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/sbutils.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/sbutils.c @@ -2,7 +2,7 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils.c index c495efd5b..9cd334c10 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils.c @@ -2,7 +2,7 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils_priv.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils_priv.h index 43aad34bc..c8e6c4f0a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils_priv.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/siutils_priv.h @@ -1,7 +1,7 @@ /* * Include file private to the SOC Interconnect support files. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wb_regon_coordinator.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wb_regon_coordinator.c index a2586b2e5..f193f857d 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wb_regon_coordinator.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wb_regon_coordinator.c @@ -1,7 +1,7 @@ /* * DHD BT WiFi Coex RegON Coordinator * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wifi_stats.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wifi_stats.h index a4d2e7393..7e8eb1cc8 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wifi_stats.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wifi_stats.h @@ -2,7 +2,7 @@ * Common stats definitions for clients of dongle * ports * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.c index 6ea73b677..67efb2d38 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.c @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Android related functions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -3149,13 +3149,6 @@ wl_android_ncho_private_command(struct net_device *net, char *command, int total bytes_written = wl_android_get_full_roam_scan_period(net, command, total_len); } else if (strnicmp(command, CMD_COUNTRYREV_SET, strlen(CMD_COUNTRYREV_SET)) == 0) { bytes_written = wl_android_set_country_rev(net, command); -#ifdef FCC_PWR_LIMIT_2G - if (wldev_iovar_setint(net, "fccpwrlimit2g", FALSE)) { - WL_ERR(("fccpwrlimit2g deactivation is failed\n")); - } else { - WL_ERR(("fccpwrlimit2g is deactivated\n")); - } -#endif /* FCC_PWR_LIMIT_2G */ } else if (strnicmp(command, CMD_COUNTRYREV_GET, strlen(CMD_COUNTRYREV_GET)) == 0) { bytes_written = wl_android_get_country_rev(net, command, total_len); } else @@ -4070,10 +4063,9 @@ wl_android_wtc_config(struct net_device *dev, char *command, int total_len) wlc_wtcconfig_info_v1_t *wtc_config; u32 i, wtc_paramslen, maxbands = WL_DUALBAND; u8 buf[WLC_IOCTL_SMLEN] = {0}; -#ifdef WL_6G_BAND struct bcm_cfg80211 *cfg = wl_get_cfg(dev); -#endif /* WL_6G_BAND */ + BCM_REFERENCE(cfg); WL_DBG_MEM(("Enter. cmd:%s\n", command)); #ifdef WL_6G_BAND if (cfg->band_6g_supported) { @@ -4915,11 +4907,11 @@ int wl_android_wifi_on(struct net_device *dev) return ret; } -int wl_android_wifi_off(struct net_device *dev, bool on_failure) +int wl_android_wifi_off(struct net_device *dev, bool force_off) { int ret = 0; - DHD_ERROR(("%s g_wifi_on=%d on_failure=%d\n", __FUNCTION__, g_wifi_on, on_failure)); + DHD_ERROR(("%s g_wifi_on=%d force_off=%d\n", __FUNCTION__, g_wifi_on, force_off)); if (!dev) { DHD_TRACE(("wl_android_wifi_off: dev is null\n")); return -EINVAL; @@ -4933,7 +4925,7 @@ int wl_android_wifi_off(struct net_device *dev, bool on_failure) } #endif /* BCMPCIE && DHD_DEBUG_UART */ dhd_net_if_lock(dev); - if (g_wifi_on || on_failure) { + if (g_wifi_on || force_off) { #if defined(BCMSDIO) || defined(BCMPCIE) ret = dhd_net_bus_devreset(dev, TRUE); #ifdef BCMSDIO @@ -10455,6 +10447,7 @@ _wl_android_bcnrecv_start(struct bcm_cfg80211 *cfg, struct net_device *ndev, boo { s32 err = BCME_OK; struct net_device *pdev = bcmcfg_to_prmry_ndev(cfg); + dhd_pub_t *dhd = cfg->pub; /* check any scan is in progress before beacon recv scan trigger IOVAR */ if (wl_get_drv_status_all(cfg, SCANNING)) { @@ -10496,6 +10489,17 @@ _wl_android_bcnrecv_start(struct bcm_cfg80211 *cfg, struct net_device *ndev, boo } #endif /* WL_NAN */ + if (dhd->early_suspended) { + /* Set BEACON_RECV in suspend mode */ + WL_INFORM_MEM(("Already suspend mode, Aborting beacon recv start\n")); + cfg->bcnrecv_info.bcnrecv_state = BEACON_RECV_SUSPENDED; + if ((err = wl_android_bcnrecv_event(pdev, BCNRECV_ATTR_STATUS, + WL_BCNRECV_SUSPENDED, WL_BCNRECV_SUSPEND, NULL, 0)) != BCME_OK) { + WL_ERR(("failed to send bcnrecv event, error:%d\n", err)); + } + goto exit; + } + /* Triggering an sendup_bcn iovar */ err = wldev_iovar_setint(pdev, "sendup_bcn", 1); if (unlikely(err)) { @@ -12028,16 +12032,7 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) #endif /* DHD_BLOB_EXISTENCE_CHECK */ bytes_written = wl_cfg80211_set_country_code(net, country_code, - true, true, revinfo); -#ifdef CUSTOMER_HW4_PRIVATE_CMD -#ifdef FCC_PWR_LIMIT_2G - if (wldev_iovar_setint(net, "fccpwrlimit2g", FALSE)) { - DHD_ERROR(("%s: fccpwrlimit2g deactivation is failed\n", __FUNCTION__)); - } else { - DHD_ERROR(("%s: fccpwrlimit2g is deactivated\n", __FUNCTION__)); - } -#endif /* FCC_PWR_LIMIT_2G */ -#endif /* CUSTOMER_HW4_PRIVATE_CMD */ + true, true, revinfo); } #endif /* CUSTOMER_SET_COUNTRY */ #endif /* WL_CFG80211 */ diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.h index 2e86bc3dc..3c8af69c0 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_android.h @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Android related functions * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bam.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bam.c index ec9e91ca3..014822a4e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bam.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bam.c @@ -1,7 +1,7 @@ /* * Bad AP Manager for ADPS * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bigdata.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bigdata.c index fc7798304..caffdb27b 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bigdata.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_bigdata.c @@ -1,7 +1,7 @@ /* * Bigdata logging and report. None EWP and Hang event. * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.c index d00ce0025..6583f60e8 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.c @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -762,6 +762,11 @@ static s32 wl_bcnrecv_aborted_event_handler(struct bcm_cfg80211 *cfg, bcm_struct const wl_event_msg_t *e, void *data); #endif /* WL_BCNRECV */ +#if defined(KEEP_ALIVE) && defined(DHD_CLEANUP_KEEP_ALIVE) +#define KEEP_ALIVE_ID_MAX 8 +void wl_cleanup_keep_alive(struct bcm_cfg80211 *cfg); +#endif /* defined(KEEP_ALIVE) && defined(DHD_CLEANUP_KEEP_ALIVE) */ + #ifdef WL_CAC_TS static s32 wl_cfg80211_cac_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data); @@ -7530,7 +7535,6 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, #ifdef RTT_SUPPORT rtt_status_info_t *rtt_status; #endif /* RTT_SUPPORT */ - int bcn_li_dtim = 0; RETURN_EIO_IF_NOT_UP(cfg); WL_DBG(("Enter\n")); @@ -7585,31 +7589,9 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, _net_info->ps_managed_start_ts = OSL_SYSUPTIME(); } - /* Set MAX bcn_li_dtim in suspend */ - if (enabled) { - /* PM Enabled */ - dhd->max_dtim_enable = TRUE; - dhd->suspend_bcn_li_dtim = CUSTOM_SUSPEND_BCN_LI_DTIM; - } else { - /* PM Disabled */ - dhd->max_dtim_enable = FALSE; - dhd->suspend_bcn_li_dtim = NO_DTIM_SKIP; - } - - /* Set bcn_li_dtim if suspend mode */ - if (dhd->early_suspended) { - /* LCD off */ -#if defined(BCMPCIE) - int dtim_period = 0; - int bcn_interval = 0; - bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd, &dtim_period, &bcn_interval); -#else - bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd); -#endif /* OEM_ANDROID && BCMPCIE */ - err = wldev_iovar_setint(dev, "bcn_li_dtim", bcn_li_dtim); - if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); - } + if (dhd->in_suspend) { + /* Enable/Disable bcn_li_dtim if suspend mode */ + dhd_set_suspend_bcn_li_dtim(dhd, enabled); } return err; @@ -10109,7 +10091,8 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev #ifdef WL_FILS wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_FILS_SK_OFFLOAD); #endif /* WL_FILS */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) && defined(WL_ACT_FRAME_MAC_RAND) +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) || \ + defined(WL_SUPPORT_BACKPORTED_ANQP_RMAC)) && defined(WL_ACT_FRAME_MAC_RAND) wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) && defined(WL_ACT_FRAME_MAC_RAND) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) @@ -11456,6 +11439,12 @@ wl_post_linkdown_ops(struct bcm_cfg80211 *cfg, } #endif /* WL_NAN */ +#if defined(KEEP_ALIVE) && defined(DHD_CLEANUP_KEEP_ALIVE) + if (ndev == bcmcfg_to_prmry_ndev(cfg) && cfg->mkeep_alive_avail) { + wl_cleanup_keep_alive(cfg); + } +#endif /* defined(KEEP_ALIVE) && defined(DHD_CLEANUP_KEEP_ALIVE) */ + return ret; } @@ -12384,7 +12373,12 @@ wl_notify_roam_prep_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, BCM_REFERENCE(sec); if (status == WLC_E_STATUS_SUCCESS && reason != WLC_E_REASON_INITIAL_ASSOC) { +#ifndef WES_SUPPORT WL_ERR(("Attempting roam with reason code : %d\n", reason)); +#else + WL_ERR(("Attempting roam with reason code : %d, Current %s mode\n", + reason, (cfg->ncho_mode ? "NCHO" : "Legacy Roam"))); +#endif /* WES_SUPPORT */ } #ifdef CONFIG_SILENT_ROAM @@ -12415,7 +12409,7 @@ wl_notify_roam_prep_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, dhdp->dequeue_prec_map = 1 << dhdp->flow_prio_map[PRIO_8021D_NC]; /* Restore flow control */ dhd_txflowcontrol(dhdp, ALL_INTERFACES, OFF); - + DHD_DISABLE_RUNTIME_PM(dhdp); mod_timer(&cfg->roam_timeout, jiffies + msecs_to_jiffies(WL_ROAM_TIMEOUT_MS)); #endif /* DHD_LOSSLESS_ROAMING */ @@ -12716,6 +12710,7 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, #endif /* LINUX_VERSION > 2.6.39 || WL_COMPAT_WIRELESS */ #endif /* BCM4359 CHIP */ + wl_update_prof(cfg, ndev, NULL, (const void *)(e->addr.octet), WL_PROF_BSSID); if ((err = wl_get_assoc_ies(cfg, ndev)) != BCME_OK) { DHD_STATLOG_CTRL(dhdp, ST(DISASSOC_INT_START), dhd_net2idx(dhdp->info, ndev), WLAN_REASON_DEAUTH_LEAVING); @@ -12735,7 +12730,6 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev, goto fail; } - wl_update_prof(cfg, ndev, NULL, (const void *)(e->addr.octet), WL_PROF_BSSID); curbssid = wl_read_prof(cfg, ndev, WL_PROF_BSSID); if ((err = wl_update_bss_info(cfg, ndev, true)) != BCME_OK) { WL_ERR(("failed to update bss info, err=%d\n", err)); @@ -13432,8 +13426,9 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, } err = wldev_ioctl_get(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN); - if (err < 0) + if ((err < 0) && (err != BCME_NOTASSOCIATED)) { WL_ERR(("WLC_GET_BSSID error %d\n", err)); + } memcpy(da.octet, ioctl_buf, ETHER_ADDR_LEN); if ((ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION) && @@ -14149,6 +14144,7 @@ static void wl_del_roam_timeout(struct bcm_cfg80211 *cfg) /* restore prec_map to ALLPRIO */ dhdp->dequeue_prec_map = ALLPRIO; del_timer_sync(&cfg->roam_timeout); + DHD_ENABLE_RUNTIME_PM(dhdp); } static void wl_roam_timeout(unsigned long data) @@ -14160,6 +14156,7 @@ static void wl_roam_timeout(unsigned long data) /* restore prec_map to ALLPRIO */ dhdp->dequeue_prec_map = ALLPRIO; + DHD_ENABLE_RUNTIME_PM(dhdp); } #endif /* DHD_LOSSLESS_ROAMING */ @@ -16449,8 +16446,17 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg) } #ifdef WL_SCHED_SCAN - cancel_delayed_work(&cfg->sched_scan_stop_work); + if (cfg->sched_scan_req) { + struct wireless_dev *wdev = ndev->ieee80211_ptr; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) + wl_cfg80211_sched_scan_stop(wdev->wiphy, ndev, + cfg->sched_scan_req->reqid); +#else + wl_cfg80211_sched_scan_stop(wdev->wiphy, ndev); +#endif /* KERNEL >= 4.11 */ + } #endif /* WL_SCHED_SCAN */ + #ifdef WL_SAR_TX_POWER cfg->wifi_tx_power_mode = WIFI_POWER_SCENARIO_INVALID; #endif /* WL_SAR_TX_POWER */ @@ -21225,6 +21231,16 @@ wl_android_roamoff_dbg_dump(struct bcm_cfg80211 *cfg) return; } +#ifdef DHD_PM_CONTROL_FROM_FILE + { + extern bool g_pm_control; + if (g_pm_control == TRUE) { + WL_ERR(("Enabled RF test mode\n")); + return; + } + } +#endif /* DHD_PM_CONTROL_FROM_FILE */ + /* Dump roaminfo */ WL_INFORM_MEM(("Last ROAM Disable(%02d) "SEC_USEC_FMT"\n", roamoff_info->roam_disable_rsn, @@ -21255,3 +21271,25 @@ wl_android_roamoff_dbg_dump(struct bcm_cfg80211 *cfg) return; } #endif /* DEBUG_SETROAMMODE */ + +#if defined(KEEP_ALIVE) && defined(DHD_CLEANUP_KEEP_ALIVE) +void +wl_cleanup_keep_alive(struct bcm_cfg80211 *cfg) +{ + int mkeep_alive_id; + + for (mkeep_alive_id = 1; mkeep_alive_id < KEEP_ALIVE_ID_MAX; mkeep_alive_id++) { + if (isset(&cfg->mkeep_alive_avail, mkeep_alive_id)) { + if (wl_cfg80211_stop_mkeep_alive(cfg, mkeep_alive_id) == BCME_OK) { + clrbit(&cfg->mkeep_alive_avail, mkeep_alive_id); + } + } + if (!cfg->mkeep_alive_avail) { + WL_INFORM(("Stopped for all keep alive id.\n")); + break; + } + } + + return; +} +#endif /* defined(KEEP_ALIVE) && defined(DHD_CLEANUP_KEEP_ALIVE) */ diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.h index 52ed8697b..4c5a0f80f 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg80211.h @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -1645,6 +1645,16 @@ typedef struct wl_roamoff_info { } wl_roamoff_info_t; #endif /* DEBUG_SETROAMMODE */ +#ifdef CONFIG_COMPAT +typedef struct compat_buf_data { + u32 ver; /* version of struct */ + u32 len; /* Total len */ + /* size of each buffer in case of split buffers (0 - single buffer). */ + u32 buf_threshold; + u32 data_buf; /* array of user space buffer pointers. */ +} compat_buf_data_t; +#endif /* CONFIG_COMPAT */ + /* private data of cfg80211 interface */ struct bcm_cfg80211 { struct wireless_dev *wdev; /* representing cfg cfg80211 device */ @@ -1917,6 +1927,9 @@ struct bcm_cfg80211 { #ifdef WL_SCHED_SCAN struct delayed_work sched_scan_stop_work; #endif /* WL_SCHED_SCAN */ +#ifdef DHD_CLEANUP_KEEP_ALIVE + uint8 mkeep_alive_avail; +#endif /* DHD_CLEANUP_KEEP_ALIVE */ }; /* Max auth timeout allowed in case of EAP is 70sec, additional 5 sec for diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg_btcoex.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg_btcoex.c index e5ef7a853..91ac9ebdc 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg_btcoex.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfg_btcoex.c @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgdbg.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgdbg.c index b28947560..57639cd5a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgdbg.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgdbg.c @@ -1,7 +1,7 @@ /* * Debug ability related code * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.c index 29bdf1f78..610f986c8 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.c @@ -1,7 +1,7 @@ /* * Neighbor Awareness Networking * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -3560,6 +3560,8 @@ wl_cfgnan_config_handler(struct net_device *ndev, struct bcm_cfg80211 *cfg, goto fail; } + WL_INFORM_MEM(("Cluster merge : %s\n", merge_enable ? "Enabled" : "Disabled")); + lwt_mode_enable = !!(cmd_data->nmi_rand_intvl & NAN_NMI_RAND_AUTODAM_LWT_MODE_ENAB); @@ -3578,6 +3580,8 @@ wl_cfgnan_config_handler(struct net_device *ndev, struct bcm_cfg80211 *cfg, goto fail; } + WL_INFORM_MEM(("LWT mode : %s\n", lwt_mode_enable ? "Enabled" : "Disabled")); + /* reset pvt merge enable bits */ cmd_data->nmi_rand_intvl &= ~(NAN_NMI_RAND_PVT_CMD_VENDOR | NAN_NMI_RAND_CLUSTER_MERGE_ENAB | @@ -9324,7 +9328,7 @@ wl_nan_print_avail_stats(const uint8 *data) int s_chan = 0; char pbuf[NAN_IOCTL_BUF_SIZE_MED]; const wl_nan_stats_sched_t *sched = (const wl_nan_stats_sched_t *)data; -#define SLOT_PRINT_SIZE 4 +#define SLOT_PRINT_SIZE 6 char *buf = pbuf; int remained_len = 0, bytes_written = 0; @@ -9352,8 +9356,10 @@ wl_nan_print_avail_stats(const uint8 *data) buf += bytes_written; remained_len -= bytes_written; - bytes_written = snprintf(buf, remained_len, "%03d|", s_chan); - + bytes_written = snprintf(buf, remained_len, "%3u%c|", + s_chan, ((s_chan) && + (slot->info & WL_NAN_SCHED_STAT_SLOT_COMM)) ? 'C' : + ' '); /* Committed */ } WL_INFORM_MEM(("%s\n", pbuf)); exit: diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.h index 13525a657..2fe96dc65 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgnan.h @@ -1,7 +1,7 @@ /* * Neighbor Awareness Networking * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.c index 2ff41c245..dbee8ecca 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.c @@ -1,7 +1,7 @@ /* * Linux cfgp2p driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -412,8 +412,10 @@ wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg) * After Initializing firmware, we have to set current mac address to * firmware for P2P device address */ + CFGP2P_INFO(("p2p dev addr : "MACDBG"\n", MAC2STRDBG(p2p_dev_addr->octet))); ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", p2p_dev_addr, - sizeof(*p2p_dev_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync); + sizeof(*p2p_dev_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, + &cfg->ioctl_buf_sync); if (ret && ret != BCME_UNSUPPORTED) { CFGP2P_ERR(("failed to update device address ret %d\n", ret)); } @@ -571,6 +573,51 @@ wl_cfgp2p_ifidx(struct bcm_cfg80211 *cfg, struct ether_addr *mac, s32 *index) return ret; } +#define DISCOVERY_EBUSY_RETRY_LIMIT 5 +static void +wl_cfgp2p_handle_discovery_busy(struct bcm_cfg80211 *cfg, s32 err) +{ + static u32 busy_count = 0; + dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub); + + if (err != BCME_BUSY) { + busy_count = 0; + return; + } + + busy_count++; + + if (busy_count >= DISCOVERY_EBUSY_RETRY_LIMIT) { + struct ether_addr *p2p_dev_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE); + + CFGP2P_ERR(("p2p disc busy!!!\n")); + + if (ETHER_ISNULLADDR(p2p_dev_addr)) { + CFGP2P_ERR(("NULL p2p_dev_addr\n")); + } else { + CFGP2P_ERR(("p2p disc mac : "MACDBG"\n", MAC2STRDBG(p2p_dev_addr->octet))); + } + + if (dhd_query_bus_erros(dhdp)) { + CFGP2P_ERR(("bus error\n")); + return; + } + + dhdp->p2p_disc_busy_occurred = TRUE; + busy_count = 0; + +#if defined(DHD_DEBUG) && defined(DHD_FW_COREDUMP) + if (dhdp->memdump_enabled) { + dhdp->memdump_type = DUMP_TYPE_P2P_DISC_BUSY; + dhd_bus_mem_dump(dhdp); + } +#endif /* DHD_DEBUG && DHD_FW_COREDUMP */ + + dhdp->hang_reason = HANG_REASON_P2P_DISC_BUSY; + dhd_os_send_hang_message(dhdp); + } +} + static s32 wl_cfgp2p_set_discovery(struct bcm_cfg80211 *cfg, s32 on) { @@ -582,6 +629,10 @@ wl_cfgp2p_set_discovery(struct bcm_cfg80211 *cfg, s32 on) if (unlikely(ret < 0)) { CFGP2P_ERR(("p2p_disc %d error %d\n", on, ret)); + + if (on) { + wl_cfgp2p_handle_discovery_busy(cfg, ret); + } } return ret; @@ -1855,7 +1906,7 @@ wl_cfgp2p_generate_bss_mac(struct bcm_cfg80211 *cfg, struct ether_addr *primary_ (void)memcpy_s(mac_addr, ETH_ALEN, bcmcfg_to_prmry_ndev(cfg)->perm_addr, ETH_ALEN); mac_addr->octet[0] |= 0x02; - WL_DBG(("P2P Discovery address:"MACDBG "\n", MAC2STRDBG(mac_addr->octet))); + CFGP2P_INFO(("P2P Discovery address:"MACDBG "\n", MAC2STRDBG(mac_addr->octet))); int_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_CONNECTION1); memcpy(int_addr, mac_addr, sizeof(struct ether_addr)); diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.h index 84b23f5e3..ac11bc9fb 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgp2p.h @@ -1,7 +1,7 @@ /* * Linux cfgp2p driver * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.c index 2285d4cd6..b7a3d59f1 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.c @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver scan related code * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -3861,8 +3861,13 @@ static void wl_scan_timeout(unsigned long data) bi = next_bss(bss_list, bi); for_each_bss(bss_list, bi, i) { - channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(bi->chanspec)); - WL_ERR(("SSID :%s Channel :%d\n", bi->SSID, channel)); + if (wf_chspec_valid(bi->chanspec)) { + channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(bi->chanspec)); + WL_ERR(("SSID :%s Channel :%d\n", bi->SSID, channel)); + } else { + WL_ERR(("SSID :%s Invalid chanspec :0x%x\n", + bi->SSID, bi->chanspec)); + } } } @@ -3887,7 +3892,13 @@ static void wl_scan_timeout(unsigned long data) #ifdef DHD_FW_COREDUMP if (!dhd_bus_get_linkdown(dhdp) && dhdp->memdump_enabled) { dhdp->memdump_type = DUMP_TYPE_SCAN_TIMEOUT; +#ifdef BCMPCIE dhd_bus_mem_dump(dhdp); +#else + if (dhd_schedule_socram_dump(dhdp)) { + WL_ERR(("%s: socram dump failed\n", __FUNCTION__)); + } +#endif /* BCMPCIE */ } /* * For the memdump sanity, blocking bus transactions for a while @@ -4957,7 +4968,6 @@ wl_cfgscan_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, return -EINVAL; } - mutex_lock(&cfg->usr_sync); ndev = cfgdev_to_wlc_ndev(cfgdev, cfg); target_channel = ieee80211_frequency_to_channel(channel->center_freq); @@ -5027,6 +5037,8 @@ wl_cfgscan_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, if (unlikely(err)) { goto exit; } + + mutex_lock(&cfg->usr_sync); err = wl_cfgp2p_discover_listen(cfg, target_channel, duration); if (err == BCME_OK) { wl_set_drv_status(cfg, REMAINING_ON_CHANNEL, ndev); @@ -5044,6 +5056,7 @@ wl_cfgscan_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, } #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ } + mutex_unlock(&cfg->usr_sync); } else if (wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_AP) { WL_DBG(("LISTEN ON CHANNEL\n")); @@ -5072,7 +5085,6 @@ wl_cfgscan_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, WL_ERR(("Fail to Set (err=%d cookie:%llu)\n", err, *cookie)); wl_flush_fw_log_buffer(ndev, FW_LOGSET_MASK_ALL); } - mutex_unlock(&cfg->usr_sync); return err; } diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.h index f06b23a31..edeb36976 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgscan.h @@ -1,7 +1,7 @@ /* * Header for Linux cfg80211 scan * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.c index 68e89ed29..bd071b1ec 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.c @@ -1,7 +1,7 @@ /* * Linux cfg80211 Vendor Extension Code * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -7419,20 +7419,48 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy, #ifdef DHD_LOG_DUMP static int -wl_cfgvendor_get_buf_data(const struct nlattr *iter, struct buf_data **buf) +wl_cfgvendor_get_buf_data(const struct nlattr *iter, struct buf_data *buf) { int ret = BCME_OK; +#ifdef CONFIG_COMPAT +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) + if (in_compat_syscall()) { +#else + if (is_compat_task()) { +#endif /* LINUX_VER >= 4.6 */ + struct compat_buf_data *compat_buf = (struct compat_buf_data *)nla_data(iter); - if (nla_len(iter) != sizeof(struct buf_data)) { - WL_ERR(("Invalid len : %d\n", nla_len(iter))); - ret = BCME_BADLEN; + if (nla_len(iter) != sizeof(struct compat_buf_data)) { + WL_ERR(("Invalid len : %d\n", nla_len(iter))); + ret = BCME_BADLEN; + } + + buf->ver = compat_buf->ver; + buf->len = compat_buf->len; + buf->buf_threshold = compat_buf->buf_threshold; + buf->data_buf[0] = (const void *)compat_ptr(compat_buf->data_buf); } - (*buf) = (struct buf_data *)nla_data(iter); - if (!(*buf) || (((*buf)->len) <= 0) || !((*buf)->data_buf[0])) { + else +#endif /* CONFIG_COMPAT */ + { + if (nla_len(iter) != sizeof(struct buf_data)) { + WL_ERR(("Invalid len : %d\n", nla_len(iter))); + ret = BCME_BADLEN; + } + ret = memcpy_s(buf, sizeof(struct buf_data), (void *)nla_data(iter), nla_len(iter)); + if (ret) { + WL_ERR(("Can't get buf data\n")); + goto exit; + } + } + + if ((buf->len <= 0) || !buf->data_buf[0]) { WL_ERR(("Invalid buffer\n")); ret = BCME_ERROR; } +exit: return ret; + } static int @@ -7445,6 +7473,7 @@ wl_cfgvendor_dbg_file_dump(struct wiphy *wiphy, struct sk_buff *skb = NULL; struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); struct buf_data *buf; + struct buf_data data_from_hal; int pos = 0; /* Alloc the SKB for vendor_event */ @@ -7455,9 +7484,12 @@ wl_cfgvendor_dbg_file_dump(struct wiphy *wiphy, goto exit; } WL_ERR(("%s\n", __FUNCTION__)); + + memset_s(&data_from_hal, sizeof(data_from_hal), 0, sizeof(data_from_hal)); + buf = &data_from_hal; nla_for_each_attr(iter, data, len, rem) { type = nla_type(iter); - ret = wl_cfgvendor_get_buf_data(iter, &buf); + ret = wl_cfgvendor_get_buf_data(iter, buf); if (ret) goto exit; switch (type) { @@ -7537,6 +7569,18 @@ wl_cfgvendor_dbg_file_dump(struct wiphy *wiphy, buf->data_buf[0], NULL, (uint32)buf->len, DLD_BUF_TYPE_SPECIAL, &pos); break; +#ifdef DHD_MAP_PKTID_LOGGING + case DUMP_BUF_ATTR_PKTID_MAP_LOG: + ret = dhd_print_pktid_map_log_data(bcmcfg_to_prmry_ndev(cfg), NULL, + buf->data_buf[0], NULL, (uint32)buf->len, &pos, TRUE); + break; + + case DUMP_BUF_ATTR_PKTID_UNMAP_LOG: + ret = dhd_print_pktid_map_log_data(bcmcfg_to_prmry_ndev(cfg), NULL, + buf->data_buf[0], NULL, (uint32)buf->len, &pos, FALSE); + break; +#endif /* DHD_MAP_PKTID_LOGGIN */ + #ifdef DHD_SSSR_DUMP #ifdef DHD_SSSR_DUMP_BEFORE_SR case DUMP_BUF_ATTR_SSSR_C0_D11_BEFORE : @@ -8266,6 +8310,25 @@ static int wl_cfgvendor_nla_put_debug_dump_data(struct sk_buff *skb, } } #endif /* EWP_RTT_LOGGING */ +#ifdef DHD_MAP_PKTID_LOGGING + len = dhd_get_pktid_map_logging_len(ndev, NULL, TRUE); + if (len) { + ret = nla_put_u32(skb, DUMP_LEN_ATTR_PKTID_MAP_LOG, len); + if (unlikely(ret)) { + WL_ERR(("Failed to nla put pktid log lenght, ret=%d", ret)); + goto exit; + } + } + + len = dhd_get_pktid_map_logging_len(ndev, NULL, FALSE); + if (len) { + ret = nla_put_u32(skb, DUMP_LEN_ATTR_PKTID_UNMAP_LOG, len); + if (unlikely(ret)) { + WL_ERR(("Failed to nla put pktid log lenght, ret=%d", ret)); + goto exit; + } + } +#endif /* DHD_MAP_PKTID_LOGGING */ exit: return ret; } @@ -8697,6 +8760,11 @@ static int wl_cfgvendor_start_mkeep_alive(struct wiphy *wiphy, struct wireless_d if (ret < 0) { WL_ERR(("start_mkeep_alive is failed ret: %d\n", ret)); } +#ifdef DHD_CLEANUP_KEEP_ALIVE + else if (ret == BCME_OK) { + setbit(&cfg->mkeep_alive_avail, mkeep_alive_id); + } +#endif /* DHD_CLEANUP_KEEP_ALIVE */ exit: if (ip_pkt) { @@ -8731,6 +8799,11 @@ static int wl_cfgvendor_stop_mkeep_alive(struct wiphy *wiphy, struct wireless_de if (ret < 0) { WL_ERR(("stop_mkeep_alive is failed ret: %d\n", ret)); } +#ifdef DHD_CLEANUP_KEEP_ALIVE + else if (ret == BCME_OK) { + clrbit(&cfg->mkeep_alive_avail, mkeep_alive_id); + } +#endif /* DHD_CLEANUP_KEEP_ALIVE */ return ret; } @@ -9401,6 +9474,8 @@ const struct nla_policy dump_buf_policy[DUMP_BUF_ATTR_MAX] = { [DUMP_BUF_ATTR_STATUS_LOG] = { .type = NLA_BINARY }, [DUMP_BUF_ATTR_AXI_ERROR] = { .type = NLA_BINARY }, [DUMP_BUF_ATTR_RTT_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTID_MAP_LOG] = { .type = NLA_BINARY }, + [DUMP_BUF_ATTR_PKTID_UNMAP_LOG] = { .type = NLA_BINARY }, }; const struct nla_policy andr_dbg_policy[DEBUG_ATTRIBUTE_MAX] = { diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.h index a69f374ae..6e87c196a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvendor.h @@ -1,7 +1,7 @@ /* * Linux cfg80211 Vendor Extension Code * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -498,6 +498,10 @@ typedef enum { DUMP_LEN_ATTR_AXI_ERROR = 35, DUMP_FILENAME_ATTR_AXI_ERROR_DUMP = 36, DUMP_LEN_ATTR_RTT_LOG = 37, + DUMP_LEN_ATTR_SDTC_ETB_DUMP = 38, + DUMP_FILENAME_ATTR_SDTC_ETB_DUMP = 39, + DUMP_LEN_ATTR_PKTID_MAP_LOG = 40, + DUMP_LEN_ATTR_PKTID_UNMAP_LOG = 41, /* Please add new attributes from here to sync up old HAL */ DUMP_TYPE_ATTR_MAX } EWP_DUMP_EVENT_ATTRIBUTE; @@ -529,6 +533,9 @@ typedef enum { DUMP_BUF_ATTR_STATUS_LOG = 22, DUMP_BUF_ATTR_AXI_ERROR = 23, DUMP_BUF_ATTR_RTT_LOG = 24, + DUMP_BUF_ATTR_SDTC_ETB_DUMP = 25, + DUMP_BUF_ATTR_PKTID_MAP_LOG = 26, + DUMP_BUF_ATTR_PKTID_UNMAP_LOG = 27, /* Please add new attributes from here to sync up old HAL */ DUMP_BUF_ATTR_MAX } EWP_DUMP_CMD_ATTRIBUTE; diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.c index a523f352b..a74cb4a3a 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.c @@ -1,7 +1,7 @@ /* * Wifi Virtual Interface implementaion * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -984,6 +984,10 @@ wl_cfg80211_change_p2prole(struct wiphy *wiphy, struct net_device *ndev, enum nl wl_set_drv_status(cfg, CONNECTED, ndev); } +#if !defined(PCIE_FULL_DONGLE) && defined(P2P_IF_STATE_EVENT_CTRL) + dhd_reset_p2p_interface_event(dhd); +#endif /* !PCIE_FULL_DONGLE & P2P_IF_STATE_EVENT_CTRL */ + return BCME_OK; } @@ -3253,22 +3257,23 @@ wl_cfg80211_start_ap( if (err) { WL_ERR(("Disabling NDO Failed %d\n", err)); } - /* Disable packet filter */ - if (dhd->early_suspended) { - WL_ERR(("Disable pkt_filter\n")); -#ifdef PKT_FILTER_SUPPORT - dhd_enable_packet_filter(0, dhd); -#endif /* PKT_FILTER_SUPPORT */ -#ifdef APF - dhd_dev_apf_disable_filter(dhd_linux_get_primary_netdev(dhd)); -#endif /* APF */ - } } else { /* only AP or GO role need to be handled here. */ err = -EINVAL; goto fail; } + /* Disable packet filter */ + if (dhd->early_suspended) { + WL_ERR(("Disable pkt_filter\n")); +#ifdef PKT_FILTER_SUPPORT + dhd_enable_packet_filter(0, dhd); +#endif /* PKT_FILTER_SUPPORT */ +#ifdef APF + dhd_dev_apf_disable_filter(dhd_linux_get_primary_netdev(dhd)); +#endif /* APF */ + } + /* disable TDLS */ #ifdef WLTDLS if (bssidx == 0) { @@ -3377,20 +3382,21 @@ wl_cfg80211_start_ap( wl_cfg80211_stop_ap(wiphy, dev); if (dev_role == NL80211_IFTYPE_AP) { dhd->op_mode &= ~DHD_FLAG_HOSTAP_MODE; - /* Enable packet filter */ - if (dhd->early_suspended) { - WL_ERR(("Enable pkt_filter\n")); +#ifdef DISABLE_WL_FRAMEBURST_SOFTAP + wl_cfg80211_set_frameburst(cfg, TRUE); +#endif /* DISABLE_WL_FRAMEBURST_SOFTAP */ + } + /* Enable packet filter */ + if (dhd->early_suspended) { + WL_ERR(("Enable pkt_filter\n")); #ifdef PKT_FILTER_SUPPORT - dhd_enable_packet_filter(1, dhd); + dhd_enable_packet_filter(1, dhd); #endif /* PKT_FILTER_SUPPORT */ #ifdef APF - dhd_dev_apf_enable_filter(dhd_linux_get_primary_netdev(dhd)); + dhd_dev_apf_enable_filter(dhd_linux_get_primary_netdev(dhd)); #endif /* APF */ - } -#ifdef DISABLE_WL_FRAMEBURST_SOFTAP - wl_cfg80211_set_frameburst(cfg, TRUE); -#endif /* DISABLE_WL_FRAMEBURST_SOFTAP */ } + #ifdef WLTDLS if (bssidx == 0) { /* Since AP creation failed, re-enable TDLS */ @@ -3475,6 +3481,17 @@ wl_cfg80211_stop_ap( WL_ERR(("bss down error %d\n", err)); } + /* Enable packet filter */ + if (dhd->early_suspended) { + WL_ERR(("Enable pkt_filter\n")); +#ifdef PKT_FILTER_SUPPORT + dhd_enable_packet_filter(1, dhd); +#endif /* PKT_FILTER_SUPPORT */ +#ifdef APF + dhd_dev_apf_enable_filter(dhd_linux_get_primary_netdev(dhd)); +#endif /* APF */ + } + if (dev_role == NL80211_IFTYPE_AP) { #ifdef CUSTOMER_HW4 #ifdef DHD_PCIE_RUNTIMEPM @@ -3495,16 +3512,6 @@ wl_cfg80211_stop_ap( #ifdef DISABLE_WL_FRAMEBURST_SOFTAP wl_cfg80211_set_frameburst(cfg, TRUE); #endif /* DISABLE_WL_FRAMEBURST_SOFTAP */ - /* Enable packet filter */ - if (dhd->early_suspended) { - WL_ERR(("Enable pkt_filter\n")); -#ifdef PKT_FILTER_SUPPORT - dhd_enable_packet_filter(1, dhd); -#endif /* PKT_FILTER_SUPPORT */ -#ifdef APF - dhd_dev_apf_enable_filter(dhd_linux_get_primary_netdev(dhd)); -#endif /* APF */ - } if (is_rsdb_supported == 0) { /* For non-rsdb chips, we use stand alone AP. Do wl down on stop AP */ diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.h index 79b6f17a4..2bb7792a9 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_cfgvif.h @@ -1,7 +1,7 @@ /* * Wifi Virtual Interface implementaion * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_linux_mon.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_linux_mon.c index bda82169c..b028e237e 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_linux_mon.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_linux_mon.c @@ -1,7 +1,7 @@ /* * Broadcom Dongle Host Driver (DHD), Linux monitor network interface * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_roam.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_roam.c index c6254da16..ac9f9b7c6 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_roam.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wl_roam.c @@ -1,7 +1,7 @@ /* * Linux roam cache * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wlc_types.h b/drivers/net/wireless/broadcom/bcmdhd_101_16/wlc_types.h index dd5a1a359..e35416e67 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wlc_types.h +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wlc_types.h @@ -1,7 +1,7 @@ /* * Forward declarations for commonly used wl driver structs * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/broadcom/bcmdhd_101_16/wldev_common.c b/drivers/net/wireless/broadcom/bcmdhd_101_16/wldev_common.c index 78b986fad..21ed7ce8b 100644 --- a/drivers/net/wireless/broadcom/bcmdhd_101_16/wldev_common.c +++ b/drivers/net/wireless/broadcom/bcmdhd_101_16/wldev_common.c @@ -1,7 +1,7 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * Copyright (C) 2020, Broadcom. + * Copyright (C) 2021, Broadcom. * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 4dbfdcf4f..c18ba6711 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "main.h" #include "bus.h" @@ -1809,6 +1810,7 @@ static int cnss_qca6290_powerup(struct cnss_pci_data *pci_priv) struct cnss_plat_data *plat_priv = pci_priv->plat_priv; unsigned int timeout; int retry = 0; + int bt_en_gpio = plat_priv->pinctrl_info.bt_en_gpio; if (plat_priv->ramdump_info_v2.dump_data_valid) { cnss_pci_clear_dump_info(pci_priv); @@ -1834,6 +1836,10 @@ static int cnss_qca6290_powerup(struct cnss_pci_data *pci_priv) if (ret == -EAGAIN && retry++ < POWER_ON_RETRY_MAX_TIMES) { cnss_power_off_device(plat_priv); cnss_pr_dbg("Retry to resume PCI link #%d\n", retry); + + /* Force toggle BT_EN GPIO low */ + cnss_pr_err("Set bt_en_gpio(%u) low \n",bt_en_gpio); + gpio_set_value(bt_en_gpio, false); msleep(POWER_ON_RETRY_DELAY_MS * retry); goto retry; } diff --git a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c index b46982033..d0dd5cf28 100644 --- a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c +++ b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c @@ -868,7 +868,7 @@ ol_rx_frag_tkip_demic(ol_txrx_pdev_handle pdev, const uint8_t *key, ol_rx_defrag_copydata(msdu, pktlen - f_tkip.ic_miclen + rx_desc_len, f_tkip.ic_miclen, (caddr_t) mic0); - if (!qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen)) + if (qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen)) return OL_RX_DEFRAG_ERR; qdf_nbuf_trim_tail(msdu, f_tkip.ic_miclen); diff --git a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c index 3f62f2b73..e494c8d00 100644 --- a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c +++ b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c @@ -818,6 +818,7 @@ dp_rx_fisa_flush_udp_flow(struct dp_vdev *vdev, } qdf_nbuf_set_next(fisa_flow->head_skb, NULL); + QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(fisa_flow->head_skb) = 1; if (fisa_flow->last_skb) qdf_nbuf_set_next(fisa_flow->last_skb, NULL); @@ -1230,6 +1231,7 @@ QDF_STATUS dp_fisa_rx(struct dp_soc *soc, struct dp_vdev *vdev, head_nbuf); deliver_nbuf: /* Deliver without FISA */ + QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(head_nbuf) = 1; qdf_nbuf_set_next(head_nbuf, NULL); hex_dump_skb_data(head_nbuf, false); if (!vdev->osif_rx || QDF_STATUS_SUCCESS != diff --git a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c index 7788791ea..6bffa2f9a 100644 --- a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c +++ b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c @@ -154,6 +154,7 @@ QDF_STATUS dp_check_and_update_pending(struct dp_rx_tm_handle_cmn uint32_t rx_pending_lo_threshold; uint32_t nbuf_queued_total = 0; uint32_t nbuf_dequeued_total = 0; + uint32_t rx_flushed_total = 0; uint32_t pending = 0; int i; @@ -184,11 +185,14 @@ QDF_STATUS dp_check_and_update_pending(struct dp_rx_tm_handle_cmn rx_tm_hdl->rx_thread[i]->stats.nbuf_queued_total; nbuf_dequeued_total += rx_tm_hdl->rx_thread[i]->stats.nbuf_dequeued; + rx_flushed_total += + rx_tm_hdl->rx_thread[i]->stats.rx_flushed; } } - if (nbuf_queued_total > nbuf_dequeued_total) - pending = nbuf_queued_total - nbuf_dequeued_total; + if (nbuf_queued_total > (nbuf_dequeued_total + rx_flushed_total)) + pending = nbuf_queued_total - (nbuf_dequeued_total + + rx_flushed_total); if (unlikely(pending > rx_pending_hl_threshold)) qdf_atomic_set(&rx_tm_hdl->allow_dropping, 1); diff --git a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c index 742f1c87e..469f6d94f 100644 --- a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c +++ b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c @@ -16308,7 +16308,10 @@ QDF_STATUS wlan_hdd_update_wiphy_supported_band(struct hdd_context *hdd_ctx) cfg->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY) wlan_hdd_band_5_ghz.vht_cap.vht_supported = 0; - hdd_init_6ghz(hdd_ctx); + if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO || + cfg->dot11Mode == eHDD_DOT11_MODE_11ax || + cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) + hdd_init_6ghz(hdd_ctx); return QDF_STATUS_SUCCESS; } diff --git a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_main.c b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_main.c index f4b20382e..86d2a572a 100644 --- a/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_main.c +++ b/drivers/net/wireless/qualcomm/qca6390/qcacld-3.0/core/hdd/src/wlan_hdd_main.c @@ -2218,6 +2218,29 @@ static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) ucfg_mlme_cfg_chan_to_freq(pdev); } +static uint32_t hdd_update_band_cap_from_dot11mode( + struct hdd_context *hdd_ctx, uint32_t band_capability) +{ + if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO) + return band_capability; + + if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY) + band_capability = (band_capability & (~BIT(REG_BAND_5G))); + + if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a) + band_capability = (band_capability & (~BIT(REG_BAND_2G))); + + if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY && + hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax) + band_capability = (band_capability & (~BIT(REG_BAND_6G))); + + qdf_debug("Update band capability %x", band_capability); + return band_capability; +} + int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) { int ret; @@ -2303,6 +2326,9 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) goto pdev_close; } + band_capability = + hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); + /* first store the INI band capability */ temp_band_cap = band_capability; diff --git a/drivers/nfc/pn547.c b/drivers/nfc/pn547.c index d8812a9fa..3ff2bb3f7 100644 --- a/drivers/nfc/pn547.c +++ b/drivers/nfc/pn547.c @@ -218,15 +218,65 @@ static irqreturn_t pn547_dev_clk_req_irq_handler(int irq, void *dev_id) } #endif +#ifdef FEATURE_CORE_RESET_NTF_CHECK +static void pn547_check_core_reset(char *buf, int len) +{ + static int is_error_ntf = STATE_NORMAL; + + if (is_error_ntf == STATE_CORE_RESET && len == 6) { + u64 ntf_hex = *(u64 *)buf & 0xFFFFFFFFFFFFULL; + + switch (ntf_hex) { + case CORE_RESET_NTF_NO_CLOCK: + NFC_LOG_ERR("CORE_RESET_NTF: No clock\n"); + break; + case CORE_RESET_NTF_CLOCK_LOST: + NFC_LOG_ERR("CORE_RESET_NTF: clock lost\n"); + break; + default: + NFC_LOG_INFO("CORE_RESET_NTF: %02X%02X%02X%02X%02X%02X\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + } + } else if (is_error_ntf == STATE_CORE_RESET && len == 9) { + static int power_reset_count; + + if (buf[0] == 0x01 && buf[1] == 0x02 && buf[2] == 0x20 && + buf[3] == 0x04 && buf[4] == 0x04 && buf[5] == 0x00 && + buf[6] == 0x00 && buf[7] == 0x00 && buf[8] == 0x01) { + power_reset_count++; + NFC_LOG_ERR("CORE_RESET_NTF: POWER_RESET %d\n", power_reset_count); + /* + if (power_reset_count > 1) + panic("NFC power reset"); + */ + } else { + NFC_LOG_INFO("CORE_RESET_NTF: %02X%02X%02X%02X%02X%02X%02X%02X%02X\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + buf[6], buf[7], buf[8]); + } + } else if (is_error_ntf == STATE_ABNORMAL_POWER && len == 8) { + NFC_LOG_INFO("ABNORMAL_POWER(DPD): %02X%02X%02X%02X %02X%02X%02X%02X\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + } + + /* check CORE_RESET_NTF */ + if (len == 3 && buf[0] == 0x60 && buf[1] == 0x00 && buf[2] == 0x06) + is_error_ntf = STATE_CORE_RESET; + else if (len == 3 && buf[0] == 0x60 && buf[1] == 0x00 && buf[2] == 0x09) + is_error_ntf = STATE_CORE_RESET; + else if (len == 3 && buf[0] == 0x6F && buf[1] == 0x2E && buf[2] == 0x08) + is_error_ntf = STATE_ABNORMAL_POWER; + else + is_error_ntf = STATE_NORMAL; +} +#endif + ssize_t pn547_dev_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) { struct pn547_dev *pn547_dev = filp->private_data; int ret = 0; char *r_buf = pn547_dev->r_buf; -#ifdef FEATURE_CORE_RESET_NTF_CHECK - static int is_error_ntf = STATE_NORMAL; -#endif if (count > MAX_BUFFER_SIZE) count = MAX_BUFFER_SIZE; @@ -332,32 +382,7 @@ ssize_t pn547_dev_read(struct file *filp, char __user *buf, } #ifdef FEATURE_CORE_RESET_NTF_CHECK - if (is_error_ntf == STATE_CORE_RESET && ret == 6) { - u64 ntf_hex = *(u64 *)r_buf & 0xFFFFFFFFFFFFULL; - - switch (ntf_hex) { - case CORE_RESET_NTF_NO_CLOCK: - NFC_LOG_ERR("CORE_RESET_NTF: No clock\n"); - break; - case CORE_RESET_NTF_CLOCK_LOST: - NFC_LOG_ERR("CORE_RESET_NTF: clock lost\n"); - break; - default: - NFC_LOG_INFO("CORE_RESET_NTF: %02X%02X%02X%02X%02X%02X\n", - r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5]); - } - } else if (is_error_ntf == STATE_ABNORMAL_POWER && ret == 8) { - NFC_LOG_INFO("ABNORMAL_POWER(DPD): %02X%02X%02X%02X %02X%02X%02X%02X\n", - r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]); - } - - /* check CORE_RESET_NTF */ - if (ret == 3 && r_buf[0] == 0x60 && r_buf[1] == 0x00 && r_buf[2] == 0x06) - is_error_ntf = STATE_CORE_RESET; - else if (ret == 3 && r_buf[0] == 0x6F && r_buf[1] == 0x2E && r_buf[2] == 0x08) - is_error_ntf = STATE_ABNORMAL_POWER; - else - is_error_ntf = STATE_NORMAL; + pn547_check_core_reset(r_buf, ret); #endif if (copy_to_user(buf, r_buf, ret)) { diff --git a/drivers/optics/tcs3407.c b/drivers/optics/tcs3407.c index dbff1922a..65ecf42e5 100755 --- a/drivers/optics/tcs3407.c +++ b/drivers/optics/tcs3407.c @@ -1599,8 +1599,13 @@ static int tcs3407_power_ctrl(struct tcs3407_device_data *data, int onoff) } } +#if defined(CONFIG_SEC_R8Q_PROJECT) + regulator_vdd_1p8 = + regulator_get(&data->client->dev, "vdd_1p8"); +#else regulator_vdd_1p8 = regulator_get(&data->client->dev, data->vdd_1p8); +#endif if (IS_ERR(regulator_vdd_1p8) || regulator_vdd_1p8 == NULL) { ALS_dbg("%s - get vdd_1p8 regulator failed\n", __func__); rc = PTR_ERR(regulator_vdd_1p8); @@ -3102,9 +3107,11 @@ static int tcs3407_parse_dt(struct tcs3407_device_data *data) } #endif +#if !defined(CONFIG_SEC_R8Q_PROJECT) if (of_property_read_string(dNode, "als_rear,vdd_1p8", (char const **)&data->vdd_1p8) < 0) ALS_dbg("%s - vdd_1p8 doesn`t exist\n", __func__); +#endif if (of_property_read_string(dNode, "als_rear,i2c_1p8", (char const **)&data->i2c_1p8) < 0) diff --git a/drivers/perf_mgr/perf_mgr.c b/drivers/perf_mgr/perf_mgr.c index 19d8733ce..41d139bb4 100644 --- a/drivers/perf_mgr/perf_mgr.c +++ b/drivers/perf_mgr/perf_mgr.c @@ -190,16 +190,19 @@ static long perf_mgr_ioctl(struct file *file, unsigned int cmd, unsigned long ar *we initialize boosting information of the task. */ + tmp_task = find_task_by_vpid(ofi.tid); + + if (tmp_task == NULL || + tmp_task->drawing_flag != task->drawing_flag) + continue; + if (++(fi->last_update_frame) > hold_frame_count) { fi->last_update_frame = 0; fi->updated_fps_util = 0; - task->drawing_mig_boost = 0; + tmp_task->drawing_mig_boost = 0; } - tmp_task = find_task_by_vpid(ofi.tid); - if (tmp_task != NULL && - tmp_task->drawing_flag == task->drawing_flag) - rn_sum += get_task_util(tmp_task); + rn_sum += get_task_util(tmp_task); } rcu_read_unlock(); diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 300c0d1b2..84a3d8f49 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -1,4 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 +ccflags-y := $(KBUILD_SEP_VERSION) + obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o obj-$(CONFIG_POWER_RESET_AT91_POWEROFF) += at91-poweroff.o obj-$(CONFIG_POWER_RESET_AT91_RESET) += at91-reset.o diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index 40a766f78..b56105082 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -493,6 +493,7 @@ static void halt_spmi_pmic_arbiter(void) static void msm_restart_prepare(const char *cmd) { bool need_warm_reset = false; + #ifndef CONFIG_SEC_DEBUG /* Write download mode flags if we're panic'ing * Write download mode flags if restart_mode says so @@ -534,6 +535,10 @@ static void msm_restart_prepare(const char *cmd) qpnp_pon_set_restart_reason( PON_RESTART_REASON_BOOTLOADER); __raw_writel(0x77665500, restart_reason); + } else if (!strncmp(cmd, "recovery-update", 15)) { + qpnp_pon_set_restart_reason( + PON_RESTART_REASON_RECOVERY_UPDATE); + __raw_writel(0x776655cc, restart_reason); } else if (!strncmp(cmd, "recovery", 8)) { qpnp_pon_set_restart_reason( PON_RESTART_REASON_RECOVERY); diff --git a/drivers/samsung/Kconfig b/drivers/samsung/Kconfig index 3761f2b96..b01251d7c 100644 --- a/drivers/samsung/Kconfig +++ b/drivers/samsung/Kconfig @@ -68,8 +68,10 @@ config SEC_FACTORY default n select SEC_DEBUG_FORCE_ERROR select SEC_PANIC_PCIE_ERR + select SEC_PCIE_KEEP_LINKBW select SEC_GPIO_DVS select EDAC_KRYO_ARM64_PANIC_ON_CE + select CNSS2_DEBUG help It will support a sec factory mode endmenu @@ -80,7 +82,7 @@ source "drivers/samsung/quest/Kconfig" config SEC_CLASS_TEST bool "KUnit test for sec_class_test" - depends on KUNIT + depends on SEC_KUNIT help TODO: Describe config fully. diff --git a/drivers/samsung/debug/Kconfig b/drivers/samsung/debug/Kconfig index 4898b7d81..a7e4a4878 100644 --- a/drivers/samsung/debug/Kconfig +++ b/drivers/samsung/debug/Kconfig @@ -59,6 +59,13 @@ config SEC_LOG_STORE_LPM_KMSG help store sec log when LPM Mode boot +config SEC_STORE_POWER_ONOFF_HISTORY + bool "store power onoff history" + default n + depends on SEC_LOG_LAST_KMSG + help + store power onoff history + config SEC_DEBUG_SCHED_LOG bool "Samsung Scheduler Logging Feature" default n @@ -68,6 +75,20 @@ config SEC_DEBUG_SCHED_LOG Enables IRQ scheduling history. This feature is enabled in defconfig. +config SEC_DEBUG_SCHED_LOG_PER_CPU + bool "Samsung Scheduler Logging using per_cpu" + default n + depends on SEC_DEBUG_SCHED_LOG + help + Samsung Scheduler Logging using per_cpu Feature for Debug use. + +config SEC_DEBUG_SCHED_LOG_IRQ_V2 + bool "Samsung Scheduler IRQ Logging V2" + default n + depends on SEC_DEBUG_SCHED_LOG + help + Samsung Scheduler IRQ Logging V2. + config SEC_DEBUG_MSG_LOG bool "Message Log for ram dump debug (DEPRECATED)" default n @@ -279,7 +300,7 @@ config SEC_QPNP_PON_SPARE_BITS config SEC_DEBUG_TEST bool "KUnit test for sec_debug_test" - depends on KUNIT + depends on SEC_KUNIT help TODO: Describe config fully. diff --git a/drivers/samsung/debug/sec_debug.c b/drivers/samsung/debug/sec_debug.c index a738f8550..defb7d431 100644 --- a/drivers/samsung/debug/sec_debug.c +++ b/drivers/samsung/debug/sec_debug.c @@ -58,6 +58,11 @@ static inline void outer_flush_all(void) { } #endif +#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP +unsigned long sec_delay_check __read_mostly = 1; +EXPORT_SYMBOL(sec_delay_check); +#endif + /* enable sec_debug feature */ static unsigned int sec_dbg_level; static int force_upload; @@ -387,9 +392,6 @@ void sec_debug_update_restart_reason(const char *cmd, const int in_panic, { "from_fastboot", PON_RESTART_REASON_NORMALBOOT, RESTART_REASON_NOT_HANDLE, NULL}, - { "disallow,fastboot", - PON_RESTART_REASON_NORMALBOOT, - RESTART_REASON_NOT_HANDLE, NULL}, #ifdef CONFIG_MUIC_SUPPORT_RUSTPROOF { "swsel", PON_RESTART_REASON_UNKNOWN, @@ -621,6 +623,8 @@ struct __upload_cause upload_cause_st[] = { { "qdaf_fail", UPLOAD_CAUSE_QUEST_QDAF_FAIL, SEC_STRNCMP }, { "zip_unzip_test", UPLOAD_CAUSE_QUEST_ZIP_UNZIP, SEC_STRNCMP }, { "quest_fail", UPLOAD_CAUSE_QUEST_FAIL, SEC_STRNCMP }, + { "aoss_thermal_diff", UPLOAD_CAUSE_QUEST_AOSSTHERMALDIFF, SEC_STRNCMP }, + { "stressapptest_test", UPLOAD_CAUSE_QUEST_STRESSAPPTEST, SEC_STRNCMP }, #endif }; @@ -785,15 +789,17 @@ static int __init __sec_debug_dt_addr_init(void) return -ENODEV; } - watchdog_base = of_iomap(np, 0); - if (unlikely(!watchdog_base)) { - pr_err("unable to map watchdog_base offset\n"); - return -ENODEV; - } + if (of_device_is_available(np)) { + watchdog_base = of_iomap(np, 0); + if (unlikely(!watchdog_base)) { + pr_err("unable to map watchdog_base offset\n"); + return -ENODEV; + } - /* check upload_cause here */ - pr_emerg("watchdog_base addr : 0x%p(0x%llx)\n", watchdog_base, - (unsigned long long)virt_to_phys(watchdog_base)); + /* check upload_cause here */ + pr_emerg("watchdog_base addr : 0x%p(0x%llx)\n", watchdog_base, + (unsigned long long)virt_to_phys(watchdog_base)); + } #endif return 0; @@ -838,7 +844,7 @@ static int __init sec_debug_init(void) case ANDROID_DEBUG_LEVEL_MID: #endif -#if 0 /* FIXME: */ +#if defined(CONFIG_SEC_A52Q_PROJECT) || defined(CONFIG_SEC_A72Q_PROJECT) if (!force_upload) qcom_scm_disable_sdi(); #endif diff --git a/drivers/samsung/debug/sec_debug_internal.h b/drivers/samsung/debug/sec_debug_internal.h index 6a9793db2..0d41f13c7 100644 --- a/drivers/samsung/debug/sec_debug_internal.h +++ b/drivers/samsung/debug/sec_debug_internal.h @@ -18,7 +18,11 @@ extern enum sec_debug_upload_cause_t sec_debug_get_upload_cause(void); /* <> sec_debug_sched_log.c */ +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +extern struct sec_debug_last_pet_ns *secdbg_last_pet_ns; +#else extern struct sec_debug_log *secdbg_log; +#endif extern phys_addr_t secdbg_paddr; extern size_t secdbg_size; /* < #include #include +#include +#include #include @@ -27,7 +29,12 @@ #include "sec_debug_internal.h" +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +DEFINE_PER_CPU(struct sec_debug_log, sec_debug_log_cpu); +struct sec_debug_last_pet_ns *secdbg_last_pet_ns __read_mostly; +#else struct sec_debug_log *secdbg_log __read_mostly; +#endif phys_addr_t secdbg_paddr; size_t secdbg_size; @@ -50,6 +57,20 @@ static int __init sec_dbg_setup(char *str) } __setup("sec_dbg=", sec_dbg_setup); +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +/* save last_pet and last_ns with these nice functions */ +void sec_debug_save_last_pet(unsigned long long last_pet) +{ + if (likely(secdbg_last_pet_ns)) + secdbg_last_pet_ns->last_pet = last_pet; +} + +void notrace sec_debug_save_last_ns(unsigned long long last_ns) +{ + if (likely(secdbg_last_pet_ns)) + atomic64_set(&(secdbg_last_pet_ns->last_ns), last_ns); +} +#else /* save last_pet and last_ns with these nice functions */ void sec_debug_save_last_pet(unsigned long long last_pet) { @@ -62,6 +83,7 @@ void notrace sec_debug_save_last_ns(unsigned long long last_ns) if (likely(secdbg_log)) atomic64_set(&(secdbg_log->last_ns), last_ns); } +#endif static inline long get_switch_state(bool preempt, struct task_struct *p) { @@ -74,11 +96,22 @@ void sec_debug_task_sched_log(int cpu, bool preempt, struct sched_buf *sched_buf; int i; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu); + + if (unlikely(!sec_dbg_log)) + return; + + i = ++(sec_dbg_log->sched.idx) & (SCHED_LOG_MAX - 1); + sched_buf = &sec_dbg_log->sched.buf[i]; +#else if (unlikely(!secdbg_log)) return; i = ++(secdbg_log->sched[cpu].idx) & (SCHED_LOG_MAX - 1); sched_buf = &secdbg_log->sched[cpu].buf[i]; +#endif sched_buf->time = cpu_clock(cpu); sec_debug_strcpy_task_comm(sched_buf->comm, task->comm); @@ -92,30 +125,89 @@ void sec_debug_task_sched_log(int cpu, bool preempt, sched_buf->prev_prio = prev->prio; } -void sec_debug_irq_sched_log(unsigned int irq, void *fn, +void sec_debug_softirq_sched_log(unsigned int irq, void *fn, char *name, unsigned int en) { struct irq_buf *irq_buf; int cpu = smp_processor_id(); int i; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu); + if (unlikely(!sec_dbg_log)) + return; + + i = ++(sec_dbg_log->irq.idx) & (SCHED_LOG_MAX - 1); + irq_buf = &sec_dbg_log->irq.buf[i]; +#else if (unlikely(!secdbg_log)) return; i = ++(secdbg_log->irq[cpu].idx) & (SCHED_LOG_MAX - 1); irq_buf = &secdbg_log->irq[cpu].buf[i]; +#endif irq_buf->time = cpu_clock(cpu); irq_buf->irq = irq; - irq_buf->fn = (void *)fn; + irq_buf->fn = fn; irq_buf->name = name; + irq_buf->context = &cpu; irq_buf->en = irqs_disabled(); irq_buf->preempt_count = preempt_count(); + irq_buf->pid = current->pid; + irq_buf->entry_exit = en; +} + +void sec_debug_irq_sched_log(unsigned int irq, void *desc_or_fn, + void *action_or_name, unsigned int en) +{ + struct irq_buf *irq_buf; + int cpu = smp_processor_id(); + int i; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_IRQ_V2) + struct irq_desc *desc = (struct irq_desc *)desc_or_fn; + struct irqaction *action = (struct irqaction *)action_or_name; +#endif + +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu); + if (unlikely(!sec_dbg_log)) + return; + + i = ++(sec_dbg_log->irq.idx) & (SCHED_LOG_MAX - 1); + irq_buf = &sec_dbg_log->irq.buf[i]; +#else + if (unlikely(!secdbg_log)) + return; + + i = ++(secdbg_log->irq[cpu].idx) & (SCHED_LOG_MAX - 1); + irq_buf = &secdbg_log->irq[cpu].buf[i]; +#endif + + irq_buf->time = cpu_clock(cpu); + irq_buf->irq = irq; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_IRQ_V2) + irq_buf->fn = action->handler; + irq_buf->name = (char *)action->name; + irq_buf->hwirq = desc->irq_data.hwirq; +#else + irq_buf->fn = (void *)desc_or_fn; + irq_buf->name = (char *)action_or_name; irq_buf->context = &cpu; +#endif + irq_buf->en = irqs_disabled(); + irq_buf->preempt_count = preempt_count(); irq_buf->pid = current->pid; irq_buf->entry_exit = en; } +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +void __deprecated sec_debug_irq_enterexit_log(unsigned int irq, u64 start_time){ return; } +void __deprecated sec_debug_timer_log(unsigned int type, int int_lock, void *fn){ return; } +void __deprecated sec_debug_secure_log(u32 svc_id, u32 cmd_id) { return; } +#else void __deprecated sec_debug_irq_enterexit_log(unsigned int irq, u64 start_time) { struct irq_exit_buf *irq_exit_buf; @@ -178,7 +270,7 @@ void __deprecated sec_debug_secure_log(u32 svc_id, u32 cmd_id) spin_unlock_irqrestore(&secdbg_securelock, flags); } - +#endif int sec_debug_sched_msg(char *fmt, ...) { int cpu = raw_smp_processor_id(); @@ -187,11 +279,21 @@ int sec_debug_sched_msg(char *fmt, ...) int i; va_list args; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu); + if (unlikely(!sec_dbg_log)) + return 0; + + i = ++(sec_dbg_log->sched.idx) & (SCHED_LOG_MAX - 1); + sched_buf = &sec_dbg_log->sched.buf[i]; +#else if (unlikely(!secdbg_log)) return 0; i = ++(secdbg_log->sched[cpu].idx) & (SCHED_LOG_MAX - 1); sched_buf = &secdbg_log->sched[cpu].buf[i]; +#endif va_start(args, fmt); if (fmt) { @@ -217,11 +319,21 @@ int ___sec_debug_msg_log(void *caller, const char *fmt, ...) int i; va_list args; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu); + if (unlikely(!sec_dbg_log)) + return 0; + + i = ++(sec_dbg_log->secmsg.idx) & (MSG_LOG_MAX - 1); + secmsg_buf = &sec_dbg_log->secmsg.buf[i]; +#else if (unlikely(!secdbg_log)) return 0; i = ++(secdbg_log->secmsg[cpu].idx) & (MSG_LOG_MAX - 1); secmsg_buf = &secdbg_log->secmsg[cpu].buf[i]; +#endif secmsg_buf->time = cpu_clock(cpu); va_start(args, fmt); @@ -237,6 +349,9 @@ int ___sec_debug_msg_log(void *caller, const char *fmt, ...) #endif /* CONFIG_SEC_DEBUG_MSG_LOG */ #ifdef CONFIG_SEC_DEBUG_AVC_LOG +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +int __deprecated sec_debug_avc_log(const char *fmt, ...) { return 0; } +#else int __deprecated sec_debug_avc_log(const char *fmt, ...) { struct secavc_buf *secavc_buf; @@ -257,9 +372,17 @@ int __deprecated sec_debug_avc_log(const char *fmt, ...) return r; } +#endif #endif /* CONFIG_SEC_DEBUG_AVC_LOG */ #ifdef CONFIG_SEC_DEBUG_DCVS_LOG +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +void __deprecated sec_debug_dcvs_log(int cpu_no, unsigned int prev_freq, + unsigned int new_freq) +{ + return; +} +#else void __deprecated sec_debug_dcvs_log(int cpu_no, unsigned int prev_freq, unsigned int new_freq) { @@ -278,8 +401,16 @@ void __deprecated sec_debug_dcvs_log(int cpu_no, unsigned int prev_freq, dcvs_buf->time = cpu_clock(cpu_no); } #endif +#endif #ifdef CONFIG_SEC_DEBUG_FUELGAUGE_LOG +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +void __deprecated sec_debug_fuelgauge_log(unsigned int voltage, + unsigned short soc, unsigned short charging_status) +{ + return; +} +#else void __deprecated sec_debug_fuelgauge_log(unsigned int voltage, unsigned short soc, unsigned short charging_status) { @@ -299,6 +430,7 @@ void __deprecated sec_debug_fuelgauge_log(unsigned int voltage, fuelgauge_debug->charging_status = charging_status; } #endif +#endif #ifdef CONFIG_SEC_DEBUG_POWER_LOG void sec_debug_cpu_lpm_log(int cpu, unsigned int index, @@ -307,11 +439,21 @@ void sec_debug_cpu_lpm_log(int cpu, unsigned int index, struct power_buf *power_buf; int i; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu); + if (unlikely(!sec_dbg_log)) + return; + + i = ++(sec_dbg_log->pwr.idx) & (POWER_LOG_MAX - 1); + power_buf = &sec_dbg_log->pwr.buf[i]; +#else if (unlikely(!secdbg_log)) return; i = ++(secdbg_log->pwr[cpu].idx) & (POWER_LOG_MAX - 1); power_buf = &secdbg_log->pwr[cpu].buf[i]; +#endif power_buf->time = cpu_clock(cpu); power_buf->pid = current->pid; @@ -330,11 +472,21 @@ void sec_debug_cluster_lpm_log(const char *name, int index, int i; int cpu = smp_processor_id(); +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu); + if (unlikely(!sec_dbg_log)) + return; + + i = ++(sec_dbg_log->pwr.idx) & (POWER_LOG_MAX - 1); + power_log = &sec_dbg_log->pwr.buf[i]; +#else if (unlikely(!secdbg_log)) return; i = ++(secdbg_log->pwr[cpu].idx) & (POWER_LOG_MAX - 1); power_log = &secdbg_log->pwr[cpu].buf[i]; +#endif power_buf->time = cpu_clock(cpu); power_buf->pid = current->pid; @@ -354,11 +506,21 @@ void sec_debug_clock_log(const char *name, struct power_log *power_log; int i; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + struct sec_debug_log *sec_dbg_log; + sec_dbg_log = &per_cpu(sec_debug_log_cpu, cpu_id); + if (unlikely(!sec_dbg_log)) + return; + + i = ++(sec_dbg_log->pwr.log) & (POWER_LOG_MAX - 1); + power_log = &sec_dbg_log->pwr.buf[i]; +#else if (unlikely(!secdbg_log)) return; i = ++(secdbg_log->pwr[cpu_id].log) & (POWER_LOG_MAX - 1); power_log = &secdbg_log->pwr[cpu_id].buf[i]; +#endif power_buf->time = cpu_clock(cpu_id); power_buf->pid = current->pid; @@ -371,6 +533,56 @@ void sec_debug_clock_log(const char *name, } #endif /* CONFIG_SEC_DEBUG_POWER_LOG */ +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +static int __init sec_debug_sched_log_init(void) +{ + size_t i; + struct sec_debug_last_pet_ns *vaddr; + struct sec_debug_log *sec_dbg_log; + size_t size; + + if (secdbg_paddr == 0 || secdbg_size == 0) { + pr_info("sec debug buffer not provided. Using kmalloc..\n"); + size = sizeof(struct sec_debug_last_pet_ns); + vaddr = kzalloc(size, GFP_KERNEL); + } else { + size = secdbg_size; + if (sec_debug_is_enabled()) + vaddr = ioremap_wc(secdbg_paddr, secdbg_size); + else + vaddr = ioremap_cache(secdbg_paddr, secdbg_size); + } + + pr_info("vaddr=0x%p paddr=%pa size=0x%zx sizeof(struct sec_debug_last_pet_ns)=0x%zx\n", + vaddr, &secdbg_paddr, + secdbg_size, sizeof(struct sec_debug_last_pet_ns)); + + if ((!vaddr) || (sizeof(struct sec_debug_last_pet_ns) > size)) { + pr_err("ERROR! init failed!\n"); + return -EFAULT; + } + + for (i = 0; i < num_possible_cpus(); i++) { + sec_dbg_log = &per_cpu(sec_debug_log_cpu, i); + sec_dbg_log->sched.idx = UINT_MAX; + sec_dbg_log->irq.idx = UINT_MAX; + +#ifdef CONFIG_SEC_DEBUG_MSG_LOG + sec_dbg_log->secmsg.idx = UINT_MAX; +#endif + +#ifdef CONFIG_SEC_DEBUG_POWER_LOG + sec_dbg_log->pwr.idx = UINT_MAX; +#endif + } + + secdbg_last_pet_ns = vaddr; + + pr_info("init done\n"); + + return 0; +} +#else static int __init sec_debug_sched_log_init(void) { size_t i; @@ -455,4 +667,5 @@ static int __init sec_debug_sched_log_init(void) return 0; } +#endif arch_initcall_sync(sec_debug_sched_log_init); diff --git a/drivers/samsung/debug/sec_debug_summary.c b/drivers/samsung/debug/sec_debug_summary.c index ea77d70e0..25471579a 100644 --- a/drivers/samsung/debug/sec_debug_summary.c +++ b/drivers/samsung/debug/sec_debug_summary.c @@ -107,23 +107,17 @@ static inline void __summary_save_dying_msg_for_user_reset_debug( #define ARCH_INSTR_SIZE 0x4 #endif -#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP -unsigned long sec_delay_check __read_mostly = 1; -EXPORT_SYMBOL(sec_delay_check); -#endif - int sec_debug_summary_save_die_info(const char *str, struct pt_regs *regs) { #ifndef CONFIG_SAMSUNG_PRODUCT_SHIP sec_delay_check = 0; #endif - if (!secdbg_apss) - return -ENOMEM; - - snprintf(secdbg_apss->excp.pc_sym, sizeof(secdbg_apss->excp.pc_sym), - "%pS", (void *)regs->PT_REGS_PC); - snprintf(secdbg_apss->excp.lr_sym, sizeof(secdbg_apss->excp.lr_sym), - "%pS", (void *)regs->PT_REGS_LR); + if (secdbg_apss) { + snprintf(secdbg_apss->excp.pc_sym, sizeof(secdbg_apss->excp.pc_sym), + "%pS", (void *)regs->PT_REGS_PC); + snprintf(secdbg_apss->excp.lr_sym, sizeof(secdbg_apss->excp.lr_sym), + "%pS", (void *)regs->PT_REGS_LR); + } __summary_save_dying_msg_for_user_reset_debug(str, (void *)regs->PT_REGS_PC, (void *)regs->PT_REGS_LR); @@ -136,16 +130,15 @@ int sec_debug_summary_save_panic_info(const char *str, unsigned long caller) #ifndef CONFIG_SAMSUNG_PRODUCT_SHIP sec_delay_check = 0; #endif - if (!secdbg_apss) - return -ENOMEM; - - snprintf(secdbg_apss->excp.panic_caller, - sizeof(secdbg_apss->excp.panic_caller), "%pS", (void *)caller); - snprintf(secdbg_apss->excp.panic_msg, - sizeof(secdbg_apss->excp.panic_msg), "%s", str); - snprintf(secdbg_apss->excp.thread, - sizeof(secdbg_apss->excp.thread), "%s:%d", current->comm, - task_pid_nr(current)); + if (secdbg_apss) { + snprintf(secdbg_apss->excp.panic_caller, + sizeof(secdbg_apss->excp.panic_caller), "%pS", (void *)(caller - ARCH_INSTR_SIZE)); + snprintf(secdbg_apss->excp.panic_msg, + sizeof(secdbg_apss->excp.panic_msg), "%s", str); + snprintf(secdbg_apss->excp.thread, + sizeof(secdbg_apss->excp.thread), "%s:%d", current->comm, + task_pid_nr(current)); + } __summary_save_dying_msg_for_user_reset_debug(str, (void *)(caller - ARCH_INSTR_SIZE), (void *)caller); @@ -329,8 +322,13 @@ static void __init summary_init_infomon(void) summary_add_info_mon("Hardware name", -1, __pa(sec_debug_arch_desc)); } +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +#define phys_addr_of_secdbg_last_pet_ns_paddr(__member) \ + (secdbg_paddr + offsetof(struct sec_debug_last_pet_ns, __member)) +#else #define phys_addr_of_secdbg_paddr(__member) \ (secdbg_paddr + offsetof(struct sec_debug_log, __member)) +#endif #ifdef CONFIG_SEC_DEBUG_VERBOSE_SUMMARY_HTML static void __init __summary_init_varmon_verbose(void) @@ -352,6 +350,20 @@ static void __init summary_init_varmon(void) uint64_t last_pet_paddr; uint64_t last_ns_paddr; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + /* save paddrs of last_pet und last_ns */ + if (secdbg_paddr && secdbg_last_pet_ns) { + last_pet_paddr = phys_addr_of_secdbg_last_pet_ns_paddr(last_pet); + summary_add_var_mon("last_pet", + sizeof((secdbg_last_pet_ns->last_pet)), last_pet_paddr); + + last_ns_paddr = phys_addr_of_secdbg_last_pet_ns_paddr(last_ns); + summary_add_var_mon("last_ns", + sizeof((secdbg_last_pet_ns->last_ns.counter)), + last_ns_paddr); + } else + pr_emerg("**** secdbg_last_pet_ns or secdbg_paddr is not initialized ****\n"); +#else /* save paddrs of last_pet und last_ns */ if (secdbg_paddr && secdbg_log) { last_pet_paddr = phys_addr_of_secdbg_paddr(last_pet); @@ -364,6 +376,7 @@ static void __init summary_init_varmon(void) last_ns_paddr); } else pr_emerg("**** secdbg_log or secdbg_paddr is not initialized ****\n"); +#endif #if defined(CONFIG_ARM) || defined(CONFIG_ARM64) #if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) @@ -375,10 +388,36 @@ static void __init summary_init_varmon(void) __summary_init_varmon_verbose(); } +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +DECLARE_PER_CPU(struct sec_debug_log, sec_debug_log_cpu); +#endif + static void __init summary_init_sched_log(void) { struct sec_debug_summary_sched_log *sched_log = &(secdbg_apss->sched_log); +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) + sched_log->sched_idx_vaddr = (uint64_t)&sec_debug_log_cpu + offsetof(struct sec_debug_log, sched); + sched_log->sched_buf_vaddr = (uint64_t)&sec_debug_log_cpu + offsetof(struct sec_debug_log, sched) + offsetof(struct sched_log, buf); + sched_log->sched_struct_buf_sz = sizeof(struct sched_buf); + sched_log->sched_struct_log_sz = sizeof(struct sched_log); + sched_log->sched_array_cnt = SCHED_LOG_MAX; + + sched_log->irq_idx_vaddr = (uint64_t)&sec_debug_log_cpu + offsetof(struct sec_debug_log, irq); + sched_log->irq_buf_vaddr = (uint64_t)&sec_debug_log_cpu + offsetof(struct sec_debug_log, irq) + offsetof(struct irq_log, buf); + sched_log->irq_struct_buf_sz = sizeof(struct irq_buf); + sched_log->irq_struct_log_sz = sizeof(struct irq_log); + sched_log->irq_array_cnt = SCHED_LOG_MAX; + +#ifdef CONFIG_SEC_DEBUG_MSG_LOG + sched_log->msglog_idx_vaddr = (uint64_t)&sec_debug_log_cpu + offsetof(struct sec_debug_log, secmsg); + sched_log->msglog_buf_vaddr = (uint64_t)&sec_debug_log_cpu + offsetof(struct sec_debug_log, secmsg) + offsetof(struct secmsg_log, buf); + sched_log->msglog_struct_buf_sz = sizeof(struct secmsg_buf); + sched_log->msglog_struct_log_sz = sizeof(struct secmsg_log); + sched_log->msglog_array_cnt = MSG_LOG_MAX; +#endif + +#else sched_log->sched_idx_paddr = phys_addr_of_secdbg_paddr(sched[0].idx); sched_log->sched_buf_paddr = phys_addr_of_secdbg_paddr(sched[0].buf); sched_log->sched_struct_buf_sz = sizeof(struct sched_buf); @@ -410,6 +449,8 @@ static void __init summary_init_sched_log(void) sched_log->msglog_struct_log_sz = sizeof(struct secmsg_log); sched_log->msglog_array_cnt = MSG_LOG_MAX; #endif + +#endif } #ifdef CONFIG_QCOM_MEMORY_DUMP_V2 @@ -804,4 +845,4 @@ static int __init sec_debug_summary_init(void) return _sec_debug_summary_init(); } subsys_initcall_sync(sec_debug_summary_init); -#endif \ No newline at end of file +#endif diff --git a/drivers/samsung/debug/sec_hw_param.c b/drivers/samsung/debug/sec_hw_param.c index 860c05c56..9061f55fd 100644 --- a/drivers/samsung/debug/sec_hw_param.c +++ b/drivers/samsung/debug/sec_hw_param.c @@ -1123,55 +1123,100 @@ static ssize_t show_extrt_info(struct device *dev, if (tz_diag_info->magic_num != TZ_DIAG_LOG_MAGIC) { special_scnprintf(buf, offset, "\"ERR\":\"tzlog magic num error\""); + goto out; + } + + if (tz_diag_info->version > TZBSP_DIAG_VERSION_V9_2) { + struct tzbsp_encr_info_t *encr_info = (struct tzbsp_encr_info_t *)((void *)tz_diag_info + + tz_diag_info->v9_3.encr_info_for_log_off); + + if (encr_info->chunks[1].size_to_encr > 0x200) { /* 512 byte */ + special_scnprintf(buf, offset, + "\"ERR\":\"tzlog size over\""); + goto out; + } + + special_scnprintf(buf, offset, "\"TZDA\":\""); + special_scnprintf(buf, offset, "%08X%08X", + cpu_to_be32(tz_diag_info->magic_num), + cpu_to_be32(tz_diag_info->version)); + special_scnprintf(buf, offset, "%08X%08X%08X%08X", + cpu_to_be32(tz_diag_info->ring_off), + cpu_to_be32(tz_diag_info->ring_len), + cpu_to_be32(tz_diag_info->v9_3.encr_info_for_log_off), + cpu_to_be32(encr_info->chunks[1].size_to_encr)); + + for (i = 0; i < TZBSP_AES_256_ENCRYPTED_KEY_SIZE; i++) + special_scnprintf(buf, offset, "%02X", encr_info->key[i]); + + for (i = 0; i < TZBSP_NONCE_LEN; i++) + special_scnprintf(buf, offset, "%02X", encr_info->chunks[1].nonce[i]); + + for (i = 0; i < TZBSP_TAG_LEN; i++) + special_scnprintf(buf, offset, "%02X", encr_info->chunks[1].tag[i]); + + log_v9_2 = (struct tzdbg_log_v9_2_t *)((void *)tz_diag_info + + tz_diag_info->ring_off - sizeof(struct tzdbg_log_pos_v9_2_t)); + special_scnprintf(buf, offset, "%08X%08X", + cpu_to_be32(log_v9_2->log_pos.wrap), + cpu_to_be32(log_v9_2->log_pos.offset)); + + for (i = 0; i < encr_info->chunks[1].size_to_encr; i++) + special_scnprintf(buf, offset, "%02X", log_v9_2->log_buf[i]); + + special_scnprintf(buf, offset, "\""); } else { if (tz_diag_info->ring_len > 0x200) { /* 512 byte */ special_scnprintf(buf, offset, "\"ERR\":\"tzlog size over\""); - } else { - special_scnprintf(buf, offset, "\"TZDA\":\""); - special_scnprintf(buf, offset, "%08X%08X%08X", - tz_diag_info->magic_num, - tz_diag_info->version, - tz_diag_info->cpu_count); - special_scnprintf(buf, offset, "%08X%08X%08X", - tz_diag_info->ring_off, - tz_diag_info->ring_len, - tz_diag_info->num_interrupts); - - for (i = 0; i < TZBSP_AES_256_ENCRYPTED_KEY_SIZE; i++) - special_scnprintf(buf, offset, "%02X", - tz_diag_info->key[i]); - - for (i = 0; i < TZBSP_NONCE_LEN; i++) - special_scnprintf(buf, offset, "%02X", - tz_diag_info->nonce[i]); + goto out; + } - for (i = 0; i < TZBSP_TAG_LEN; i++) + special_scnprintf(buf, offset, "\"TZDA\":\""); + special_scnprintf(buf, offset, "%08X%08X", + tz_diag_info->magic_num, + tz_diag_info->version); + special_scnprintf(buf, offset, "%08X%08X%08X%08X", + tz_diag_info->cpu_count, + tz_diag_info->ring_off, + tz_diag_info->ring_len, + tz_diag_info->v9_2.num_interrupts); + + for (i = 0; i < TZBSP_AES_256_ENCRYPTED_KEY_SIZE; i++) + special_scnprintf(buf, offset, "%02X", + tz_diag_info->v9_2.key[i]); + + for (i = 0; i < TZBSP_NONCE_LEN; i++) + special_scnprintf(buf, offset, "%02X", + tz_diag_info->v9_2.nonce[i]); + + for (i = 0; i < TZBSP_TAG_LEN; i++) + special_scnprintf(buf, offset, "%02X", + tz_diag_info->v9_2.tag[i]); + + if (tz_diag_info->version == TZBSP_DIAG_VERSION_V9_2) { + log_v9_2 = (struct tzdbg_log_v9_2_t *)((void *)tz_diag_info + + tz_diag_info->ring_off - sizeof(struct tzdbg_log_pos_v9_2_t)); + + special_scnprintf(buf, offset, "%08X%08X", + log_v9_2->log_pos.wrap, + log_v9_2->log_pos.offset); + + for (i = 0; i < tz_diag_info->ring_len; i++) special_scnprintf(buf, offset, "%02X", - tz_diag_info->tag[i]); - - if (tz_diag_info->version >= TZBSP_DIAG_VERSION_V9_2) { // sm8350 - log_v9_2 = (struct tzdbg_log_v9_2_t *)&tz_diag_info->ring_buffer; - special_scnprintf(buf, offset, "%08X%08X", - log_v9_2->log_pos.wrap, - log_v9_2->log_pos.offset); - - for (i = 0; i < tz_diag_info->ring_len; i++) - special_scnprintf(buf, offset, "%02X", - log_v9_2->log_buf[i]); - - } else { - special_scnprintf(buf, offset, "%04X%04X", - tz_diag_info->ring_buffer.log_pos.wrap, - tz_diag_info->ring_buffer.log_pos.offset); - - for (i = 0; i < tz_diag_info->ring_len; i++) - special_scnprintf(buf, offset, "%02X", - tz_diag_info->ring_buffer.log_buf[i]); - } - - special_scnprintf(buf, offset, "\""); + log_v9_2->log_buf[i]); + } else { + struct tzdbg_log_t *log = (struct tzdbg_log_t *)((void *)tz_diag_info + + tz_diag_info->ring_off - sizeof(struct tzdbg_log_pos_t)); + special_scnprintf(buf, offset, "%04X%04X", + log->log_pos.wrap, + log->log_pos.offset); + + for (i = 0; i < tz_diag_info->ring_len; i++) + special_scnprintf(buf, offset, "%02X", log->log_buf[i]); } + + special_scnprintf(buf, offset, "\""); } out: diff --git a/drivers/samsung/debug/sec_log_buf.c b/drivers/samsung/debug/sec_log_buf.c index 6d0e67384..0153e6bf3 100644 --- a/drivers/samsung/debug/sec_log_buf.c +++ b/drivers/samsung/debug/sec_log_buf.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "sec_debug_internal.h" @@ -50,7 +51,8 @@ unsigned int get_sec_log_idx(void) return (unsigned int)s_log_buf->idx; } -#if IS_ENABLED(CONFIG_SEC_LOG_STORE_LPM_KMSG) +#if IS_ENABLED(CONFIG_SEC_LOG_STORE_LPM_KMSG) || \ + IS_ENABLED(CONFIG_SEC_STORE_POWER_ONOFF_HISTORY) static unsigned int lpm_mode; static int check_lpm_mode(char *str) @@ -228,6 +230,59 @@ static struct notifier_block sec_log_store_lpm_kmsg_notifier = { }; #endif + +#if IS_ENABLED(CONFIG_SEC_STORE_POWER_ONOFF_HISTORY) +static void sec_power_onoff_history_store(time64_t local_time, time64_t rtc_offset, struct rtc_time *tm, + unsigned long action, const char *cmd) +{ + onoff_history_t *onoff_his; + + onoff_his = vmalloc(sizeof(onoff_history_t)); + if (!onoff_his) { + pr_err("fail - vmalloc for onoff_his\n"); + } else { + if (!read_debug_partition(debug_index_onoff_history, onoff_his)) { + pr_err("fail - get onoff history data\n"); + } else { + if (onoff_his->magic != SEC_LOG_MAGIC || + onoff_his->size != sizeof(onoff_history_t)) { + pr_err("invalid magic & size (0x%08x, %d, %ld)\n", + onoff_his->magic, onoff_his->size, sizeof(onoff_history_t)); + } else { + uint32_t index = onoff_his->index % SEC_DEBUG_ONOFF_HISTORY_MAX_CNT; + onoff_his->history[index].rtc_offset = rtc_offset; + if (lpm_mode) { + if (onoff_his->index) { + uint32_t p_index = (onoff_his->index - 1) % SEC_DEBUG_ONOFF_HISTORY_MAX_CNT; + if ((onoff_his->history[index].rtc_offset >= onoff_his->history[p_index].rtc_offset) && + onoff_his->history[p_index].local_time) { + onoff_his->history[index].local_time = onoff_his->history[p_index].local_time + + (onoff_his->history[index].rtc_offset - onoff_his->history[p_index].rtc_offset); + rtc_time64_to_tm(onoff_his->history[index].local_time, tm); + } else { + onoff_his->history[index].local_time = 0; + } + } else { + onoff_his->history[index].local_time = 0; + } + } else { + onoff_his->history[index].local_time = local_time; + } + onoff_his->history[index].boot_cnt = s_log_buf->boot_cnt; + snprintf(onoff_his->history[index].reason, SEC_DEBUG_ONOFF_REASON_STR_SIZE, "%s at Kernel%s%s", + action == SYS_RESTART ? "Reboot" : "Power Off", + lpm_mode ? "(in LPM) " : " ", cmd); + onoff_his->index++; + write_debug_partition(debug_index_onoff_history, onoff_his); + } + } + } + + if (onoff_his) + vfree(onoff_his); +} +#endif + #ifdef CONFIG_SEC_LOG_STORE_LAST_KMSG static int sec_log_store(struct notifier_block *nb, unsigned long action, void *data) @@ -235,14 +290,19 @@ static int sec_log_store(struct notifier_block *nb, char cmd[256] = { 0, }; struct rtc_time tm; struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + struct timespec64 now; + time64_t local_time, rtc_offset; + struct rtc_time local_tm; if (!rtc) { pr_info("unable to open rtc device (%s)\n", CONFIG_RTC_HCTOSYS_DEVICE); } else { - if (rtc_read_time(rtc, &tm)) + if (rtc_read_time(rtc, &tm)) { dev_err(rtc->dev.parent, "hctosys: unable to read the hardware clock\n"); - else - pr_info("RTC(%lld)\n", rtc_tm_to_time64(&tm)); + } else { + rtc_offset = rtc_tm_to_time64(&tm); + pr_info("BOOT_CNT(%d) RTC(%lld)\n", s_log_buf->boot_cnt, rtc_offset); + } } if (!sec_log_buf_init_done) @@ -251,11 +311,20 @@ static int sec_log_store(struct notifier_block *nb, if (data && strlen(data)) snprintf(cmd, sizeof(cmd), "%s", (char *)data); + ktime_get_real_ts64(&now); + local_time = now.tv_sec; + local_time -= sys_tz.tz_minuteswest * 60; // adjust time zone + rtc_time64_to_tm(local_time, &local_tm); + +#if IS_ENABLED(CONFIG_SEC_STORE_POWER_ONOFF_HISTORY) + sec_power_onoff_history_store(local_time, rtc_offset, &local_tm, action, cmd); +#endif + switch (action) { case SYS_RESTART: case SYS_POWER_OFF: - pr_info("%s, %s\n", - action == SYS_RESTART ? "reboot" : "power off", cmd); + pr_info("%s, %s, %ptR(TZ:%02d)\n", + action == SYS_RESTART ? "reboot" : "power off", cmd, &local_tm, -sys_tz.tz_minuteswest / 60); write_debug_partition(debug_index_reset_klog, s_log_buf); break; } diff --git a/drivers/samsung/quest/Kconfig b/drivers/samsung/quest/Kconfig index abd5c6943..732bf7e02 100644 --- a/drivers/samsung/quest/Kconfig +++ b/drivers/samsung/quest/Kconfig @@ -1,21 +1,18 @@ config SEC_QUEST bool "Samsung QUEST Feature" default n - depends on SEC_FACTORY help Samsung QUEST Feature, to test chipset quality config SEC_QUEST_UEFI bool "Samsung QUEST UEFI Feature" default n - depends on SEC_FACTORY help Samsung QUEST UEFI Feature, to test chipset quality config SEC_QUEST_UEFI_ENHANCEMENT bool "Samsung QUEST UEFI ENHENCEMENT Feature" default n - depends on SEC_FACTORY help Samsung QUEST UEFI ENHENCEMENT Feature, to test chipset quality @@ -64,21 +61,17 @@ config SEC_QUEST_CAL_HLOS_SUPPORT_FUSION config SEC_QUEST_AUTO_TRIGGER_KWORKER bool "Samsung QUEST AUTO TRIGGER CONCEPT Feature (using kworker)" default n + depends on SEC_FACTORY help Samsung QUEST AUTO TRIGGER CONCEPT Feature (using kworker) config SEC_QUEST_AUTO_TRIGGER_INIT_WRITE bool "Samsung QUEST AUTO TRIGGER CONCEPT Feature (using init.rc write)" default n + depends on SEC_FACTORY help Samsung QUEST AUTO TRIGGER CONCEPT Feature (using init.rc write) -config SEC_QUEST_UEFI_ACT_TRIGGER - bool "Samsung QUEST UEFI TRIGGER CONCEPT Feature (using act)" - default n - help - Samsung QUEST UEFI TRIGGER CONCEPT Feature (using act) - config SEC_QUEST_UEFI_USER bool "feature to trigger uefi quest from user binary" default n diff --git a/drivers/samsung/quest/Makefile b/drivers/samsung/quest/Makefile index 3381e25e9..5236ac1e8 100644 --- a/drivers/samsung/quest/Makefile +++ b/drivers/samsung/quest/Makefile @@ -1,4 +1,8 @@ obj-$(CONFIG_SEC_QUEST) += sec_quest.o \ - sec_quest_param.o \ - sec_quest_qdaf.o -obj-$(CONFIG_SEC_QUEST_BPS_CLASSIFIER) += sec_quest_bps.o \ No newline at end of file + sec_quest_param.o + +obj-$(CONFIG_SEC_QUEST_BPS_CLASSIFIER) += sec_quest_bps.o + +ifeq ($(CONFIG_SEC_FACTORY), y) +obj-$(CONFIG_SEC_QUEST) += sec_quest_qdaf.o +endif \ No newline at end of file diff --git a/drivers/samsung/quest/sec_quest.c b/drivers/samsung/quest/sec_quest.c index 471e022ac..fc57d6521 100644 --- a/drivers/samsung/quest/sec_quest.c +++ b/drivers/samsung/quest/sec_quest.c @@ -63,14 +63,18 @@ extern char param_api_gpio_test_result[256]; // sysfs struct device *sec_nad; +#if defined(CONFIG_SEC_FACTORY) struct device *sec_nad_balancer; static struct kobj_uevent_env quest_uevent; +#endif // etc extern unsigned int lpcharge; +struct mutex sysfs_common_lock; + +#if defined(CONFIG_SEC_FACTORY) static int erased; static int step_to_smd_quest_hlos; -struct mutex sysfs_common_lock; #if defined(CONFIG_SEC_QUEST_AUTO_TRIGGER_KWORKER) struct delayed_work trigger_quest_work; #define WAIT_TIME_BEFORE_TRIGGER_MSECS 60000 @@ -81,6 +85,7 @@ static int testmode_enabled = 0; static int testmode_quefi_enabled = 1; static int testmode_suefi_enabled = 1; static int testmode_ddrscan_enabled = 1; +#endif /* Please sync with enum quest_enum_item in sec_qeust.h */ @@ -115,14 +120,19 @@ char *STR_SUBITEM[SUBITEM_ITEMSCOUNT] = { "SUEFI_GROUP3", "SUEFI_GROUP4", "SUEFI_GROUP5", + "SUEFI_GROUP6", + "SUEFI_GROUP7", + "SUEFI_GROUP8", + "SUEFI_GROUP9", "QUEFI_GROUP1", - "QUEFI_GROUP2", - "QUEFI_GROUP3", - "QUEFI_GROUP4", - "QUEFI_GROUP5", - "QUEFI_GROUP6", - "QUEFI_GROUP7", - "QUEFI_GROUP8", + "QUEFI_GROUP2", + "QUEFI_GROUP3", + "QUEFI_GROUP4", + "QUEFI_GROUP5", + "QUEFI_GROUP6", + "QUEFI_GROUP7", + "QUEFI_GROUP8", + "QUEFI_GROUP9", #else "QUEFI", "SUEFI_CRYPTO", @@ -132,6 +142,7 @@ char *STR_SUBITEM[SUBITEM_ITEMSCOUNT] = { "HLOS_DUMMY", #elif defined(CONFIG_SEC_QUEST_HLOS_NATURESCENE_SMD) "HLOS_NATURESCENE", + "HLOS_AOSSTHERMALDIFF", #else "HLOS_CRYPTO", "HLOS_ICACHE", @@ -150,6 +161,10 @@ char *STR_SUBITEM[SUBITEM_ITEMSCOUNT] = { #endif }; + +#if defined(CONFIG_SEC_FACTORY) + + #if defined(CONFIG_SEC_QUEST_BPS_CLASSIFIER) static void sec_quest_bps_print_info(struct bps_info *bfo, char *info) { @@ -547,13 +562,11 @@ static void setup_scenario() QUEST_PRINT("%s : (step=%d) reboot while running quest_hlos\n", __func__, STEP_SMDDL); QUEST_PRINT("%s : Let's check lastkmsg\n", __func__); - if( param_quest_data.smd_subitem_result_first==0 ) - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); quest_initialize_curr_step(); }else if ( total_result == ITEM_RESULT_FAIL ) { QUEST_PRINT("%s : (step=%d) total_result == ITEM_RESULT_FAIL, so initialize step\n", __func__, STEP_SMDDL); - if( param_quest_data.smd_subitem_result_first==0 ) - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); quest_initialize_curr_step(); } #if defined(CONFIG_SEC_QUEST_HLOS_DUMMY_SMD) @@ -565,8 +578,7 @@ static void setup_scenario() __func__, STEP_SMDDL); check_and_update_qdaf_result(); - if( param_quest_data.smd_subitem_result_first==0 ) // due to boot after abnormal reset - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); // due to boot after abnormal reset quest_initialize_curr_step(); } else if( exist_incompleted == 1 ) @@ -584,8 +596,7 @@ static void setup_scenario() #if defined(CONFIG_SEC_QUEST_NOT_TRIGGER_SMDDL_QDAF) QUEST_PRINT("%s : SMDDL line, but skip to run SMDDL QDAF\n", __func__); check_and_update_qdaf_result(); - if( param_quest_data.smd_subitem_result_first==0 ) // due to boot after abnormal reset - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); // due to boot after abnormal reset quest_initialize_curr_step(); #else QUEST_PRINT("%s : SMDDL line, so run SMDDL QDAF\n", __func__); @@ -595,8 +606,7 @@ static void setup_scenario() else { QUEST_PRINT("%s : ERASE seq, so do not run SMDDL QDAF and finish step\n", __func__); check_and_update_qdaf_result(); - if( param_quest_data.smd_subitem_result_first==0 ) // due to boot after abnormal reset - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); // due to boot after abnormal reset quest_initialize_curr_step(); } } @@ -786,8 +796,7 @@ static ssize_t store_quest_end(struct device *dev, #if defined(CONFIG_SEC_QUEST_NOT_TRIGGER_SMDDL_QDAF) QUEST_PRINT("%s : SMDDL line, but skip to run SMDDL QDAF\n", __func__); check_and_update_qdaf_result(); - if( param_quest_data.smd_subitem_result_first==0 ) - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); quest_initialize_curr_step(); #else QUEST_PRINT("%s : SMDDL line, so run SMDDL QDAF\n", __func__); @@ -797,13 +806,11 @@ static ssize_t store_quest_end(struct device *dev, else { QUEST_PRINT("%s : ERASE seq, so do not run SMDDL QDAF and finish step\n", __func__); check_and_update_qdaf_result(); - if( param_quest_data.smd_subitem_result_first==0 ) - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); quest_initialize_curr_step(); } #else - if( param_quest_data.smd_subitem_result_first==0 ) - param_quest_data.smd_subitem_result_first = param_quest_data.smd_subitem_result; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_subitem_result); quest_initialize_curr_step(); #endif @@ -1097,30 +1104,8 @@ static DEVICE_ATTR(nad_acat, S_IRUGO | S_IWUSR, show_quest_acat, store_quest_aca ////////////////////////////////////////////////// /////// NAD_STAT ///////////////////////////////// ////////////////////////////////////////////////// -char str_mxcpr[CPR_BPS_SZ_BYTE] = { '\0' }; -char str_cxcpr[CPR_BPS_SZ_BYTE] = { '\0' }; char str_bps[CPR_BPS_SZ_BYTE] = { '\0' }; -static void make_cpr_stat_string(char *mx_str, char *cx_str) -{ - int modeIdx = 0; - int count = 0; - - for(modeIdx = 0; modeIdx < QUEST_CPR_MODE_CNT; modeIdx++) - count += snprintf(mx_str + count, CPR_BPS_SZ_BYTE - count, "MX%dF(%d),MX%dC(%d),MX%dR(%d),", - param_quest_data.smd_mx_cpr[modeIdx].Modes, param_quest_data.smd_mx_cpr[modeIdx].Floor, - param_quest_data.smd_mx_cpr[modeIdx].Modes, param_quest_data.smd_mx_cpr[modeIdx].Ceiling, - param_quest_data.smd_mx_cpr[modeIdx].Modes, param_quest_data.smd_mx_cpr[modeIdx].Current); - - count = 0; - - for(modeIdx = 0; modeIdx < QUEST_CPR_MODE_CNT; modeIdx++) - count += snprintf(cx_str + count, CPR_BPS_SZ_BYTE - count, "CX%dF(%d),CX%dC(%d),CX%dR(%d),", - param_quest_data.smd_cx_cpr[modeIdx].Modes, param_quest_data.smd_cx_cpr[modeIdx].Floor, - param_quest_data.smd_mx_cpr[modeIdx].Modes, param_quest_data.smd_cx_cpr[modeIdx].Ceiling, - param_quest_data.smd_mx_cpr[modeIdx].Modes, param_quest_data.smd_cx_cpr[modeIdx].Current); -} - #if defined(CONFIG_SEC_QUEST_BPS_CLASSIFIER) static void make_bps_stat_string(char *bps_str) { @@ -1133,8 +1118,6 @@ static void make_bps_stat_string(char *bps_str) #endif static void make_additional_stat_string(char *additional_str) { - make_cpr_stat_string(str_mxcpr, str_cxcpr); - #if defined(CONFIG_SEC_QUEST_BPS_CLASSIFIER) /* if bps data successfully initialized and if magic needs to be checked */ if (sec_quest_bps_env_initialized && @@ -1158,18 +1141,22 @@ static void make_additional_stat_string(char *additional_str) "FHST(%d),FHET(%d)," \ "FHITH(%d),FHMTH(%d)," \ "FNSR(%d)," \ + "FMATD(%d)," \ "SSIR(%llX)," \ "DET(%d)," \ "QUET(%d)," \ "SUET(%d)," \ "QUPT(%d)," \ + "SCT(%d)," \ + "SCTH(%d)," \ "BR(%.2s)," \ "HST(%d),HET(%d)," \ "HITH(%d),HMTH(%d)," \ "NSR(%d)," \ - "%s" \ - "%s" \ - "BPS(%s)", + "MATD(%d)," \ + "BPS(%s)," \ + "CHIP(%llX),"\ + "CPER(%d)", param_quest_data.smd_quefi_init_thermal_first, param_quest_data.smd_quefi_end_thermal_first, param_quest_data.smd_suefi_init_thermal_first, param_quest_data.smd_suefi_end_thermal_first, param_quest_data.smd_subitem_result_first, @@ -1181,18 +1168,23 @@ static void make_additional_stat_string(char *additional_str) param_quest_data.smd_hlos_start_time_first, param_quest_data.smd_hlos_elapsed_time_first, param_quest_data.smd_hlos_init_thermal_first, param_quest_data.smd_hlos_max_thermal_first, param_quest_data.smd_ns_repeats_first, + param_quest_data.smd_max_aoss_thermal_diff_first, param_quest_data.smd_subitem_result, param_quest_data.smd_ddrscan_elapsed_time, param_quest_data.smd_quefi_elapsed_time, param_quest_data.smd_suefi_elapsed_time, param_quest_data.smd_quefi_total_pause_time, + param_quest_data.smd_ft_self_cooling_time, + param_quest_data.smd_ft_thermal_after_self_cooling, param_quest_data.smd_boot_reason, param_quest_data.smd_hlos_start_time,param_quest_data.smd_hlos_elapsed_time, param_quest_data.smd_hlos_init_thermal, param_quest_data.smd_hlos_max_thermal, param_quest_data.smd_ns_repeats, - str_mxcpr, - str_cxcpr, - str_bps); + param_quest_data.smd_max_aoss_thermal_diff, + str_bps, + (param_quest_data.ap_serial)? ((param_quest_data.real_smd_register_value)? + param_quest_data.ap_serial^(0xfff00000 | param_quest_data.real_smd_register_value):0):0, + param_quest_data.smd_cper); QUEST_PRINT("%s : additional_str : %s\n", __func__, additional_str); } @@ -1385,6 +1377,7 @@ static ssize_t store_quest_smd_subitem_result(struct device *dev, else if (TEST_DUMMY(test_name)) item = SUBITEM_QUESTHLOSDUMMY; #elif defined(CONFIG_SEC_QUEST_HLOS_NATURESCENE_SMD) if (TEST_NATURESCENE(test_name)) item = SUBITEM_QUESTHLOSNATURESCENE; + else if (TEST_AOSSTHERMALDIFF(test_name)) item = SUBITEM_QUESTHLOSAOSSTHERMALDIFF; #else if (TEST_CRYPTO(test_name)) item = SUBITEM_QUESTHLOSCRYPTO; else if (TEST_ICACHE(test_name)) item = SUBITEM_QUESTHLOSICACHE; @@ -1468,6 +1461,11 @@ static ssize_t store_quest_erase(struct device *dev, param_quest_data.smd_hlos_init_thermal_first = 0; param_quest_data.smd_hlos_max_thermal_first = 0; param_quest_data.smd_ns_repeats_first = 0; + param_quest_data.smd_max_aoss_thermal_diff_first = 0; + param_quest_data.real_smd_register_value = 0; + param_quest_data.ap_serial = 0; + param_quest_data.num_smd_try = 0; + param_quest_data.smd_cper = 0; quest_sync_param_quest_data(); } @@ -1517,7 +1515,7 @@ static ssize_t store_quest_main(struct device *dev, param_quest_data.main_item_result = 0; param_quest_data.hlos_remained_count = 1; #if defined(CONFIG_SEC_QUEST_UEFI) - param_quest_data.quefi_remained_count = 4; + param_quest_data.quefi_remained_count = MAIN_QUEST_QUEFI_REPEATS; #endif #if defined(CONFIG_SEC_QUEST_UEFI_ENHANCEMENT) param_quest_data.suefi_remained_count = 1; @@ -2145,8 +2143,8 @@ static ssize_t store_quest_smd_info(struct device *dev, const char *buf, size_t count) { int idx = 0; - char temp[QUEST_BUFF_SIZE * 3]; - char quest_cmd[QUEST_CMD_LIST][BUFF_SZ]; + char temp[QUEST_CMD_LIST * QUEST_CMD_SIZE]; + char quest_cmd[QUEST_CMD_LIST][QUEST_CMD_SIZE]; char *quest_ptr, *string; QUEST_SYSFS_ENTER(); @@ -2157,51 +2155,50 @@ static ssize_t store_quest_smd_info(struct device *dev, } // parse argument - strlcpy(temp, buf, BUFF_SZ * 3); + strlcpy(temp, buf, QUEST_CMD_SIZE); string = temp; while (idx < QUEST_CMD_LIST) { quest_ptr = strsep(&string, ","); - strlcpy(quest_cmd[idx++], quest_ptr, BUFF_SZ); + strlcpy(quest_cmd[idx++], quest_ptr, QUEST_CMD_SIZE); } QUEST_PRINT("%s : %s(%s)\n", __func__, quest_cmd[0], quest_cmd[1]); if( strncmp(quest_cmd[0], "smd_boot_reason", 15)==0 ) { strncpy(param_quest_data.smd_boot_reason, quest_cmd[1], 2); - if( param_quest_data.smd_boot_reason_first[0]==0 ) - strncpy(param_quest_data.smd_boot_reason_first, quest_cmd[1], 2); + QUEST_UPDATE_SMDDL_INFO_WITH_STRING(param_quest_data.smd_boot_reason_first, quest_cmd[1], 2); } if( strncmp(quest_cmd[0], "smd_hlos_start_time", 19)==0 ) { sscanf(quest_cmd[1], "%d", ¶m_quest_data.smd_hlos_start_time); - if( param_quest_data.smd_hlos_start_time_first==0 ) - param_quest_data.smd_hlos_start_time_first = param_quest_data.smd_hlos_start_time; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_hlos_start_time); } if( strncmp(quest_cmd[0], "smd_hlos_elapsed_time", 21)==0 ) { sscanf(quest_cmd[1], "%d", ¶m_quest_data.smd_hlos_elapsed_time); - if( param_quest_data.smd_hlos_elapsed_time_first==0 ) - param_quest_data.smd_hlos_elapsed_time_first = param_quest_data.smd_hlos_elapsed_time; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_hlos_elapsed_time); } if( strncmp(quest_cmd[0], "smd_hlos_init_thermal", 21)==0 ) { sscanf(quest_cmd[1], "%d", ¶m_quest_data.smd_hlos_init_thermal); - if( param_quest_data.smd_hlos_init_thermal_first==0 ) - param_quest_data.smd_hlos_init_thermal_first = param_quest_data.smd_hlos_init_thermal; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_hlos_init_thermal); } if( strncmp(quest_cmd[0], "smd_hlos_max_thermal", 20)==0 ) { sscanf(quest_cmd[1], "%d", ¶m_quest_data.smd_hlos_max_thermal); - if( param_quest_data.smd_hlos_max_thermal_first==0 ) - param_quest_data.smd_hlos_max_thermal_first = param_quest_data.smd_hlos_max_thermal; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_hlos_max_thermal); } if( strncmp(quest_cmd[0], "smd_ns_repeats", 14)==0 ) { sscanf(quest_cmd[1], "%d", ¶m_quest_data.smd_ns_repeats); - if( param_quest_data.smd_ns_repeats_first==0 ) - param_quest_data.smd_ns_repeats_first = param_quest_data.smd_ns_repeats; + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_ns_repeats); } + if( strncmp(quest_cmd[0], "smd_max_aoss_thermal_diff", 25)==0 ) { + sscanf(quest_cmd[1], "%d", ¶m_quest_data.smd_max_aoss_thermal_diff); + QUEST_UPDATE_SMDDL_INFO(param_quest_data.smd_max_aoss_thermal_diff); + } + quest_sync_param_quest_data(); out: @@ -2213,6 +2210,23 @@ static DEVICE_ATTR(nad_smd_info, S_IWUSR, NULL, store_quest_smd_info); ////////////////////////////////////////////////// +#endif // #if defined(CONFIG_SEC_FACTORY) + + +static ssize_t show_quest_fv_flashed(struct device *dev, + struct device_attribute *attr, char *buf) +{ + //QUEST_SYSFS_ENTER(); + //QUEST_SYSFS_EXIT(); + mutex_lock(&sysfs_common_lock); + quest_load_param_quest_data(); + mutex_unlock(&sysfs_common_lock); + + return snprintf(buf, BUFF_SZ, "%d\n", param_quest_data.quest_fv_flashed); +} + +static DEVICE_ATTR(quest_fv_flashed, 0444, show_quest_fv_flashed, NULL); + static int __init sec_quest_init(void) @@ -2239,14 +2253,22 @@ static int __init sec_quest_init(void) return PTR_ERR(sec_nad); } + ret = device_create_file(sec_nad, &dev_attr_quest_fv_flashed); + if (ret) { + QUEST_PRINT("%s: Failed to create device file\n", __func__); + goto err_create_nad_sysfs; + } + +#if defined(CONFIG_SEC_FACTORY) + #if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0) sec_nad_balancer = sec_device_create(0, NULL, "sec_nad_balancer"); #else sec_nad_balancer = sec_device_create(NULL, "sec_nad_balancer"); #endif - if (IS_ERR(sec_nad)) { + if (IS_ERR(sec_nad_balancer)) { QUEST_PRINT("%s Failed to create device(sec_nad)!\n", __func__); - return PTR_ERR(sec_nad); + return PTR_ERR(sec_nad_balancer); } @@ -2393,7 +2415,6 @@ static int __init sec_quest_init(void) schedule_delayed_work(&trigger_quest_work, msecs_to_jiffies(WAIT_TIME_BEFORE_TRIGGER_MSECS)); #endif -#if defined(CONFIG_SEC_FACTORY) atomic_notifier_chain_register(&panic_notifier_list, &quest_panic_block); #endif diff --git a/drivers/samsung/quest/sec_quest_param.c b/drivers/samsung/quest/sec_quest_param.c index 227266a30..a67cac781 100644 --- a/drivers/samsung/quest/sec_quest_param.c +++ b/drivers/samsung/quest/sec_quest_param.c @@ -112,11 +112,12 @@ void quest_print_param_quest_data() QUEST_PRINT("curr_step : %d\n", param_quest_data.curr_step); - QUEST_PRINT("hlos_count(%d) quefi_count(%d) suefi_count(%d) ddrscan_count(%d)\n", + QUEST_PRINT("hlos_count(%d) quefi_count(%d) suefi_count(%d) ddrscan_count(%d), num_smd_try(%d)\n", param_quest_data.hlos_remained_count, param_quest_data.quefi_remained_count, param_quest_data.suefi_remained_count, - param_quest_data.ddrscan_remained_count); + param_quest_data.ddrscan_remained_count, + param_quest_data.num_smd_try); QUEST_PRINT("err_codes : (%llu)\n", param_quest_data.err_codes); @@ -141,11 +142,16 @@ void quest_print_param_quest_data() QUEST_PRINT("smd_quefi_elapsed_time : (%d)\n", param_quest_data.smd_quefi_elapsed_time); QUEST_PRINT("smd_suefi_elapsed_time : (%d)\n", param_quest_data.smd_suefi_elapsed_time); QUEST_PRINT("smd_quefi_total_pause_time : (%d)\n", param_quest_data.smd_quefi_total_pause_time); + + QUEST_PRINT("smd_ft_self_cooling_time : (%d)\n", param_quest_data.smd_ft_self_cooling_time); + QUEST_PRINT("smd_ft_thermal_after_self_cooling : (%d)\n", param_quest_data.smd_ft_thermal_after_self_cooling); + QUEST_PRINT("smd_boot_reason : (%.2s)\n", param_quest_data.smd_boot_reason); QUEST_PRINT("smd_hlos_start_time : (%d)\n", param_quest_data.smd_hlos_start_time); QUEST_PRINT("smd_hlos_elapsed_time : (%d)\n", param_quest_data.smd_hlos_elapsed_time); #if defined(CONFIG_SEC_QUEST_HLOS_NATURESCENE_SMD) QUEST_PRINT("smd_ns_repeats : (%d)\n", param_quest_data.smd_ns_repeats); + QUEST_PRINT("smd_max_aoss_thermal_diff : (%d)\n", param_quest_data.smd_max_aoss_thermal_diff); #endif QUEST_PRINT("smd_hlos_init_thermal : (%d)\n", param_quest_data.smd_hlos_init_thermal); QUEST_PRINT("smd_hlos_max_thermal : (%d)\n", param_quest_data.smd_hlos_max_thermal); @@ -169,9 +175,11 @@ void quest_print_param_quest_data() QUEST_PRINT("smd_hlos_elapsed_time_first : (%d)\n", param_quest_data.smd_hlos_elapsed_time_first); #if defined(CONFIG_SEC_QUEST_HLOS_NATURESCENE_SMD) QUEST_PRINT("smd_ns_repeats_first : (%d)\n", param_quest_data.smd_ns_repeats_first); + QUEST_PRINT("smd_max_aoss_thermal_diff_first: (%d)\n", param_quest_data.smd_max_aoss_thermal_diff_first); #endif QUEST_PRINT("smd_hlos_init_thermal_first : (%d)\n", param_quest_data.smd_hlos_init_thermal_first); QUEST_PRINT("smd_hlos_max_thermal_first : (%d)\n", param_quest_data.smd_hlos_max_thermal_first); + QUEST_PRINT("smd_CPER : (%d)\n", param_quest_data.smd_cper); QUEST_PRINT("======================\n"); } @@ -220,8 +228,6 @@ void quest_sync_param_quest_ddr_result_data(void) void quest_clear_param_quest_data() { - int modeIdx = 0; - param_quest_data.smd_item_result = 0; param_quest_data.smd_subitem_result = 0; param_quest_data.cal_item_result = 0; @@ -255,6 +261,10 @@ void quest_clear_param_quest_data() param_quest_data.smd_hlos_init_thermal = 0; param_quest_data.smd_hlos_max_thermal = 0; param_quest_data.smd_ns_repeats = 0; + param_quest_data.smd_max_aoss_thermal_diff = 0; + + param_quest_data.smd_ft_self_cooling_time = 0; + param_quest_data.smd_ft_thermal_after_self_cooling = 0; // let's keep last information //param_quest_data.smd_subitem_result_first = 0; @@ -271,22 +281,9 @@ void quest_clear_param_quest_data() //param_quest_data.smd_hlos_init_thermal_first = 0; //param_quest_data.smd_hlos_max_thermal_first = 0; //param_quest_data.smd_ns_repeats_first = 0; - //param_quest_data.smd_quefi_rework = 0; //param_quest_data.smd_suefi_rework = 0; - - for(modeIdx = 0; modeIdx < QUEST_CPR_MODE_CNT; modeIdx++) - { - param_quest_data.curr_mx_cpr[modeIdx].Modes = 0; - param_quest_data.curr_mx_cpr[modeIdx].Floor = 0; - param_quest_data.curr_mx_cpr[modeIdx].Ceiling = 0; - param_quest_data.curr_mx_cpr[modeIdx].Current = 0; - - param_quest_data.curr_cx_cpr[modeIdx].Modes = 0; - param_quest_data.curr_cx_cpr[modeIdx].Floor = 0; - param_quest_data.curr_cx_cpr[modeIdx].Ceiling = 0; - param_quest_data.curr_mx_cpr[modeIdx].Current = 0; - } + //param_quest_data.smd_max_aoss_thermal_diff_first = 0; quest_sync_param_quest_data(); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 45a30032b..844fbed28 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3221,6 +3221,9 @@ static int sd_revalidate_disk(struct gendisk *disk) rw_max = min_not_zero(logical_to_sectors(sdp, dev_max), (sector_t)BLK_DEF_MAX_SECTORS); + /* IOPP-max_sectors-v1.0.4.14 */ + rw_max = max(rw_max, (unsigned int)BLK_DEF_MAX_SECTORS); + /* Do not exceed controller limit */ rw_max = min(rw_max, queue_max_hw_sectors(q)); @@ -3609,12 +3612,13 @@ static int sd_probe(struct device *dev) #endif struct request_queue *q = sdp->request_queue; - /* decrease max # of requests to 32. The goal of this tunning is + /* decrease max # of requests to 32. The goal of this tuning is * reducing the time for draining elevator when elevator_switch * function is called. It is effective for slow USB memory. */ q->nr_requests = BLKDEV_MAX_RQ / 8; - if (q->nr_requests < 32) q->nr_requests = 32; + if (q->nr_requests < 32) + q->nr_requests = 32; #ifdef CONFIG_LARGE_DIRTY_BUFFER /* apply more throttle on non-ufs scsi device */ q->backing_dev_info->capabilities |= BDI_CAP_STRICTLIMIT; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index aba60d35e..5e9fadbf3 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -117,15 +117,18 @@ enum { UPIU_CMD_FLAGS_READ = 0x40, }; +/* UPIU Command Priority flags */ +enum { + UPIU_CMD_PRIO_NONE = 0x00, + UPIU_CMD_PRIO_HIGH = 0x04, +}; + /* UPIU Task Attributes */ enum { UPIU_TASK_ATTR_SIMPLE = 0x00, UPIU_TASK_ATTR_ORDERED = 0x01, UPIU_TASK_ATTR_HEADQ = 0x02, UPIU_TASK_ATTR_ACA = 0x03, -#ifdef CUSTOMIZE_UPIU_FLAGS - UPIU_COMMAND_PRIORITY_HIGH = 0x4, -#endif }; /* UPIU Query request function */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 161c6971c..31db643eb 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1987,31 +1987,6 @@ static inline void ufshcd_hba_start(struct ufs_hba *hba) ufshcd_writel(hba, val, REG_CONTROLLER_ENABLE); } -#ifdef CUSTOMIZE_UPIU_FLAGS -SIO_PATCH_VERSION(UPIU_customize, 1, 1, ""); - -static void set_customized_upiu_flags(struct ufshcd_lrb *lrbp, u32 *upiu_flags) -{ - if (lrbp->command_type == UTP_CMD_TYPE_SCSI) { - switch (req_op(lrbp->cmd->request)) { - case REQ_OP_READ: - *upiu_flags |= UPIU_COMMAND_PRIORITY_HIGH; - break; - case REQ_OP_WRITE: - if (lrbp->cmd->request->cmd_flags & REQ_SYNC) - *upiu_flags |= UPIU_COMMAND_PRIORITY_HIGH; - break; - case REQ_OP_FLUSH: - *upiu_flags |= UPIU_TASK_ATTR_HEADQ; - break; - case REQ_OP_DISCARD: - *upiu_flags |= UPIU_TASK_ATTR_ORDERED; - break; - } - } -} -#endif - /** * ufshcd_is_hba_active - Get controller state * @hba: per adapter instance @@ -4048,6 +4023,29 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE); } +/* IOPP-upiu_flags-v1.2.k5.4 */ +static void set_customized_upiu_flags(struct ufshcd_lrb *lrbp, u32 *upiu_flags) +{ + if (!lrbp->cmd || !lrbp->cmd->request) + return; + + switch (req_op(lrbp->cmd->request)) { + case REQ_OP_READ: + *upiu_flags |= UPIU_CMD_PRIO_HIGH; + break; + case REQ_OP_WRITE: + if (lrbp->cmd->request->cmd_flags & REQ_SYNC) + *upiu_flags |= UPIU_CMD_PRIO_HIGH; + break; + case REQ_OP_FLUSH: + *upiu_flags |= UPIU_TASK_ATTR_HEADQ; + break; + case REQ_OP_DISCARD: + *upiu_flags |= UPIU_TASK_ATTR_ORDERED; + break; + } +} + /** * ufshcd_prepare_req_desc_hdr() - Fills the requests header * descriptor according to request @@ -5306,6 +5304,13 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, return ret; } + /* Check param offset and size what we need is less than buff_len */ + if ((param_offset + param_size) > buff_len) { + dev_err(hba->dev, "%s: Invalid offset 0x%x(size 0x%x) in descriptor IDN 0x%x, length 0x%x\n", + __func__, param_offset, param_size, desc_id, buff_len); + return -EINVAL; + } + /* Check whether we need temp memory */ if (param_offset != 0 || param_size < buff_len) { desc_buf = kmalloc(buff_len, GFP_KERNEL); @@ -12727,7 +12732,7 @@ static ssize_t SEC_UFS_HPB_info_show(struct device *dev, struct device_attribute if (!hpb || !(ufsf->hpb_dev_info.hpb_device)) return 0; - if (ufsf->ufshpb_state == HPB_FAILED) + if ((ufsf->ufshpb_state == HPB_FAILED) || (ufsf->ufshpb_state == HPB_NEED_INIT)) return 0; hit_cnt = atomic64_read(&hpb->hit); diff --git a/drivers/security/samsung/five_tee_driver/Kconfig b/drivers/security/samsung/five_tee_driver/Kconfig index f374aee59..66c4124ad 100644 --- a/drivers/security/samsung/five_tee_driver/Kconfig +++ b/drivers/security/samsung/five_tee_driver/Kconfig @@ -3,7 +3,7 @@ # config FIVE_TEE_DRIVER - bool "Integrity TEE Driver" + tristate "Integrity TEE Driver" depends on FIVE default y ---help--- diff --git a/drivers/security/samsung/five_tee_driver/Makefile b/drivers/security/samsung/five_tee_driver/Makefile index 9f863d38e..e563b54b9 100644 --- a/drivers/security/samsung/five_tee_driver/Makefile +++ b/drivers/security/samsung/five_tee_driver/Makefile @@ -5,14 +5,15 @@ FIVE_TEE_DRIVER_PATH := $(srctree)/drivers/security/samsung/five_tee_driver TEEC_CLIENT_PATH := multibuild/source/gp-api/client PROTOCOL_PATH := multibuild/source/gp-api/protocol -obj-$(CONFIG_FIVE_TEE_DRIVER) += five_tee_driver.o +obj-$(CONFIG_FIVE_TEE_DRIVER) := fiveteedriver.o -ccflags-$(CONFIG_FIVE_TEE_DRIVER) += -I$(srctree)/security/samsung/five \ - -I$(FIVE_TEE_DRIVER_PATH)/$(PROTOCOL_PATH) \ - -I$(FIVE_TEE_DRIVER_PATH)/$(TEEC_CLIENT_PATH) +fiveteedriver-y += five_tee_driver.o + +ccflags-y += -I$(FIVE_TEE_DRIVER_PATH)/$(PROTOCOL_PATH) \ + -I$(FIVE_TEE_DRIVER_PATH)/$(TEEC_CLIENT_PATH) # Emulator -obj-$(CONFIG_FIVE_USE_EMULATOR) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ +fiveteedriver-$(CONFIG_FIVE_USE_EMULATOR) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ $(PROTOCOL_PATH)/teec_param_utils.o \ $(TEEC_CLIENT_PATH)/teec_common_emulator.o \ $(TEEC_CLIENT_PATH)/teec_operation.o \ @@ -20,7 +21,7 @@ obj-$(CONFIG_FIVE_USE_EMULATOR) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ ccflags-$(CONFIG_FIVE_USE_EMULATOR) += -I$(FIVE_TEE_DRIVER_PATH)/multibuild/include/gp-api # Trustonic -obj-$(CONFIG_FIVE_USE_TRUSTONIC) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ +fiveteedriver-$(CONFIG_FIVE_USE_TRUSTONIC) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ $(PROTOCOL_PATH)/teec_param_utils.o \ $(TEEC_CLIENT_PATH)/teec_common_tbase.o \ $(TEEC_CLIENT_PATH)/teec_operation.o @@ -28,8 +29,8 @@ obj-$(CONFIG_FIVE_USE_TRUSTONIC) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ ccflags-$(CONFIG_FIVE_USE_TRUSTONIC) += -I$(FIVE_TEE_DRIVER_PATH)/multibuild/include/gp-api ifeq ($(CONFIG_FIVE_USE_TRUSTONIC), y) ifeq ($(CONFIG_MACH_MT6768), y) - ccflags-$(CONFIG_FIVE_TEE_DRIVER) += -I$(srctree)/drivers/misc/mediatek/gud/410/MobiCoreDriver - ccflags-$(CONFIG_FIVE_TEE_DRIVER) += -I$(srctree)/drivers/misc/mediatek/gud/410/MobiCoreDriver/public + ccflags-y += -I$(srctree)/drivers/misc/mediatek/gud/410/MobiCoreDriver + ccflags-y += -I$(srctree)/drivers/misc/mediatek/gud/410/MobiCoreDriver/public else ifeq ($(CONFIG_SOC_EXYNOS7570), y) PLATFORM := exynos7570 @@ -48,13 +49,13 @@ ifeq ($(CONFIG_FIVE_USE_TRUSTONIC), y) else $(error "Unknown SoC") endif - ccflags-$(CONFIG_FIVE_TEE_DRIVER) += -I$(srctree)/drivers/gud/gud-$(PLATFORM)/MobiCoreDriver - ccflags-$(CONFIG_FIVE_TEE_DRIVER) += -I$(srctree)/drivers/gud/gud-$(PLATFORM)/MobiCoreDriver/public + ccflags-y += -I$(srctree)/drivers/gud/gud-$(PLATFORM)/MobiCoreDriver + ccflags-y += -I$(srctree)/drivers/gud/gud-$(PLATFORM)/MobiCoreDriver/public endif # CONFIG_MACH_MT6768 endif # CONFIG_FIVE_USE_TRUSTONIC # QSEE -obj-$(CONFIG_FIVE_USE_QSEE) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ +fiveteedriver-$(CONFIG_FIVE_USE_QSEE) += $(TEEC_CLIENT_PATH)/tee_client_api.o \ $(PROTOCOL_PATH)/teec_param_utils.o \ $(TEEC_CLIENT_PATH)/teec_common_qsee.o \ $(TEEC_CLIENT_PATH)/teec_operation.o @@ -82,14 +83,14 @@ ifeq ($(CONFIG_SOC_EXYNOS7885), y) endif ifeq ($(use_teegris_v2), y) - obj-$(CONFIG_FIVE_USE_TZDEV) += $(TEEC_CLIENT_PATH)/teec_common_teegris_v2.o \ + fiveteedriver-$(CONFIG_FIVE_USE_TZDEV) += $(TEEC_CLIENT_PATH)/teec_common_teegris_v2.o \ $(TEEC_CLIENT_PATH)/tee_client_api.o \ $(PROTOCOL_PATH)/teec_param_utils.o \ $(TEEC_CLIENT_PATH)/teec_operation.o ccflags-$(CONFIG_FIVE_USE_TZDEV) += -I$(srctree)/drivers/misc/tzdev/include \ -I$(FIVE_TEE_DRIVER_PATH)/multibuild/include/gp-api else - obj-$(CONFIG_FIVE_USE_TZDEV) += $(TEEC_CLIENT_PATH)/teec_operation_teegris_v3.o + fiveteedriver-$(CONFIG_FIVE_USE_TZDEV) += $(TEEC_CLIENT_PATH)/teec_operation_teegris_v3.o ccflags-$(CONFIG_FIVE_USE_TZDEV) += -I$(srctree)/drivers/misc/tzdev/include/tzdev endif diff --git a/drivers/security/samsung/five_tee_driver/five_ta_uuid.h b/drivers/security/samsung/five_tee_driver/five_ta_uuid.h index b615e2d21..0a574fdf6 100644 --- a/drivers/security/samsung/five_tee_driver/five_ta_uuid.h +++ b/drivers/security/samsung/five_tee_driver/five_ta_uuid.h @@ -25,6 +25,14 @@ static const TEEC_UUID five_ta_uuid = { .clockSeqAndNode = {0x00, 0x00, 0x00, 0x00, 0x46, 0x49, 0x56, 0x45}, }; #elif defined(CONFIG_FIVE_USE_QSEE) +#ifdef CONFIG_ARCH_LAHAINA +static const TEEC_UUID five_ta_uuid = { + .timeLow = 0x66697665, + .timeMid = 0x5f61, + .timeHiAndVersion = 0x7070, + .clockSeqAndNode = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +}; +#else #ifdef CONFIG_ARCH_MSM8917 static const TEEC_UUID five_ta_uuid = { .timeLow = 0x6d736d38, @@ -40,6 +48,7 @@ static const TEEC_UUID five_ta_uuid = { .clockSeqAndNode = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }; #endif // CONFIG_ARCH_MSM8917 +#endif // CONFIG_ARCH_LAHAINA #elif defined(CONFIG_FIVE_USE_TRUSTONIC) static const TEEC_UUID five_ta_uuid = { .timeLow = 0xffffffff, diff --git a/drivers/security/samsung/five_tee_driver/five_tee_driver.c b/drivers/security/samsung/five_tee_driver/five_tee_driver.c index a514a038d..6c49f0fd9 100644 --- a/drivers/security/samsung/five_tee_driver/five_tee_driver.c +++ b/drivers/security/samsung/five_tee_driver/five_tee_driver.c @@ -19,10 +19,10 @@ #include #include #include -#include + #include "tee_client_api.h" #include "five_ta_uuid.h" -#include "five_audit.h" +#include "five_tee_interface.h" #include "teec_operation.h" #ifdef CONFIG_TEE_DRIVER_DEBUG @@ -209,8 +209,7 @@ static int send_cmd(unsigned int cmd, rc = TEEC_AllocateSharedMemory(context, &shmem); if (rc != TEEC_SUCCESS || shmem.buffer == NULL) { mutex_unlock(&itee_driver_lock); - five_audit_tee_msg("send_cmd", - "TEEC_AllocateSharedMemory is failed", rc, 0); + pr_err("FIVE: TEEC_AllocateSharedMemory is failed rc=%d\n", rc); rc = -ENOMEM; goto out; } @@ -235,12 +234,12 @@ static int send_cmd(unsigned int cmd, if (rc == TEEC_SUCCESS) { if (origin != TEEC_ORIGIN_TRUSTED_APP) { rc = -EIO; - five_audit_tee_msg("send_cmd", - "TEEC_InvokeCommand is failed", rc, origin); + pr_err("FIVE: TEEC_InvokeCommand is failed rc=%d origin=%u\n", + rc, origin); } } else { - five_audit_tee_msg("send_cmd", "TEEC_InvokeCommand is failed.", - rc, origin); + pr_err("FIVE: TEEC_InvokeCommand is failed rc=%d origin=%u\n", + rc, origin); } if (rc == TEEC_SUCCESS && cmd == CMD_SIGN) { @@ -318,31 +317,8 @@ static int send_cmd_with_retry(unsigned int cmd, } } while (retry_num--); - if (rc == TEEC_ERROR_ACCESS_DENIED) { - five_audit_tee_msg("send_cmd_with_retry", - "TA got TEEC_ERROR_ACCESS_DENIED", rc, 0); - } - - return rc; -} - -static int send_cmd_kthread_vec(struct tee_msg *cmd_iovec, const size_t iovcnt) -{ - int rc = 0; - struct completion cmd_sent; - size_t i; - - init_completion(&cmd_sent); - cmd_iovec[iovcnt - 1].comp = &cmd_sent; - - for (i = 0; i < iovcnt; ++i) { - spin_lock(&tee_msg_lock); - list_add_tail(&cmd_iovec[i].queue, &tee_msg_queue); - spin_unlock(&tee_msg_lock); - } - - wake_up_process(tee_msg_task); - wait_for_completion(&cmd_sent); + if (rc == TEEC_ERROR_ACCESS_DENIED) + pr_err("FIVE: TA got TEEC_ERROR_ACCESS_DENIED rc=%d\n", rc); return rc; } @@ -356,39 +332,6 @@ static int verify_hmac(const struct tee_iovec *verify_args) (size_t *)&verify_args->signature_len); } -static int verify_hmac_vec(struct tee_iovec *verify_iovec, - const size_t verify_iovcnt) -{ - int rc = 0; - struct tee_msg *cmd_vec; - size_t i; - - cmd_vec = kcalloc(verify_iovcnt, sizeof(*cmd_vec), GFP_KERNEL); - if (!cmd_vec) - return -ENOMEM; - - for (i = 0; i < verify_iovcnt; ++i) { - cmd_vec[i].cmd = CMD_VERIFY; - cmd_vec[i].algo = verify_iovec[i].algo; - cmd_vec[i].hash = verify_iovec[i].hash; - cmd_vec[i].hash_len = verify_iovec[i].hash_len; - cmd_vec[i].label = verify_iovec[i].label; - cmd_vec[i].label_len = verify_iovec[i].label_len; - cmd_vec[i].signature = (void *)verify_iovec[i].signature; - cmd_vec[i].signature_len = - (size_t *)&verify_iovec[i].signature_len; - cmd_vec[i].rc = -EBADMSG; - } - - rc = send_cmd_kthread_vec(cmd_vec, verify_iovcnt); - - for (i = 0; i < verify_iovcnt; ++i) - verify_iovec[i].rc = cmd_vec[i].rc; - - kfree(cmd_vec); - return rc; -} - static int sign_hmac(struct tee_iovec *sign_args) { return send_cmd_kthread(CMD_SIGN, sign_args->algo, @@ -398,38 +341,6 @@ static int sign_hmac(struct tee_iovec *sign_args) &sign_args->signature_len); } -static int sign_hmac_vec(struct tee_iovec *sign_iovec, - const size_t iovcnt) -{ - int rc = 0; - struct tee_msg *cmd_vec; - size_t i; - - cmd_vec = kcalloc(iovcnt, sizeof(*cmd_vec), GFP_KERNEL); - if (!cmd_vec) - return -ENOMEM; - - for (i = 0; i < iovcnt; ++i) { - cmd_vec[i].cmd = CMD_SIGN; - cmd_vec[i].algo = sign_iovec[i].algo; - cmd_vec[i].hash = sign_iovec[i].hash; - cmd_vec[i].hash_len = sign_iovec[i].hash_len; - cmd_vec[i].label = sign_iovec[i].label; - cmd_vec[i].label_len = sign_iovec[i].label_len; - cmd_vec[i].signature = sign_iovec[i].signature; - cmd_vec[i].signature_len = &sign_iovec[i].signature_len; - cmd_vec[i].rc = -EBADMSG; - } - - rc = send_cmd_kthread_vec(cmd_vec, iovcnt); - - for (i = 0; i < iovcnt; ++i) - sign_iovec[i].rc = cmd_vec[i].rc; - - kfree(cmd_vec); - return rc; -} - static int load_trusted_app(void) { TEEC_Result rc; @@ -443,8 +354,7 @@ static int load_trusted_app(void) rc = TEEC_InitializeContext(NULL, context); if (rc) { - five_audit_tee_msg("load_trusted_app", "Can't initialize context", - rc, 0); + pr_err("FIVE: Can't initialize context rc=%d\n", rc); goto error; } @@ -457,7 +367,7 @@ static int load_trusted_app(void) rc = TEEC_OpenSession(context, session, &five_ta_uuid, 0, NULL, NULL, &origin); if (rc) { - five_audit_tee_msg("load_trusted_app", "Can't open session", + pr_err("FIVE: Can't open session rc=%d origin=%u\n", rc, origin); goto error; } @@ -479,9 +389,7 @@ static int register_tee_driver(void) { struct five_tee_driver_fns fn = { .verify_hmac = verify_hmac, - .verify_hmac_vec = verify_hmac_vec, .sign_hmac = sign_hmac, - .sign_hmac_vec = sign_hmac_vec, }; return register_five_tee_driver(&fn); @@ -507,90 +415,6 @@ static void unload_trusted_app(void) #ifdef CONFIG_TEE_DRIVER_DEBUG -static int sign_hmac_vec_test(void) -{ - uint8_t hash[SHA1_DIGEST_SIZE][3]; - uint8_t signature[SHA1_DIGEST_SIZE][3]; - size_t signature_len[3] = { - SHA1_DIGEST_SIZE, - SHA1_DIGEST_SIZE, - SHA1_DIGEST_SIZE - }; - struct tee_iovec sign_iovec[] = { - { - .algo = HASH_ALGO_SHA1, - .hash = hash[0], - .hash_len = SHA1_DIGEST_SIZE, - .signature = signature[0], - .signature_len = signature_len[0], - .label_len = sizeof("label 1"), - .label = "label 1", - }, - { - .algo = HASH_ALGO_SHA1, - .hash = hash[1], - .hash_len = SHA1_DIGEST_SIZE, - .signature = signature[1], - .signature_len = signature_len[1], - .label_len = sizeof("label 2 xxxxx"), - .label = "label 2 xxxxx", - }, - { - .algo = HASH_ALGO_SHA1, - .hash = hash[2], - .hash_len = SHA1_DIGEST_SIZE, - .signature = signature[2], - .signature_len = signature_len[2], - .label_len = sizeof("label 3 zxzxzzzz"), - .label = "label 3 zxzxzzzz", - }, - }; - - return sign_hmac_vec(sign_iovec, ARRAY_SIZE(sign_iovec)); -} - -static int verify_hmac_vec_test(void) -{ - uint8_t hash[SHA1_DIGEST_SIZE][3]; - uint8_t signature[SHA1_DIGEST_SIZE][3]; - size_t signature_len[3] = { - SHA1_DIGEST_SIZE, - SHA1_DIGEST_SIZE, - SHA1_DIGEST_SIZE - }; - struct tee_iovec verify_iovec[] = { - { - .algo = HASH_ALGO_SHA1, - .hash = hash[0], - .hash_len = SHA1_DIGEST_SIZE, - .signature = signature[0], - .signature_len = signature_len[0], - .label_len = sizeof("label 1"), - .label = "label 1", - }, - { - .algo = HASH_ALGO_SHA1, - .hash = hash[1], - .hash_len = SHA1_DIGEST_SIZE, - .signature = signature[1], - .signature_len = signature_len[1], - .label_len = sizeof("label 2 xxxxx"), - .label = "label 2 xxxxx", - }, - { - .algo = HASH_ALGO_SHA1, - .hash = hash[2], - .hash_len = SHA1_DIGEST_SIZE, - .signature = signature[2], - .signature_len = signature_len[2], - .label_len = sizeof("label 3 zxzxzzzz"), - .label = "label 3 zxzxzzzz", - }, - }; - - return verify_hmac_vec(verify_iovec, ARRAY_SIZE(verify_iovec)); -} - static ssize_t tee_driver_write( struct file *file, const char __user *buf, size_t count, loff_t *pos) @@ -642,12 +466,6 @@ static ssize_t tee_driver_write( unload_trusted_app(); mutex_unlock(&itee_driver_lock); break; - case '5': - pr_info("sign_hmac_vec: %d\n", sign_hmac_vec_test()); - break; - case '6': - pr_info("verify_hmac_vec: %d\n", verify_hmac_vec_test()); - break; default: pr_err("FIVE: %s: unknown cmd: %hhx\n", __func__, command); return -EINVAL; @@ -725,5 +543,8 @@ static void __exit tee_driver_exit(void) kthread_stop(tee_msg_task); } +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("FIVE TEE Driver"); + module_init(tee_driver_init); module_exit(tee_driver_exit); diff --git a/drivers/security/samsung/five_tee_driver/five_tee_interface.h b/drivers/security/samsung/five_tee_driver/five_tee_interface.h new file mode 100644 index 000000000..6ff986d05 --- /dev/null +++ b/drivers/security/samsung/five_tee_driver/five_tee_interface.h @@ -0,0 +1,47 @@ +/* + * Interface for TEE Driver + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 INTEGRITY_TEE_DRIVER_H +#define INTEGRITY_TEE_DRIVER_H + +#include +#include + +struct tee_iovec { + enum hash_algo algo; + + const void *hash; + size_t hash_len; + + const void *label; + size_t label_len; + + void *signature; + size_t signature_len; + + int rc; +}; + +struct five_tee_driver_fns { + int (*verify_hmac)(const struct tee_iovec *verify_args); + int (*sign_hmac)(struct tee_iovec *sign_args); +}; + +int register_five_tee_driver( + struct five_tee_driver_fns *tee_driver_fns); +void unregister_five_tee_driver(void); + +#endif diff --git a/drivers/security/samsung/five_tee_driver/multibuild/source/gp-api/client/teec_common_qsee.c b/drivers/security/samsung/five_tee_driver/multibuild/source/gp-api/client/teec_common_qsee.c index a5d295378..440e8159c 100644 --- a/drivers/security/samsung/five_tee_driver/multibuild/source/gp-api/client/teec_common_qsee.c +++ b/drivers/security/samsung/five_tee_driver/multibuild/source/gp-api/client/teec_common_qsee.c @@ -40,6 +40,8 @@ #define SBUF_LEN (sizeof(ProtocolCmd) + MAX_SHAREDMEM_SIZE) #define RBUF_LEN (QSEECOM_ALIGN(SBUF_LEN) - SBUF_LEN + QSEECOM_ALIGN_SIZE) +#define TA_LOAD_RETRY 5 + typedef struct QseeSessionStruct { struct qseecom_handle *qsee_com_handle; struct qseecom_handle *listener_handle; @@ -103,6 +105,7 @@ TEEC_Result QseeLoadTA(void *ta_session, const TEEC_UUID *uuid) char ta_name[MAX_QSEE_UUID_LEN] = "five/"; char qsee_uuid[MAX_QSEE_UUID_LEN] = {0}; QseeSession *qsee_session = (QseeSession *)ta_session; + unsigned int retry_num = 0; if (!ta_session || !uuid || TEEC_SUCCESS != TeecUuidToQseeUuid(uuid, qsee_uuid)) { @@ -119,30 +122,41 @@ TEEC_Result QseeLoadTA(void *ta_session, const TEEC_UUID *uuid) BUILD_BUG_ON((SBUF_LEN + RBUF_LEN) & QSEECOM_ALIGN_MASK); - qsee_res = qseecom_start_app(&qsee_session->qsee_com_handle, - ta_name, - SBUF_LEN + RBUF_LEN); - if (qsee_res != QSEE_SUCCESS) { + do { + ++retry_num; + qsee_res = qseecom_start_app(&qsee_session->qsee_com_handle, + ta_name, + SBUF_LEN + RBUF_LEN); + if (qsee_res == QSEE_SUCCESS) { + pr_info("FIVE: Load trusted app from five dir attempt: %u\n", + retry_num); + status = TEEC_SUCCESS; + break; + } + if (qsee_res == -EIO) { qsee_res = qseecom_start_app( - &qsee_session->qsee_com_handle, - qsee_uuid, - SBUF_LEN + RBUF_LEN); + &qsee_session->qsee_com_handle, + qsee_uuid, + SBUF_LEN + RBUF_LEN); if (qsee_res != QSEE_SUCCESS) { + pr_err("FIVE: Can't load trusted app after -EIO attempt: %u result: %d\n", + retry_num, qsee_res); status = qsee_res == -EINVAL ? - TEEC_ERROR_TARGET_DEAD : TEEC_ERROR_GENERIC; + TEEC_ERROR_TARGET_DEAD : TEEC_ERROR_GENERIC; } else { - pr_info("FIVE: Load trusted app\n"); + pr_info("FIVE: Load trusted app attempt: %u\n", + retry_num); status = TEEC_SUCCESS; + break; } } else { - status = qsee_res == -EINVAL ? TEEC_ERROR_TARGET_DEAD : - TEEC_ERROR_GENERIC; + pr_err("FIVE: Can't load trusted app attempt: %u result: %d\n", + retry_num, qsee_res); + status = qsee_res == -EINVAL ? + TEEC_ERROR_TARGET_DEAD : TEEC_ERROR_GENERIC; } - } else { - pr_info("FIVE: Load trusted app from five dir\n"); - } - + } while (retry_num < TA_LOAD_RETRY); exit: return status; } diff --git a/drivers/security/samsung/icdrv/Makefile b/drivers/security/samsung/icdrv/Makefile index 058481bd5..841897185 100644 --- a/drivers/security/samsung/icdrv/Makefile +++ b/drivers/security/samsung/icdrv/Makefile @@ -3,6 +3,7 @@ # ccflags-$(CONFIG_TZDEV) += -I$(srctree)/drivers/misc/tzdev/include +MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) obj-$(CONFIG_ICD) += icd.o oemflag.o ccflags-$(CONFIG_ICD) += -I$(srctree)/security/samsung/five @@ -20,8 +21,10 @@ else ccflags-$(CONFIG_ICD_USE_TZDEV) += -I$(srctree)/drivers/misc/tzdev endif -ifneq (,$(filter $(CONFIG_MTK_PLATFORM), "mt6768")) - obj-y += kinibi_atf_oemflag.o +ifeq ($(MTK_PLATFORM), mt6768) +ifeq ($(filter a32%, $(TARGET_PRODUCT)),) + icd_driver-y += kinibi_atf_oemflag.o +endif else obj-$(CONFIG_ICD_USE_TRUSTONIC) += kinibi_oemflag.o endif diff --git a/drivers/security/samsung/icdrv/oemflag.c b/drivers/security/samsung/icdrv/oemflag.c index 4a5596d0c..8182b0913 100644 --- a/drivers/security/samsung/icdrv/oemflag.c +++ b/drivers/security/samsung/icdrv/oemflag.c @@ -39,24 +39,27 @@ int oem_flags_set(enum oemflag_id index) if (name > OEMFLAG_MIN_FLAG && name < OEMFLAG_NUM_OF_FLAG) { if (check_flags(name)) { pr_info("[oemflag]flag is already set. %u\n", name); - return 0; + return OEMFLAG_SUCCESS; } pr_info("[oemflag]set_fuse_name : %u\n", name); ret = set_tamper_fuse(name); - if (ret) + if (ret) { pr_err("set_tamper_fuse error: ret=%d\n", ret); + return OEMFLAG_FAIL; + } ret = get_tamper_fuse(name); - if (!ret) + if (!ret) { pr_err("get_tamper_fuse error: ret=%d\n", ret); + return OEMFLAG_FAIL; + } oem_flags_check[name] = 1; } else { pr_info("[oemflag]param name is wrong\n"); - ret = -EINVAL; + return -EINVAL; } - - return ret; + return OEMFLAG_SUCCESS; } int oem_flags_get(enum oemflag_id index) diff --git a/drivers/security/samsung/icdrv/oemflag.h b/drivers/security/samsung/icdrv/oemflag.h index c68988e7c..1c18f311a 100644 --- a/drivers/security/samsung/icdrv/oemflag.h +++ b/drivers/security/samsung/icdrv/oemflag.h @@ -17,6 +17,9 @@ #ifndef __OEM_FLAG_H #define __OEM_FLAG_H +#define OEMFLAG_SUCCESS 0 +#define OEMFLAG_FAIL -1 + enum oemflag_id { OEMFLAG_NONE = 0, OEMFLAG_MIN_FLAG = 2, diff --git a/drivers/security/samsung/tzic/Kconfig b/drivers/security/samsung/tzic/Kconfig index 1bfa20da2..48f1ec2ae 100644 --- a/drivers/security/samsung/tzic/Kconfig +++ b/drivers/security/samsung/tzic/Kconfig @@ -3,7 +3,7 @@ # config TZIC - bool "TZIC Driver" + tristate "TZIC Driver" default y ---help--- Enable TZIC Driver support. @@ -13,14 +13,14 @@ choice depends on TZIC default TZIC_USE_QSEECOM if QSEECOM default TZIC_USE_TZDEV if TZDEV - default TZIC_USE_TRUSTONIC if TRUSTONIC_TEE + default TZIC_USE_TRUSTONIC if TRUSTONIC_TEE || TRUSTONIC_TEE_SUPPORT default TZIC_DEFAULT ---help--- Select Secure OS for TZIC config TZIC_USE_TRUSTONIC bool "TZIC based on Trustonic Secure OS" - depends on TRUSTONIC_TEE + depends on TRUSTONIC_TEE || TRUSTONIC_TEE_SUPPORT ---help--- Use Trustonic as base Trusted Execution Environment diff --git a/drivers/security/samsung/tzic/Makefile b/drivers/security/samsung/tzic/Makefile index 00171de4b..3692ba6ca 100644 --- a/drivers/security/samsung/tzic/Makefile +++ b/drivers/security/samsung/tzic/Makefile @@ -4,25 +4,33 @@ ccflags-$(CONFIG_TZDEV) += -I$(srctree)/drivers/misc/tzdev/include MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) -obj-$(CONFIG_TZIC) += tzic64.o + +ifeq ($(CONFIG_ARCH_LAHAINA),y) + ifeq ($(CONFIG_QGKI), y) + obj-m += tzic_driver.o + endif +else + obj-$(CONFIG_TZIC) += tzic_driver.o +endif + +tzic_driver-y += tzic64.o EXTRA_CFLAGS += -I$(src) -obj-$(CONFIG_TZIC_USE_QSEECOM) += tzic_qsee.o -obj-$(CONFIG_TZIC_USE_TZDEV) += tzic_tzdev.o + +tzic_driver-$(CONFIG_TZIC_USE_QSEECOM) += tzic_qsee.o +tzic_driver-$(CONFIG_TZIC_USE_TZDEV) += tzic_tzdev.o ifneq ($(CONFIG_TZIC_EXYNOS7885),) - ifeq ($(CONFIG_TEEGRIS_VERSION), 3) - ccflags-$(CONFIG_TZIC_USE_TZDEV) += -Idrivers/misc/tzdev/3.0 - else - ccflags-$(CONFIG_TZIC_USE_TZDEV) += -Idrivers/misc/tzdev - endif + ccflags-$(CONFIG_TZIC_USE_TZDEV) += -I$(srctree)/drivers/misc/tzdev/3.0 else -ccflags-$(CONFIG_TZIC_USE_TZDEV) += -Idrivers/misc/tzdev + ccflags-$(CONFIG_TZIC_USE_TZDEV) += -I$(srctree)/drivers/misc/tzdev endif + ifeq ($(MTK_PLATFORM),mt6768) - obj-y += tzic_mtk_atf.o + tzic_driver-$(CONFIG_TZIC_USE_TRUSTONIC) += tzic_mtk_atf.o else - obj-$(CONFIG_TZIC_USE_TRUSTONIC) += tzic_kinibi.o - obj-$(CONFIG_TZIC_DEFAULT) += tzic_default.o + tzic_driver-$(CONFIG_TZIC_USE_TRUSTONIC) += tzic_kinibi.o endif +tzic_driver-$(CONFIG_TZIC_DEFAULT) += tzic_default.o + ccflags-y += -Wformat diff --git a/drivers/security/samsung/tzic/tzic64.c b/drivers/security/samsung/tzic/tzic64.c index c8ff9af1f..eec781b54 100644 --- a/drivers/security/samsung/tzic/tzic64.c +++ b/drivers/security/samsung/tzic/tzic64.c @@ -373,9 +373,9 @@ static int gotoAllCpu(void) } #endif -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Samsung TZIC Driver"); MODULE_VERSION("1.00"); module_init(tzic_init); -module_exit(tzic_exit); \ No newline at end of file +module_exit(tzic_exit); diff --git a/drivers/security/samsung/tzic/tzic_qsee.c b/drivers/security/samsung/tzic/tzic_qsee.c index 0614c6eb8..0c7ec3292 100644 --- a/drivers/security/samsung/tzic/tzic_qsee.c +++ b/drivers/security/samsung/tzic/tzic_qsee.c @@ -18,7 +18,12 @@ #include #include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) #include +#else +#include +#endif #include "tzic.h" #ifndef SCM_SVC_FUSE @@ -36,8 +41,13 @@ static int set_tamper_fuse_qsee(uint32_t index) desc.args[0] = fuse_id = index; desc.arginfo = SCM_ARGS(1); +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) return scm_call2(SCM_SIP_FNID(SCM_SVC_FUSE, SCM_BLOW_SW_FUSE_ID), &desc); +#else + return qcom_scm_qseecom_call(SCM_SIP_FNID(SCM_SVC_FUSE, SCM_BLOW_SW_FUSE_ID), + &desc); +#endif } static int get_tamper_fuse_qsee(uint32_t index) @@ -53,8 +63,13 @@ static int get_tamper_fuse_qsee(uint32_t index) desc.args[0] = fuse_id = index; desc.arginfo = SCM_ARGS(1); +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) ret = scm_call2(SCM_SIP_FNID(SCM_SVC_FUSE, SCM_IS_SW_FUSE_BLOWN_ID), &desc); +#else + ret = qcom_scm_qseecom_call(SCM_SIP_FNID(SCM_SVC_FUSE, SCM_IS_SW_FUSE_BLOWN_ID), + &desc); +#endif resp_buf = desc.ret[0]; if (ret) { diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 9399845a7..784084caf 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -229,3 +229,9 @@ config SEC_SLPI_SLEEP_DEBUG help Say Y to make a force crash when slpi can not enter low power mode Say N to make silent restart when slpi can not enter low power mode + +config SEC_SENSORS_ENG_DEBUG + tristate "For debugging sensors" + default n + help + Say Y to provide debugging, crash etc only ENG binary. diff --git a/drivers/sensors/a96t3x6.c b/drivers/sensors/a96t3x6.c index 4905d13cc..3d3173eec 100755 --- a/drivers/sensors/a96t3x6.c +++ b/drivers/sensors/a96t3x6.c @@ -33,6 +33,7 @@ #include #include #include +#include #if defined(CONFIG_MUIC_NOTIFIER) #include #include @@ -630,13 +631,16 @@ static void a96t3x6_firmware_work_func(struct work_struct *work) ret = a96t3x6_fw_check(data); if (ret) { if (data->firmware_count++ < FIRMWARE_VENDOR_CALL_CNT) { - GRIP_ERR("failed to load firmware (%d)\n", + GRIP_ERR("failed to load firmware ret %d(%d)\n", ret, data->firmware_count); schedule_delayed_work(&data->firmware_work, msecs_to_jiffies(1000)); return; } GRIP_ERR("final retry failed\n"); +#ifdef CONFIG_SEC_SENSORS_ENG_DEBUG + panic("grip fw doesn't exist\n"); +#endif } else { GRIP_INFO("fw check success\n"); } @@ -2856,6 +2860,10 @@ static int a96t3x6_fw_check(struct a96t3x6_data *data) data->md_ver, data->md_ver_bin); return ret; } +#elif defined(CONFIG_SEC_SENSORS_ENG_DEBUG) + if (ret) { + panic("grip fw doesn't exist\n"); + } #endif ret = a96t3x6_get_fw_version(data, true); if (!ret) { @@ -3344,6 +3352,12 @@ static struct i2c_driver a96t3x6_driver = { static int __init a96t3x6_init(void) { +#if IS_ENABLED(CONFIG_BATTERY_SAMSUNG) + if (lpcharge) { + GRIP_ERR("%s: lpm : Do not load driver\n", __func__); + return 0; + } +#endif return i2c_add_driver(&a96t3x6_driver); } diff --git a/drivers/sensors/a96t3x6.h b/drivers/sensors/a96t3x6.h index f789aa28c..3bb4da1fa 100755 --- a/drivers/sensors/a96t3x6.h +++ b/drivers/sensors/a96t3x6.h @@ -157,4 +157,8 @@ enum { SDCARD, }; +#if IS_ENABLED(CONFIG_BATTERY_SAMSUNG) +extern unsigned int lpcharge; +#endif + #endif /* LINUX_A96T3X6_H */ diff --git a/drivers/sensors/vl53l5/src/vl53l5_k_ioctl_controls.c b/drivers/sensors/vl53l5/src/vl53l5_k_ioctl_controls.c index 6b7acbd7c..2b7d8f591 100644 --- a/drivers/sensors/vl53l5/src/vl53l5_k_ioctl_controls.c +++ b/drivers/sensors/vl53l5/src/vl53l5_k_ioctl_controls.c @@ -767,7 +767,7 @@ int vl53l5_ioctl_init(struct vl53l5_k_module_t *p_module) vl53l5_k_power_onoff(p_module, p_module->iovdd_vreg, p_module->iovdd_vreg_name, 0); vl53l5_k_power_onoff(p_module, p_module->avdd_vreg, p_module->avdd_vreg_name, 0); - usleep_range(10000, 10100); + msleep(20); vl53l5_k_power_onoff(p_module, p_module->avdd_vreg, p_module->avdd_vreg_name, 1); usleep_range(1000, 1100); vl53l5_k_power_onoff(p_module, p_module->iovdd_vreg, p_module->iovdd_vreg_name, 1); diff --git a/drivers/sensors/vl53l5/src/vl53l5_k_module.c b/drivers/sensors/vl53l5/src/vl53l5_k_module.c index 5e45d194b..7596106b2 100644 --- a/drivers/sensors/vl53l5/src/vl53l5_k_module.c +++ b/drivers/sensors/vl53l5/src/vl53l5_k_module.c @@ -641,7 +641,7 @@ static ssize_t vl53l5_distance_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vl53l5_k_module_t *p_module = dev_get_drvdata(dev); - uint32_t i = 0, j = 0, c = 0, idx = 0; + uint32_t i = 0, j = 0, idx = 0; int min = 0, max = 0, avg = 0; int status = STATUS_OK; @@ -684,23 +684,14 @@ static ssize_t vl53l5_distance_show(struct device *dev, } out: if (p_module->read_data_valid) { - if (!p_module->test_mode) { /* 300 mm test 64 zone. */ - for (i = 0; i < p_module->print_counter; i++) { - for (j = 0; j < p_module->print_counter; j++) { - idx = (i * p_module->print_counter + j) * p_module->max_targets_per_zone; - p_module->data[idx / p_module->max_targets_per_zone] = (p_module->range_data.core.per_tgt_results.target_status[idx] == 5 || - p_module->range_data.core.per_tgt_results.target_status[idx] == 9) ? - p_module->range_data.core.per_tgt_results.median_range_mm[idx] >> 2 : 0; - } - } - } else { - for (i = 2; i < p_module->print_counter - 2 ; i++) { - for (j = 2; j < p_module->print_counter - 2; j++) { - idx = (i * p_module->print_counter + j) * p_module->max_targets_per_zone; - p_module->data[c++] = (p_module->range_data.core.per_tgt_results.target_status[idx] == 5 || - p_module->range_data.core.per_tgt_results.target_status[idx] == 9) ? - p_module->range_data.core.per_tgt_results.median_range_mm[idx] >> 2 : 0; - } + for (i = 0; i < p_module->print_counter; i++) { + for (j = 0; j < p_module->print_counter; j++) { + idx = (i * p_module->print_counter + j) * p_module->max_targets_per_zone; + p_module->data[idx / p_module->max_targets_per_zone] = + (p_module->range_data.core.per_tgt_results.target_status[idx] == 5 || + p_module->range_data.core.per_tgt_results.target_status[idx] == 9) ? + p_module->range_data.core.per_tgt_results.median_range_mm[idx] >> 2 : 0; + } } } else { @@ -709,17 +700,10 @@ static ssize_t vl53l5_distance_show(struct device *dev, } } - min = max = avg = p_module->data[0]; - if (!p_module->test_mode) { /* 300 mm test 64 zone. */ - for (i = 1; i < p_module->number_of_zones; i++) { - if (p_module->data[i] < min) - min = p_module->data[i]; - if (max < p_module->data[i]) - max = p_module->data[i]; - avg += p_module->data[i]; - } - } else { - for (i = 1; i < TEST_500_MM_MAX_ZONE; i++) { + min = max = avg = p_module->data[1]; + + for (i = 2; i < p_module->number_of_zones; i++) { + if ((i != 7) && (i != 56) && (i != 63)) { if (p_module->data[i] < min) min = p_module->data[i]; if (max < p_module->data[i]) @@ -735,32 +719,23 @@ static ssize_t vl53l5_distance_show(struct device *dev, p_module->data[i+6], p_module->data[i+7]); } - if (!p_module->test_mode) /* 300 mm test 64 zone. */ - avg = avg / p_module->number_of_zones; - else - avg = avg / (p_module->number_of_zones >> 2); + avg = avg / (p_module->number_of_zones - 4); i = j = 0; - if (!p_module->test_mode) { /* 300 mm test 64 zone. */ - j += snprintf(buf + j, PAGE_SIZE - j, "Distance,%d,%d,%d,%d,%d,", - DISTANCE_300MM_MIN_SPEC, DISTANCE_300MM_MAX_SPEC, min, max, avg); - for (; i < TEST_300_MM_MAX_ZONE; i++) { - j += snprintf(buf + j, PAGE_SIZE - j, "%d", p_module->data[i]); - if(i != p_module->number_of_zones - 1) - j += snprintf(buf + j, PAGE_SIZE - j, ","); - else - j += snprintf(buf + j, PAGE_SIZE - j, "\n"); - } - } else { - j += snprintf(buf + j, PAGE_SIZE - j, "Distance,%d,%d,%d,%d,%d,", - DISTANCE_500MM_MIN_SPEC, DISTANCE_500MM_MAX_SPEC, min, max, avg); - for (; i < TEST_500_MM_MAX_ZONE; i++) { + + j += snprintf(buf + j, PAGE_SIZE - j, "Distance,%d,%d,%d,%d,%d,", + DISTANCE_300MM_MIN_SPEC, DISTANCE_300MM_MAX_SPEC, min, max, avg); + + for (; i < TEST_300_MM_MAX_ZONE; i++) { + if ((i != 0) &&(i != 7) && (i != 56) && (i != 63)) j += snprintf(buf + j, PAGE_SIZE - j, "%d", p_module->data[i]); - if(i != TEST_500_MM_MAX_ZONE - 1) - j += snprintf(buf + j, PAGE_SIZE - j, ","); - else - j += snprintf(buf + j, PAGE_SIZE - j, "\n"); - } + else + j += snprintf(buf + j, PAGE_SIZE - j, "N"); + + if (i != p_module->number_of_zones - 1) + j += snprintf(buf + j, PAGE_SIZE - j, ","); + else + j += snprintf(buf + j, PAGE_SIZE - j, "\n"); } return j; @@ -1193,7 +1168,7 @@ static ssize_t vl53l5_enable_store(struct device *dev, status = -1; } #endif - if (status != STATUS_OK) { + if ((status != STATUS_OK) || (p_module->last_driver_error != STATUS_OK)) { status = vl53l5_ioctl_init(p_module); vl53l5_k_log_error("fail reset %d", status); status = vl53l5_ioctl_stop(p_module, NULL, 1); diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 9160aab15..a4bbb3086 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -660,7 +660,7 @@ msm_get_crash(struct device *dev, { pr_err("intentional cdsp runtime failed! comment out-just footprint!\n"); #ifndef CONFIG_SEC_CDSP_NOT_CRASH_ENG - //BUG_ON(1); + BUG_ON(1); #endif /* CONFIG_SEC_CDSP_NOT_CRASH_ENG */ return snprintf(buf, PAGE_SIZE, "Qualcomm Technologies, Inc\n"); } diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 7e745c4da..8135f6c6c 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1124,7 +1124,7 @@ struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, task_cputime(current, &utime, &stime_e); stime_d = stime_e - stime_s; if (!IS_ERR(dmabuf) && stime_d / NSEC_PER_MSEC > 100) { - pr_info("%s ion_heap_id: %d mask=0x%x timeJS(ms):%u/%llu len:0x%zx", + pr_info("%s ion_heap_id: %d mask=0x%x timeJS(ms):%u/%llu len:0x%zu\n", __func__, heap->id, heap_id_mask, jiffies_to_msecs(jiffies - jiffies_s), stime_d / NSEC_PER_MSEC, len); @@ -1191,6 +1191,97 @@ int ion_alloc_fd(size_t len, unsigned int heap_id_mask, unsigned int flags) return fd; } +#define MAX_ION_ACC_PROCESS 16 /* should be smaller than bitmap */ +struct ion_size_account { + char task_comm[TASK_COMM_LEN]; + pid_t pid; + size_t size; +}; +static struct ion_size_account ion_size_acc[MAX_ION_ACC_PROCESS]; +static int ion_dbg_idx_new; +static int ion_dbg_idx_last; + +static inline int __ion_account_add_buf_locked(struct ion_buffer *buffer) +{ + int i; + + if (ion_dbg_idx_new && + (ion_size_acc[ion_dbg_idx_last].pid == buffer->pid)) { + ion_size_acc[ion_dbg_idx_last].size += buffer->size; + return 0; + } + for (i = 0; i < ion_dbg_idx_new; i++) { + if (ion_size_acc[i].pid == buffer->pid) { + ion_size_acc[i].size += buffer->size; + ion_dbg_idx_last = i; + return 0; + } + } + if (ion_dbg_idx_new == MAX_ION_ACC_PROCESS) { + pr_warn_once("out of ion_size_account idx\n"); + return -1; + } + ion_size_acc[ion_dbg_idx_new].pid = buffer->pid; + ion_size_acc[ion_dbg_idx_new].size = buffer->size; + strncpy(ion_size_acc[ion_dbg_idx_new].task_comm, buffer->task_comm, + TASK_COMM_LEN); + ion_dbg_idx_last = ion_dbg_idx_new++; + return 0; +} + +static inline void __ion_account_print_locked(void) +{ + int i, heaviest_idx; + size_t heaviest_size = 0; + size_t total = 0; + + if (!ion_dbg_idx_new) + return; + pr_info("ion_size: accounted by thread group\n"); + pr_info("ion_size: %16s( %3s ) %8s\n", "task_comm", "pid", "size(kb)"); + for (i = 0; i < ion_dbg_idx_new; i++) { + pr_info("[%d] %16s(%5u) %8zu\n", i, ion_size_acc[i].task_comm, + ion_size_acc[i].pid, ion_size_acc[i].size / SZ_1K); + if (heaviest_size < ion_size_acc[i].size) { + heaviest_size = ion_size_acc[i].size ; + heaviest_idx = i; + } + total += ion_size_acc[i].size; + } + if (heaviest_size) + pr_info("heaviest_task_ion:%s(%5u) size:%zuKB, total:%zuKB/%luKB\n", + ion_size_acc[heaviest_idx].task_comm, + ion_size_acc[heaviest_idx].pid, heaviest_size / SZ_1K, + total / SZ_1K, totalram_pages << (PAGE_SHIFT - 10)); +} + +bool ion_account_print_usage(void) +{ + struct rb_node *n; + struct ion_buffer *buffer; + unsigned int system_heap_id; + struct ion_device *dev = internal_dev; + bool locked; + + system_heap_id = get_ion_system_heap_id(); + if (IS_ERR(ERR_PTR(system_heap_id))) + return false; + locked = mutex_trylock(&dev->buffer_lock); + if (!locked) + return false; + ion_dbg_idx_new = 0; + ion_dbg_idx_last = -1; + for (n = rb_first(&dev->buffers); n; n = rb_next(n)) { + buffer = rb_entry(n, struct ion_buffer, node); + if (buffer->heap->id == system_heap_id) + __ion_account_add_buf_locked(buffer); + } + __ion_account_print_locked(); + mutex_unlock(&dev->buffer_lock); + + return true; +} + int ion_query_heaps(struct ion_heap_query *query) { struct ion_device *dev = internal_dev; diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index 9e8d06bdd..3413d6593 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2011, 2013-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2021, The Linux Foundation. All rights reserved. * Linux Foundation chooses to take subject only to the GPLv2 license terms, * and distributes only under these terms. * @@ -86,7 +86,7 @@ struct cserial { struct f_cdev { struct cdev fcdev_cdev; - struct device *dev; + struct device dev; unsigned int port_num; char name[sizeof(DEVICE_NAME) + 2]; int minor; @@ -873,13 +873,16 @@ static void cser_free_inst(struct usb_function_instance *fi) opts = container_of(fi, struct f_cdev_opts, func_inst); if (opts->port) { - device_destroy(fcdev_classp, MKDEV(major, opts->port->minor)); - cdev_del(&opts->port->fcdev_cdev); + cdev_device_del(&opts->port->fcdev_cdev, &opts->port->dev); + mutex_lock(&chardev_ida_lock); + ida_simple_remove(&chardev_ida, opts->port->minor); + mutex_unlock(&chardev_ida_lock); usb_cser_debugfs_exit(opts->port); + put_device(&opts->port->dev); } + usb_cser_chardev_deinit(); kfree(opts->func_name); - kfree(opts->port); kfree(opts); } @@ -1103,13 +1106,10 @@ int f_cdev_open(struct inode *inode, struct file *file) struct f_cdev *port; port = container_of(inode->i_cdev, struct f_cdev, fcdev_cdev); - if (!port) { - pr_err("Port is NULL.\n"); - return -EINVAL; - } - - if (port && port->port_open) { + get_device(&port->dev); + if (port->port_open) { pr_err("port is already opened.\n"); + put_device(&port->dev); return -EBUSY; } @@ -1119,6 +1119,7 @@ int f_cdev_open(struct inode *inode, struct file *file) port->is_connected); if (ret) { pr_debug("open interrupted.\n"); + put_device(&port->dev); return ret; } @@ -1138,16 +1139,12 @@ int f_cdev_release(struct inode *inode, struct file *file) struct f_cdev *port; port = file->private_data; - if (!port) { - pr_err("port is NULL.\n"); - return -EINVAL; - } - spin_lock_irqsave(&port->port_lock, flags); port->port_open = false; port->cbits_updated = false; spin_unlock_irqrestore(&port->port_lock, flags); pr_debug("port(%s)(%pK) is closed.\n", port->name, port); + put_device(&port->dev); return 0; } @@ -1714,11 +1711,17 @@ static void usb_cser_debugfs_exit(struct f_cdev *port) debugfs_remove_recursive(port->debugfs_root); } +static void cdev_device_release(struct device *dev) +{ + struct f_cdev *port = container_of(dev, struct f_cdev, dev); + + pr_debug("Free cdev port(%d)\n", port->port_num); + kfree(port); +} + static struct f_cdev *f_cdev_alloc(char *func_name, int portno) { int ret; - dev_t dev; - struct device *device; struct f_cdev *port; port = kzalloc(sizeof(struct f_cdev), GFP_KERNEL); @@ -1768,27 +1771,24 @@ static struct f_cdev *f_cdev_alloc(char *func_name, int portno) /* create char device */ cdev_init(&port->fcdev_cdev, &f_cdev_fops); - dev = MKDEV(major, port->minor); - ret = cdev_add(&port->fcdev_cdev, dev, 1); + device_initialize(&port->dev); + port->dev.class = fcdev_classp; + port->dev.parent = NULL; + port->dev.release = cdev_device_release; + port->dev.devt = MKDEV(major, port->minor); + dev_set_name(&port->dev, "%s", port->name); + ret = cdev_device_add(&port->fcdev_cdev, &port->dev); if (ret) { pr_err("Failed to add cdev for port(%s)\n", port->name); goto err_cdev_add; } - device = device_create(fcdev_classp, NULL, dev, NULL, port->name); - if (IS_ERR(device)) { - ret = PTR_ERR(device); - goto err_create_dev; - } - usb_cser_debugfs_init(port); pr_info("port_name:%s (%pK) portno:(%d)\n", port->name, port, port->port_num); return port; -err_create_dev: - cdev_del(&port->fcdev_cdev); err_cdev_add: destroy_workqueue(port->fcdev_wq); err_get_ida: diff --git a/drivers/usb/gadget/function/f_conn_gadget.c b/drivers/usb/gadget/function/f_conn_gadget.c index 79ace3f6a..8a1a2d735 100644 --- a/drivers/usb/gadget/function/f_conn_gadget.c +++ b/drivers/usb/gadget/function/f_conn_gadget.c @@ -59,6 +59,7 @@ #include #include #include +#include /* platform specific definitions */ /* ex) #define __ANDROID__ */ @@ -124,6 +125,8 @@ struct conn_gadget_dev { /* flag variable that save flush call status * to check wakeup reason */ atomic_t flush; + + struct kref kref; }; static struct usb_interface_descriptor conn_gadget_interface_desc = { @@ -231,6 +234,7 @@ struct conn_gadget_instance { const char *name; }; +static void conn_gadget_cleanup(struct kref *kref); static inline struct conn_gadget_dev *func_to_conn_gadget(struct usb_function *f) { @@ -711,6 +715,11 @@ static int conn_gadget_open(struct inode *ip, struct file *fp) return -EBUSY; } + if (!kref_get_unless_zero(&_conn_gadget_dev->kref)) { + CONN_GADGET_ERR("already device removed\n"); + return -ENODEV; + } + fp->private_data = _conn_gadget_dev; /* clear the error latch */ @@ -757,6 +766,8 @@ static int conn_gadget_release(struct inode *ip, struct file *fp) atomic_set(&_conn_gadget_dev->flush, 0); conn_gadget_unlock(&_conn_gadget_dev->open_excl); + + kref_put(&_conn_gadget_dev->kref, conn_gadget_cleanup); return 0; } @@ -1245,6 +1256,8 @@ static int conn_gadget_setup(struct conn_gadget_instance *fi_conn_gadget) atomic_set(&dev->flush, 0); atomic_set(&dev->ep_out_excl, 0); + kref_init(&dev->kref); + INIT_LIST_HEAD(&dev->tx_idle); INIT_LIST_HEAD(&dev->rx_idle); INIT_LIST_HEAD(&dev->rx_busy); @@ -1294,7 +1307,7 @@ static int conn_gadget_setup(struct conn_gadget_instance *fi_conn_gadget) return ret; } -static void conn_gadget_cleanup(void) +static void conn_gadget_cleanup(struct kref *kref) { printk(KERN_INFO "conn_gadget_cleanup\n"); @@ -1370,8 +1383,8 @@ static void conn_gadget_free_inst(struct usb_function_instance *fi) fi_conn_gadget = to_fi_conn_gadget(fi); kfree(fi_conn_gadget->name); - conn_gadget_cleanup(); kfree(fi_conn_gadget); + kref_put(&_conn_gadget_dev->kref, conn_gadget_cleanup); } struct usb_function_instance *alloc_inst_conn_gadget(void) diff --git a/drivers/usb/notify/usb_notify.c b/drivers/usb/notify/usb_notify.c index fc21534bf..a3d7f3abd 100644 --- a/drivers/usb/notify/usb_notify.c +++ b/drivers/usb/notify/usb_notify.c @@ -1393,7 +1393,7 @@ static void otg_notify_state(struct otg_notify *n, } u_notify->ndev.mode = NOTIFY_HOST_MODE; if (n->is_host_wakelock) - __pm_relax(&u_notify->ws); + __pm_stay_awake(&u_notify->ws); host_state_notify(&u_notify->ndev, NOTIFY_HOST_ADD); if (gpio_is_valid(n->redriver_en_gpio)) gpio_direction_output @@ -1475,7 +1475,7 @@ static void otg_notify_state(struct otg_notify *n, if (enable) { u_notify->ndev.mode = NOTIFY_HOST_MODE; if (n->is_host_wakelock) - __pm_relax(&u_notify->ws); + __pm_stay_awake(&u_notify->ws); if (n->set_host) n->set_host(true); } else { diff --git a/drivers/uwb/sr100.c b/drivers/uwb/sr100.c index 174c506d6..6eb8e3408 100644 --- a/drivers/uwb/sr100.c +++ b/drivers/uwb/sr100.c @@ -58,16 +58,16 @@ extern long p61_cold_reset(void); #endif static bool read_abort_requested = false; static bool is_fw_dwnld_enabled = false; -#define SR100_TXBUF_SIZE 4096 -#define SR100_RXBUF_SIZE 4096 -#define SR100_MAX_TX_BUF_SIZE 2053 +#define SR100_TXBUF_SIZE 4200 +#define SR100_RXBUF_SIZE 4200 +#define SR100_MAX_TX_BUF_SIZE 4200 #define MAX_READ_RETRY_COUNT 10 /* Macro to define SPI clock frequency */ #define SR100_SPI_CLOCK 16000000L; #define ENABLE_THROUGHPUT_MEASUREMENT 0 /* Maximum UCI packet size supported from the driver */ -#define MAX_UCI_PKT_SIZE 2048 +#define MAX_UCI_PKT_SIZE 4200 #define DEBUG_LOG /* Different driver debug lever */ enum SR100_DEBUG_LEVEL { SR100_DEBUG_OFF, SR100_FULL_DEBUG }; @@ -427,6 +427,7 @@ static int sr100_dev_transceive(struct sr100_dev* sr100_dev, int op_mode, int co count -= NORMAL_MODE_HEADER_LEN; } if(count > 0) { + usleep_range(30, 50); /* UCI Payload write */ ret = spi_write(sr100_dev->spi, sr100_dev->tx_buffer + NORMAL_MODE_HEADER_LEN, count); if (ret < 0) { @@ -495,7 +496,7 @@ static int sr100_dev_transceive(struct sr100_dev* sr100_dev, int op_mode, int co if(sr100_dev->IsExtndLenIndication){ sr100_dev->totalBtyesToRead = ((sr100_dev->totalBtyesToRead << 8) | sr100_dev->rx_buffer[EXTENDED_LENGTH_OFFSET]); } - if(sr100_dev->totalBtyesToRead > MAX_UCI_PKT_SIZE) { + if(sr100_dev->totalBtyesToRead > (MAX_UCI_PKT_SIZE - NORMAL_MODE_HEADER_LEN)) { SR100_ERR_MSG("Length %d exceeds the max limit %d....\n",(int)sr100_dev->totalBtyesToRead,(int)MAX_UCI_PKT_SIZE); ret = -1; goto transcive_end; @@ -510,10 +511,10 @@ static int sr100_dev_transceive(struct sr100_dev* sr100_dev, int op_mode, int co sr100_dev->read_count = (unsigned int)(sr100_dev->totalBtyesToRead + NORMAL_MODE_HEADER_LEN); retry_count = 0; do{ - usleep_range(5,10); + usleep_range(10,15); retry_count++; - if(retry_count == 200){ - SR100_ERR_MSG("IC not released the IRQ even after 1ms\n"); + if(retry_count >= 1000){ + SR100_ERR_MSG("IC not released the IRQ even after 10ms\n"); break; } }while(gpio_get_value(sr100_dev->irq_gpio)); @@ -763,13 +764,10 @@ static ssize_t sr100_dev_read(struct file* filp, char* buf, size_t count, * Description : Used to read data from SR100 * * Parameters : platform_data : struct sr100_spi_platform_data * - * sr100_dev : struct sr100_dev * - * spi : struct spi_device * * * Returns : retval 0 if ok else -1 on error ****************************************************************************/ -static int sr100_hw_setup(struct sr100_spi_platform_data* platform_data, - struct sr100_dev* sr100_dev, struct spi_device* spi) { +static int sr100_hw_setup(struct sr100_spi_platform_data* platform_data) { int ret = -1; SR100_DBG_MSG("Entry : %s\n", __FUNCTION__); @@ -1130,7 +1128,7 @@ static int sr100_probe(struct spi_device* spi) { ret = -ENOMEM; goto err_exit; } - ret = sr100_hw_setup(platform_data, sr100_dev, spi); + ret = sr100_hw_setup(platform_data); if (ret < 0) { SR100_ERR_MSG("Failed to sr100_enable_SR100_IRQ_ENABLE\n"); goto err_exit0; diff --git a/firmware/Makefile b/firmware/Makefile index d1b35f6f1..6fca8b882 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -77,6 +77,7 @@ endif fw-external-$(CONFIG_TOUCHSCREEN_MELFAS_MSS100) += tsp_melfas/mss100_r8.bin fw-external-$(CONFIG_TOUCHSCREEN_ZINITIX_ZT7650) += tsp_zinitix/zt7650_r8.bin +fw-external-$(CONFIG_TOUCHSCREEN_STM_FTS5CU56A) += tsp_stm/fts5cu56a_r8.bin ifdef CONFIG_SEC_C2Q_PROJECT fw-external-$(CONFIG_SENSORS_VL53L5) += range_sensor/vl53l5_c2.bin \ diff --git a/firmware/epen/w9021_gts7l.bin b/firmware/epen/w9021_gts7l.bin index 0764efd90c1071984cc5c5f9b85ff5db3291e259..d06bd0941ed6ee9c632f8c00280ea15aba6c458e 100644 GIT binary patch delta 7120 zcmZ8m3wTu3wchK@oXMFyAVU(8Kmrqa4MHGPKnhZZf{+*}aEpq(3>GB3>;#JhmChs? zuJLsP1UyjT7JBIgsjZMeMg>Rr;w*WCqQ3-ehTbkpk<&JK`(<|1=Y0CK=wKs z+d;nv?F9V~XfsF!Z3S%r)pDZV=~mCdOzqQ-ENxKjR|T0V31K=sKats4;dfM4OT#j0 zYkl^xM|%!?>Gu+Q*2?Uykncji4SL|O5_`T;Vsj5kY}+x3h5jV5oc$7O*eS8r`khmv zSv{t{DlrXE%SMU)0QvrF61xf6_x1XB7yV(PH29VJ`Fr=8GnOb48;^O%fmWdHgj`UY z`<695PW^{r=W3&GL{Cv8%Nk&Q@f)f{EImAosK^n50eaNY-|TQ?y;R z1KW<#{Q7Hc`9%KO-1DocxPJ5bOO!pYBQfANN)lOlSM9kDGuksndsY3`Z|9h3RsF4t zW6hZ*9ae2ihbdsy=5!=#_lJ`-HJYMrsx7)&BmX5#?5WzXt`=u~({9yr1uD>c$agZ0j9jU@d>N6NNj2SJMBJ`T!F>@wsuwIL2}d|iu{o>i`o^fqTLiw zw2AO#4<%}zNV2we^J=<~`EgLuB%wPNv}!vM2St*!h`NgC4S6p@+U@HjQBa~8YOYL~ z10DVR#zHGAXO5(1zcC9ftHaVvT35qif44~SF#C}J*^{&j>O7g&O4f+lDwAEl*pZ?w zP{~3gGQSL40}>FQhvmSZ>sY?j!h6l?R15W_aq1Ea4U#g$>T4Eyk{X)LW$!&VwZQ+)#yX@rU1@;#nH zw-Qojpr-y8b;fJ$VRbqlFuSUuH`mQaIwe}5V;Wk%I! z`_pLpNIlq}7N=}z=XG%gb&;f1r~?PkI7=d8>!qkq4WO4KOS{@WfR@vz>S6~Cpbyj< z2Mwcx>JbMOD>I^Gw`$4lYWhGxYSoH?Gy%CgHju{94=UYDze>4caQEvIxcjfvvU^EQ zyA_hP{4kGI3t6<25vw-H*K-gJvZVhrC~I9%1+vx>v}k`uT_zj8*~4gxNlJ?P_6(;6 zk{?2F#p;rgR7^{K2S?IWQ}%(7nJuhigUv0>j-m=#m;I?&3%_lkDEC|&kN_jfzzzeb8)9@;!X#Iy1>F4WsdgdL@hb=blhv1@H!^$ zH5O*i&@vI;v{2%G+KrASaaW50<&jB8(MrpnpHNGiYm?o{M%w8wxp`limJ z3sTB^D7C+!zYp|~Z~PqEF4Hxizl7FOT7i+k60pZp%&e4^J989mfbZ8&P?6cqz4GFH z5LUc^Cqh<(JQ)8?0<%{#iIqd%hI}5f0n!6mKoavpE`_Xy>@G>{6-eAO43%VGj{YXd ztQ3iDfxOZSj{wLI3MBRcbR$i897xh6=0amH=n=ET80byV>=6%7{i6?;U$zkW(>UXI{f4^#5N`LP9Q78#RYa?=AO<{u8sGeF%nRGz?W+|PZ zCF=fVw4JW{rY)!KNs>8Ny}FtnNVex%OJ`_i@*7$C>d12X1jQh)p?>cEVdijZU#+vV z#yW&yaGB^}TCFDqe7&b1__eBg!HcT~f&Zm4AN<40A>dzE4h4U=ssQ|A#W3)Gl|KRh zS>=7;k5-NbKUFyf{6wV_{Ozg<;DO3X;0r5%0j|3%r*TEaeDJEO1>kuVzjBl|FLJDE zeiFUkc}l_8RxAfU;&Fk8Jx_y=uJC~CRTbdL-b(O1Z#DP`?@{nV?=kR)yiMR!yvMTLsm#`_KUdhfU3?*I0F2T||62!7c6J@}{IOW>!ym%+dAUIG8wdlmeg_Zs+h z?+x(0bq09+$y6+XNo=hg+@YwDr6n3jLoZ_LF# z%Nz+Ue&cPlrfUlGyN!K9-3#g+7?d0-P;W|fmM?cGEsJ1Y-J{xNg7gAs3-}E@2+B>4 zWT2KOdde5U9Y>Y)XmXh$=L&CngWtfr4<>UWV82l)CeCen5{OYi5ae)3zu_J(RNaJX za9rgOs^mm|H=3E>U_F!)3PklsB24=jt_`>*$2|z)GFneMa$A z`hG%l8Y6tlW}!J?z2kRJw&E^H5BQBe!XaPzHng6`%DKb!afh#Pb4;I!>0ie5&jVwQ zWx(1fGT;KbBwHzyA?E_kwAH}P1WpoRPPFoT=C&+=epGfWpTk8k?oj|SM>nA=;1dBd zSg4Xa<1}Z-*8h1JrvQ#a3f}^;e#KM10FIxARUj+21+7_p{Q+Q@!!9&uFv9(w7McUf zo%O$&h4pt0_>DIOSP|fDaqt!{vFh!Z)P_l`fia6o%aumtD7U2)E|+J;R$VGwFBg8g z3C+T|pAw;Qc1}7fE4G-j@HgkM{{=9SMKb#;Y>f-$G!1UEvI@&Akm)e~`#E04$vu%) zNCnbwn3GsJ>O!>f1i(r&uz9Tsth7M$Fsw9FDRJH&;Y1$r#sn^E3H6S%p@=Qt7sI+S zw5Jo?AixJY!FvF%MU)OPg;V>lD(4S#QvJp&0_TE@>0-Kt@E}eG`g{@>>{i20v&7E8 zO4#)PVy3Vg)oC|4)6EU>Xo?%+aFon};oEV;N2+40$PtFD)9_|@ZWlWtd_sOg#=-79 z>@4C4pRqXCOhX}0vipsb-K)zIAe*|!j&LJT2_onF+!oK8Nk}?}?dslCra- z$Ad_(;>QYy1&QA!iqgq&Qc#qBV~gmgqQ4&fNE1Hp-v(E)RIZm}sr-cM(?o1v7sA#*Yc%Z5UxWBPHB$r(*TnlqG@K;aCfYP^(hrWc~0)!9FvUcHjr zx289(Oolv@&Ns0EFH5nTb)P$3DM=29_a|h6KN{XN^G5^0*$#j+v7&7lVGgM!s-J4N z0&5q2rP)@jtZ3fbR2db zutR`-68svl97Gs9$*Bm?Z#YHe^VAK;Q9EKs1`r&-56tO>LWa_+g}j;8B;@5ZrHt#( zrxgm>npQ33>9i&xPo^m=p?4cc(+YXRXh^GGnFRTE8c)$S)14HpPvZfgk4KK&a=ehQ zidrP?+2BiOx!pdTmWaMKhzy9ONG%b4M_38GFOW{H91GhLmb52=E6)<}9)Vv3d?D~| zp4f<94TJi)K?w{zFnB09`z$|r(}ls*;Dg&yPx4z|aD`ehbwvVDi`~nEWHKE^ZRlM;c0CaonWI6V-)8YnOJ$dYS9V#D% zC2P*GDB$=?ccFHw12O$+p)Uw~;{Btd?+BO2`v*kd9(Kk1yF@=LTpE}zW-_A~43ZM?x!ah96#k)ZRS%@SoiOC9Q^Y_}mwN)sh! z#}1uGKNcnG9;-MV>Kl(DS@chaasu~?DfsSpi6#V+M9+p^LX@;nG&x|$NTS2^uiV1i zB5V1?nK|e?b9xjhu3?868;T!3sR!`{;3cXa^HQ;NDX4Z^M?>5piAU^Y{9SD^3TGn1 zYD`c*Ls-znN~pD)QZft2@-#*YL{T+i1Q!j*-e|;XnMSZp7AL@rm77J&)cn2vM)kF5S_`Sv)y^!R$(VDL9 zV1DC(aI#+baH3x=!t!*6S+3^&C*`_liMc(9)2V&$L7AdIT|69|Fz{fynel0-cjK=M zS)KY+=u-k^2!!8>zebQdfbJVd+XdQ=ABy}nH3w2={8trAbk;djV^^|aD|EZ~pht-f zd}pi1?}#6RPTQKq*d5GKn^K17A>Fyx57-LJN+?w;VHcTA%OYh09>uo(L6&;lX44Wx zf4!|5Hrt5d@NBX1Wo!}cO*S|0RChWnwKW0g>Fm$4@rTGP+81Pu9HuXM`WFfZC2-Jq zV-nUj+*Y_U5#!TsitDCM#^eC@nE3X1c;#Sw4907N=izcH-%1NBK)bKaTHffWtNyw5 z??@2cuJg?E8{ehguB(3dnVhQ^gcBU|P^#j(q5o4o_X71vS`SaL_o`~uR*h0+iaNWR z_R_1W{35NxFU^-vNzg0j=?sy-e?$Xtg@5hVuFh2+Q`U{;gdYL_)vdsP47&>AG@ ze7oAKmY%?g_f^*7gCbR^7dPQs*;qAyGrkxuR%dLcO!>ZGSf8S<*i2Q{Of;_;Vcntz zH`7lu!|f6M=h2XU0Qov9-tL}i4(XHBqSt6bzp9RqKED0BJ`ms4W=BvUc<$gj!BI0e zUqa**2utDf1f5k$r5akNZcyn#dcpU(N~=l!dxxg)^8IovS-a9!-@HBa z4q1=G@ocPgsjv55I!4l!u=?$v=pG9AtZ!1Wm3I3cK1egne8CfR$!1-H3DWV^ew2FUE9xx`iTb*HO(RW37a{`#H}#8={()Qi zLXbT zcEQzZwup#6EtFv3j&m@xBTFry2eK`nW#$U#DLFaUbSC(o1oFcl=9t`IBP) z+?@`kyBq@lBZsED0yM=P-kHF3SAeFw{KeIs^O=P|_y4WPd{>0#xW%0b%y&7AcRL-* wcLgZlP5L<7&|HAkV@{RA1p1Y~uyk_bp&2jGD`LUGxZ-W7p>i_@% delta 7118 zcmZ8m4SZC^wV!i$@9y1vm@L_l4-!~JbfZv$fCYiFDqtd^fMNwH5)?F4Y!mz-D7@Vy zON}58Fu;XZ{T1IsMZ^kO;yxkK&_WvoZK7DwQg=g9Kqy`%aPMZn-hXD7^htidbI#11 zbN+MY%$d1&Z#H?eH+i$|hSN7VirJffIVse<64fMn*V!r{^fUf<^ zgx(I~f4PujV6(QH*gDX9&_+;q2=X;zD%zVtO`umn1lz%&QJ`6%`#|@D9ymoM>=85; zgB}Ad0X+_y4_W|P2$~C;2Wp~04x6_nPxD9ewXCLpl;&lgk5b!1Y0SyW&eFIh8kt86 z{RJZ*7%=kQ-%IRS8*}b}+zF8qU#&>w z7v`>$m{_n|B&szUOyLOp#M=BD#1M^M-jX~QDS<+Pe zj!MIuTHaCR!5ACrpS8zNjYk%f6BYRv)E3jqFm!Y*Lok( zF8{>$-|1hFrhSu0*9IDE8_U!hn@Ua{ zraS%Lof=N`MpNKl@U|OrcH{ZX#-;E+H;9at+uKB;(Ga+7_r-${&8_y{*hjrM#Ab)Z<@9}nyxWe z#SFjuyLOU#t$ykIW}BR5mDsKR_j&^+c`+9IaMRQADYV6ZApRQV4ewR7#l5DGqPc)& zj;3jg;u+e)&CBUb-XFq>_6=61Xm5sX+G@n{HR3p>K27wd{GVv94GfVeEKz}4EK^>| zmZ3pok&V?dS9)jAn1hzhW$7d>%h=-FU#@tW^I(Xa>Dp0szD%p6f5p_3GCAdsBAMD0 zl`J$S?}L~vB*Ef9Ob)%>%!W%{ythxCZlM7*L|tN`Tck)--D06fsW=d`(Bov^;tU$j zLXMsg=o8fy3Z1vPqLP5RL4CqTL&&6Vw9#;SRQjv7kaC`bKhC@rDw>Q8T^JETZlefCDW zo!(MgZluRDpYG*#aRPObt}RweZlXz+PXPRlRsHo%v_|?itoGhSOUbW3=AxVEb#=Xq zM$$I*po^v{V-n=FXjnY1kEJ;B<22&o{H<2trEl5EfjVw$-Ef7$>y@9FY=~<$-z`+R=%%G`( zSIg;l65Xv%te~Ib_&i-fgHX_$D`=L5{u(%QFHM&Va*$Mh`(3TbH_#prdN4434xN!Q ze~XIv1NwVF{Q`H)qgQ15G!U$$Rg~i}tjvl%t}wGIR_iWOwDiDl9;R}$hokc1odPdj zz>^^xL1h?!%F3MgFp1Sdz7M$)(g*2}AL`r4m~MT^w{slBTk;CW$Qr4Kz!v1M(@z>&Hk;pDM9qb0qd5`ahE;W(L)Q znn4d)B&LA&ffmh|*f@37WAu4eC`N7G7B)C&RGF>X7wRKbG=ui4{wi9S>y6p4C8HBp zEq0i!+B0g&5^AuIj-^3mNyu;Sobw}by52Nc zc3L%ejKGJ)vN12$9E~&d2dMU6(c4*XMbj~~DlQLRUuM;Is2}}`@@T92^{?nCO;`6m zPOs1>ff-Bbm2~M?k$Q1CO~^P~WUHE`nJH+5hN-vJ(#I$Uc?Aviq{W!at^IMeleIS^ z41>!w7t=O)Gr`w+hk~DPxEcKJhFidQ)ei^%WBpISzpNht{%%7l_}6tK!3Wph3VwV2 zDDeC0ZwEh8KOX!q^=|Ne4R?W`te*;AS^snJOP=}}Tv7KBxTj$u_`teHT#GvwyOwo6 zik|AN0$)+L6#RW}HF&T0N${W6dBHC=)PXC$dhjCOA@EY)Vengh9pIyVN5F6ModBQd zI|crb?`!Z{-#6gD^_>Ox{LXg{;x*s5-~r!x@K)ai@Pod8f&bZe5&Wp{JMb@jm%weS z4e;w$W5TwCJ|Ej6vnQIk)u_KF~f$ruzs$J=BL&V88l8Ree2IpuK&vz z(?;?2D|`$1`dbxm?Lq)Q3GY4m$t~C|ym!Nfxtv0?BZa$NXncLRwZP2^@%0O1MHpA5 zj2CfWlB3TRNPgCDJSG7*F07LPY@{mgl2RKrBrCL`=(S zF;E#iWMtA4GOPi zDpw*(!@{R@qKeuc1b2|uOJFWR5` z<-^aDj4lI?li}Eya-7tVT!mJ^SJ7#?I^iMV7!q~NS9Kh9?1JAu_*ujO-f3~Kn1M2$ z>I@n$_iwDRLT>G!Jir@ZWfkS?wRl%dMb4*spnj@O=q7@uI5m}30G%K}XCs6g z> z?^UlusmurkjUtbk?;3wFtVD~yieiUh%&?-RLML@4^sZhTj5SkohcDG7^p0LhI~o30 zH}1rgRa}20&aIB6tU`5h{lU1T9SMI4D`%fohp^g_vhsWcvkzeQZul=SyI{JSx=;>J zokJWMo;n3b?VuAG$VuJ@$8*ZWy>Kk2QOH9%9YVI|C^h`P*q2i#Ei3 zvW)9D<&<&hF<#7RT$YZ3MgU{Y2q2lFN)Z71c;LugZDoAz)Fo*Tho9``06v_SxLy}V z2E$(ycAT!d{L^+CAZU-30sD!hT8k&qB|w*TLHJM#}sin6HNUsPN=& ze(YSr{NC{XKJ#Z_{&LEC6s&&@>!R>*0e%bxo@r#vemLW2`tB_O1mf?R#FVPL>)uC*0;ZF0~2W6_&JZ#;(x) zDXZ7LgV~X091&<`ts?eHXhur2jcYtm;SB+*NijSCMPc*HVFwDkF_d)e6#5Y{Z>rxe z`ZvXDQ+;^Be^9JC)!#1qd9kY0ROYVaOX*z05-Jsw&+B4N!W;7gAP4#I4kK#^xXtY&-h=Cma$d`sTh+qoTlYs8DcD=+B~`3_M>1@@e#jRA7qeAB`4; zO2n+#qEUKD!Wv2!T|0K{`UGi_L`G;3M$%lSFN?~G%WbujXAeN%T~t`ERF7;^H6P89 zti9?ztLZ1@3=_9sax?yXTT+J`oA<5CX9z^%A@M^O>Zepbh+}yIBc)>G7)J2q629$N zGQ-dOgRAjl^>FNaUBy;hfN2so2gwo;{N@n={E6iQ03Yw{m#jem@?$5w+7ZkR$YCpf z5HZ(4z&yrN7?3x&X7z}H7wwI3+DZ(EYm=R?W0Poa5N%%{*dlue z>{j;mXWRMXWH#*yGe$1c-}wer3ZGxXzx~owEUnaDwk!?f6?Ub%M;~C^9l~22@y+&P z+wOK_-+CA?6P|~&*?gBRtQ2jh-B#P)+<2$$6Xb`kG<)acd6s>px$*vIiY}fJAh-pL zY^C~=uBmyAG$j2+043kBeCm`&nx<}Qq@DDpI`IWsO`YnWUZC+g34H#MLNPs(U``3Y zQe*m?s(lSjvi&Wk_(Yw%hFa{2L`**cYK_PAmq2f+gVs__K^#lK8&U=@kgU&Q`f{jN zf;I=0y~kAziOi>o(F1``*|O`scCX__D{eL*AJFfZDy0re{72i20G2{vV(V>iCyvNb#TI z%=JtsA+g8sRvXpVM5Fo=jOBI4^e5EkUZT5i+K!`D7Pn~g5imZX^5ca%PVYRguZwfX zMR3&gb?Uj7XnwXeB5T#X3H^ryE07!(QGd}y5981W_BY{MBE6yx-i*&=bJfM0F?mC{ z9d%u*WwZBD*L>HD@bVSYXM|&VmHOIdYOsw$(+0X;9l3?Zr? zb!Sw6SgqSacMbi0B&yHv{a&AfZ)^|7ais9xnhe&AVAn(`6xFAz=eE$@wtj#-X~guH zI!>ka^s0J9r7843fvl~xoaBoUO>YmZ-A1-7Y6)!KN$-*EYXCokO#C+Rz%DvWk}a+d z+)dY0G;qgmnr5Rv1=h9DEHged2H&Fv^ozix{WL%tGBh!xr+;;?-V^7C{B(}u{l1Mc zXK9vuKfY`q0JW;CS}9NF-$aYmZLOqdu8Ajo=Ei&Vf2yyv(crv6Xx8Az_N}3~emrsJ zOt0P_BUORV+9-!;oO%{qaN<2;ZlCD+S5%Bm7EQum}14a{}V2A=f9r= z{5w&W^P+wN`e$Q?UK@Ds6t&2<5r(15pn-vLXDKV4x&!5xXozGpwkQAnQ4x6hGCgj> zcbjg5@+4bS?KS9T*)cYrn4p$~>40a+L43#rkwomnEsQ;f_GaEU;XgaK|G&PO82{_j z%RlbJ{YQE!g?ANSx&}{5;(7W2rE36T|06)tH36DZfLA9lT@#?`8oZRcZ$7iY^Za{7 z=4&D}r#!AsV7>-0)$Ie6uL)4T22Z{wK$!#NV~tlQNUk^4e||-T0xKfYb3IMjgT|^o Q-cmMzZ diff --git a/firmware/epen/w9021_gts7xl.bin b/firmware/epen/w9021_gts7xl.bin index e83bfc5a19625870360b79c4b20c541a4c417d73..43b718ae09c7278fdda47cc195a30985538eca1d 100644 GIT binary patch delta 7199 zcmZ8m3w%_?)t_^BH+y%JK$axrL4q3*SRScCqaui`B9e#*SXyZj2nrZl^xK3M5|!@e zK?#B-8p=fr{b7rrT17Amt}PEkiy8`QVq=R4?m|F}2;A`S-c9!I_CK>rzEAe|JLk-q z^O!Sd&dj}cc7rc%gD=fN857)0{LJizq7M$PdBUqc&I7su`KO8904M-l|GNr# z7{Gr9=$TGp;{g)@69M-CUN{B%8nG#8PXL;=LK(C@N z?0^34vt&7sX1Bk3XHc?)(EQRr*MH7r%4Sm2)Ig~%f1AWQ;PQZfOJHr1?dwFKTm579 z|Cs1S|El+Q49rPZbM<8PVcir;Rx|Y!wL6@u&W!X^A8MNR@86Tt-}&!pMCDCmj*gcG z_4=PW`U%mU{t3tSm?TR-f6s|yX3JMhVt;J<;#5smL)fmigiRs4S{F`M=l7IvR=D7-AGn<#8TC_nqIiLK53pLvB9RMVd?`}MvqOsO{nQT zcC{mttQJFUjDNLyfM~zJ^wOVgmS!yC1%G#Mz+`zPmZJW#X?tukx%`)7uTs{M9$9^* z#}ty)h4AE#*wwAk6m^TTgXnD5w_#bmQ3%h3ZR!EUQ2^m!WxGUgSpJESJ_^h+(VeE8 zGgya~=0QcQ*)yf3IZsf}ZZ^!NY)_(`{x0X=N@X9`Bt*_+^{n!F60MYMQDv5uoR+TM zRCR$;ZKd08{nD_7BxwA{u!OcZvqGtzb8SXU`?Qz2sEs+@p_o<>jkm{zQq_sdNh^(# zvJ9o4OpB>2@N1d=ha4_vP|wTdL&n6Ak0@7dbk25fL=yh*R=Vsogz}ZtWGW<|GCr9m z&@!bunMTpnz^loa61^D+_M`LGR6e!8pa6Lhb}3&Bguy2PYZiTOqGN#*xwMvYYN7HJ z-~#f@bM1p_4d9DFO&*OmTm0y|7&zdhe_685#gfz^s5^`Lb%ohLYAQ*Th-97ZqE zF=g^_T0(o39mDA!DJ!O28cyTrBc;$qPo%!k!)xUzY9(2%QC@M;MEgb_8z9@(^t)pN zH;y2Wl+>eCj-aLVsS+GP!|CsebtH|U-O8OKX{tOkMoycW(xa>!36&-#Jd!5SL}kJ# z8c&y$>QVG~>Uo`y(rD$QoKU((k&=EjVo?hX9Zm}|Xd0E2@$axj?T7lX zsO{k-bvr6HMGt&-3q5F(l4Akq?X;IHUm(6?%E>!uDqRQ^j-_d)oLvz!TiDD-o7F11TyJF1M)7BrY9cW!`v#WPR)ZE!-cbY;moe4M3yC7R0tR2d(-x%?KZP`kb@$>6v0i0r^~%d5}uxbCJ#$Oa4~Iu z!qeH_1#wR{Hea|J*c;e?7d=h%YT(YhDVQP+=oiSHN-s-NdOzjeX>>cCQO-}J8&KD& z57EpdIv1Efi>6snDBFKVS<=ANz=uDhucg!}NOChOZkMRKzdlM^EOasO$YZpU(u;H} zvtmsjG_!J6<<67U;eoS{Q>oc|3|72mOJT+9wghw?AOmOaudK{@i$!8ppv|Dqf>wh1 zKreyTb9s`)8aNNS4)jG(RF3mutHd^devmG)O`sP>NNh7`mK#w*c8e^rOIGOtR*6P4 zpwcF>0f5f{t&?%O&yiSeB^2#^T95-S0d7eK1-uA&7y%z%fyc@767wiy-k@|PWeK(P zkKiHZ+sz7sdb!!EURAzaLeuGEWz;WdLFQ(|hUF-ZUDMcRvZ^mCul$1Q7R@m15GBPd zFdU8U62XU}T$M|{jdGW1kc`IweEprw*KAei8A(FQ@u4W)XezKct?Hu&0Z%m2V9h0m zqYV5V%9>x&_Te8zlF_v?YAIM>VpUrNH(LzE`yazVYtX+-nY)w@(-LLGle7g}=Od70 z$(*k&uBN+EocXr$nW~wBdUm1mb~Sy1N?G|d4fPH)n9Hr6SmnfdjHq=^?JlM^`BH%! zeM5mS){O+7S~m*#?b<@%4{Lt}{8jDEz<;YN0`96A13a|$7T~*UZv}p&b{z1>wc~*g z*Sdk(_0I!M*G&2VPmT6!?J8 z18n$~0gtQk0c&+Nz$x{$zyW|_qW-e=cP=61t8LG^J zUVWz!4~BRvIwe;s#2f7Hs--TueG$wXavMA*(0b@OLP7mmXqj9o&{}HuRV{)$u2q)X z>M?^pD!gfXgSu+tgSioKP{&3^JHLG~G{!=MK#M_xy0=(}1_;sUgvcdCDRzEvnpse1 zxpEnWV%krmO#LTZ;|;8eTsI@IbpPN3O7d zJ_>E7u7KVw=t&~X`)oX)`RxlJADa`;XR!#zI~GdJH9&}p_&`t@Ekr4Oahh}D^Z$>5 zT>!@snJO!>f zxWG&^v3SR=th`9|G0ZeeE^~i>n;Ut+TNSXVCDc3ihAftRXI$5duGjmN_X=e^lu&qF z`E@8aAxf7R!ma+U&V6Z4T2Nmn^gM7eLkzbN9>mT_*m+>L0(NQ=56!Js!Y&sYvxME) zKD*IbUT%n2wS*xyN7)=0zLzlkXMte~v}<6F1|T2_(so!%s0_5DaXSKBtQwL%8n3bh|9pD6AItS$Supqx00MQzv11 z&=ODA@mhZ1j1{KEeWutI7|_*c>IDBGtQr$m2WpXU(UwsQX6O~EJkSUV&Ke5pS5SiS zo^R0e1}s}F%!~Em>PJO=a`ht+=0bflT*Xt_Xo;utAtz43%y=q&nX-pF-P&ij0d`(E zT`EGD1)sAl*UGUZlZRd|%9YT<9!gVrDPPGb0iWH+pU!Bgi z+>1A>_{qA{n<1B_gv84hGQl4WZ<+a{f#7T_l(R6S&FEn+sXeBB++%~TQ}AxpUK`U6 z_DJfLuo+ra39YC$KgzWtrubrNHBlVgl6o@SeKM%e=+inVw7eY&wbM}B1GP`WUqLMo z5yp3N8UhUJZc+I>b;a0f2b{2f9HUj1Nt32*3o(;F(2LElT~DcWqhmZHXV9sqbeaxCqKO8Bg(T~eP8KX;Pb z?Zj@0YAeIYfS8KZ9@VxQa_D`b=~k;Su}y}gJ{GP#NznHR{YB6(fxed~HmWtiz@IQE zgMkkQ4}^byl5e~j!eCnXLm}td70`YypUoIhgxE7!w6-Z%>*(gf4bZ2PoBKw;EhdM4lNjlH zUsNlMNoq(}L;UC{QD)ZD&EByv`B!LF!X&2MuFIh(5+<#_nD!%GQk(U^hfw%pw>aA8 zC!~M%q4+IQ12(#aaKyVHk7=o4Nqt%WOX#Nwt^f5EutUu#0!S_DG-FF>dP4FNmv|w% zfaWOAVp8X@`&(8NLL6Q1C9JD#7m(ywmU`_-%sEHp)XY#8BpTr+8z% zTTcoViJm#_xcyNl8IOd#qeaJ$v74}0%3Ch8H0-UmpuVtgpvBpS^#8N^| z^w?ddWBDcdrM9a3X61o*=jE2lo-z9vQ;L2|v!!!k<+T5ClQ&L6IOxdoGEDk-#@vb^Ub-C7nF292LB2KON@xB9IQ)e3%wct*Hk;=_Qm5(Cc|z@N9-eeyJ=do^Wx zZ%T-rLhQuXB!4~41GO;zdByDRW_McrDApY%9^U7ZDX?r4RcuaBSY;LncPv@^^YxlCX3gfA2}Ww39#d_SgE>?o55GW z;m9SvB0gRkSP`A^#pikWE{(5V5-URcCWo!6rMcl=+h@oRec$Yx8`Qr^`@Xs1C(H9L zoE1K>yCZ4b?S5s>8XA(^2uJbPsRm`u8k#CGS@~=Y{e_-aRz63oXqRGIOXJf!aVI2& z3@sRAP6?l@hW5NNb1hA@{VgGQS9xhI?RIp=3~eu9Yt+z|1J*0^*HJ}|p~YgzRtm4? z{+}D#9Ei#Q)q$>c^uCE!C~q`U0S#9UH&Tx6X2Z~Kju={ra=ww~(gtPf3-pEMV$W4= zl``T*T5tO@Y++JJ)1FWcyhzg>D~(IqpN&FX1v2%Z&(Ovz1x++9bsk*Y(`#st0os&j znrKM=Yq%6#-bTpn5q#}Lw5K8wZ5sNr+6--`vZslr3?FB7YlEXnYQ2ua#494UBT6^9 z?VRSv=Qoo!)^}rY`{GuKFb$u#NF8h z<<*TC{E2W2c2yA`2m2E{E)OqThIVV%&>mFIY@|9{7MkaELrYRB6uJ}Fwo&cgSOhm# zs88{R_f%U%yI(n=(4?Vv_C~aOdb+hixOl6HqFV6mi3e*&useGx6w$^gBR0_#+xKwU z0ywEuZ=&^7px9ob$+S8!{UusKmVv#h<_;WwnQZ;3Ch++i^jEUI1IPCw6AuTJH|YbS z&y~5`aTnSesM$_aZS-2;<9BJMnd+4r_RxG97x3<(LDCRgZ2Fafo*wOJly7UCp1y7z zan7Rt?msb!{TZ-L*|(3fEd06@*QEPMOMNODx0w*_(LPd6?5Bb(6PiE4*Yz!-sMZlX zd$vdGF?zHI1DWqrI^k|z8QDTN;tD+QPz&9gg4@d%j?hrrp#+W~^r}F`$8^qNOU3n6 z25$JjQ5FSpH}+LvRgms5m7a}`2wl;-qQgR0wJAMAP(=H~PTtS#63g)V5_(d5uYZ6V$RRE-o%ClyMk!%A@{%^R^R9MPUL@^Q4sT;{ex zeMdaM80zo5plyTvX+zf@4eaTp-4 zFs(P`P?Q)`lXY>It=e_w+;N%tI+@H74p>&-?=>Nc>>AC<-35VAP zFkKg*={kQ2ao>1m;m`YjGcsQnp*dl3Z2p^=!dqMj_2TsyJ_AMI6K><()=p^V6 z=s%z%pmxyLphoJQWA$#$)BYOmq3vxvUYytetr+c`X=6@Sa+c2RBi5=gmLZ|f(=3F< zpQAZ{$h|#>{M0J3e^{CG;XM-j5ON3TA3sSfo{-pWI>rKbm{^!%I?;=5-XnFIH5AP*< zu(^KMd)@PGT0D`i-DsGCHZ7FM&<=&{+6~ce+R(-c-@Hub=9Aw{AS!Mga(IN42sb}* z_)DT*&9@%iZj$!fo5RPCn&mf{#O5>}IZ=~0H)PY+hPbCkL+RS+NQU-$%&x6ztUUQC z!rgSLh-g^j?9&VA&gSE%&r|-Ch%Fc}%51DEQ(F)*qdi%)E1NscOf^aE_U7Bpk2L2! z6tQZ{Bc`BLyFX&nhQ-pg#)Ms4*7)LurD+2siG3$E4$$t(>j+!5d;vQawrT&4rfWR_ z%WZyE+fDRLbLlUyTjhn=#BI$#NBkza9+RzY+?W_kE1EkKZ&2QZu%gw6O+iH~fv0{^ zo92sWXf^74L}&883@KWgQ0@s?wKtH545g%Ql;~~wU8J<$Kh;FHnDRGbA6lAv7PF>` zJ6oCxg{;`h2CPswrcr+83g-uWP5nfuJu(rEHp@pMAdEz&7sZy zzbW)ra;$I$jKTsQG9f~aP=B@3dFz0vB>Z2cp0iP3BGsNwMKnttkxsYL{c3eO4WjG( zZ=_>NwA3HyMn78Yd}{BY0C^E^R*!UtL6hH-M~6)Gn*VqKJx}>}0dgZ~8`hbxwHMGD z(5wEMLKRBtsF+Jq-(R)S6wv9_Ar9Z1NE>r{?F0wD+W@9^nFO3 zH<0F1vlfI$336IBEu=2F29O16=o%VLebrkB(FpoRtsX>= z*xL;rWtoLX*{z-%L~8btsH{0+JmrJYG;LGds%82c2h*UmoDV{>_6tg1*0zSyv=<|a zrX~De4W;oW=|bG^ypeX0{3`N$P3^de#?dx^(aki$l)o}+X0w{uU~@Zj+O%2GG-kps z*|h0u;|MC6Ha$vxGSQtHU0K=XV@&UD#(Sh#1=sghx9^z0O{j;$Ohg| zlh_i-2O&{8&H{_XmP5XfEwPo5+XhPP70AFSoDb;2pbsq49c;LQ0nl)(#EwG#6LQ&D z-0o8)cA^qM^cUKo2YmnvbD1u&2SEi$xN(8RcBsFW(|5Tw<+nvnYWYKPqr3o$Pd*XDJsgLZmXzmz+_l;%2nrrsP8Tvid#eboVSFewzW9aF) z+-GTtMO!O+4~Rf~d?o@d#`sEg+FaU86V!o^(`x$4|2aguw69Q|Q%xf?&K6qB@6pT@ zFoJ{CcdO}36v)#HslUe-V=lM$QN0t_FtRqdw7HnJ%xedK!P_7FeBCwRch(I8f2Xzx z{G-}y!H?En2fnSY82oh25b!>=L&1mF4gTv78dxTkIg_?0z}xMsJ_cFk*>gP!Uw2d}P~3;v}=3VywB5BQC~!{C#AC%_-}od&P+eFy%G?<~0IU%qn?Z}`3k_xsL+ z@9_NqzT5XB_-DSK!1wwtfFJR7f?Mki@NV@8xHF+o!#>IE@g`eQ+EJ9Lv8Lehrjq*} zFZ}fk@2xCQDwvkLGhn!I`7)QKJzzATHAz!gz*xk!9xV;(3JgjvJJe-1chy{%(mosJ zlM5OuOpucRbOZwiPFa=7l>yX9o40B<+;LQKL2HE>aN;3->ZTU(W1rz#|IMbTox)rX;brn+hH(GOC zz1ru(;fDN@3JG$Zu-+iT_ZOPADZguk#@pq$3Vw5f0i((z9P*i$qctBh=MEoAIedVd zBYXkE&qw$YV9d!Cu(pU5r~tY+U#XNK2LsKt>A*RGlSG<1R=%FS+Gjwowx)NMWlu)+4~n1Q-3%y%3>b4oKMVa?=$|=(B<18q2ip{bMgV97m+A0Pwj`CYQ2IPA=u$PTYmL z$)%i>t5k5OPj=bi)RdLO=}6&pGE(R#Un;R4xqPk03#`Nfh8x%xc*}v8>mf68JtY<0 z(J<#WR5&4{Ijt3cguIxeRPwF)A*ZA=5Asw_L**#QV>zut9?VhZp*(Q{vNR717@y>n zp#MWxe@jloJZ`@sr*&Qiq#Xkq~yZBOVZP|hw? zt3a(yp*;Hm+XdLR(C2{tV7jz)!EC;CIpWChrBiU!b~~{G*~$ChV0MYP7xra02>D5N ztB^agl}dhJY{@PWazl25kZZGBg?uGjnaB0ZvrD-27)!Dn=A~nx0gf?eB#>O9GLZoK zc;LwGJ4^W7sa?`$hURy02R@vZxLy;&3W&K#?Qwl=ObIp%q+6STiMX(Gok0`7l5AqRtkO>;PrqH3ytaE$Id0-e++%l1%C?gS5oLzr--m*7 ziL^dJtFIV4i`JE*wN4%6qw9)Rq8h0q>4L|flu&|CryTy~jq4=|Ny9D&`CTwxeHJEz zM#ALlV0|iwgno~q1m~noTD=Lq)R45z#z(<`akJXtqwJn8S!zJ?GU1xWIjBnLu8^dy zGTsT^r)Jhuu4jB~b#P+J!zyndwx>1DuySSs8D{&*P=ojf=PXw&|eqxrur?S ze|4-X)rS@Ad&eqL{WYSW7b{OiGPft+E~gl2!-K^l_|$ghB)kmY9~>t+k|J394_yHCbWr3rBGI1i$v*;(Y>>;9l9qpIOLJ|GF(Zb+B5rQxI zz=S23E_x31u1b&=Nn`|jW5nh%9W5;BRcfsoGr1@F?!tmnrDDj=Vfa~-wH3FRD6)R) zf@i2yvV_%-o}p_!3~97F3G#yzyh15^5J&4UMvBGAK8)b$ zBWznRTc(*{n;`<2F>|wMncBYBt+Ai=Vc3=*V4IASjdc?~aaNYh6fXI5$Oo5P(RM}h zbRq-*bA?$8((4DeJMf!~xvs=QZ$WF4wgz^a1a67&<4*a(RV4a6`6t!=&r+{PCksbj zRF= z+3ca-(|`)S=qRah;8wQtT+1XT$h-hf;A-HyL*Z@yo+OIS8Dt7wAGPF#Pq|U9r2j{5@@}uE}_c&xZcyi`%DHe@61CneF0R9 zKrj3Iyg<85)TnkWqdt8{$7E+h|2Rt8c|20CHB8#~25Dyi92WycWBM$$|BEz@HmP+l z(h)g5@~i%;I^!i;YSlwBlY+Wlr-ojliH=pVU-VtEB7DkY+9%$ae!n`UktWy|!o{>m zO#cVy2erA8`u6%5AN8JUBdqm4yp~4w=b};lF^uK4#q`J3&PKXZ{u7STaCOvj%C#TB z4{f|N0jcSu)fvlaT9zduYZc*y{>%1iED(#RUoNMaIO6`HFXO`?)vK#k;A7Vm_4o>W z`Kwb&r963JD5jUIy;Q2R4nxxlx=MXprCajyBXRxqL{x7};H^Ns$UV^()n}?9l}7i! zFA~+Kg@4v>!iTY%I8F^-EOD-JuFP%c^?eZvM)e8mjFoh!^$NH=X2kTEx_KonrCZfM ztfH~>y8qc#w1DKH5lw%{Z~7NmGikNo{tmrQ*8On&FlPFM|G;|sl;~&m<&DVrl>hyW zG|oyN`(;1fW5zea`?u3{`jg+koq9^6`X?q{>|PPpFUI*XK9#L_f8NQMvpCcJXMCvs z3urEg--1Iyc!hS(fLxcxoc#OdX4UZ_>GtR1Nhed{Vg00rMa80NrFNH6;cHFY0n)K=4=nk#JvB&C!q({8XqH_?OXw;LrMna2|MJ zI0w8l;s|!?FB#o}Kk4>Fdhmko#j{+~d#Sgcq#}GBQsEC>ga?@#{|MQD9M7EyzBKZ#jx1Yka)Re!6|5HXwH^et)&1Nv? zd!5XCQs1n;9iu_=tYPuQ67@)owtG50!oOrbCPosmFIF(tiN2lpO~hUp{{Q-Bc*I|q zUjBU_=D*WRDSwyzOPBeRlKwnh4yDT+0{=UQrpppEr5s)gV7e?p(`Eir>aKWZ;m`Ab zGcsS6p*dx7DS-JhhpBFtL;11<<;(oZmnA532R$&yO97JeP4(*sN?Qk-_Fibr>V30% R@q+0}X@vW&c84kJe*xz=ozegR diff --git a/firmware/tsp_sec/y79a_c2_4layer.bin b/firmware/tsp_sec/y79a_c2_4layer.bin index 1abc6b72c3493d0b63dad02b2c3dc5bd55a79417..c3b64bf5bf9f55f243f7c130f70fc33e0556ce00 100644 GIT binary patch delta 11839 zcmZ8HcR&=!*ZbxwAOZqX6ubkG!xCET8Y!|KmH;-y5+U}eQ8Y%>7{HQfj1hC{VDAxQ zRPZz_8iPiSn*4|mV1c43bu-&;(6U%u~;-FffLo7pL^&70l#xZU-~?ZU>g z@naZZ7-NKjS@Gqi!oXb8S5E>QV#i0M1m*(#e|U44H&ktoALHh5Ig9D5XBf9}4C9GU z^ycH2q1l`ckt&BnRawmR&V*?;A6G9WejnWd0~GDHGYo6kZ3hMn$|6;M*oE1whS!^- z9g{YiW5W`_Il98vGIx~Ry^^Px@UEdiYe^89bR|F21QA{?ukVGi3F5v*s=9qhlT5)8e(qKG7>n8xZItQCHhQHw zIYOg`A*QMQw!3{*7Qm|N_|ywk3!_fQEBVh%4*fTIy;HWitpQUz)D1gZDAy|aNb|}5 zQwdBpB@K#nalPPrCUB%Yz5t_=e+Ov;2kGuysB(>pww1VbK$=gko6+^m#W`;A+Nf5k zxIyN1M7r~x1aV2479njLq(Mk=$9#QIgc>%QnqoqImfX84Xqk(3%+ez<>xzQe*+U1g z;jDu1YKo2RMV#-M7R3&5di!1g5@#d1#>~a;b^ysdZd8S1_^7)HBA?b|B)swN;nW%F ziTVbFW9}yE?O48Z_i%cKUP7q<-3)y_mc32WCd9d?mqlb4G9Hd_9U8;vS#Or`vrXqG zB*P$+drCBPGL1_KBHA+3Cn^5U_B#O?A?#@8AU3v{j-;4it$E-?6LjfWp2cPsba^+L z4aOBBt_;hFW@8vPgm0Q&Oj-ccG-dKum~Ij#4}`Z&p;Lmv*OWYE57M12`jf2)vNChGq}__}Fun%=A9Zr3vz`kRQKYOBl8 z7bEa=)bLvVD3HvB70-x&|rQ-mhSv-iml{ zr1MyYml34*Zlk|IJOt^_u?#Bffb@_ydNtyHNUy@u$GmfSg#y-_mVFuwOU(N}byLD4 zvw2md0#*Lm+Ey2@Yf{zhsLoZXjBeot!yIC0|GQy*qwtftWvdCCf3Y$>+ZBP1(b&`M&pEw;K#r;I`)APET*1{6SZ=;?E?$k>=YA;=s?2>a9R{!YHllOp zA2ciQ-O|kP>4l(c65clpKg}R8&y;d?NS9&!ug@4A;eT&1uxftuYwI&zMw4*P*50Da zunVDP?y47Y&$Jz0_+;U}WvvF)@4UX&*d%;xesFE018HApURb)TJyCvdYHxX|DzCQ* z=gjaR1XMu?PB4W&^n=BwQ4eFG#Ju^TC#aIF4Z=~=u}8g8^dCH099&+Ig_6rety6;z zj%G2D_;?_!G8Ex#uURGOY)gY+G_80%5Gu{w<0A@`!l_jhhMT3T!2qvKy=y|@foVof zmmYuCDGlC5T7zQ==<0-D>eQCu1$Dx&e^bR$rt4L^N7n6Ub+~;eYo-zRY^hbMdhIz9 z&~R2Q(#^ID8RnoDTV*SE{?&1!tv7$bUkCWk9BHcrh%~v2bD_nQDMrJ$=1XFxH~h>+ zJHriE_<=h4!+cmvm-)j^$l^S^zzk4zmR<@?T&50O09MjXdhqf}uS?(=hj)!xvt32T zMNyKWe1O9Qcz`GjkzPn0nwlhC zvrYO>izxXuHc8(%ycFsW5nd)IWZ0;$-|RJ0NWv>Q^sg!V(e(6DEQH& z{@?{u>74$sTQ%PHLg-DM1|az4n=B@l9v=W+#MwrF9ss*M1`Dg%DRHXOMNA4?VV|cK z1t*?BWU$kN%%0&?!F$mT|GA$j1Yf;NdgWxc@Ev;8ul(j6A#KGQ&1xc-RSS+sW3pzIz z<^sq46$_ULjOVtqAOZZrZ8oAHYs_^@_LcA*Jrj?!FXYPOAr5e#^&=o&ZaM-wX|9PX zWVuK;;`UPQT`~=Nz?XFYG)RN}R52a;!x}nxI{0Y%T64@Vg&JmboFvHBL1{=IfN2*9VIK^4(z7oDGL9v&^-j{-v9{CFT1`5J#SdZL1J@nD;IH|_rpCHmbmL~2;X=>5#8+TUXO%UqdhG%pLg}oItgjuNAgX&IIWyBZ4Wk*A|E+8Y^A2 z1r|XueX<3TH7EFz!dl@HjopeJ?4c{S;=-iU-CJ?*CQ1%DHNpqfX&bEYi)PtHA@hlNncR#(|k~$h28b#+;UN?G=)~CTaEA?m$n_vk8>R= zRE?m*C~cwE}D9dywMdmy|Q%RyL9b^u)v!UlwY!1`qf zPooWcVF7q^bM}EJ0HvAxp&)RmRhL>L)bjiAon%eL*t1tPpRgfeL;gBe#r`n6Mu?U9vN zI92iJG84RuYJ`I{^B~-GTJc{(A1>t(Oa-ElxO0c$IXIbY)xzd_TTZpGh87$F&t3=X ztA#J>v)O9FRKFVEE9zIV+wIBBcDq|gRoyR3qkL6$!5=ext3$OgjS5H5)kM?2c@P~m z99uEE>YSRK+MMS(FLGYyyvpIR<6!KeS_rFGcJ-0Gu6T&F8w$Z0oZ8x zN$~Of1t)R_<-1zQN9d+)Fn*b%Q?Ux(rOQr2LysgIj<1{25^d4#0G$@MtXaBkM}rWM zk#~CgbKz3m^ME9FaNcv_2f8~SZuxN5f!N7@t32>sRx~34dOS!y7g%n60d|W9?%*jX za4zLl$WX{<;Tz@1jGL|%(IQm~N}juO8oU*d&sjMn!xb*A5URCK(RIfH=CHpQYlWTM zxSt?cp(?4)V(!rFtGEE4P`{tyAR6&YKf@9DlACi4{Wt8QTYtqazTs5=L8AqCxZb}( zCr~-!@%S+}?j~FYc+UBh%C=Rc%l<^iF_RYkiIR7Z-u@HfotseVp9;U=E<6=VxgLL^ zWOoX#@02rLKO1G;$2Jcg^6C7if@8e~Il{SPcTiO|AJqBgJQbGH+A=t)@vP?yo(k9L z{=0C{`5Z=B*qU2qRl-0gxA`LtpP_NGJ2 z_f+uV%J0Eo@QM_{pePN=&9P5ljD?ojU?8PW1p^JekCwEnunJk1_ai#&0gibiH{$_DR?bDd%zYC#v90P6tcPT-^bs5d&0Z;+eIlHs*-uc`r*K!F zKm};_)GKqI2Re^W^Q8=CCjwR~q9 z>xR9t^qL#4L0|5P8&N@cS$;N~s5j(k`NvI6*FjqbZ+U0SkS$SLqPN6siQO`EOL2AF z&_G>cPDS;^3}@>;$H}ylJMrr>F*l0I_K(k*lnYIa&B#vPuI0U&km|2KH9BV!O?D?k zGH5=>vWdADPhIq%kTWJXD(6xor2@+++jJeO}))SH-1}EPVyFJ+pt`+O|eb6O|{MOxMrJno5Qwo z+j<$U6#46ta(oIRGIir}{B`4VChSGO=0rkM?kup3&CQA{{yjc7+kbTK-ydMKykFC# zT&)$fS#d9KvD*`Kvty!!h-{p4+@O<__bA06DTLLrO7TN!04qy{N=&dS#U7H(!34`3 z9)EL8L5^_Nh#Y5lC#C2s4L@pRUrTXxlLztZG*4piaGX#xS2;76F{~`zV>xg2b|Izi z;zN4PgT!_kzddE>x)@UKE}pOJS8%$4VU~uyG-%7*MKjfVlHTfZJ0=dziJ=ob$#_S` z5^UKPqqxh2(6gSTr+ad)mcP)z=H|zoEn>I%JaZQ>Q^}L~jhvVp&yrIftd=$IY?Zpd zo|y}Vdqt!h1Wnf!S2NmTyLMl3wPHp*8-P4uk@EmDr|0WgxrRcS`%2N2eAzn|cBZKv zNkFEiUN5Ij#l-sItQ&eRrPxzaiq7?KxF&6n&y9{XqI8xwyrJ}}ZcR9DyEk9Sx3m=7 z|D(oJ6uSx|r)p!RJ%6>c)zv|h@yuBBE|XDgPgFm_Y?>nHi805{*&CT*o*CF)rJgJTisdY9M3OfD)7^?G#A@1cKgLxVL#hZ%QxGxROiQN}}Yufbs`u)`?USq$Y1aSm$43XRU9f#*gscoxDIeFm^0 zC?3W3v3(r*0ravL8J8I;CKf1pp+##@m#9UXq%x2achOTY7O2Hq#8f5zJwL5*7uyMp zVR>l+@1aGdadH>EL}S6Kp4ainAE9-c;7#DcfHVE++c%DgD0lRJ6g8s-+U&V9e|?v<})$>=QEF*xRCyl~y-*(MaYqmf~9{u!#g)QM>opQjPQkE$B=S{K> z|6y?#&xwp-8IIzOKn!nNqE=}Db@L^IUFFTX%a*aub+^+zEDS^E`4U5i3i}V;@aZ#% zO|l2LPO%5-=r&(cpE>npsO6u5%WJ%-G1&6IJCfQkq2Qk-`Zt%d(F2E3ZDkBY#M>v_ z#XeRr43SDsO#gd1|IPcd;orNqsj)Y!wgB#KOSZP0WU*mmNx zx;HBfF1{$C9VN9m7%iDcInEeWUoXgaCra@HK^?ejxGWw@k%~&O8%^#^#)Kch#ujy0 z0bs>zscREr9oMa@uve)8kC^V_@7Aya`D5+yV`2EQFKBsZG73ZY5I>UXeS)vFx7)v( zWrAcLS(*DGPqRob`jM`F)uK$5wQd4ZAGTqEh%veC#BvJ$B-G_{8!-ThI%N5Q4)G^x zE*sj2xQ%VZHT0xE>FqbCjVLEBWX|{7F#X@yBnn+{P>;BTE@TcsS6ZkeDMYe!9(tlx zVv5Qyh$Ns>ogaiQ7E(BCH?oAl96Bq6=?*x0E>W>^4lEs*Ejf!(>Y(V~csE_>8XYPD1pP+bU!mW5nT(;}dF(+8A_C zI!qxCZ6)Ghdb2wjGdO_nAijg*;8fZjJ(G@Ym40iHzvhGu<#~4CC$Vp87|QU;jdGp5 z?{b}zPVGTHceyCZL`@sfNi3vwJqUFwtRv{lTrYGGXHwdeTqVuT^u1o>YdFPOdy!(| zwWz*dft$FX9t=_ZsBH397C$`OO}t5Ohml~H&zl|jRv>{8&@Z<|%A!u;qzfFPJ;F(# zYjANL}Vg%EB7#obO1O* z>qesluw2|24D7Jc`f(%(-lHeS;lw7=o8!nB@{*@r$CJnI1-9#EOb)p8L1WH1B(P1= zOxh`#tkzt!O(^sfi@C$eav#UI>J%~wz(nIFk*TNG$?0a&on}P zw$*nKU)Q%vC9Mpfz=AMZzjWsgME(%$Uu27YW=A72f#Q995BW96t zn#Y)PB4PwRGK)0zJt3ht^Hdo+mb6NtEru9%$(IFh6u?*X7M(0(|BH1H2D1OuY~adf z6HG;3prhuJ%a}EEn@1)oou}ggMLxI>!c*^LZrMU|97t+&mTt-*+e7A}Pt%s*mAW`vWH1FV4!ay((E+pD zYZ#~6EX@FR4x5NHBTZUHk^=L^A;yc#8PsWqw#Y8kC;L<%tlnGRh9@*i;q>Y<(u=g9 zEnh}blYYLJ+WE>U$DX%uxs9|epIrc{N^h5|^@gBCs|>8g)#{kL#)GRYG_Axp?6L*Qd> zQ#QG+#0>6?&j=p* zSL=qgdLgIM{mZa{S$wYjJW{||7Rrcr1TT#U@ z1yH>W?TaH#pk%IFz#U>xl}==}RxR{n-NbnMD<#1WY9wn)oy60$iIV*;ZeqQpD9lYc zNr!OSV>bzh&UDIdJg2$Q6}!nsxXC%}L7R}|Tb9~6N=x+3()(pT@jY0t;aav?T3XgD z`Io)Vgs|?$Rw=#NBOY|?(idJ>ct(Y_OqttA(CadqC1aV(@E+^|Ya+<4CSxlF-MtUB zz`~{NC(C48SAGC(;YJ#G5H)roopO-q^{I7?K~d2ng*CNG#~NM5k1^VbMlp63=ZcI@ zk~+}62hlV{(BgxnFOFMvi0HlID;WGwVqJx@Ypayp*vG>3a;tC@FVew>h|etH?!E%j zRcCoEy}T>uXzX~A1%`GdVIM>l{A|}{{cP`=^_iVP8{jCekeIH{mVcFw2j9(hG-(mwy9BMc46GN-YlM=NK>kOH?JP zse;-Lk+GWNb~Rfs0UdQ1w|xgSA10BZ-9*yUyGYsdol;5izu$G_!a~dPRJ{G}ic1{a zC|~~RjgnMzpV4>0auN0XhJ?UaI^-MT=N4D-Z zv_zyGsx+|fZJO+QrcpXyj?Y~N-DsmUslt;^IYRv0ALhzc2e9hE-&HYm(h+n|H|UBZ zB*F0Y_f8c18dC6_emEsC5v=_#zH*}QEPD7 z{b1Y)G;QKt`q2r}9j?>8Cy1BN*1L@U5pJbl+5g?VcJ$^65*V^ey!~!iMpx|8DOVvb z6?fV_8Sg?D(IA1rzeL951fz?nqn%C?9|)wqPvW`iugVMY4jJ*xYbm3J(fw+VVq8Td z|I1TmYelt2f1#l(qu8kum3Xwv6fd3#%LqW5B1wZ?6SD(xlv@H@;~C3fk3PprMqf)GX!SX_DSAk1A-AhT*7ImNPiM&k(wISCVcuw@9lh z-neQl21qDsB^qOsl)guPf4Ju&r#EAe3K`Vp4C$gDAZpJyO6yy_3tU9J*fIE)IEbH$ zXA2#~RpLJRO%u+b$^MD1JVO$kYlS=KUBvH&FyuDVvNI%7gPHUK2hoqZe@|ApTx(Jp zJnlA1cV4e6Y>^7+?(fl8d_=uC5)Htma2O`S=k&%|j9}yHm8^rz(V;QXR!*^_BMP`@glfPi&Uz@2d>$N*kqR&2LhM>e4`V zIHnHNc`l-chMptgZok^TuqzW`yL_HjZf=rXY5F47^1ne<0}&<_aZ7q7LE; zdi)0x=r9MRXmp8-7)i^1K(FS-xm_SYm`FhhKnT5EvRfb8{3vY zYn1$PeIIZSE|L{02RQ~6Dd;A1Gkzxh9UzSEy@}D}bXswfqyz?)>Dr^q$hsnE0!O!H zlNzLt%AD)gr8Y=KWlTX|IK=(^se!rzh65u zc>KOT)%~BpUunB)qVv{j`X#tx&AW;oGm@6;YmPk4NjNQD@Ab@h@X()I`o!67zaOT7 z?_^e+(RB_GcqY78Ac0AU4W#9!?=d|I#fD4`WKJSy~yT|!*)W&pu z`k(Rq(-qUcO)R~%b7hK;&FpQx5zugYcIHYK<#!i~#v~2%S#V&@!scPVeRnO$bcL#uu}1^!f!@a`WGIm`E1pbD6KVw_orI`9rU;pxchw?Gw_pWOm;ISm=$Ip%* zANin*rvKW)#}1plZw9%?M`UbO>|Vd|JJsZG{dXQXm^gamZ_ieaUol|L1n2r)wjDd1 z6sJk|!9Tz2`PF{gvB7@Vtt!vMwNc5dE@ck-b5qpO$BTrnpAX(X@a@SPR-K*jeOb%*T&zufFa|#>B z#*JlwVYEH%n4(?-Ey3BOuhvcJ5i_A@QgAlF|6k7v^M)%~abw*c|C-M9(=m+Oc!u%B z$0zIbZ*bSV1bQj$*S<_=X0<2GUGr(xO5#7`0q7zBfQ?~T{Q(;=pjYH8bHegcST*l# zjIy7olsnutAF%Ia2S)P^r^^cHW8UEA9{?SVM|yaM_#G^_t^Lhl8W9~Yrq5)mGr+ET zJ(3|l2IHadSbs&CC1tT0w9V4z zP35*hS@9p~O&UwQ$ShItV~o(#%cZI`jExr$FI8F(Bkrj&w5PxO-BQM)vP2nVyrLC< z%RI5CS_NH<)BEpnTU{K)Dy{sCyqAk3&&4VDrAGUR9bTP_vsyba)x+Fyu*Gt#f)6yG zjhIegq%m<&FBjK5*Ym-nAQr{?ja%N)WZ9>$A&a-)Ipy&oQ% zF?&gZt{&^%A13H*SayDRY)Pt4!dl3~R9zjGI^)bqvF_7~d#37BpNw=J7R~5bZ>d|+Ig6yW^qK~QQZb_{bAJ3lfWPcp(1^T5eQ2=p#VXVXl9 zA4RcYsnLwP0r;!sVX0AUG~)c;e)Mh zsk#EJXB$@}>)?fvCJ(kxDNEIzL)?HE-o%SNMt;RhMJt@cmsR(x0|BGjqaOuM0z zA)d$5znCDtPb>a4!k&nKg{50@Tf}#2#aAM1kNB5ZD$V;=m)XGzXZ*!Mr#vJ zn-9=s0Ef+Pd$xhPzcrn05F*S+_ZAQsV_b3|5QZAF4lILQqw-)PWEv+P3@0_U=C2O^ zq=atfe&0)WM6jB}PAqjq87nvY8UJP0f+yAnl7)iNVs7W-R%FK~G%hyP3vYQ~57;zJ zMzmvLy-;l&dCnh-&GXJ}Be2$Jy-)!fa~W4nV2=5ZOK~b>pZnEdG=}}I9s{qWTB3F4 zA2-?IySa(sm*j%BQTWI#{5qS!BxBO`p@F^lTNR9!@PF6qSrwo4uBJkp+9>=`+s2|z zwF!P^?z$IopI>`y@$5=_t8O)dLEQ zv#SET{AyL`z4JACheFU=g$q`dWrWEpa38Q@5!2zi%_IF@g%#O%wrVDEUnsRmFW-5N z0yLa2mugdN!Yp&h>s_*yyZrVv5v}G=`I`XQ=3ces0D(q#aXwTU)5Iv)ZN4g|dBe|K zlr#L{3MZ&z04#(hbX5TCg9V&tAj}4(MtUPuaA{g_0hmX3=)lWsnl+wh>_0N3r?`rY zi(O%=ZpaC%u$<=UU^I-TjzN$HDRf&9_=6KY83ci_kozMDu&cYcfqf_U<0D;^g-nne zo1FbdaH7xwTd&aI4v?$7D83P@xyK!#i$a-S`$jlO-8w;xaxGTR(xguChtdx zJ?KKA7fggFG^rQt0z%*R0x!3E{+f`kx-Kx<&Cy*8YlIEdt2e|zA~&Ts7y+E=+djA? zUZ|63KwoI@zeLhUd*?$3dqet`D?(&gq=^^GB#mBC$O|*+#J&)Web@8_B~gyB^1@Ga zQ-3h|4HYMj$c(lxoH%0QNMPHh`lXIxCdZ61h=M&$i~uhfN#{kt0cCXUYe7dH2Vgbt zhjhk|o*n>Rq`rp!J^=Q6bP_hO(_)oHOPM6L%(g%!2$DoU9|&{cH(E9jh2Rt&IS4jE z3@sXjd+`q^4T59fHnUD;QB<=`GUHSo$q2$jdU^;X20PaB!opgV3C))_@ANNiUih?2 zx8rX%Fj@s_<6A*Vbwgn!Or#5kLa{PPdL;lI83}7tztz1G>gwoUk>Cx{^m!zN!#?U2 z1$~sK1VI=^6QiIL6wozM$e04UD+;n;C=HE{}t5o{z)TALB~mAQq6%x{(kkcO40SYO|}4SFtW0Zdmy9zB8)CvL>O zCGw~4a)XyaED2sDFuEWE(^Zq7k?`3gJ+=Z4sUsu> z0?~Bj=P+08FR2h{$K`$w3kj6d&{e1&XctyNsCuI{1KZZo>Q#`1zGedg;dH}lv=|Pw zXf^a8wIU^J-~nume{nvt*daAe{8^&`3*Fp$Uvw{+# zq1@araOYtr4c!1yC};DqP#@vtA@*{n4QPVk1ufbL+u;y5eG^Pnz&?)K3I~YVAf~g` zLL4{cYd|MBMNBtU3vKA@?Qp<l+okgK)>K} zAqDBb6*PML!k6>BO^o(sa)q=31z(@8$yuByj|Ds6hI$s-k7~4$w|BrAb>G_c2xw_y zCftU9QC${pxlN!cSrDL3sa0Xy7P>tPrr1xeWvkLv)j}^?lLf=oU2Eh)2GOD4B3l>H zRo_B4&~V4U1xHXW;;V&p%3&y{?2Xk}+HEJq5P_#lcfwN0rO$W5MD=R=j#WZ7m%InfkMmlD{tzqz1vl?7cmiyoX-B{m z99E;9Q6>DtAIA6Kni&{qcB|y$x5aPE*}^K>Us9@sKsxq2nAzqvFHe6bs%(|ez|(8r zK~J4~jjIUp@jOv7e7g+0olG{_ugX;KtP-kt1=3YhucI){@h*@4G2T1BO4vcuj>2un zx&Mm@;*!3H=|JArahHz4D{xG!trXVP)n---i>c{2cy`-SS1Ej6m%&yFX>}X$J-2Q> zyT>+>*<*8Sr?mdLGSXLR4gH+qTkI=^cq$x6SJRF5I{{H4eX$p#t<0>-tj>Iu`8xAW z=G#mj2X@C1DuwoSDts&GffGRC4DE9g;$aWnbP{(RhdBu~z|iMEVgRs@%Qyu+fHVm7 z=bzvQpZ!9nZK7*!cBPOZI9pe&Lp|8xdcIP~g)h1Bze1>;@M++t0nuFLRbI1!Y}X zy8s>Xxtte5omGt#{@ketsH*A-R^QAQ!W>#%3}@9)$D3XV=jf4#aMbw+45@HDQKmjf z6HCy2EvJi0pafKOWGSkduhko=3+SR!NOFHBD3DGRI^k$es9i4vC09}kgTX6M1if8R zr|eAIB*u_yNdY}6dLekw9*@wHx(e%&R7+Pr0-ef5cp)^@at9y5B!C%IDu;N_`L(WM zMw%LX%)uHHuPS_j;l~sU1gZmS<*8|Ch6T*-XOM|6gn!jA`2G7efbZLM_+y;&DsJ{; zjI5kb@iO&gWMXU6Q`ibIT+vfF3F>W92K!vtM>C$ItjBTJpF;Uf5h}Y2Q-d&K# z9wMmmJwZsvcRV-z4ZJ1lk{TsK=of1+Y=9t|Tnl%cMHIE?LNTwx_upKU06qj_=@ctE z`%sQrAxe|9_9equFuk)tWyi?bnMurh_!`2D0<<|whS`Yi9vV9)8}&dj;5{t2-$nX# z!Z1zP-b&Blflcuq_MqYKAYMJMnIEO%W4JHhVO)iw^PLvRh)Zkgbb`r*V4om3>3PDD zf7;?u9n16#@;qtJFKIen)05a&vj8XT`A^eX&^yln= z_yc^-=?G~gFpcw9k}lwX!xs5-SS|^QV-?vB{1w}p)l5g&!w|fSLsB?1K87{ZO8_wIf(d*_D_lu% zM29AI^)S#>4`VvB8s5Jt2mLsDal}NnVmz7_f54EO_c+`PWJFj*zKWJ?M}=bp3UqgyX|%>b~~I_?pE*C?6%+CO@A#vK%1C}PRwz_A<`o$ z?ZG0;xa{=Udw<7eX9SGN{xBe;;oTaOvNbiJNsoPVhuxEqoe>==bkD#=#tu3=`Jh7V zCUs)9tU~-;8oZ86zxAy%tnfE)_@dwyh03;Mw~RT@1)T!YL=;{ z-+K^mzvU8xr{DOh`HETDjDBs=Ud!bgZx>SJE>_WhJV=b!q*zkoE?&3xH=V0zn3Z8~ z^qOLKF^~4~Bz?%FSi0DgOmNs8t$fIIVk{jjw9u1ubswLt;m_Bz**Vb{^V!}074G6~ z>e7z*yG_cDW694RtcEr0YmxfCn?(mBIzR?Gyqle^&z+SGxKUGbWM`M#9xU<+pQg4W zL22%FIyvzvPOTfkx}iH#i2Wsn=u`KeHf~Q+c2tZ3Mea`hdrY^=miW`Pr3)3jwYk9d zm#W%;%ye|FakW>cRvM{`RhD;li{@f5bufTRqr4l3gXQLtW zgsIF{+7Z}-G;DNb$v!83Sc5*5;Q0ZvoyBxspK6bFBvLtxs}NHBFSL{oL)TK;&Ylmp z71%DS^r_0$wu?wPi(kc*;m2k1EU;bac*{^`yVy>{*V(XCRavGIA7L*PBHlqm_j{B6ev+WMtl+*qakXgVPxgH$P53`w zks9T%;N#fGmvt9=V^>XK8M4}ySGjoO4y4ykGI`J=J~+SjwPCp`aX2oE6ke`jFm-YX z-;sRJ49qL$$}{!G_cN89-mw%l1PA`9?pWN#0+G?DV$b)S9f7=(P4{Tp&zB4iD6{?2(b;-08Oy%1=qB2NTpzN< z>@-`j*4;uk`Vu`E#L|EHlDgqD&i1g#td_S_Ui#*SP|JVzetG>Q(|IHcN=!t%;!%Q=K|Spw$X68#@e4r}ynlrJd4+gNREPs;T6;1!`~r5isKQKu z4ezA>jR>{dvcAmrQU!R(a~EIKgqh@zIpN2`@M8z5oj(~3D`}!XNrPW$kw5Vyu2%Ze zpLFnV7G+XdFD4;rT`Lrf5R>gBzNMW4NDr5PT9HAB)FMeCof|-sT@JM(kw2}-Z2C_C z>Epky6)EQmWXjK5A>9XP5$zO+vyixzfn**)fBINUl89qHH%Lb`3Rp&CLr6S~)7jiRfTFHFY8}&K11Eq73>}r`EcOk12G<@mLz)ne^zfpO=>*TNVXQ zd{-+ZTNWAmrWKNHi41*-hP{!V?o2xA7PmIYR=|MMoyW&l88p%8A+(sH9o9m`L@ISA zW0igRw&EBX--Y-=M>=0Fyy=%+$d@j6CHbRj?5|}V#RBTzl~Bh5D?#0M&1);JrukjT zb>iAgH+Li7!tb0`4Jgz;#1ljMnZe+YjWUQfCNKO z|LkUICnl47h5@i`YakUUi(kGe(U)Ka*_Xfhn|V817ZEYrXp&UqA> z58%zM8clitY@#PWBCp{BrSYW3^MKX4uGC+4PfV~cEAy_6XygtgU=QL{%Q=i8Z2|tE z{$r8*levXsF^<9!OyfxiET#X9CxP%8mBy2?gw)Vc6Ua07>$Nw{xoBPbqN!!<OPI+!b+}S8fgSfE&ef`bRkNKtD8)jqw%Hg zb8+gQ(PeYVc(o0aH$-IV?YTJfU+JwB;^)^@bhL~!y_aWSv7;b+LRq$b#X}s-BbdG` zqATW;-@t>5SU{#IoCjf0FCTV2@Yb|9cVsa+4aD8VB`hUhgF2Mgvz}rP`g9q&A6iPIzMn@YM8m6aM&NoTk6vT|GGw{65#QemzZeNQ0WkV<;tag|FY zdpf0|o6!{F)v~x&Wbkx6-q0Y;DQk;~-;Io8b-H>0JC993+*G=16-f-fCJr@RS zL@D==0se3vo`kYN`w};71D5ipeS_r%eC~1utI22uuFNluEK!a^k_B8=8hH*VBP%n= zQ22`DGRQpzG;!NE6Fi_Vqm!4dE^ui4RdHNDP|Fo?OW; zlzq$$xKXqM0dyrL^WFMBAbMrdWL8t7f&Q$UIE@OFgxdQeT3zHQ-lX`Wz>%o7q64or z5mt?-f2G(%Xp*)!|7l|uGhP2etH)?VTlW;Si-)_OSBWocRbpK&Xysc`mG~H;x14eh z!3)dpXw-gUblz6hKX)S!3N34sHqpoX$r3!4jy*ua1H($oZI&zjNA@2b&qoG%bS$+o zk-afp`In7hnxznW^Z?loPr2}esN8t6;1N+Mq9a^M`4Sg+4H@7ke@vf*fHA=HvT*WJk+82g>T9~^Bm*krJPEwZ~Hjxfm z%R7mb(67EHTG&BPeUBFJAA0M1;?wuf2cSiXJH)iU@t!}0>7X?^iq5r+{w7|`sKiP9 zJj0d$l2S=>K~*|N#;MQSRBWB(Nmm?0j-R0=$4D>d0V3(@ov-LRq)5Vj^811K*uQ(k z=mHIrw3!b6fpo%4vAI7G|Gr6O|1J8Glvt)5rN#W}B*v8o7Z;2C=SQg$wDMs?P6bRl zB`X8H^aJsAzr**!&{~cGHJM_&j9Lt2IcAXyS1a*sCsEZn%IA7d|vhDAU9lQe`67yvP7ozJ)O? zmMxNDi)?h8q%wN+I0^CDSQdrRRHIZ-<}k7+hJ0GAZ+p}zZRH*xCtCsj;^v->$ zP}tYhAPM!6CZc1sj-s1&0B)a7?@*+)^v3@V5-_p|w2BpqJ&xH5acJx2%JErQC2>`V z{pf+yBnB_T9-k)L&|@t;gLX_)Lie8`ox@9u7w1}5&%o>a3d1|;?`HWn^EvYRaH z6iZB0{~yuOQt1o{j>!@4eH5130l(pxZ6|IM_t`ud?_3vgkOcaGLK%`XZ!ThQ>7uE` z7Ku>1LRmO2whD(HtyDic?JUuyRhQ?**{8-a@1)dbMtciMUB#*VpD&nQWtD1OUVR6~ zZl6;0##2+8c;!r3Y7p8TNgC9wK*1ei)3J79h!oZ;N%BM@#8V&SN`cTDs~!XYUd?_V zM5bO^Q;yFg`Ec%W9tJuoAG? zSxyX>gSicb4N`M)y<{z`m!wh#w`njMQ+drz(zOST(&r_SXhf%!G)h?|3{H42*7%2# zbf>9V+FkbEv1>3uLeVT#8ycle2j%zrgIBmXGsdFuHSKqv1nNE#HJ2Nttu5Xr7qJ7L zLVXME#c#!nx%T32@v!`+E6<}@zfX^yC-KfL!h_2$;-5koQs1C(f%H=M#_KnGF`N#( zK-RdFG%EET4;!Qh@3!PNOV{c33+PX_(4icO0#7c3!!Qvqi)$`oY?@T3VC}^?x+a$- z68BpA?_8pX6;#S4p#i(@qwZGPyJ}*Tg&OgGovX>Rm7poGtcq-JS>k1Q zyh^^2TZcc?sQzw}_S4{e65?2FRh=lar3ADQuXAJb@%ZNMT^!CPppYgP%h9RgM1wS# zny-*pw}|2qY)ot7szK_Bn{4ImuaY%NdpSB4DQJ6h+kYn!_ArdzxQ&73AgU}RNx>1t z+BTTlNWUhigU7U{a_Xfm#m?3(GwP)~#Y|?s6v1T_5=^Ymp&RayfnebB?~sLdFplf? z4>_b5xxPfsn%SgVB}}lKABn_za|wFkD75$c@Cq)U_Bm-H-t|k;MV{C88ouDM)N;EkG99l0f*eR_W$$qDD7QIwBBt(EP7XL`R`vz?l)v2Pby1(|LAe=5bi~LWt%5-aSuE1G>2~B2HsN6X`9WI{(I!C(OKK7#o38BUB5m&%YOZow>uk8{59D$E$Qi^ ziT%GCwKaH1r8#-(l1ni^GFRH#owRrcU5Kk%*ypFh!C!MjYCm~6((YyDx$)!v_(Po% zb>+`8{in;*dR3fp`fOZ9*Ec`BvfuXox?#76e65lm-OH<=vV0?x+f*{tzEKfB>)ERA zebcjpCVoDz{g^oZ#hOcb9?nnF3>jHnKT3=HV5h-}c?nmZ zE=yaJ@cZLer?RHZ|EW*+MZGudtL!|ZuSGa|d&XzKeU{PZX45N&jCl-qhT;DDqo6j7JnAN{@(e1Q?-@m!9UH)Ba@rvd1cjR_8e|tZzNAu&D;Ey-x58U`{ z_b1(lZZ*}|E&aJ^c*@ku*k5~fkM4bBns&s?Mz2rC-9EAFT1&~m zjv?Xm@4G(aUv=xAb+<=mao*k^9n7;2g?Aa1H#XyC?&{;^`t7$L{W5!4e+h1l3rv|B z`_cLXh2Lzp4G&mbbhXK6#gMfp#`=|*53L<4?djdn^{b9Q98amaJa^aY=Xc%SlFPBs b{b~p|`11G;D=!Cz@B8e@h;{9xX-obe8kz*( diff --git a/firmware/tsp_stm/fts1ba90a_gts7xl.bin b/firmware/tsp_stm/fts1ba90a_gts7xl.bin index e80a4ddce1f344ac1aacae0df375026285fbd66f..c349c77e824385301fa622d1c4184dcbb63fd460 100644 GIT binary patch delta 93 zcmbO*i+utRNoZIyFfhn4GBE-v24h|Z23{rxhBf;c85DqQ7?A$Sx~S1%s{`Yj{gOdH nitOB(85q{G_a5Bw=l_2(21^DeAm4a9>j6e~UY40}F02Cpe%}{? delta 93 zcmbO*i+utRNobfcFfhn4GBE-v1_NFO23{rxhBf;c85DqQ7&x@1LZ;DSs{`Yj{gVEd nZoF`3W?}ye#ily_^96lH3>4 diff --git a/firmware/tsp_stm/fts9cu80f_bloom.fw b/firmware/tsp_stm/fts9cu80f_bloom.fw index 8fda3db2d9be685425f9397192fa3fd803ff8e2e..3b98cdfa82938ade83ddbfbd77a27262de2428cb 100644 GIT binary patch delta 16691 zcmZ`h30PIt)_a{hGG9RE>0Bm3L_srgzK9<0RS+=Ep-eC>Ow((cUYh`CGhf)Y4raYH z8!)pVA~eOJvNE4}Db391i(Uf`m75&yx#RiQxj^~e|Nng7I(u4s@3p73*RU^#4(bja z)D=&AYuZ~t2)T0@A!UOIp_quobR0qwfKo)_f(Qvx6LRP@kV7F#PWRu5zfF6}yJX4V ze_uujS65fLwK%VO$7&$E5tP4!93gu#-i&Yr;UvO2gdY*EA-EBAYk))|oIu-w5&*8^%w znHowN;UZZgy~f4q!}gPw81{=y4XR{y1alvugH(@kEfRf4HE(2$6O3(_3?{>=k6?#nI$1qDBS-$;VoEG^)wrhS z$ENP;iY4*vD~V*7I!eZmvVUjRSPjfc_o+8P3mu{vG2~Tgs_`vzJo~$}T~ZUs0=q6t z+pekCy2#C4q(F#g%~GL|CG=tYe5$$^%_H+-SOI-qlMh4aIn8)O9Q%h{dSw##l$mUg zW1q^jzqW>7r(|gd39~Hsn&a40a-nb!hE6$On1$g@nf^nYl~Q>`*VuN6J)3)(P0$F1 zW}KtI>B9F?|E*K8k6Ie3n++mesw;sUdPEl!nc~S@iufB0I4J>U1t*$b)+L0LxZ*m_ z=ndq6ije&@Tt6!ON4L?U02{((L~2M6YIm)&%3U~0&A?^{HBRZq&X zRZ6!8=A=I9&5Ii=C~2El*=1o}MonL#=QhMX_vN#s&^gURCC&XiqV*>RCB_%~7QN8Qjge#!Nla=o~ zQIfSFh7F=agWnx-+}V51V%Rp1G6OMenJ3Ry&_psKScQ9DGU{V}8{>T`ENRh^WtuhFT`HW&lC)Fh70 zp(8>Qf^IoYO-ee3^`n)c#_;D{5iH!L^gGO7|4vFn7jVD0sV}rZ|D~i9{NSde!|v{9 zl!;N*uLh$%bN{2kbspKV-+SNW##*Bgm^uhq(Fi)*FbWds z4#Om~JLCgI2<|}$hUD82_F##=r$i6ox0Sp^_eBolu6gLC z$o+-cKCQ43hu_yXX`)&P5kA6Ud~`XYs+460ma=|9F>Icj^c{`_6Js0;lJZP&MGyL- zRJ-&ZF~+dj^oKqZQt}aJv@pnz70b@ayeZqHFXHX&JwTj(bVAew&i5g$iy97M^U0`X zppIsr$aHMXtdzZ;Q#dQpY!8NN&>NLqtn+FGy-|%ZjvkCLjwqJ;+%T1bov>NX3Jshk zj5uWn=hHS4Ug3Vxtma7WWnZaUAbd2NgDfVR-HU8Cn$4s!u_@e9A1#QTg$IJhj)D=i zJvK5t#E%q+4A)nxRMOC!u_C-px5N#G=jgFG3#_C;@y|vzAHw5R$QP%SyzeBWmSo}1 z%%JbaKa99Z2?^C%Z3Qh#{ZG8_{t-iB*>pEaExkdeE<~1Uzyb9Joyjt_? zsZgah2QDX7JgXi%u`-rbx(nK@c&9H%25)EqVPvWgne+5N*+ewEc_^=CL(fJX;&PZt zou>)$D%Y~w9?q`0>7|6^fEBJ&mqT%$m(#GsjE60< zk|KOW-8W`!orw>r)79yXp*Z9FT^gKw1IC(NTuxR1qAA2nbBK% zW8=~jNaScQmx^VW7v}A*h2ja{r>=p-)O}POvz^E3>Q8qiPLIFkzNl{BWI;YqqTB@H&y(2@1 zS?mNpwvJ@<>)E~c(-b~QIUb|=_1u0B{gk&tH63cqhX?2aV4vV|`?sUdCj%n0_GY)YK)-Y(pN`mM3-l#^suC+oz`9hlx8 z%Z@vv%qtQjUeH=Y*>fI}S=a%6gBzmQ1fRjYMY_ZKy~Ni9*Qxw@3sH{i=5o<&IDIqC z7_G<{!x9LIW;$oRLR0&bRG$*qj4Ew+-Vo>myrmY=!A?>Dd95VWk;Yp4=;1ihTO|?p;G3PpwTcvl0$OGo=;)BlnITD%GR^UlGQb$RBQquDDL>ap z@#iN>Sf@}SK8Chu8e`s+dvA^?HvWimAghqv^)#SwdCF!_?~F#VS%^na;29=&A3+1l zq^tU7!!EkJZ!SDd+xvb7uh8vTrLeO3a@I|NSo(dxG|*F3&KN@!`&l+6fAn6q0QFJq z2boUEsYrT9CRxE3mFv=w1s4njq=WFiD6i7fIfDZp_xAU5&XvtU{Q-i{cq$eY5))ox zr#&<__ceHew&hY7M#~3`hiEDe$mL`&{dB^!I+xv3Kj8Vt&%Im{sdXHa@#`{Op zRYs!N2i~koz43W-6l?M}-*@LjpsT?PqYrzMo*tT@dm49OAGU#Z4Nc&F_R`RTaWmiY z?$oKyW(#ZiF!q|a!XICU@xOa{e|$a0>%A3P1!ptHpY!tm_%j%P#@nG$@;6|7y?3WZ zgK_0r+lc9>=-z@-sB3l?Bmswu89)3^OS}iSLb*c1$6j-%iFnSIvKri|eb_-SVc*N6 zI|*5fTYV$KGYEAE+YsszUPD;(3afqz!<}^d@C(pLA006}I@1Hfw5X z)Pqr(Ff(~Z_c4Hlj5Or3O<+CgxI3sr?(FSJV-GQF zYY2PLM_89z83jRJ_2ogL=~lt^fp34ZN2o-bYYqPeP&6dd;T!XqR8g;gPNRz2aeMLh^HCrVO zsj#-mjxS_aCor$n-MG;`+}zu-20K3LAuI_e*@RXS*+SlHBjw z^UcJjL6uyab*6ntg)$*8cUoKemh?`TvNRLj&>=hUl4Co(12fHF3pk)Mf>lB39p|T> zWb9scER)rOmR)ftValXZpG~BXn^Fp+unuJF+6mT*G=mjbke5SQlSkEZ2uf((tMKcG zh8Ec|-mfBOcPgu(uya$JfxJzBFh#;=^rq>4*h^;?KCe%7qbSHy-1JsqKX{ND$M%I_ zYQgU{x^(QOxJxd`>SM3Nv28rS+iXpHY_(&9zYaj{E3)WGxK6hgMaJFdlO20~HQ3BZ zl!yo$<1$^*XbH2>wjyW9RkVI6i=jue#3uUjxM=~OA~80E{nR+V@6h)#Ru*I+;o}IY z!eKn(JKkA^t?Y9i^M|$0woZ}}spz+Sh;fUgHvDc0sra2%k2mK3Vj;ZVS|voXOk(gf)X1T}7wB8k*1DPBOqvE>47A3vvB5mP^&oM#Kn>T~{kNx$Z!;*U#} zo7`w485_q!dx0&sDO_PT&QVsQZKFgC8P*}zJew&o&-(e#xGhbhBZ#u%uXop(hdWw@8!P(H3i=LImfDr7k!-Ded*vswGGR}7 z#Xq|Xz?x2HUeoPZFC0C9`{XeQ~9p|Wk5 zxY4Z1QQNgSoIT2_uE}c)w~=gj`)V3FA-8%-G2gQnL$RMdPRI&u*CJJIIKXc9jpZLfgT(P#~##A+n4OLWuw)EL@(BdoHgjl=-}EmkN-%M6wr-$d2b-j?RL% zax6QFi~^8RO!mihc9VaK9^;Pcz;3{Nf-r%GnbTCa++*kvb6WKW9@3%XvzGp#EoDH+ z*-J|+b>wW-Qr@hs;LU2}1EOn%Irvbw0NyFYr)9AkXoCqfL!5`z(3sK_V> zvl^iWp%!5^^_pXqg}C{u zds8iSQY%rmFB+*nRBSv^4BR2e-(Qk~@w;7`LYpj6)hi{1B%5!d{}?LxN_z9*V4flC zQ}CBc%6FB&)xN zT*Wt;lFb#+u8dl5vrb4r@|DYHuVIre_-vvj01t%ToaIhxoJm9AJngImdpt{=^8F@+Z8GD?{v=O)==JsI**}9fEUBjtU}XE=b`wvsdRQ! z7GA#{HvYiR*0_!WylGVJQS1)tF3kvkI@4M6p4!rf6&yi%5G}C1*Z$XZUHK~^Q=H?H3%leYDxCe%G=EBD z(*4r$$@{w?Oxymcd9dx%i59_>7tUs&J`u?ZY2}pdV59CSZBYjHzWgwr9>_A-vpN=8 z9yW)wFna2)gK7h7l<6~5Kj4^;j+@p1)0%&qRtkO2No$1twww-57;RH5FMU{>kCsi( zJ6AP96q88=A481w6G!2A;dE&?fb#b`&2k?d7ZH${1-VWv};4X8308X}n5&DD)XL+3DL^RJ;P zD-iPoF<)}g_ZJSzS?kf(Wtvr62MKx3DAa0qKM^jJVYlU;SDy$I(02Qr()g5QWFRzr zQ4)mHfr}QvI=X$)Y*uJr zRBlpQ{KiekJ^Tci>9L2$aPmRQEnXCI-ess$+E>3A$@AuB7KudpIoX`E{qR~t4;J$Lv;w67Xj(3H=m~{mp^$PmNo=~Qg&~j@W zs%i_ZNkvPh0{JKIz2P_oMx25i*HK-fT~!~leJtT{X;!%+>dOU_A+pXa49D^WEC;;l z`qa(9v<9h&peL=vxSLL@T{@CGgM(OF6|=%cj3(hziPS~1?Kpm7EW^6b(2tk?3@_3> zk31haz*$hWej*wQ42{l(gYv5M>~mVaY#=IxwaZF#F1s6^0OTnPEDxDOShV}nV<^qE z=T(KUC2kX{Skkk|&;_-iLd(2+*~_qkZeN}NfwX0LUpP)LE;qtrDlfMfKf=>A1aGY0 zafE7&>k&K+;P=eDfO((L1&{WHBXsMd<^4=&-uBE3m&PsSJ>PM|-35 z(jyqpOKWOCZXD1=Ls!H{y*e?%2K}`5U1k*4c(7HVlDiBvU8>5<_zjnb^N_?p5=aW#dOz?wTP zjnWxTUt?%{_d2Oj#GY7ld}$5ZTeqUFxmC)m(73fXxDNE9729S&J$>DlqWJ{Z@*{e} zHb+%%oVJr}MA%wNd1$4`* zG{~b(tESD!YftM4$9&nbPu7rZ`!?q_;P2pAl>D0XO?g2TUf0i%Ow$cgQL#3@Ln-B$ zQASOqJ=e=NqMShWDj162w+E?|rOR z8~eF?-B|LSMp%)k8Sv8uqoD5MNeF9mH;=1L=D33{I&V!~!eCcTX~BV=4?$LPyCUEX z46f0|o#llHmQKUg4uj#;vi5$oLG4?+n>+8MQ`WtMY#7$Z86QL)h!=v{{m4K+#H~fz z=NVQdJbqP6G~X3q{&YHG{j=&|c2=feu209vF`3@-NA}4ydBdIDPdQZO5jsbDnxn6UjZbj;HeAc1ap zdLXE1>(l!(p7P~aeU2wStE$mC$nb%aBf;z;pS4Cw-+^g@>AB6DHlI>%z3E#@(d72# zmIE+`R{rf8M9}hQ<3K|fK06GaX@33Lg^gXGY=m!4_a~C~J zjdumHJ=iizI{(q~3~ad$o#lUFZ;}Vy*6v6CRByWn{{!d|$GqtZ5n zY!6}v>e!Y6F*ND;2HjL~iX410YcHvAD3Gve{)3urinw^a};qbpy?fQj_w7w$oar1OP@lu+NcOFE+N8mU@? z;aX{VnbcO@efy*av*+nxu>`kXtvCYR3~l1pxDv01gxF2E5N5BfsLp+p@s&!dkUm&H z0;ba4^%+pue4;*$3y<~glafh4Aq_=}nSudl%ll$BhXc>r@ieyCyki}VZ65a0Qa}Ux z-j~;bK=c1z2~o}T@8cn4p1bhYYt|=>{5S)vY5w_@A`bR9XTLfJxCR$}diQWNRUhB& z42pD?-Z)u#%WPnw^u%kIVN`ST>-b3JaoY067`TVteB(&M!=9Q0_0m*rwm_~PCFH7! z(_dXp7Nv%3h^RRbcf#B0_RcgL417$n3 z;{Me5SWxw!8ILtDXgUCB&rNII1RLqT=IKFGT&YRnNt%X0Rzkzx9~d;`&vYKOyk7(v zbj$k-6h0=s-;X=xY))@c1B|5EA8a**vOna~QaLr(xW6hCk5%&*A8Z3KHqY5Vo(tf8 zQ;nGop(si2`)~=qsYyC$F?{20b&|ZXLVt7I_CR*p-Mr%9a1N4aQ(HOoqpHK@u_s+M z!fL#G3!3t(rU-S?bA4<{0qm%YE;`&lcb%KJJz^P49x;cqYWEUEt7w{Ej2z!KmMq4+ zN3nbnmM_Bi5_e*FUi}r|qLV8J^l#p1JsAvC{b(k|2=}1g$!1Q-AE%;%O?vH*0{cx z>el?Eh#ZChHW7_-N~{A#i84Ck_;lz`>G6R<6P!oQ#7L?_*=Bm`_>i~YEyE39?4}I#iFNV5EhrVM)A~)dDh3zQq6_TBc zLzu3a+UEmAG&|dM5V8wtDK(QP_c!U;MjG<^8A|E-i<^*%-T$v3Kx4v^?{_D?;nXym{h}X=Z>3_RBAq`cOhu(H znBCJnutVfHw~K!M??doX^SU2@gxDZ=_|MPaTg>y*)g1Jljzfq0q{CK;244;%QeT~7%NVFMe?!t)b&A% zWxnnQe{5RwFewb;1Mvlg8kaN+dFE-94rk)3=}92UU(Iu!_d!sAtgqW++g}yPg6T=u z`I1+BwF30lp5KWLD!HOhT?ZYfBtxB1P}0x(g6k?0yURBDpl)YRe2tGojM(}>w!#;H zu^5ciHg~yCa@>A5J?wi2O$86j2e|KDuV>+n&@5&HOs+c~3W%f&5f*vdJbBCmmD7$lC- zK(ji4ojW4l(!fMmD;8=YC0j9oD9Yze#~1ioLoQv{NHX>cXjCubcs)b^=3a_d?kz{K zxJe5+83|IJO^sG<;BPpNdJf>T!ER-!6*p=Ct3u!2bw{&!UJDtzUHAs+y5nV0ql00( zT7Tk6al8&nk(TFmkQRN@$8)AD6O4sdHu5GWgNj$NS0(XF9mM9XmS4tWRNr*X;r3e1 zRz(e}3ipq)%exp|9vZ}5BXy5e#~OWNv>qBbw@*B($H8jF@AWVchKXSTFfimk+3R@1 z<#c@Dz3G@GP6~igA=5DH0T*FKo|}%b;`0HJ5~4Uoc$|nNg#F^N02mBUi#G$HG-cD{$b!Ug z!m*7KF+T#PWsG*O7Oc3fW(WbSz+EeRkl5vq4|3}SJc{1Pe@c#M+kEqHGOdpLu}Svb{dBA`Z+$*89TDl@IwGSMZ^Omc596pFIfg z%d+DtK2jJXX&M!iRh~)9o;j?H@mv4wUW|hTjba%1MD)f%TKG$VE2ebCgQrE$uBM(2(0x3l=v33GOcVmwqPtn}zn@PRD8D!^`HYQk6On88hs z{O+g{BNL#nuGt%FCTxyam;gE1AG>0kfX}W1b_yMp_u}h-^EgVjp`b-MU|MuTEI_uP zW&OnG6CeW|;=u$kR{w6UFVJ-C?8<}SY~8n4&9;IvDL;=~Jw{AbQJ7x{kj;Jjv)NGa zN9WwENc+yN9hejO?GI+SS_oy55pioF-Y(^ z=AB*333{NuJ!6T@FPHN2042fGop#I4VLt^H-0DPcO|G{6OL2Z8`ujdER$VR9tQDV6 zgi+8Wew_#zog`wF#Dc9@Q+(M~HnMjp|zlLrhfzdIJVU$cZ_>F`(Dl95nU{z7m++t1I*c&yeY1YbOl9pzLj#NwqRuCIueZ}%*NJ)tI z^meO40#_d<>>0(QW&22H5jQ7;u~e|=YXF_pvf}}?+#A|d8;dL?HL^*Y7F0nx0xL`w zvQb}SGIKSGuLm}kH;tI6Glo};^ylN3$ND|qo*@KNX=Hnim;<1paRe>=pB z15+TOI?|%NdQ;|1nJt4a&cfUD75XL)A5r_sWHpt_dl}VXLmRPi?9D@*tuWCbaBSZp zC4K4;A!qggnXwoA_U^ZFA1i$1)+PgK#8C0tJcV#$4)DGEdmN^f{r;2AkVAgK$Q6W3 z2+I*_5XPY0MukM7=fmImaddMU+C-KD$pf4H@$UJ`L&ne93vZBc=rAhZ3cY_AyLxaq zTb4MAhnRx8o(!-ho71y(xV}&kVN5dXS%jNl(;DL~bQG#=6O#)QNqVes({Yc77qH7` zc*qQ@{IfZ|*oMsomH9K2AvB6V@DLT^G%NdC-!T$hgSSLig|a~3BI{9nPX_-u+j~+dQltl(*j4`=*2HCpwQD=VvxDq>c3?ZYG}6O5 z)ae{g7;|zR`gGD^NN*AIQz0^^$r4z#daT;sy90Llo3yr&G?E>5k+WHnHT{CVdacBi zXci$2V#04P3dW-CqBj*Xs-HF6^KcH(N~{+Q6RZ;qEyzdwyBC*=J=8OUr8kIwLGSJ% z9M2v;M3Ehn|4b85(n4>Vb>olzGu@4UXHQ!3cq(rQP8Rv!cO2=>-bm7G(G|+2oA8~) zIHp%`Yx>)_jvUlxs8}t zhoHR8c@1G3g7`@W@cc~qjz2pqS6Zu7C`rWDzUUORCf#SE;X;gpLfWP2VK`X6>9yIi^jgtH{@N((Bp&Eu*I#@`oa!~AAlmCvdPtg zjy2&UKSP_2{p~RRIO1(FFdNPO%f$=XPz^ESJ^i2rE{J>jK`wkEp6dtsBfiEP4K%>( z*q2I-jK4zA@r~TDt%f%!A@0mRc(-|6cNvY=sYdiV1@5wTShdU{7UjT#klF5?j|B1f zG#=4u>wz2?kIIE8_lK0~ot{)78$A??M4)5a4-x+|D4g!h+kj7ROK+%_PB!aUuD2NP zp<|Mon}iy0VFg%q>|QVF8K;(ghGTo=1Hz9(qqL5ddgp$ijP{WafFFZ7qs(@+W$K%B z`1ngHv0_O<@vsu3_;N0cj~wmELPwyc{R|@EuU*=8Y@v8F7iL3;c-H_tpO5R4Ea#^j->Gh5u92YulS@njy911~1! z!w7JRGxK52h_77f=6-&M^C+@$S?`*px?{}-{Jn;uK*z?qcylm@Pq~vZ)UucSmz$0) z60hgOQYaPY4?=N%qqubtj0m6R1bic?Z9jyS3vh9@;>AJmHGCsB4MwDYix&sO{a_Xg z?||BZB~Gq^u*=SK#gIYx`PQ8^JC|~N$5IXJ=i_TNEX}9oG>rENR}6ebt?3VH;8z#@ zQO1j|JK$~I8=jp@fxRN`8v?^ZAM~QVjKH2M!RyHKiZ_P9*t=r98CEOKtwu22s?WFK zs=Y0(DqdmPi9gF&{oboJS$M+@^5Ym<6bvh3?2wk36?cGgFD^0<$k(#2BUXQD6_!3D zZn_gD!2{yiJMnzCU`a_aKK8IRAa_+-FeA<+F=!~vgeS%MLvg?lid%=`I@~Qb4}}aU z63-8X>F~LjUjX+&gSe#t*Y7cLUjY=tOz~O)4Ceaz#Ct`UD%ys@AV?GU4ufo1-g~^B$sfe74!lOu`ihnw#rFK%-$t{<{ z{0Dfdl!8{pC&aFi@Ji;ii4j%LNp_yHo)two7s?2m-Pw{zF0%TWiO_Kn|{pO@(lp8{!dHkA-pf zM0n;Us`~$Wf#cN-^%y*{z7|N&Df!iLj~j$Osjs8WUCUaW1FC*?OmTB>;nOG7cr!}z zy-ho*$46=HhsUCuCjD2(zumt&3f)i#dw?HU@vGx!5gGa%JWsVnxJXs4`--4d4IQoX z&Gd(u0^my00*c8Ujz;n9><`9EqD za=g#6@5sSlh+pm5DVCJr6f}yr}Dd zWS?SCV?Vle#y}JV-jH-g<>yPUN?u2#&+B;Cqi*myhDo{xjEhO-&^I*N=W`6fDnZg! zhtVTWDTh>0i;tG$mi38ZIqpuC*jf$);}kvTCFHgXrO-y@Y-l=(F&8OH7v*x)#WsqM zPeI1CLVRTkPRgg^!6~p1>cqZx!8A~}K6w{>)(6U4$5(+$4SB7WMX-$1RzC=&{lV6c z7DJ#aAYgH~uQamt>{3MHt}bo;?opVfN0n~KQ{aG8t+~}W@=#@857!&WtP2Kmb*Z?x z28N>oyQc3&oMuN4hIqku?^y3s^f*kxp3$7eY;FJmGCwO<6*xW2`Ld*F$3bV6*~sznlsa z?zEuJc$M@SfaNK&IC?#doTkTe+&s04|JZ0zN;@65d_Pp}Df*$J)8X_fwXLX)#Vch| zgy%8$7vJS7BZgP}rHVNuM2N5?qk*uy{x{<3^{7+YeVvX^#cS&!3O*J!8z4XARpreY zJ{waAd`&Fc0LCbaZTybUk>V`mY7K#_HR?_jOjapHw%*QfD|$eDcLOf>ed6g2@GzI+ z6Gv}^0xr-e+BQNBeBJ8Y2uA>Bv>tdG?;&oSM~r<2UW2aIwr5}igkIl_ssT~)gjA&d zyjh&`H(1Oq*wXsZ-{1=f?cDNL;rT7CFV?{<4uV^6J_o8Os1%)V!UZ@Xo^8MzYPjfa zK$C_?%-sXms>dfQ6$yz+0hAdDX-n)*pXdqOd&09lp&LW|tu2|K)Q#WL6Mo+l{?HTt z*c1MYp@QGp6JGAgzuFyElizwWM)h>i8(!-#h1GH(_}>KM!mg&kj=N{TY894Do?_E4TegcIk&~{zb)SRe|Gkt?fZ$q z{{4S{QS_fk4`QSL7jbP!kn&S%rEDK|=KsUs|7+*}%dft@pcWfd)=K%iJ^z*4^1VGX zp>%m20e#btDd zz4g~&zJlMIPU}fe>It93_BJ4Ft;WwTgeHVz2<-^NGJ#YgEJgUOFAy0aD65;$fPVNJ zcZ9(RcOkSPTtko%!gGM6Aq+v7fG`tbA;J=bWe6(~HX-alc!LX5kp?cPRsRm^DbOP3 zzKfSij%dMPSW{1D$_Vgx`~H#CoJBzgGum;a%AZo!dkSjKp}hgq`^1;ug_Ri>79srz zL94N^2k^J~OK`9c1F6O^&I+XUDImtyVT}-@5v`}erhF2`vKG8%o@m|N0u1CC1O;xJE@%0mKIiR(6Kk_w*6lZ@37VdX%Yr}`|zCV2k zwsW6)MClOR4KKEqw!y=|{pc1CABIKT+itP{5%?Cyv}%sR2^Gw0J^eA916bVp=5ds| z)HfYp%B`0^1+OlxnxV+|v|&QvNSF+{Ny5~UL27Qs;J4)9nE*-ZsdaXhs6P!i; lH!fBYa_-#+S8nylawPr-1U1f4Tx*mac89354}UoPe*hL4lS2Ri delta 16986 zcma*P2Y6IP_b@)^ZcX1Lq>*+vjSUbQ0Lg2Cs389LhNI=o0$xFe2?%e!ZidZf@&3z5QJ!i|NcwFy!4LzZmU47-v=?Fo4}kKMPykSKp=5dDGlN7&s{3a?C7-tx zCY8CX+~e}%({^5uC!JZEi)0o$N{1HMe>7`s26m0^QLlw}X>ZMd-hWHujPIB`v%jRR zlA3@C>^hUSMN^}7lYe%Se4#T_xrzjn(24o{s_K``19RipI{KC-4_4FfHA4-ZS&~$C zWd!$(nQZOMVkO#LTgA7^n5FG0OtL&=PGH~2MZ$yFg+KqF-xGsr5&6b`ri;)*HwH6(Rd*q`n}sm)B^~@x~JUJi_xh-dH+CpBXz}=J+@^S61P7wj61W z&yQo_Uiz{=D|>FBXtvzW`8f9Y5khWF0p1j3Ap3L%VnaBDaFAZsXU}zbi7}Orxc;)M zt6;P?U$PaZrmr@~GtVJg<0|v2lCqms(}}g{Y2I42FdOIU3&c-G{1tcblhYR?{;!C? zbfh{tOfU+$h_}ycvMv}-uC9VjgVo=rq^Ajam}{rYgAyX!{KS}oZQSoN7v{!Hr*Uw9*1*e5w z_Ps;2SM_8xw)!jG6x=QCq%SvNu%M*B@F`Ljas8-7(s5MN@&q$dl;)*B2geVn^O+J? zkRl{K$k7kKwg0RzC9t>dYVI|xt`{P%ixQ;2%;gFB0?yx*cqY-jkZ!3LT_HSS%`Rfx z#7D9DUbh*HMK+jcXf`w^us7*bA&I8ruJYvx>@yee<+kz)zFzA{U>~{oC~;Y#-QtJlE6No1HuzShPw;vm2@0iN~eY!BQLt6*mSqj@A^RfHI#ONIqeu`(N%GKe9Eht5XYBA(l<0 zHzIpk7Re+{`>vwl;@A+xR0f*vHdPqvqgagV&o=0;va7m-UDG|hC6>J=J4%jUj)GXW zT|R!f6Xf#mTcg-ew}CxG=SHQX+IS)A@jk;`r!RBqhT??cDukX`n}*6>x#0#L`XP7)m)H!0QQJ&9b2WiAZWpf@T~Ji(_G^hPzt#?XUt#sS-Ctd_EeJ-IF{6dczzmxxizvDx@Z^LShgUbFk{&mpRz5h?UAh5OD`p+1byZ{c{v>U ze4IukWzN|uD=ET9RsYAVtuExls&&ohL@6jOd4H#2-h8CYPLpAwlKzX*Hsm6i( zW)P@}XY+hzH`mQOfkZy<an&D}#BJq~UCZdsqzRn`?>R-3 z3lmTE-dk^zn4ZO=fWXcocthcqpu}@s>=5V(Rs-+bXm&t@H-7jO$_eiYA60) z7tKvg$zA7CBaKl=<4V_%;)o6!jRJ=>{^OY%pz*p#p)m+)#4Yxj)b4PSzMGm3XX&Zb zUdelX?ZfX>eZ?%c0UuvYGP?$(H=Z@nR6bc*9)tKboZd%2<85$?_BH0ghjfOq2zAQ4 z#>w%AUFR-GbqpuT-c=|P)HSheq?ht(S==x$HKz^laZ%PALu+H%FEYvME!=MZ39O0g zAi#(iJIP4v=yw`DmKFzodL}J9yq8-M;as;O!Z~hgNFOvYn#Dp+RjUSRcN&;karO6 zxZ47=f$mB-#ws>OzeGY}*#uXOLF^-!oi#CRj-(7~rlbt; zak?!lHSU{$)|eZ}pDkgXB8B+JX-k$d&MDvCIbztBBg%rbBDw#eL0v|tp7q}5XbgJ? z@dz3`>*e+(Xg~$Hq)Rqjr*Cx0fgfp0m(SrE-D)a>&l@hA{sFMk^Ig;70jlbDpCOj@ zmI_lo-kU7|%2S?1$8;-C_RGW+dQRCc4JJ5i$R`fMx1+?czv-!Ny@I~-bq{FH&l^Iz z1B7Py%4ZajLfphseKbDjP57EN=TKNrN8d9P9;4ztIb4~aes<5uB;KDWX$)Mp-afCM zY+XKBeQrg95f^j}>+GkwJ%rKMJP!yn&@#E|F=3OVu*r)aE5@`naqNPJH+I5RD0{ja zgD~`Tq@5k<8y+sLP{_vG$1&F4&Jp@~4+~eZn?~h696jHsOCdj23?4N!?3@ut9D^p( z%G^Atq>Z`P!hZ0Qt05ffPs~3<>+>?<2>m{9JZg!Yp2eum=k?5ka{5M33yhqMXAwiIy~D@aBp7-;XL11rp@4I$1oqQ?0q0>kMEVz2MRvL zEw2;X?fdj{Ebc#=>!U~v)A~(Q^~Npc7zX}^hx^O~ogFufPV6K-)i+W1BT8T=_C3Ac zH<9b@r{VcSCi;ClbgI^DVHF?2Bwu+Tz8d3y`}jb74aWcQm1`B8jTpb^;{)+$G4Aj= zG)n$jjQ{A{q0wMm+1A!!`dj*Lei=9#Jo(AM;beC1-^Vi3i=r@EAtBmtZYw0-)-qOw zg4&6N_z62B4{9T%3PpVt!a9U!5vmb3BkVv}`5LRN!Eig>+W#!PM;8s49Q&jfgdZfr zYdspqT`eU2aqr4U6JbCKXYx_~K$9`LIk1EpN0~>DB$;Y!u2o$O*k`q`&}cTtqP;wN zpcwg}kL2j>3iV)A7*<1F1Ct?`#uelxuJx{x3T*RclI$S6-n>f68#OI=CMlm9iwoqD zf}xrpQEz-t_Y}kptM?HW>NlaWdV(C)ai~+Kdci>$9s^jjf0R*$EtlY71K^tMnoMD9_NRjy@>h76i9@s^Kcx1@0PHX70z%_kD zggE53+dXOQVP-)y2v68|2Z^Tr2&SmXDg-^IKcOcFC4?;Sk?!GkuXBxi zF}*%0uCn@|p&5-}{)A3vpKDR^LDo&u(x?+UVh`bM!wii_b#e9?W`dM|4xok8h1!T# zuk&H|bTe3sm>!_q>m2V^jt58~ZqS|B&& zJjK<^yg=A8sdu@pS$2LVyW4=BlG-~N?HL##S|LD#1Z?*b=0x}oVY-K~*L>Xzd2FNd zg+L>daGuuU9EN#*Xd^k_xAZiV3Jsp@wWgMq-sK8kUuv^8no4i;U76wT9&pIcjWS^~ zeO=5@5p+Oh1e=0!d(^LZQ;`VSIZ9RwTGs4QQiUpYYl=m~lMKBr)?uRe6~;UmhqWPF z*FvyqwGuz9J#d}D@NHMl$BE0Y#_B5s&Sr`xqs%) zobN7t1kL)eqAhxl8_iATchh%@xq3 zC9M1$?KRYx*J>fW-eyG_8hpCCT*ZRT2xr^fq#iP62x=6VITEQ+QoMkcY2%l4_0TDm zD1mH;ul|l0s89^j-GHtiMMOA9yADzWEt*|CqWDM%TjzW0f8dAQ!Ph(RDAl6WjAp0g zyX$^|bqSm0d+AQiAnfU{M_sw~ccWc6qEwdJ42{o~5PnCw!?qz%;ZHbv1ENqB0AVU( zU?u*-Bp#3SSK4yXH$pNXQ&q8Y_)4>;o7%4J#@SZ;u4$O@9}X?cbQ4a=!~qJ-}d zx^V3HRTr3oTeQd&Jqq=6E{&kXlO>Wf&`ywepZsX);}%ne-u4*wZ>T4%zgtmN|Daz? zcJi`DxZRq2GA)cWAFZ%1>{A~{516}kS^Jv-*F`9T8&59Ey7>V^Wvx7g@nr~r@j9Ap zNvKSg=a!I6EuU$NW z#jtFTg16V-|IV;J_fHR~wRQ=OX1RxLjlImh14F5tk6pbQsIt|cQ-XY`h-M%7AxG6B zI~!0lgxbrk#AHArQ?vr0$57#qlG=V)`99-U@#W=&|GUlBoNO^$`TD{Xb2+pCu3~+K zZCC=5uk17L8rJLdtqGQ(3UxNRDYC)NWs?@5M~0W`TxLQp3?(#i#HUayEQd5K$m)|*1RvQft2*m5XdSkHT7+PF@XBWT0sCIx> zi}AT~RX_u6cAsmj(w%K>*GJE}WoMiFbX(P4wWSk#=}0HmbOhb^D9?(VU!Xfjzh8bPf%5yFh{aubn2KG-G_Lzh-RAMdPLsR+2!{e2y96qH#9Hy(Md=H<{$>lk)fNm^5 zn0(mfc)Io~fiL%JuNHy^twYW+7+u3A!NBV1BU7{c1iRb0u{5xdl!NyYb0-#rC&wuE zmwU1KyyV!~PpET|+(l;2igq3<=13R)c&ZJKH}sm;8@Mbto%zVaNY#l)7ULnk=+QVl zbWeQr1DHaCrdzmiG95Sl5`5TD@YpUu=icv+mjZ5P*3kve`wNwc$UAvii{=uk=8RS$ zm`T!k=`=07Ns4ZocT2>ekQB{U$ciq`Bgcp#kJLn?*?G)r;YRpr=!^_5-%oqaSQYe` zpG$|da5jw|nGqL!zaP>&3*l^xpE_m~q9@Tfvkd0Zc{4p+XCHlHR$Adc@BZrqQtgUQ zj~JsF@wL;FTiCDg~~jab)lesnQT?CPNLgW zalu64$?U`vz2Q+RKat0c@X(%f@8xnm)H?U?=r`QqFPp9aq+KE8-DL_>AEt9`33xbP zYfCPU7>~DFD5L$6Ek&K0C)3kX5xt=(%dDghoZelDHK9fjwG;?~;x-yQ!x>xA=dB1~1Kb^lN z`dL@LbFmzJVNY{|8T zv6G%cJe5f=;Km@R1r-}k;}*V>e0qP*WoOyIvNd%^^S}!AW@05q6fs`ev#hjbVHY?- zT?>scpC&G{7!TuG?2UTlFC4cT<9cPi?uNh>&r6thl&)UX1rE|Zi$+%#oqjK{X(YFT=XR^FMO_csfH@TllsmGQrEvbdRJ~%nF!R8brzRa3 zdtm4As0!$+weK*aTZe~=a)0bO1j)rzZ}(>q5i;i5}~ro&hCDlpml7p z?375|TL^C=ETx}6*{w87wwX}{kiq0hJnSsN!9}q~xxzdduiP#z$D>`{lV;_ME4ThD ziHur@pi;auWPy2sW#Mp@ec_123Qf0g`#1HI=zWXh;7>YXaldZMT*J&$hJ!V#qF&n1 z1=rV0hd3NmqiXLYr9XZG_GZT3WGABs7pFoQJ-fJDd8;p|j#s=wFZ8q+8iP^^Z!Yg+ z(cApaT3@=kczE#$Vy%-hq9d#7q)F+Ws|rUXR25o+t9o1Nq|=CF&*m2Ft*2sAY9#H4E(PG>DKCJ#1;3M5mvPFNSt-jPs}Q4!4$cwEChr2cgG zl62@vPc9i>es4>I^ppMd&GF`efH|9LrvAIb28NN>X-mp&^MM79> z!;z)Swee}*)q}~88sW(#%{{-JH45tMJPBiQ-i8O3r*K@1hgPhtPJGT?RhEBX$4oG# zv?zvUkI*VzLMtysv1e%ds(#3*$*Ug0C3tMr8(c3peQfpn1C+h24cEkmDZndw;w-{k zgiv-2PfffKik<+q@DYj~X?fJJB=M=MTB7+eAM@*J*_s#BVaO-?%bE;~BuX@RtrF2m zwCCDB+#s3GT>A|AS}(7C3L5D2b(N^UeqYyu+hNoCZ1|R5SU(~0ZTYyQ=Sm$$flm&_ ztDfUhDEgubvHh)d?1o{mh;G}^118h2Htfm#!JlXS0yT=sTIcF%_|U~6mB;=#nl^^BmCm%;L%5nP&TvwE|kSEQh+C7VOp zM^cN$^aPh)m`AER3p=kXOnXE6+M@2FWg#)wTusCgQP}efMzSC7k1WE9(x#wNYBuPr@b~7<};eWfs5VXlAZ!W-_hHaY@li!!au6GJX_6@g;P;J%^;L`BS zRZF(0H;1qt^t;VnA}eK04PIX&x!T&Wts!hC4cU^3dw<@RxX#n@`UHk&{jZu6Wjbw3 zT2%kLs)l3LOqss4r7$f;*1W@|M+!QJVn-GZjvza5FIa~9|FD^0zoTR-ZApre{blUY zAP$%NL?Nj5ByMFP>@3ZGDZ8J;-`>ER0rW(L2(vQt+Uwm_WHXnRBq$OP!oEfurZaA; zw`;#cH@=h!Z_@gg9)u@pn3#wz=WH<*6F|Z#ST(1>#u&<%u z^(nw{9{TDV{lP`gyx|I&<0`xP)zn*N1Ma2g-n-T(u7Gy)| z2d_bBwpW#wCp>@#V}_SXbxT9ecy4E$Zg{%>0Ki|gZ^L@!MzCQ*$b0Uz8bu8X??AI|{1L<>ILWQbrTQdyatmSfy+jldPs z@bib80iJ4Duzx5QwA4S&m{l9jo}|Yuo}7d9cvkoUk>RWqTVo9PH1* zV)|+GXvm^*heyX}qII(Zl}3Jju62x1Exp*OA~}e4_Ry-s-E+=+_=@?K!DPNUoSpH^ zMYQtz=_RP}D+ZG%Fz*zW&&KlE7(YSJ9DV`bqBD-<;icxbBiEx2p?D^ts#OkHOA%J> zZg}qwLiOh_ zK`s6D^WKo#knlw-g#9cBS8tU#Lt0H3b5PHTB3uRqUs}RmmRAa{y+7car7-p^rC+vm zD)db=RK;frMR*|SiMl$B_4Uz;uX3YOeDks3-|Sc){phQoW8U@-yCu(WFTght^OYLg z>7K7=#XRC>o>`; zls0|S4ez;r{boXFKkv?pc0zmksBo$!HZ@)r$n2)}A%8!=RCVLD_ZP;a>4luhR z>{}g#d9aT%GkJP{y`KF-jo+=tTclmzJq_PAWS&+5SLAN!+ByUxgVBSbYe~oZ&53w} zBRTJBsQgbJr2izpUvZxU)i1J5mR2H_9LC(J&GPVKPwDy(`rY?S(wgp+?Y*n)P03V| z;2>49{OsF*P~_UbS|K6KNfRE{)X;nk1FTG zKYx;81pV{edel~ne+~h-L06uCBbm50b>@K4hlX33Sf^O>FAC%E$Qa5R8;Ttw$Bp;U zpME(6w;Hzo`YXhTvR=}EPf{q$mgwf+AC7d%OFO2uKhAatyG~UXXTfW9?!`siC|AS9 zi?M)r#=f=#@OVShrHveCl!C%`Wat$*q`Je;4qmIyt^x$yR& z25jiXsNm7dJt~kc!u0YAGp2_G(#tV@ERZgAHFUlH1VCNG*1sPFoST1ch#b5?pSzU_ z%V@)`JzQ@Wo#yP%#kuIK&U?_?bJE!x%@38-EAC5VeR;~Uz3Q3}whx(qArSkZp;U^1 z&LJ#CQsb1GQ2S>~8jPKh^l0@ZN)1oC9)^%dWPSDSiv8ALd<1vieWujqUoJp*?U^0e zpptvtudW8iNy$)c6qNL3e`s}iQhV92eyHBj5kKeW5F@@OnA!b77>mQ$*#?dGD~^lu z(r^9m!$)+ve1Plcd21l5{tv_gfNrp_X$HXO5PQ?vO$u1?%N0vJRL}@Fotcs-s9+S7 zh@uLvB_5aO<0>~6L-{r5p@6r){q9H4z7cn-VUux!yNp4|kicQ<9qy=B*J?4BU9oUr z4gRNgR4{v19IJr_bui1@F9vI2I8=$_wUC;v7^sS2`j7LoLwE~awz`gFzAGrIh2!<; zGt|6GFX_lFr(S$T3*9moNx2nj^sWJa(|O2y0ADM%ABNCzW({H=aF4iK2k8%&$vjthWtg$($~wM~$)Ms@_#_50p;q%A zsos1kf_R)0WxP*NbG(lIB)@_SuBQH)Q{%UpZOT!}8X4e+$M*!@m1wZ`1*x4YIuEQ2uca5_bndYFHJrj7OFwBkU7fgP<2&5`%(qU`NG?!H@`h#YMr; z%#A%H-WvjsajA#I?IF;e(|g4)Ltqk4duAy5O`%R48vzGX_XO^>%5IwGMc^*-#X)p& zV#CUuC}sgU0EX&h{X483f!?kF~ut6CJtF0iRbZ1|u@kr!Z@ctN9O8d+SJ z0OkmXKf*k9rr&wRtHRuy;#Ucf7;^EjGMpa*JiCq=8pVxpRE+El>5^w#CJQx)WqdpJz73s;;ljULZ&8s zxsJ{BkRyLN=Zjqup^GleA8*DhS8;qIbjxmb$JYa&Z3Wg1Z|Oe5M+s+eKx}P(qq6X{ zY@}}nstYY!CGJi{S#*o162Vw`-CUEeaqPIBi{_T@hri4f`J<$~TypgoDYRx`ei1-6 z_roQ#A^-2TY3Q2YhMv*iOuT)^^@SwZ)b)p7Eab>&DK{6;y!*ZFXG?9rY5BL>w&kO# z2WQQp*qRYrTMl7M%~r^$9;|DL#CM)G!_*=dmpbGDq*h+XQ{N+9*2dJ3c_R(NmIqQcfz9473Fa(`Cwv93gXEd`8a7K^?L@H8nq zAH%B!L$hj~U?FMI_1g51a^eUsFSd|%`l@0xSEXDe!Mf4)gNEyjk>&RV^6|@KeJmje z!NNc>A{BCUBHlS0nzO{xR7k8$uqf~D6!s|tit(pf_zHcwzMeyucz`%oHC17h{;;8$ zRB%j-11(B22pkIyq`Nmqp$A5VE#U1*0P_Z}3B)A}@rA$oJqWnomFrkVecW1aAn##V zhoD@`-W-Acf!ix!2xcfN!h!G$!bODN5Ede|bEO|@G0t9evnmoCM&(m38} zuF)f=8zDXHhFN8$k|pe@F4lfs9BYK^yl8wxXuu0uweY(+Odwfc?N_hR@{1WdxXKBH;p!YQx9 zctfKhz>_aJQfQH61fexz$d0tDe(G1xW#e6yBQiVG&S!_TL^>eD;815wVfaf3HptC6 z^cloq$k>Z_C-D)X(rfbNzJH=UP zC{pcn^>X`MF%EF9ly3)>a|2Zsp;V^iD_u1<&DjStJ%tvGZl6g-N#Fb}nOsE~K^ng@vv~adx)f=R)fc#;MKtW@HG{ zt2fvG<&MR)t&FFOwfx>khD&?v4;hm4Fro#*9VcWQi(HIyN2 zy@RLlQT!So)WN-?DFaNE>V`j^8|0usl}JZ9u3lyHy1inRRjgd3DJxldo}@fYQbx?Uzxc z+}GL^)&|%tF3Ex}VWTBO$K|<(&1~9}1>2x=S9}7aOs!hbu|4?s($K798x9jvvPYbT z-GWW*l?{~;EjDCBDSR(NSI9xjtVdVK3pwS-N1Ynrb?i%VR#!-lmfT~FM%y?e-r)uB zv^i{Ac0=6O6=sA@^z4`)!sBlfc!Od1IZ1<)K*?8Zh?0Gu2u-CB> z;>qri056Me-C=BWf3FE|S2ZoC(R+)`Y|*jD#nK#@3_pqQ=0G}pDW1x~(S0l?--9Mv zomg-W900Y5XQP6I0(?zikaAOp6KW}}Fyz72LQ-SVu{^P~2kPk{ac&Q^=O&7t9?%6o z6Vr2HG$e_Oa$x}666Zc{EdWY^f&&LoKTbY}qh0giFGTuT?A;3R17E(p@b66qens)$W+INc7v9so?%gpD*fvqq z8~TN7e5<5|1a?~mpYuzvSkfB?kB#2S@jac)1U9d5jp+7tP1}#Js*R0gj97`=WMvQ~bRz zPS=y7CLfAmyf`c$&kkAQQ~9tKQbkoi$OcJ~d8CZLVxwDq04@Ybj%gM_FH#>^#+lwFa9)zCC}5 zuwYHJE;=MSIyhPkFMytKMl33T-f&o4T!3ceYhq&oQm{chUx1V^7Bz#QTliD1%4Waw zVY#xI5dM8}&>$EBqs5hj5Ce}xgYcITIqpZ3G~NF`+k8o04uXJ6B;zAO>Y6SLf*u^a zAx0L#DeiZV_)8HCdGKS;qe-gnf1KrbHN#^SE--&1WOOV2!x`cMp;Ovh=;qh5M%O*o zKb)M0dk0@~vEy=P89q2_AvL%+v>YCc_e&XnIA8Sq;k@pKYS;~YkMcj9Tg2sqQFMP2 zFAT<6h;Irjh9))q)b!~vd_57fUE1u@=Kit-Z~vY z5qNsrE+&+~qSS-(|EN*K@qTChk%JdW;Apm8+*5)q*e8Bh0*j%iIHDB!*j-$%1YWVJ z6c2;rMcqi8xsSvFBcYW0)hlio39};~ayxYC_8q$P(~-tq*yOk-T^V8(SG!0?`Ch_a zkRDA+?e02z)w$ZGVt>khXRAxie)Z^#!MyTxL}yff?)AFlbH@37&IYf#*6%EkbhQ{4 zpB@EW!aMu@&VE=WM7rukD{Sv5NCP6ajzXDyUv!Q_@zaTMqoGH_HGI6j9rfWXDZEY* zeoY%O<{(8Tamr{sFXoG9N28+266MjzlrP1^F)#}@i)+UKUU@g28v~zrg6mChJq{{0 z9BNoaHa z?H8@9A*u7Pel!FEPs}2OJ{COJUL~FG!SYjn@zvEZaQuEON8wqnT%H>(N@<((ZT|)9 z?&1sOZO+|++BQ5!c2>$_2+w2gOa9ANBZe>EX**1avZM&rLVNu+VvjX=7_RcSIiD2E z)<6s_5T~z!ys$9=0&@cdjuYQl1ICzQY~wF{(}ho^u2vDaTBUAt=80#NBGc{8?<$HF zBT%hCxY%PY%;8S?#8=lsKKGGN{9!Fr!OEtI>);5$A594xa9`nWdc=y2@FwhRN`4mA zQ8;}Tk1RyR6H=bG`dM-BbMOQg^n6p=^YA5vuYLaC!X?i)xnF=u9PDTs|01YjAX1#T z3(mr)V((hqV7?J2*P@5zb@91cxK^2$qEsZrg`pC|^J^g8*bz2&gvUBUJlGPn$jRvB zcKn?k;a45u$&T<;N7#a)g8yAd*xHf*eS26*&U9pCcXV(&Jll~U*Fo6C4npVt7v63B z{|-a=_JQOez7pG++8!#SyNydoB_Wspj|GIxzy{izAf$H(5rN8>ufd2?R&ZCm=&tyu z|37X1+i?dG*ni;fe-(7(55-1r6LB}rZX^ib8V1S=u(QA)26yB9zr-u=Mw)|-Ds!d$ z-JQSjuKe>IoKU*#(lN^0xH*`{-^SmmdprOC61I=O?|(Jaf}@T$0y&9c2x?0ue5E5) z;&;Pj#8ZgbhN1GOlqr9^JM#NtJtgPCj&MpxxCKMCGXGmUGEQ`a!_wO;OvX^*#-|-& zL`HjhQD%F2V@DX$kzasm1^+eyXFKv$9r?dv`+p)h5p>vQ972~${Pab*kOd^D3y=ha zEhhXw00<2T%3pm~Am1UJMera@?}qya!Y+gZ2wx$bL%44u^?gX}AJ@6PM`alJtMdRwV~q%>;b_i!+~^gM=Wwy8_67$AQeS;Ye}wNyYF0!h}j7$C}>y z0OB;_s7Bmf>`faRfr8rU)JS4l6O_Ygab**_Jok$So1iJ;Az5WyX-yM2zGm1h=lG`O z`%#_2iP9msAO318Yep)#zFzV0VVKPkuh{(v`~b8` za}-Xf;QgjkpTPG3A2;p#6pbzQEoYk4bm=qj>Cz+aW5DNbFbsp-WMN!sPc`>YuXp6o zi2%v!an*K(HKP6$+)Rj`vLf*bO#ZRs>EAYaWjPxEQG^;965kYKhd091m7X>1{{vKS B@$vuw diff --git a/firmware/tsp_zinitix/zt7650_r8.bin b/firmware/tsp_zinitix/zt7650_r8.bin index 7147f24cc888cb04bc39e071212e5e1b0326eddf..28cb8cd780069469c860bc42835a9f11af83e97f 100644 GIT binary patch delta 17648 zcmbt*dt6gj*67|lfrJZM;0l6XN_ElVJEMZy8ug6BWTi6YHuD#Yce*3U~zKp*6c;_}m2_@-i`kSIUG zwD@vEjoJ{Dh9o2h$&m@QNDU*e78v}mma#~V0eMG`YJ=W{#BUkj`_D7a-;ZEM+z*Fx zV~yTtA10+v;esM)eko@}m^Go&)dSzcf$z$JZ^6KK@xV9VG8QecHL_4P za)A~pf^L-NXjULKv?<{04@m`eW+7vcjg&?R`v?6%R__;_%8lgOJt4$*3fXc%nCJTg zG0YQ;enZKmJYlh49+?y)T=1(RFZ2k7{yMUGm9X7EInlV)D#y}vw|iuKaBGY?5P8Sj zTjR{jQN9VqFM+fU(ppF`5+pUD%|=14as|bQKve>yI7maGNn%2qZVQK1tz>1Puw88? zD=k7h{lwHT0gRNSOsiQH)Q8F6+l9iAW40BC801^vD$W^&Fq7n4&@?F1%_(1U_wniI z@2oMw?q-tIN83F$-|tLbT2U7te8X%F!EzHCddjFp$S~}NIetOg-0T&|Z7swa6Z(Rt zi;zwT<{2Z<$5=sNRUAEUeNO^h@hlEk{@K5Y5v%i`KzGd7lYQ|3N4SO9;90 z8Lu^Jz0&%nPsy9mm1-0EQ;={pEQ>f(1!Z^yaV83J;b{Re@g@|L22&>OpRyQ(z=s=1 z|iGy9Yvjhsh@Mb#{dG-ARe)g07b#N;Kj!0WD) zUXvEG=h{Gz5~c(sHSEfBVij37lbg)c^~C7fF@B)BpOzqzpp>Gs)^w0cgpLTSM-R7umc~MDo@}u>5B(*r z1M!%D=Cfz)4gQNTQm`MRa&Gf!!Aj zBU=yNEi$3?9rbyK?QTxi>1{%b+L>wH7m9{$7{V>=l)1v7=0>}o$H`0g@!#)Ev(R}e zI%m!G?CCUyQ}1NSFuQ%{>HO2T%A1ERpOlE`h#mw2M@xm0^o8c*S8Fqndzh&S=j{=f$krl zHMvm693}X*BPj~+r z-{Is4^nv;g7pZ!J2w*QYd$~8=Ap&TdG1OEx=zVr1h&xz3h zBfVREcP)I=C)FcGy8B5V?InpvFkIOM=O4CYvZ=IZ_9q=oaQ6jsFu4aaQx~5Q{amKo z&0CYG97#Sh<|4#cV3;|c@?{`4FTNsL)q8u!T~P9Cm{1cMHT9HNJc{-)6Y>L;(#;a& z7jKD{nWvG)v}3O> zZI_+Rf=0{o@1pAwnR*f$xp%H_2v2DNq7f`FRRGy5x(XyQ?}fIqcW!KmWqbO3HjHG; z0k3TNe{=~*Y90@5>^m)vVs`mzAIEw&74X>QS9KQTWu6Ibs&{^J3`wa6h779$Jk|2= zbsX|``kC$PVH_1Oj`WnDfTe9yNscgM4#|78HtsL4L1@6K!4GY1pGp zT(}{!lRdb>gx-GKYcxz~J=p2P!5On5os*f+{K-8&hWCHEYzP@tmf659wh)Apj6-1w z*IlBkl_Xu}1MqpEUO~0nH?B?6FH_spL~9O^K6)>TE$7tEYt}*yUEa#r!3f(r)@s>e zPHpazmRs}bvU>%9y!rOanwN@-u|@lSI+}{lig_&`o4ch~4gS9%khzE#n|;)_k;rvM zVVi(^s1$zbW$Zv+Dd#7+sD6~%v(RDlH0k#sc&c+#;1rSIW_SFqlQNtJu~l$!Z(?^3CoGwh2gL|3+n)-N{m2l0-_>Td=Lm>&IK(B{$ea=FODj zoSH>_ip}8;Eo&*G^6%@K?b^qxI1K7huZrY`!gmOKhk10r+dXz98b>|qFom?s}m7(*W-wOo%=Y{bKZk+P@yrQHL-?~zaWEuC(BoG zc}+|9pt2~3en0EnCBDISl_@O2F69;<$66qD9E`l|d(f{Wb_0pQK^_viwLqY)EhxJS2uyZ)2t?O&#AZg3XDJCE z4~glN#2yS3QfMbqt^F&No8;wt<8SI@Yu9=3J zoovR$x(|*=T2(mIsv<#Fl_bD!RZ0D_#fjcQevhx=@HE5rtb)krwK-$=Q&m z({H&pc_yUHa&1O{{W`D?p$8VejenZu4>Cp`b;WDJzR}Vh@u=PI5i}4os)VbeQNLl`gV`B6*L~M~L@^oN!84$<@(fq_=)a^o)D8=@n*n9pA z*pv2u?qSaXwg#{_I40^~e|h-)+I^@sMqjf-^=w4h2fnMI{jdB2`mfu+iV|?PS_u_O z_ZpbS7^cAQ71v9)4s^=g_2`d=7@5V8G^mV6hN-`xl4kzK@Z)d`vG^9b-f&N0BQ&zp z@ht5?Wss8HB9(8@Pj5#4(G46S*&KnrQf@0nsK`Ev-CGg1#gy_BQadVVpGT3p0FF%k z5~*z*huGkXF!2>z02g^$PBwAKaf}VvKF;yN{+#IJ9($q)x;em(EkkN&-sw12TBfjA zVAKm8`spp4Kb>|0+t1=3R6hGFgt%&UW=B{#7T<74XJ5B-kvbJ3Q*Qvn3d*oL%r(fS zf@zjZjsrt4))IciQTNvzm}tzXV044rsTK`~Suc%DeC5@^QoPTsP zFa)Nyk3e+&g35~&?D|Szn9=}4l+L~lL+s}m037Ylvh*QEV335fs_=1+m;g10>6*h8 zugJN}HSvjp^+z($6ltg8S*ozMz{K*re1p`(v;`5OL4-1-jEhp(y}&dj%y5A6YPC;a0V0N2765g_L>AlCJ)Q`dV~F^%T2-Y zD%gJ^^xQ_5!QN9@Bw!E(ZXZuGQXZ;lOsE zlh|~d^MP+XFqhHoN)Owl&JAkYWbTxC;-dtceP$6o+7r!Lk7DVezJ8+=PW6Dxy%oR2a zGg^=jH7gK{&oZxdhq`vROavq92daSRIhlmL)M$Ls*_8U#KBCnT-m<$4Lwhr9yhJ*v zlzJvKr4fNredGtXm{9XHlul1ZXiIys*-On%mD=UDF4Sc1?tKEizfaYjS%;G8C@BG` ztAaWobF@1N3<$M(qI(Qo5_6zC0hYrTZWM7~P6e7ryJJi!b}d}n&rs_I7+y>(16A5k z^wTUqs!H8@x^yP@{ZcFP7#I_K1xNTYfJxc|ZIg_)C5#GOZqbZ=ozz zZ-2B93hw(F@YU1+!6Vep^2|8cS#-u(cC}*j4w!Rk%Wf7a73MCtzD3h(WVJBk$LWms zCO$g>_4_Hkd+k7PU(JlxC%@d_8(}j*+h|-0 zZE_$Q2}HZ`+q?(x&S*Rz+7v)13XD=(-VNnJjMP`xG8kar<1>Ixw9OCNB-ma7 zjlMugPYIzPc{30iVv_+O$-}A?Ff#d1`KeSjl^=J^v-lyb+r^QT+XY^|Z^0?))*yCQ zwJfDxBb$Dclg!uyx2Y2kH?wY}Zey$+c$l?=1ZLI;m8aa6%Gs_$l=&6H(Kk8b#La8i z15D^xb`J`4N&a6T6oN%a{S1t7#~4N)W(&$m+w2d$*-jJ)#s)SAK4f|W*evcyQuZdF zr0z{VoFscH0{!qXfs5$kHB&k8(%Evmq|Es43lxi!NTCkewbyrnYvfRj8 z|KtSBd05NfTXzQP5Au`vAy9t+)+V%nZG<&xv9U1Y&-E{z`}zRrDt;mlH~1%oycU3i zdDiAnmrJ;qmOKF}BKwQ(jsfr$yorASzzcv>ME~Ob+8Z06&c{I8ENF`cNfTa~JVFLE z^dMz|eR3puP$*PP{t?fp;nEXv+=*Q3aW$$W-A1jX$AnfG;fTI3 zN;euwbkQ85ROidjW0a}$6k;%oycJ_mQ&Xyl>OkcM$5TS-VJ4M&;%`z-!7zboE2{>-ri#+L5P_XIeUkc6qURJz7_~O>|p#Kd@aRA>pW%FQ$8alc)h0#5e8;Z=VmD?a(K#G zPq|Er@kUzaIcVKvn0!M+dj?+>?Lke|95t5h=*ChT=4+1SeF6m@OW%S%FPZn8&u=3r zn>X5L2b`cX&v?$x8xJK_bfBlCe0>6xhP5y8l(Jus_S%uNVx3A@{rXV*{LLo!`9w%& z5{T$>!_j%(0(k}GG32K}Uda>4P1=>nOZMjOy~YMq$e-AuhS_z9msTyWs$o@7GZSh? zQy*jnpYA?Cj(XgRJQH@OPg;OCaL2zNmIi~C7U7LBQ72z%)?!A8n*W@4V;f*f1$KTS zY3veK&L2k_zZLe+k06a-3uou+NaJClW4j`0$g-3+8MLM#uQc%9Jii}7X9B)j(^);v7 z_*zM9SA?>{E5x?AX7Qi@iSbOq@ODJVA6K+X0aa^=Y}sxY*>bf%Eb+(unw4+g^Rn-& zd-<&VJ4Wj--szcPMl$|#i5FAgf1m$5uVkgFFm@WGT}XW-Qhao`h}rRQ67$}}iM*uu zB5ZPGi2Ma*Hv7hGKQ882IuJ=>AF3^h@5N-_=iHgs5Z*D-mWm>i65dl=?!Onqj#Pz; z`8%Yv#WsqIOzQZDU2Vyt4a(5z*O7bsKX-W9?n8rRi#qd;Zwwn%7niKt%9=rUNZL&r-5`NNMS9b^AYGYz9K9z;=`- zZ2Jc`H;}e$QnRC&(Cr_z{CDYb=uVhZC4S~AbD_p{%ot@U)1!RfmdOpCk;h?I!R(vd zV5lu~MsZcFGuI!Hwusz#lubq<7yH4J% zvDajPI~r~Ph28 z1Pyyd(rf)puBEqq&W!Fn;h zesXKf*^qeu*0@uHIPAz20maDVd6&Gk_YvRI;g#=P|#_F!RPV6PVUQ{klcuVV@AUK19B91oa#*J0WDO zPl#Ko_7tj^$z7=i@rH%XijlF!DjB<56UOFgA$qeC^?M?hl?&DD!{sY}@gS@f&aO`m zHA4t+#XM%a{5$Jbx(;}ZN86(8eS+38#oL?(&51&RBZ6cv7s?!?pI=39XP#KuVA*1% zmHijMgWV!q0tP~;(Ci2uw<62nf6rn<1+9RaF_3QtFry*z#(cxb8{iO~k@{P?B@xQW zH3=JnaKQ8fbZ0{w-Q}wxY*{7bY>Wt<1}+x25~{(toK^^yRwLwPCil&GLfOWnWW`Uy zly^VC^J-e&y(b~Z9tc<8zYp3cin9op%bJ4iJO}GtHVd3dAYfn6^O3gIG;ErWNq4;v zC#0(Kw-+ILdolXEFPl*Qk2PzAOd{LYS!8nGeY@t{Epji#;!uO!|AGmnHq^9jtHO$f zj{dPN2p6_)?nA-I*pK6Y6T3cfBbm%$qei`~D@hzngP^ZFW*{ zDVc(#NLwRE1X9wW-%|TC`Dg3@fAaM}6GHun$qiD)G3hD@r_b#(qDU6J1hY(Nc85^^ zX(&l;5w3n3PEwm{dOyA7L-I3(3!g6!8auy#j5(<$WKCxz_a?*S>=SanNDjyckHlDJ zpc!J|)-^)q7xAH1#4z&jO7mu6j+_cKq1PV3Qh{Nmx-7JR5lW()Yvh0LC4Sa?6Ovf^ zEwY?bg6deQw-th1IcsVvk8Q@@(=$vcah1T-NBHgDZ*o@{P3}r~A>eaH$gkIVSDrPw zt7i#i^%_!qR;a2kC;J=%b3E+Di>`WW0`9dYNxb+kJ(gnvfoQ$*u!yWIzHMbC_e^Ne zi%lmP&NrWVmrCipbr3A87s`(72!B;Ld^}aV4pD3DPM-;t+@gmv-HqSx{H;z1I#EFk zLxrO!a>>g zmL@H)sOs|AE3-jn+!dO=WB0CP1E75=wQ?$yRpa*_@xZ^uOQ0+@p@falVb0|K=oAwt z|88eytL~P>8sjaT{?eC>j}b0^89hWpErJ|`W2kA#qu)BNtnD`*)7=-p5VQ?JGeY5> zt7~Xd(H8-*H|5WTn-Jd!-?jnM*9hgW`AC5J3gU2b=oAVy(o&P32S;m=hk`KihvDml z_&v-fe?V|HMCc-6E)o)8`@Y#PAJZV5H65O~&>S!Y6u5Lh~-c*BLkts#eZDHSlFR#^N1tDL9?dY^5OhaEJbwNFfN zC4}~Gg`Shi@n2o7mx~hqOD5fKHna3mR1=s})knDIdY|4U>yI-@ezRY`^C${P$xZGC zoiOWE1PMPTtUeV>)>a7Br*@Kka0@)0LBj9WxK7W)o;02wU?t|I37)H?tO`GR$m^g)kiGXDvL{`9??T4+{C;yh%pLh30Q^L&7HVI2{q6 zoD>cl-~=?Gs5%HSVtynJl`4%@m7uGJVy>H4w{T*2*3PIcQAm% zI!E_1A9jbp6ay)IQaF3IfF#|hF`Qe3iG7Q(uQ8b<`3tR$StR;1A^H4hyg*oT-au{* z5)Pi%*dL8cout=8s7sQgDp5N0m8Un)cYXb(w_{yZMNTGSKh0(RkeVHg;P#|9WP2eu zDA@Mmb-h6ozd|d>PNcdK(g4@CEIE;E(PJxSN-}o$&}qD^s0Oyzukm} zoe@?yZ6j}A7DB$gLWVvOdcK_zKO!717`fsf=XW>9MP|iA`;olWx)n~%|%X%^{KyY48Bk?NX(&ZWYRc6q~(7z$@ z++fNvX7W8t>H1k+Xax9g#Iz3dUe0}IxnTZou|0YUNNq0lvVtTWg}k*tpM4whFgU#i zz81Kfd}L9}S=wgQ!n>tGdlx~y5iXe@(K<_jgWk7ky$$N&WmSNb)1DelVf*R*`6ASV z!qKm8is=QDo$}LP;3vo+n+w@*nx5yC1J&1f$w2MZrU2e=p!QqdYoPX@O)?Kr_s@(_ zcqM|2h!?hA85{j!y%+c_!3WT%HMzgOWO8p+xazrjYmygS>z-tp+{cm7ab;e}l)*gV zwT2j~|0Yl15y$dTCU;MUu=qcrev`|8do^XcCzStZBHkuk{?BVTRTy)1Hg*Z+SKrj7 zUn2h0S2m>rzEb$|@b!XkK73(APdOmOeLvTpWr(~7Ppe=GMs~8?@y_>6Xm|%LTLR(M zGLk+A8{Xz=50P0c(e$Jp-fVKWe{FJKReGM?A?ZQSVezllJP0oDv&K*}Pg(`;7hg}{ z8!4_cx&ALQD*q(cXxA$yH1S&+IPZTPWmhzRW?`htn9TD<7UKlBV^T9JH0Gkhl4!G+ zatZaio4XaOn(JAACJdaF;3Gcb^~npC08Y-VRK8%S4#_tENx9tC%_W+IpHs2OZ!rJ6OaR@7n*%VFK0JYE{P!4Wb8a56kN_O3xax*kB<%gb3WeGtor%gm{R zer9ET3QZ^6BQbbO^?(S$G(%xXj(NzSClGxAW`l0)B-})n17hBz-~|r+W{Sv zYPt}1CV?<<9+(b**}G@PH6uv2oz(&auHH~|(^A37?Xi>LfyyMr+X8@SfMT3(JrI35 z0`S)>MzB3F0)+RconS|t)K=9;yq1B$*=~Ae49e@)I1K{=qv3evk>lEJXdKkc6 zL^NvwZz9CsypYP$4FQ))Xr)aDymUUdboV*?Gl(ic^!afBQL5oQ3?-H!5b9mQ$${ab zeuh3Lblt#kGB6C#kAue#GIM~>Q8w7a&|9NM*fJPtGa^uK>_j>^pUV&rfn{{BZf;`XeijG(_1PDGIwbbpfbpQ;m z3j>Q&&2p<18n6Fhlty>iue9c}9CU3k`rVM6ZDy%^n=NdBm?&WbfYc=9U7gwAdwZp@ zy*bLR@_oV9;lAG{-53)9d0mBXtnIEH%I~HJKwekoJKWYo+uw}|fV?i(H_p~g+c%yH zfIPsDcm{ri&f*(y>+;a64uCx1k9-Dyq)z3V@C?5MI}jN441rO)0^dYiw}(Jm0OWzd z=w}Fw2KX`0z>fijW1nF-7CJcYnGTKv{PEA=k9QWhzJm+0)|w2VXM}40e(fD%w{a*E zqNSsqMeJJ@q3pcsP%%1yY^jEHMtmgJSfY^DlEo1#tE1laR0#Q#_4O^S>f6e(=5Atc zIcM(n+Qd&(#Vf}`Sc7ePT+*vmYBgY zhJ1}``VAz>no6IRt>@r<(n~cxEuolrj}}y|X5yVC zRm`eEQYUEwKuC3T*E@)A> zBsz{mc8DfI^WftMgG)zlEqPk$}SE#Ug`_oPWgk%6hs_B9K@;(Xyh&clgb{GeMNC!Z?2SBs{ zGUazfyapiT0}wF)G5U895UKHWMB$7dfJp$Du-{+?+Le}(D2YO3ME||d9$Nv5pwe9k zlG(_9%!GlE{K&CWo4jnY$#x!lhfouw3Z7 zHC}z4zM~NT;$F@^fu~trEhBC*DOh)oTFlY+b}9Q-+Q@H&eb zq1eq37ds)hv-3Kz`E^oN)AI8I3_*{K_NkZ?wzt28X9<_vC*mXkH-!n{LTar*;#j9z{7=gcU}r!=!{xl?|LQhw%?DL&{b;yeGu|^jnI52 zoGn2CeCdx+9KoXiKR?Lzb)?+ZVu;)YLjD1}`vGR}dh$ovEIo#(8q`15vrF_43w>-A zR(3Q6W^%hey5`V_fL~7hcSgWJK0NunP}VgbuMy(9V#htsXDcf(`#L4^_zXL#0JB}5 z{O*+7F_@j|$*=i6iDLyq*-znuvMYid%c4~5PZ)MHV3t$%PqwqWp^JMc=94$sN(Qr& zJo#*!+uq1Uuo5`u2R2zKN;Sn%37MFj{?iw=V8f)&lyOxdaQylrJ`jd3`U3kp;n`r_^k@qLyx4SpF|D=O+ zuK!e#R;NI%w%Ps^SOuGio?8L5_je!s3cl8J2q8_0r~bmPXION<*`U#K6#g$%g;A9T zSJMX`V~V8@0PgBD?|@2c0F^euqtXgMrR9Q3`wEvdUo8q}i|wFLVqEXC*rU@3=rk~- z0O18gdPp{a&0~uTWJP^!cSRUC)fMPbTX=9iz^OPn=(Y0ZGu#w58V=|{c&Ufj3ZR2E zu(>TAaDbPfZ7E-BWtK{4`M4vD-2$qOAk6Cf6dHI0n0b=3%QeG56L_Jmtbk;!q%w@v z!YRHBMh%ZQGzaJg0v)%WQ-M+e80gF__Tx%Wq^t_5;l->%6U<2mH-Krf7Ti0-xDa6K zqD%bXd^2`{#Hv$7u z)4|~*{Zq!f7tL+}pcr-&OqiZi)1|522y8K(I_SL|?3Bf}3Xpp(tA^)M@3KWefzDRx zGqcqIFgpPzoW=BQ5v%nKP^!^CGgG{KiQQHXK=J{g{#o$W?0ROZ^zJ3LT>wK^49vj3 z9hj+pX8kkO05FuQj^!NWj5GcdGO0$j{M$MI@A?YUATrBdu( z+a6^J~2Xw%N66pLBQk?dB8gNYD&|XY@LN1-lktpR;v> zH5f$&@;B2P>V1FLK@d~0GLfbN%uP@`JAc>6f(*lz0_xY;2CTuS3W%Qiz}y7}mxEmf zOkR3c>2%jWQ%|XQt{DKom4?ok(f4wTkBcAPX=h%2G@NH?*uh-$Ue5?j7DfnlcdcZj zO$fR7z|Q9;O)K%?ud|zXjAM5_KZA+Bm&<+Znr4Xtchrh|bHqo@!`kAuoOZNGZg7Zw zAE|#*-BL)t~9@CG?~DAxg|)&Q=nfvaGQ2u&jU(^8+}Vb ze-J>eJXE5LdJn5gl~EMB=~n#S8`%SH$&K-EwZ^>s%cI!ygX1Gx<4y;(>~52oha$N( zpZK;IAwM4ZkO_GRLEz*M0kaWmlJfNdOA(@o<`rm>2W@`*-u7icQq3&5$Fy9!C5xZg zzVe(j{;l>mPkQsY0TU2{j%Sldgj&ZkFFzV_D-w=Fe}w2f@-UAjdLiRMXp;V(Yd}%m)em4C(=Pk2jCY|a3vm}3i)b-|J{1XGoW*!?!^kh_;8%}_;ARs z6}X4V3T;O}gtlF1c$gZHp9d=3-S2*&MDnddNN*mP)xzrDH9>3F8MW5ewpsQsr(?WioQ21z^ z_c-vcCglrN3hExTq@~InW{6|9C3e(| zlh+G`cK33!yZUdr_yH#6--%X&E6Cg*#6E)K$=t8SI0-hBxjV(x5}Zcnt`Zw0IF`(v zCw5417MYtY8l`w=Y`DfEz@s(ECq9M{{|i!o4!ZQblm0X$NwNoi+5j!;PN<7Y7L{J0 zSBJ-n30^>VPOQjz;c;Y+pLo;@8%XTe;sY<7s+!aIIDu1eFZ8DHxe&uRDNgamTIHN0 zkKw9IyPx~1_@+0GBXhQimGqliBwqB!kemiU}``+wEEQ^mEkH0QDxQU4#HMUoJ+(yB~Bp0?})dRK-<v9YHvbvEoh%Z-i3}9$Hc?IIF;zPiw}Zv64Bem#1K4&sOxLEu?@B?C0>Q_Nb z)$~0!gVe9WrSf_jOj=s5H+VqM9IA*lS;!BZG=U6K(e`$5fDQzr^u7K2#y_8{2bY!X zw2$X<3Qn>vkRZkMrso*sKLQ-#F%b6|2GK{_0ey4-*WcXi-FB-Vp|?yrk_w`N5mga5 zkBn>-S4M#FozD=rM&JnI*C8H_03r9gEVf19Q3N(Z> z`oy+KoIK7a5ncw>(V=^(`dyaOUjZ*6ggrbCPc+>~9ky0ggm>u(*M`>Awh0h>IxOaB z@y^iLt>9^GfOMh@x63(iUfci5NcXd-io!p8kLFBhbb(8Ub#{58Wd&AoLqPx>&2aHKTIO>x;#WpcnT5_NzN zf5qI^gAl6qKBe&B`+Tr{0Q+{+{ZgR#8}7ckJ6Ab7T)?%P5b9d59fc&?C`7nxU2CK2 z5$-PPDlRf{YvBlzY2Jsoh@XPCc5sWhq1-epiyQ z)_to37tQM6Ij%{1moG}^N(S&ijNN;=3XTIzOfl_uOQ4D?LU+9=a+mbVtsdOurTLV@ zMbX?wZlQ-AMROLh+`<8N8=*X(%gvCwf9b>-74DyVhzAD@1#V+^3E-?A=;SiMTHViz zqgbzWdu909+j~gHZu_mf-mKkED{KCk&8!P`E$WfnC2T1Qy@&5h*>a?6E@4yaLYq%= zQdSQn*0B@o!dfPZCtTOtytaMhd0ZXaqPwLpjdD%7D{HyVoj;J@7*={s?Cp}-dN?iT z|LMivP4!avshN>eb;??n@aI4Exh3nCwd+6qu>XZc23QE&njY}YO*eTh*eyR~mve3r z9Iq8}@c|oMFJ}oOWiy-QJ+ddk?#XOkg%2B0@53fG`v8&LPj?;2J8*-NqViCC^aao? zu_F%l z=)*WsH3HOb{$kNN0#|6>{x46w64X)KVu-8gO@rP}5ZQQuSWs147movQ+=6hEdx0WN z>+cPbg^;j=;4))P?)g8qgPhXGe!~y#>}t(xgE;Kw7scL@I6UBfb^m4_>}^D{3-EHf zqBbT0mlATIr}k(f{y{?iDy`i*4xboKK0j7FD-SOssF^w0W zEX2zO@5tFBy$nH>9q>S)aB@A`@rOo9wa72RyUE{j#F#g5F8NzDI=WY^Arce_kLEN3<+|UOSC&m`MtH)_ z8)n!Y+xuabC5zRCFx#o$ikAxUPLdiTuKY93@=G;SZPyQzIzznlXPg?JeZ;7eqcns* zGPzS4nL!VZY*xYFT3*Y9J@^dLL8D5F`lBo<$3){QtP9OPW@M-DgAgc8DGD>HA5eS_ z@GC@a71opNk7}z{;Yx3E-mf;J2-GrpIZixS3`fklB5@zQhw*!9AQI0jOzxKs)iNbG zgOK^lYB#ROp%RkxSghKJwTi6+VQ_D`cwr+BReo@}ViItIz&O<0+lV`1#*ud%v-JKL z6Y`!n&=e>3y^GJQJxx#zzi;$l#EDm(_+Ri;5irEV@4+FlHBY?!9=`eN2RZlGXC%qi z!g~&cc+m%yK~iq@K^jPfkk`RC7Sb3<45Zai7Y<)4=uG5&1O5KWMfpA+KfopZef-uy zw&8tXC|bp~_pybDqr~JgIA~p6;?XkvCUG69P1uAvOt##uJ+v9S2r2)hcFGoC(2q~ZjZ#z*ty`)CmFzS_#IcugSLz|`vZ z<6`Uqb&C7{ijNUTh`9IwUh1i;6q^r#Os}u5&G-~AB_85+V*O|M2U7AxtT=>QNy$dh zQG=bNWMXa5VH_p#;5CR$Ev_0`JgXvwi~K%n*JrOZhhUU|a`_a9K@$~=a+|&%n3Jou z@}u~^%tO1UR$7lMRTkM-2^f6a!xkB-K~7$4=pkQadO3pma#{AZ0_E1t}NO zVMx*nA5;zBI!FzWE%e0PnR}tu)`fTb{%;5c9R>gZ delta 15798 zcmbt*dt6gjw(#CNfrQ8-0Yn6Z5TYQZfQU%(G@f8YVrdMB%AiI>eAX&HZtJzQIlxgP zQluWuvDR9&XszQ|D~|N@(q6Pw9cz_oOP@Yakzy~^@DLfK=36_#89TrG`~La-x!A9@ z*4dA>*IIk+9gdT8oZKrDeUWcK2pQg5Gh)>1lO&Ku=+pm5%@#jBPP1NK@FxiVzxeU< zrBZV9R$Zg?G$G@52qm&a@`+wJCR;jccV48TAVZ0`Jmr?6j6}3MZ`_uS3>MOKd6SSN zKgHbmiW_542crxmA$drSjOa#_F5zmi&hKh9i{u!H-_28UwMHb^8J~xvm{AYInP(q{ zLAk0<>vaT^ZN);fB529BA_Ky#5p63NO6Luwc|&RLP--4Zv&<9Fn!sc(07j_>I)j0Q zvVjXQOA&Nq8xyz=sh~{(sULt6>XL-4VHUED2uFuqC;wS3RC-sCYo~-@pXubSRYH-^ zb;5in7<|W&Dc=e!eGAEyJwmhZArf;+*x;ujRcXRrzqF(&ihMbiW;&e-@gv$}OaaI< z-r62#T8ow$(X)vFnE(a=9eiDCL{(BjuCxcm{bWRO-2nFhI-p5nL~kAwPAc2UnpMJH zm5Hp$5ISiRUdQ+|QZo6Ax{X1DnA9H?HUxiWDYi4nr`TSeHx6MY)u*^+Shkb%p5z?l zGf_P$gU9Y6n1>uyf=X1rN*e!4F1c8xWdC=6Ko$jc9eD5Eha|X2l8SkPzR$hVd+qbbKyj|{i;dGki}9W26{0pXL-9AYDacUU;t(k;Y=W%!SA7*VtwrcCOdvS=jmVLB4N zM`#L*B}_$~Ba9ILoSzKE2W-_w#^kw1f!Ew3 z&zb6$MIDfkEgf~<(FZWO@~dz>CdB*7RZhmM2TVqE<@>ttVp_59o{Um8WA;5{f5wRR zR0vJ68Zx1(t|QhHlQsM59M2qz3)M-nkBT*tj`qE4JnIM%29T7^#KVv_toBYw+8EVL9<4g8m+ZLI+(OU_vQOda;F3N_C0trC@-dTWG!Ki&rY&KF^ zy31#pdQjQaM%-&)aqqNN2_X@lk?oqhvdW6=%Sa(c=`SPIsR%BHGY+hxt6cGpm22dp zdCW~8SjFvy3W2LJEk@t9ods6w?Bm|U_J#H@Ej>ux!;1>2dwF2oz?!a2*;lw==Iysp%g7Y+@rB|7mJ|GR$re5goK}tBJeMCZe}|; ztUtqqa(h8D6kGWM`#7HK;VZEn+snH*+0R0?z_a$Tyt=z=sJ2`rP`i&w^r_BI#Cded zNFjP?U}ep)Y+2J9;e+?kLvsZ3U>&?%f1XnTe!4^UWW+GuX%DbT;;hKs$vN4;8hI{{ zoMJyKygwn#szfumK;v=hFOJW2K6ZfC1-!?d%!r<5(+G(g z=Bgn+F=}MC)9U2&Q>kD{E*T0CV$3kgJX)4Yfq7AUO_Xxr-s}gU_1|DZj40vD3m)+( z%F9F~ps^B~OcLZ9Z;q0gW|IDl8W6e%o{{rj<%nsWG(|VLi{;+$DYIY6!JHIyQo-9X zCW+*o98ePcp!1w*o#bcUzqN4^r`>lZxR}E>sr~yb#0mE+!>v%HRsS0RN>FKJWlZpT z4l9eD|4_QqN01)`_#NOefHMm@@9E^js&z4b&CfIDEnKoZkKXyabLz12_O25sRi4{hAqpEYJA zHO+xG_VqT~CU$L!mu(B14sGn(tC~dQVVa1n^n-WcQ`PXnu|prcrl~=mmAqEb zL!oa1wqb8!VETO)wpQytYCpaSZBm1RX~hMunCUW*K6_#nGy;i#TO&(KQk%#{LBRiEZX*N1(nko4mmRtE% zCMa_Wa^PR`9oTP3-umWgkp8U9rF#~5jxpt+VA{gSdYVD=-Cod&B>WNJ8whw({n`GI zi?Z1dISe|S(Kj+7fJ>0R^2PSDyCWH^+1F%$#^R9VbObQddYaqH@A^F;bPK1FO{!hk z((Q5MuIHA|*_;ih^k+F0%ML1b?6qlGbG5?0V9zCS1sA4^=wi(YoL0HO1*1V{jRA-@ zqV?x=liQDTvH?Svml5&rav;lvjon^4>zyBT!NaPvo2=YQj-*B%QW#NLtS+I8O_g+c zb$Ri~JdXM;n|??Q=u%lwnHo02oHrxcot)}ToDUm0b~wToN12*kk5r(USWf;XSg67s z`L@7b^Ltzjvjy~=(TIxvgKmi5Bhy9)YCry#{w=TIqSNBNwQ1^|+B9KudVm$nVZn&x zm(7v$CWEAnmwaL>l=SnBw3{s>;+0WKa2)8?y#QNMX_g?A8nA~L(c+NGGtd9h(=67p zJsV_TKibVbXl3g7PgRz#GWFdys&Na`L2umCH*zX*ChHq0GfAYsZ(`eC6P2ia=9ZR%03GSdEnzO`CmP6+be zm2G>!l4y2tr1fsc@Z1{C&paz==gtpp22CjLw3OBalaJsZDcK zU%B7@5?cfGqupK5ltBkNI)Y|30=;FZ1HjWVhl}`%c0obAK&%%{(a?o-=t3DCg&85w z{17!bufJ!w*v*3Od2$sZJ3=qc(M{}Pv)G1$FT(T9cx1lWN`~i~C8~V0)F%0e_j>{;9r7hn)=GFyvDK(Cd z9`0+{k#1{COY+v*{p=oM)>=j_FuGAzsGybq8vqW;K8ujK8+oVcytUc4kdmh611Qj3 zhJwvGD9oIW)KI5Rn^>t%n+)j$fMkHAN_Ey+>n-?nE4A179=U{N_+56uD$WLi?$JH-GV)h z3bsoK-Cd7>k8g#&@s`!alJ;Fe`(C>T`mQ;ePsuBn`)`)F?Ije*L7hQah~8jtkMj( zI)Uo|wF{Y6=O9bX2fpI{%-jpEHMzvFK4043w{)Q+9n%=(`-1&*OBXlLp{K5|IMdP% z`AJmSSwKa8nG&C;X^M~0e6cgmMzS0IGO4C`?k1?}8E8XOG?*GMmus!Zmq06p*l&S* z-GhGaA=FJw)mt~I&;oo(f40QS9&6j%MyOS$2$pV?L`S7R%Y;xr8hYHxMD>JR%y58F zLK&$J4;4F&mjhmlsprvkX#XDkE2Sw3rO^>mTBx(RTqnt3CKzRvY0991>TpxQAPcxY zrtyPT2Ba|nrZLrsViUnfzCev9=z;i*YLMEd(mV5fsniZ8Q)O>-_Fv3Lbe0C=0g|fp zcItWVpgNX*6iq9=O*=QQ8{CcVN7IKok#UE(O-M&r%cOV*NWTLcXlK8a2~~!`B@4s< zXgvmhHNOwmBj7_7wQF}p(T5m%UAIOUq#|f0rypcrsA*cg>6yr zxp*cKgzX&=ybDl@W>|1Y7FitJVzBCJD)~&UPtcuNrf&QJzkreYjNm7?4d0QGYJI-V zC)Bb44L8liIylgKFuguuu-Rxi2Fjj*JF0ECsRzH$PkX+}C*0x-xDs3iZF1ll0X%!~ zYrGNos4af3wk6P}06vix8Ss(d15h5uB>QOE{sVB|uCG1B`$OQHv3b0H5 zUnmrVMM(7&j_}g7P%>~ruua?JJ5a=Sp#aeD*c33ZM@Y;J${(oW!n^sv861RT=9P6z znTb8k6p52ap)S)o@W!qE;OBgEs}}w?tKZ|y>UA7!jDcF1?a>wo48CU|CVzwz>YN&W zJD;$L?Jb4&M4=`#@;TScIq$jKA2;zC{1`YborM_=ZTpYA_lN3_^HcfJP=5?oBE-EC z!a!zhEX?mn_d+>u4WVx2r|?mLx`9^%@(7*<&l=`mFd5S(Lq&wU=yVLBuj7sUSU@iZ zR^jfY`e$z}d?p_QZS$Zl3gk*SZ+un;JhUKF!Xsk@`Nwxc*z_CNvu<#D688UZ3yrK9 zl#(8UTGDGo#pwc@6-yxMGp+{BOVW%-5=|6`Ij^45zy#{u%{we8&F4tex55u*J9&AdP@FAbogmFAAsVMp zmNSp6z9+QiL`JDv=0H?yCOD^_@k?*#f+sg)$hnWrXE8Xxnqz`?rj4xLA{?8U9J`vQ zKDPl8wGpj7Ni`cYqHl&SW*CH>iZ9Z7+74}p1n=Aw&1wc>Lk)~tRegVuRV91bGa$Nm zc8AHn`K+AAH4HxpMY*{o^0sg~S4$$B>soUc5xh?@%=vz#&RmQT=+(s#P?14ECBul8 zz*o0k6_WE}oL#Y-y_x^O@+Srn=<0i8wBME|2~d z1>D`hHPWsxFEl#8OV|0`2{R~R5!I;1i0V^?>Ulc<6~~|n`XRlQwt6=(TAnDh&eM=n zj|J)cL~`nmkTQQOE~smqFO`s;p9|*-^2p0?2Q`^`E!sIdaMKDLmjVCFP4>Xhj$z(|ZBuoD`QYag|wD`J$9amb%JH zC=W~Q+95^d%Ul&|TG3T4#gY}Y%yUqBOE>LyAni1yO4_+PO_2)A_V!?@MN(9kw)jIl zb}x^muR^yY`6;@|*PEg1(Vbcv9&&XZX#Y82@1^6t_JYloxrU#)bRv|LQ30-!ZRunv zMR%@pm714EdF;(w_hz-wzjTasQMJ+8Tntc20uYrBFviVQkXJw+L*52?Z=OJ|e18%z z`Jmu~o2-A0{IL~kHts*cOAoC*RL3fzW)9S>q0y@vKGWH}olpb)b>oHR>?%;g$#rCV4@ zlUAV`Dz7vP$7#|iG%wfWUpe-sJZq8j)1CjwuffVrsXKa>>AZ4;N6cUP&!-O8!icWC z)6&Dqp8u`?yzPxtRV}UA0s8Y-+DERD%E0|jDF=PLc`e4($G0Ragsc@Ank$(~U)aU- z`_Hq&ZoJiFZ})Z$FX7cfBv|eMV3R7GTrno(idN|XXz%u)hX^Iv>cvZ`*h6!$(7Qqt za>X;%qgYP6W40i|$$2%L^nv>FfROl7IJx|*V16lxT)r+Wdnqa8a#Lqus&BBIF7vg0 zyo7S)BLVpn;p9sTJoZY9%a_*$ubha7?*^Z#TNf-*>JolKuv`#fUvg3?dRar391v_T zZzOU3f^^knTwG^Zb+mM9@fJQljtWhCGsDc0>6i|1rGGJ_jZQ&uG%!$UdMa$Kk%E_#o7>-)rLGW zSRQi2nfd>idVkRVGxP30rm(}+vb)mC$Xq4o1iET!X)Zh|^WJaW8Gcs+$HYu9@gZQ{ zM&6nA$iR9add{B-b|KVa1%|)?=OW}}c%LvA0k$K^k9sN}{!~8Vsl58BeB@Jk&69lm z7SQb+xP1?A&%7Jfy0}Byx*R->5<@jC<~v;{tjx@=6ZV%{OFO{d-=x;bZqKCEol;PN z(rf$RG=WlEM{)k$B>`O z%RK7JzvGb18q=;#PJ1!}gfF!ST-axVyvSKf0Z7a3DEE&63l*8?>7g z><9a2vky>!ZH8^NU0}yiU(&gE(@lzLI^ewDa`&dDqaNx`-jzV^#ACk;$C;VkmF>sD z^*hRp?>bSnQ2d#Bt?LBf9HyPF)QbZ1lB>+mF4u6fO?vi$I<)0)psO3G@uI;Ca{;Jy zmmQfsuda6UAxs`k7qV<)$fK0H^|l#!WEJc~OeKk`DIW9tb#rddG&%>$gsWRuXa=&V zYJo2=4ApqUdYw}r#;N;tZ0JYFHRZVMr6mkER0LQ;xrbbfu%rB%s*wr40G4;&1-h}%na z3Ac~HZ4H?EC*`&zDBJ3?DueL!oI$#ippEXT5+lm#g|va%9u7mCOdSZ3u|O>k-rnQi zco?Jk5=@3S;Db+SJ_ogzAulsJe>o`}ee)BtX1uVZ>TP`T#P&W3Y1}OI?|2AWAhIk` z=oMNq(9(y*C z4Rn)tK*P%K}jllwIrkv^qPy6+HHEcwno=AsqC$@d0`ag}hq=66{+4-**P zU3YSShJ@(i>jrCIk(0EJy7hngMry6dd$>I{bwm}Jj-*I>T#nj5lB2Mvp!uo%)Aj#9 z`C8x!cLInh2vWu|naVhb-Ay;32o{cZutf89!qpQYgiR9qPlORRsxGMRTQ9PBkI>n$ zHfa10?lH~+mu!xmk@QW2h-1I7{?j!7#jy0_j}0|1f#yp>&!GG@Z1QW^EM&w;9B5-5x<+BplE5pXNoM$+nWz04z_Y2{wHZe&!+N2?+U}>Au z)#WDYY}|)S+VY9i&eHvTZQsA@grqNO$fWhcw_g;H6hTNim#9c?pdT}$jC$xK`l~V z@Hp>pEuzLAUJe|lE+dcrH307q+|FL6^BV=d&F0Q>H~GmrrKZUwLvkwj!MAis)6}A* zcfhdiU}fN~%o0a#zaMT;D|kAg4IQj4#PMy-?khk$^V5uH4w60U4v zo=XRX!{@`Tqc|AW0ZyQQD;jRQ)mikO$WCs7(m8NjQibwF2O2yne=m|)ZSwUrF@t5(Rn zkU~mrLiL3V@`bwYhYJ=Q#+`J1I(THkZW}D?HeeeZlI6;85^^r4k|w!Oc`-hPTMH`z zcj}LuU2R5s|LNWjX{+}&7?HwtzERAzW7s!vW$~;(=;dU=aWP22Wf|d!2t}=+{4y=* zTwJ4El<=Q3nZ65{)sG@uz->BW5DLB=f!7Kfz6>X!iNfwLV~O>i(Dda#^52)aB6Ylp;4WeP6|qR?z9xGO$dpYL`;VA!RP-0U%+0k?K)O z`DS)FQcd|nyAJp_*ZA>}Pwhs3`MDbp8g*OB*;l3Cg_qV-~jg!yyN2zr-A zBDvo7^t*D18%f9l^x!KAGq-0%uSZp>xW8|cY0={g#}(!X&P!`VqdH)`Cxqf}RuQd1 zX#FOQXvfrreGA9K@r}Z~mKgHP6=8Er9C_xGx|1z3Job{&`OQyY?bkE&A4QsGqHxGx zH98+1HaZ6laAcJmou^^vA9+P+`%dHiW$KfCS36Dc|9+)n25g%#-%;IKXZt<~hfH7T z-UgYVXQwZ5=cf$-PL}Y=4|~XerUh6VGA7ne7gGT4yHVfbWr1qY5eyD?JR@;uBYsdya;lR&Y zGQL>2@N))vW|g44I$QhdQ6riS9oH5ZQDzu3to0s20uRmY4xV?+cA6DuBIl}q_s98T1crlnObQ8r^3g2Fv5cR0h!|3c=538#- zI?pE?oo^quH*$^nsUA|;$~i{onF1m1dJ#Kq9Zz_*E{3W=!@E4JH>Z03Y z0OFoFjqYVObpPuC&9q#h`T7(*AOzl+iw_9JHx}SNq4~xunv5jkN26)e9z!aH^cJKZ zke-7Sc73L|u&i~Fb-ga4&+O7l;K6cdy0#n9SQ9OqLHX$t=*yt7V9jAdgJouO6t(JO zbw+3BcSh&cFt>G=9(CE9Z`un@J<>z@G1RM+9)Oe4bBxk2)jr<-0{Bm9jMO{kW3&0a zQnO*Q(+0lD2G9c=to&`0$FL9x;3b)Q6gIXB$ylNeg{u^GiQ<$;poYU{e@+g>V|D$( zxh4-qzoh_h3lTevA~tyHeR6Y(9J0LLSZ;%m03L{X1F+^UgrD7%%D>ukZZf#z!$ z|8B)8O)r|lM)PuZ|ESsQVxX}WDvq*C2Ni)%I47=#P^lJCLZwa~oM#%X_z9xJNv3W^ zm8Jj)%ON0IJ8JgLbg0?Hz7HL|9{3T$W+lAYK&VW^0nR@=6bv1LwbarM9p0MV3gTPC z$z$Og@C0WwJi4KLr&~1%Xo~(OFm{gWV@K?knfw*3{$`0Ha5O^0A@Zt$NVa(slA9e6 z;~$PnECn1Ly*la_7`+qdqW8{byQFY9R0OdJB?_P+fm)y|Km_QN@L^B*;ClB5z51f= zLnkAE&hc&^8@<~Kz4Yp2oi0LYV6Tf%Vjd0GZ3vE3i_wZ9!b?%DK)4+U1H)2U$C$dk zK4&9bRGx>k&BKv8E08OSEuf?G>U7ccI5)D7gJoqYDNoU-0R65SLdg}y);5~&bHTyqO#h;p$JP2H(uEM zOT>(HdS&fQhYMD+rLnDDb>q3)Pgs@-7*9hxM@aV#alu#v{;%*rcW6!=)YG!tN#~7^6%O9KJMkxuD zO_FJsbam_2^1tbCHiU9I`>?0}f2DVUFfft7AI{I_C*C9h7)FsTMkZix^&E zHX#(d1L3H%aw}Wp07XZ3)`i_$it$$he}4w<6u!Mb311MDjw!fC$aRdz)9Y*wxP|E# zE_CG(5+sCmPsF`KZuew-S=iY<7AFXwbx(>|v#Txg3zd?SJp4O&eUuVe$Jc|I_o&j}jccDdaS}qc1jPAeQZ|!R!e7-GK@=HwLr* zu6!mN&S1L{Y773z;M0U52A}#<27`laEihP22l2awom!09ZdX1U~3u7PIWQpppR?eaWPS@^PZ6D>_5(E zy;tsfOMe@DhzRfp{2#1y&r=`_Gt>Ft75zPG!Zw7mi;&7?!WM(YfeoMO>`VPan>D~~ zZ~_BejY|DJsf_gpLNHmZ!)0X%HAKL)ovorw)uCXfqF_-jg0ZLdpFJ^6_Byr;>h*yR zj@H}RRdN}t2@Zu|CK$(4mcZ>U{0;15>Mk)ZcgYG3;eiRRh8%VkZ2$tdAB6+eE=I8y z2iRKdl7{^*MjyHG(-ySS`uPVJ5t?I-c^wIIi&vrscteI(n>uWiBwNoO+1nx><6kl9g@n0_Mho(X>tp}bI;P{^E~BmX;9;@H(!-6vtH|Ia zgc>wd>mB)~UU|$rl47^qjh_Senyz=Uh>w4@J%)MrQS24J_yz58UwOBscPQWqrx!`) zP~}4LNB{L4fwKBg`At}Oo5&h=NM@gq84 zIpfI}_yYszZ7wO|PL!a%IeNtuQ(M0I*Z+t{c0yDF(0Jfb9s27Ugz|4->x%F+;frG{3|3Ku$ zm!^O+Px$U}amv!uU@Z60SX0+z8e!@>1`44PpaOmm0A7AdIOO5C0S_7>A8aU~o_}hI zP~uGSoX`(hi|~mvO%ZX)jS+D{7<8ulFV%rXcDm1Bl*!VRU1nTJb~o)hiQfp?bikm_ zpS#C=bPeap!BYwNoyxG?N5o8wQ<6eT=<5#0XxbIWP6$S<1t>Vp@H+_#z4Tv zRG%z`$7iG{OVoPewWM}){cca(kBRs|+#$y`r0}$u?1ke=;Q_J83;JBRQ9S8|Gf3fV zanK9Ll0sIDQQ#a>7$lY`@V?j(hgpEfIg$^(bisbjQa=v*6}F7NcutiZ^x_JkMb!m$ z>LAfD3~NZNr?_kw@GbBZKN*Ho$bw%*$1toTV-JXl-Z-5pIP!ZUr{Km8==lQp0m%C{ z&s(1G?0FhIeKVJM?b^TV3^$fj&`2I%;QRfeXB^$T`pBdfs3}a}&hr!MKS8nCg`y zu@rt=@>G2NSagQFbk zFZRL(W##5xzDvp*%!{mzP}eBNjKURZD*rA?kCgBT*KR#H^59%n#mXIJtdxaV?c-=8 zQbB-SiyY-#p@VcuDmQ{7K`L`0{IEyt9EHubX4uw*ZY zmPpK!*}Pa235dP}Vp}BcC$sK|*EP6=%sM2_i^6Q;tnD<8N@E`MxIW89H}wrax|43a z!6;QPf^@?xSo*L*^&k96b=uHz5u}@c#A;8+EGK-8oma*76&GKjcXanAU}u+ zMuS!u6XRwa)!#it5pLttK(tfG`_aiy*RzwXn_BFmmNAy4|RFLu}nwJUJR$d=swIE$psK_(4>U z!D%USUwYf-`l*r99p1@}hQJ97fDRshjijbQu6$*s3mLl} zf>1R8`?_%_NCywUkf5(DBF~AL(fC)-BnYi0Wr?XVSYws>n%7|^HwGlZ2E70&l6i2^ z<|v#9CAATGJ~o%nPj=Oq2b56m<6_KF%X{gJKHxVy=BULdhsv$+T;$S| zKr{ri2h0*&?2awx^qM6bdkw>s@J-i%ayskVVz9TYJ~atepK!@yNiwL2Jr?mWOdl3o?fUr0};jov3LTk!+=?=o&Z~Bx z|KbY0gUEEOG@=)^#$ncCu`vZOUTUvrCSrda_tHG0^QGw-YClhioCSv-H%B5CY9cz7 z?x}m`#J=wK!Vb86*fmMqn2N*v`!Bf{V7R9N$(rHaUsL_zR9r>K$A{`uC*kW7^3kdK z;K}&xGo+!Q{^|<6f{_0T5i?)L1LXA4dc!K5DkU$zD!#E6uNl5K@1S=c#0d97jIe)N zBij3?%fn(s={kIX)DMV<*Wm(E|9|Qg>+vNy;fv~jD8Y{;v&6iIwxU#7HDVnMnvNJG zSE>^kv;$sW!2Oc*6^=+y0KD7?94deI$MUN?;P()C@-MedV3qf}an>_pOexIvv>-9J z6z?M$d17xV&hgEtq7v%H$*_yLWjH-Pug{>AqYQ-JGdeSTnPL5>b|~R*JvW5rrC5{gj?FI;XbU%dwW^-KZZ^j%z(hb5i}K zt+2z0ex;aL30mOtK{57C%==Eh?!Ii|6-MXe?)ru|aTX!V*VQYkafpOG|GYRxz-q;w zbHEmEczkT4S->IQdn;W9f7!$a3WK1aopo%o8%)dbbkhbWGU z^LF8H;JFM?h{<-?@9zYPd3OBEi@Wn4R$WS!mBD2vLelMCNC{90uoIxa$_pKU^a#L7 zfChj;sM`xEy%c039_ncN&#zR9c;e7kE{OQmp{!vyd~lDqxNJ8zlece+r+0%ce7jam zeH*_*-d zSCv*Qs0WFz$gjUtk5?1QyNVIn)A%~E9T(OAh1-dZ5#CZL_MWNN{T+WTwW4ia=t6}TY6JKd;3_~XKr+i40AL1?0~7!pJ?dpe>OXs-A^-+} z{*wb#9s`DdfldK50X(TsM`uu<#I57MOWaeWpq=kGN;41(ruigu>0L1{g08i*n zehPS>d7+F%KX0D+$s~{Z;hySU{CyF SeY68lASCxuy`>u;@cF-PTyIi_sb, bh, 0, EXT4_BLOCK_SIZE(dir->i_sb)); if (filp) diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index c76ae51b1..950a81f9f 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -48,6 +48,7 @@ static int ext4_journal_check_start(struct super_block *sb) if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) return -EIO; + /* @fs.sec -- 2b51c18e3186a30147fd8c0e277b77c937163f9a -- */ if (sb_rdonly(sb) && ext4_journal_current_handle() == NULL) return -EROFS; WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE); @@ -320,6 +321,7 @@ int __ext4_handle_dirty_super(const char *where, unsigned int line, struct buffer_head *bh = EXT4_SB(sb)->s_sbh; int err = 0; + /* @fs.sec -- f3fb2f98ccf1698650e6f1f5709100c424198b5c -- */ if (unlikely(le16_to_cpu(EXT4_SB(sb)->s_es->s_magic) != EXT4_SUPER_MAGIC)) { print_bh(sb, bh, 0, EXT4_BLOCK_SIZE(sb)); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 87e03c1e0..7ddb20f93 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -475,6 +475,7 @@ ext4_ext_show_eh(struct inode *inode, struct ext4_extent_header *eh) } } +/* @fs.sec -- a86ca6a359e99cc76c71bf7f3a0f0a63cf0c8799 -- */ static int __ext4_ext_check(const char *function, unsigned int line, struct inode *inode, struct ext4_extent_header *eh, int depth, ext4_fsblk_t pblk, struct buffer_head *bh) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 8ffb1a811..e23ec9de2 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3153,6 +3153,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) inode->i_size = 0; ext4_orphan_add(handle, inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode); + /* @fs.sec -- 868333f69f69eab81cceeb26fac51f0b4de49c70 -- */ /* log unlinker's uid or first 4 bytes of comm * to ext4_inode->i_version_hi */ if (current_uid().val) { diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0ea8b4dcc..14fb6c0a3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -392,6 +392,7 @@ static void __save_error_info(struct super_block *sb, const char *func, le32_add_cpu(&es->s_error_count, 1); } +/* @fs.sec -- ed6287f38b4c758f36cd7864940cdbd81e26efee -- */ extern int ignore_fs_panic; static void save_error_info(struct super_block *sb, const char *func, @@ -463,6 +464,7 @@ static bool system_going_down(void) * that error until we've noted it down and cleared it. */ +/* @fs.sec -- 10e386db3959e3c02220744400a053e7807e07ad -- */ static void ext4_handle_error(struct super_block *sb, char *buf) { if (test_opt(sb, WARN_ON_ERROR)) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 3887d3bef..b5b99eb64 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2226,6 +2226,7 @@ int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode, struct ext4_xattr_search *s = &is->s; int error; + /* @fs.sec -- 27aa4ade7b90e77a75b0f821924eaac228cfdd43 -- */ if (EXT4_I(inode)->i_extra_isize == 0 || (void *) EXT4_XATTR_NEXT(s->first) >= s->end) return -ENOSPC; @@ -2251,7 +2252,9 @@ static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, struct ext4_xattr_search *s = &is->s; int error; - if (EXT4_I(inode)->i_extra_isize == 0) + /* @fs.sec -- ec294112f1af9d4be72e6292e7e994e522fccbeb -- */ + if (EXT4_I(inode)->i_extra_isize == 0 || + (void *) EXT4_XATTR_NEXT(s->first) >= s->end) return -ENOSPC; error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); if (error) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 7b056ae88..9a26fc711 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1193,6 +1193,10 @@ static bool __need_flush_quota(struct f2fs_sb_info *sbi) #define sec_dbg_add_time(node, type, start) (0) #define sec_dbg_start_jiffies(val) (0) #endif + +/* Flush quota limit : 10s */ +#define FLUSH_QUOTA_TIMEOUT (10 * NSEC_PER_SEC) + /* * Freeze all the FS-operations for checkpoint. */ @@ -1223,7 +1227,9 @@ static int block_operations(struct f2fs_sb_info *sbi) if (__need_flush_quota(sbi)) { int locked; - if (++cnt > DEFAULT_RETRY_QUOTA_FLUSH_COUNT) { + if (++cnt > DEFAULT_RETRY_QUOTA_FLUSH_COUNT || + time_after64(local_clock(), + dbg_entry.start_time + FLUSH_QUOTA_TIMEOUT)) { set_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH); set_sbi_flag(sbi, SBI_QUOTA_NEED_FLUSH); goto retry_flush_dents; @@ -1306,7 +1312,7 @@ static int block_operations(struct f2fs_sb_info *sbi) dbg_entry.end_time = local_clock(); elapsed_time = dbg_entry.end_time - dbg_entry.start_time; - if (elapsed_time > (F2FS_SEC_BLKOPS_LOGGING_THR * NSEC_PER_SEC)) { + if (time_after64(elapsed_time, (u64)F2FS_SEC_BLKOPS_LOGGING_THR)) { dbg_entry.ret_val = err; dbg_entry.entry_idx = sbi->s_sec_blkops_total++; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b4d5ac406..015ffdb49 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -461,6 +461,8 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal, #define F2FS_IOC_PRECACHE_EXTENTS _IO(F2FS_IOCTL_MAGIC, 15) #define F2FS_IOC_RESIZE_FS _IOW(F2FS_IOCTL_MAGIC, 16, __u64) #define F2FS_IOC_GET_VALID_NODE_COUNT _IOR(F2FS_IOCTL_MAGIC, 32, __u32) +#define F2FS_IOC_STAT_COMPRESS_FILE _IOWR(F2FS_IOCTL_MAGIC, 33, \ + struct f2fs_sec_stat_compfile) #define F2FS_IOC_GET_VOLUME_NAME FS_IOC_GETFSLABEL #define F2FS_IOC_SET_VOLUME_NAME FS_IOC_SETFSLABEL @@ -520,6 +522,22 @@ struct f2fs_flush_device { u32 segments; /* # of segments to flush */ }; +struct f2fs_sec_stat_compfile { + union { + struct { + u32 in_init:1; + u32 in_scan:1; + u32 in_commit:1; + u32 in_reserved:13; + u32 out_compressed:1; + u32 out_reserved:15; + }; + u32 flags; + }; + u64 st_blocks; + u64 st_compressed_blocks; +}; + /* for inline stuff */ #define DEF_INLINE_RESERVED_SIZE 1 static inline int get_extra_isize(struct inode *inode); @@ -1469,9 +1487,18 @@ struct f2fs_sec_fsck_info { u32 valid_inode_count; }; +struct f2fs_sec_heimdallfs_stat { + u32 nr_pkgs; + u64 nr_pkg_blks; + u32 nr_comp_pkgs; + u64 nr_comp_pkg_blks; + u64 nr_comp_saved_blks; +}; + #ifdef CONFIG_F2FS_SEC_BLOCK_OPERATIONS_DEBUG #define F2FS_SEC_BLKOPS_ENTRIES 10 -#define F2FS_SEC_BLKOPS_LOGGING_THR 5 // > 5 Secs -> logging +/* BLOCK_OPERATIONS logging threshold > 10s */ +#define F2FS_SEC_BLKOPS_LOGGING_THR (10 * NSEC_PER_SEC) enum sec_blkops_dbg_type { F2FS_SEC_DBG_DENTS, F2FS_SEC_DBG_IMETA, @@ -1716,9 +1743,13 @@ struct f2fs_sb_info { __u32 s_chksum_seed; struct workqueue_struct *post_read_wq; /* post read workqueue */ + + unsigned int sec_hqm_preserve; struct f2fs_sec_stat_info sec_stat; struct f2fs_sec_fsck_info sec_fsck_stat; + struct f2fs_sec_heimdallfs_stat sec_heimdallfs_stat; + /* To gather information of fragmentation */ unsigned int s_sec_part_best_extents; unsigned int s_sec_part_current_extents; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 611d39edb..04bcd2e67 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2805,6 +2805,9 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, if (IS_ENCRYPTED(src) || IS_ENCRYPTED(dst)) return -EOPNOTSUPP; + if (pos_out < 0 || pos_in < 0) + return -EINVAL; + if (src == dst) { if (pos_in == pos_out) return 0; @@ -3458,6 +3461,52 @@ static int f2fs_ioc_get_valid_node_count(struct file *filp, unsigned long arg) return put_user(node_count, (u32 __user *)arg); } +static int f2fs_ioc_stat_compress_file(struct file *filp, unsigned long arg) +{ + static struct f2fs_sec_heimdallfs_stat heimdallfs_stat; + struct inode *inode = file_inode(filp); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_sec_stat_compfile compStat; + + if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) + return -EOPNOTSUPP; + + if (copy_from_user(&compStat, (struct f2fs_sec_stat_compfile __user *)arg, + sizeof(compStat))) + return -EFAULT; + + compStat.st_blocks = inode->i_blocks; + if (unlikely(f2fs_compressed_file(inode))) { + compStat.st_compressed_blocks = F2FS_I(inode)->i_compr_blocks; + compStat.out_compressed = 1; + } else { + compStat.out_compressed = 0; + } + + if (compStat.in_init) + memset(&heimdallfs_stat, 0x0, sizeof(heimdallfs_stat)); + + if (compStat.in_scan) { + heimdallfs_stat.nr_pkgs++; + heimdallfs_stat.nr_pkg_blks += compStat.st_blocks; + + if (unlikely(f2fs_compressed_file(inode))) { + heimdallfs_stat.nr_comp_pkgs++; + heimdallfs_stat.nr_comp_pkg_blks += compStat.st_blocks; + heimdallfs_stat.nr_comp_saved_blks += compStat.st_compressed_blocks; + } + } + + if (compStat.in_commit) + sbi->sec_heimdallfs_stat = heimdallfs_stat; + + if (copy_to_user((struct f2fs_sec_stat_compfile __user *)arg, &compStat, + sizeof(compStat))) + return -EFAULT; + + return 0; +} + long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp))))) @@ -3540,6 +3589,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_set_volume_name(filp, arg); case F2FS_IOC_GET_VALID_NODE_COUNT: return f2fs_ioc_get_valid_node_count(filp, arg); + case F2FS_IOC_STAT_COMPRESS_FILE: + return f2fs_ioc_stat_compress_file(filp, arg); #ifdef CONFIG_FSCRYPT_SDP case FS_IOC_GET_SDP_INFO: case FS_IOC_SET_SDP_POLICY: @@ -3714,6 +3765,7 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case F2FS_IOC_GET_VOLUME_NAME: case F2FS_IOC_SET_VOLUME_NAME: case F2FS_IOC_GET_VALID_NODE_COUNT: + case F2FS_IOC_STAT_COMPRESS_FILE: #ifdef CONFIG_FSCRYPT_SDP case FS_IOC_GET_SDP_INFO: case FS_IOC_SET_SDP_POLICY: diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 9f462d281..70116b8bb 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -18,7 +18,7 @@ #include "segment.h" #include "gc.h" -#define SEC_BIGDATA_VERSION (1) +#define SEC_BIGDATA_VERSION (2) static struct proc_dir_entry *f2fs_proc_root; @@ -501,6 +501,66 @@ static ssize_t f2fs_sec_stats_show(struct f2fs_sb_info *sbi, char *buf) } #endif +static void __sec_bigdata_init_value(struct f2fs_sb_info *sbi, + const char *attr_name) +{ + unsigned int i = 0; + + if (!strcmp(attr_name, "sec_gc_stat")) { + sbi->sec_stat.gc_count[BG_GC] = 0; + sbi->sec_stat.gc_count[FG_GC] = 0; + sbi->sec_stat.gc_node_seg_count[BG_GC] = 0; + sbi->sec_stat.gc_node_seg_count[FG_GC] = 0; + sbi->sec_stat.gc_data_seg_count[BG_GC] = 0; + sbi->sec_stat.gc_data_seg_count[FG_GC] = 0; + sbi->sec_stat.gc_node_blk_count[BG_GC] = 0; + sbi->sec_stat.gc_node_blk_count[FG_GC] = 0; + sbi->sec_stat.gc_data_blk_count[BG_GC] = 0; + sbi->sec_stat.gc_data_blk_count[FG_GC] = 0; + sbi->sec_stat.gc_ttime[BG_GC] = 0; + sbi->sec_stat.gc_ttime[FG_GC] = 0; + } else if (!strcmp(attr_name, "sec_io_stat")) { + sbi->sec_stat.cp_cnt[STAT_CP_ALL] = 0; + sbi->sec_stat.cp_cnt[STAT_CP_BG] = 0; + sbi->sec_stat.cp_cnt[STAT_CP_FSYNC] = 0; + for (i = 0; i < NR_CP_REASON; i++) + sbi->sec_stat.cpr_cnt[i] = 0; + sbi->sec_stat.cp_max_interval = 0; + sbi->sec_stat.alloc_seg_type[LFS] = 0; + sbi->sec_stat.alloc_seg_type[SSR] = 0; + sbi->sec_stat.alloc_blk_count[LFS] = 0; + sbi->sec_stat.alloc_blk_count[SSR] = 0; + atomic64_set(&sbi->sec_stat.inplace_count, 0); + sbi->sec_stat.fsync_count = 0; + sbi->sec_stat.fsync_dirty_pages = 0; + sbi->sec_stat.hot_file_written_blocks = 0; + sbi->sec_stat.cold_file_written_blocks = 0; + sbi->sec_stat.warm_file_written_blocks = 0; + sbi->sec_stat.max_inmem_pages = 0; + sbi->sec_stat.drop_inmem_all = 0; + sbi->sec_stat.drop_inmem_files = 0; + if (sbi->sb->s_bdev->bd_part) + sbi->sec_stat.kwritten_byte = BD_PART_WRITTEN(sbi); + sbi->sec_stat.fs_por_error = 0; + sbi->sec_stat.fs_error = 0; + sbi->sec_stat.max_undiscard_blks = 0; + } else if (!strcmp(attr_name, "sec_fsck_stat")) { + sbi->sec_fsck_stat.fsck_read_bytes = 0; + sbi->sec_fsck_stat.fsck_written_bytes = 0; + sbi->sec_fsck_stat.fsck_elapsed_time = 0; + sbi->sec_fsck_stat.fsck_exit_code = 0; + sbi->sec_fsck_stat.valid_node_count = 0; + sbi->sec_fsck_stat.valid_inode_count = 0; + } else if (!strcmp(attr_name, "sec_defrag_stat")) { + sbi->s_sec_part_best_extents = 0; + sbi->s_sec_part_current_extents = 0; + sbi->s_sec_part_score = 0; + sbi->s_sec_defrag_writes_kb = 0; + sbi->s_sec_num_apps = 0; + sbi->s_sec_capacity_apps_kb = 0; + } +} + static ssize_t f2fs_sbi_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { @@ -531,7 +591,9 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, extlist[i]); return len; } else if (!strcmp(a->attr.name, "sec_gc_stat")) { - return snprintf(buf, PAGE_SIZE, "\"%s\":\"%llu\",\"%s\":\"%llu\"," + int len = 0; + + len = snprintf(buf, PAGE_SIZE, "\"%s\":\"%llu\",\"%s\":\"%llu\"," "\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\"," "\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\"," "\"%s\":\"%llu\",\"%s\":\"%llu\"\n", @@ -547,14 +609,20 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, "BGGC_DSEG", sbi->sec_stat.gc_data_seg_count[BG_GC], "BGGC_DBLK", sbi->sec_stat.gc_data_blk_count[BG_GC], "BGGC_TTIME", sbi->sec_stat.gc_ttime[BG_GC]); + + if (!sbi->sec_hqm_preserve) + __sec_bigdata_init_value(sbi, a->attr.name); + + return len; } else if (!strcmp(a->attr.name, "sec_io_stat")) { u64 kbytes_written = 0; + int len = 0; if (sbi->sb->s_bdev->bd_part) kbytes_written = BD_PART_WRITTEN(sbi) - sbi->sec_stat.kwritten_byte; - return snprintf(buf, PAGE_SIZE, "\"%s\":\"%llu\",\"%s\":\"%llu\"," + len = snprintf(buf, PAGE_SIZE, "\"%s\":\"%llu\",\"%s\":\"%llu\"," "\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\"," "\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\"," "\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\"," @@ -585,8 +653,15 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, "FS_PERROR", sbi->sec_stat.fs_por_error, "FS_ERROR", sbi->sec_stat.fs_error, "MAX_UNDSCD", sbi->sec_stat.max_undiscard_blks); + + if (!sbi->sec_hqm_preserve) + __sec_bigdata_init_value(sbi, a->attr.name); + + return len; } else if (!strcmp(a->attr.name, "sec_fsck_stat")) { - return snprintf(buf, PAGE_SIZE, + int len = 0; + + len = snprintf(buf, PAGE_SIZE, "\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%llu\",\"%s\":\"%u\"," "\"%s\":\"%u\",\"%s\":\"%u\"\n", "FSCK_RBYTES", sbi->sec_fsck_stat.fsck_read_bytes, @@ -595,8 +670,23 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, "FSCK_EXIT", sbi->sec_fsck_stat.fsck_exit_code, "FSCK_VNODES", sbi->sec_fsck_stat.valid_node_count, "FSCK_VINODES", sbi->sec_fsck_stat.valid_inode_count); - } else if (!strcmp(a->attr.name, "sec_defrag_stat")) { + + if (!sbi->sec_hqm_preserve) + __sec_bigdata_init_value(sbi, a->attr.name); + + return len; + } else if (!strcmp(a->attr.name, "sec_heimdallfs_stat")) { return snprintf(buf, PAGE_SIZE, + "\"%s\":\"%u\",\"%s\":\"%llu\",\"%s\":\"%u\",\"%s\":\"%llu\",\"%s\":\"%llu\"\n", + "NR_PKGS", sbi->sec_heimdallfs_stat.nr_pkgs, + "NR_PKG_BLKS", sbi->sec_heimdallfs_stat.nr_pkg_blks, + "NR_COMP_PKGS", sbi->sec_heimdallfs_stat.nr_comp_pkgs, + "NR_COMP_PKG_BLKS", sbi->sec_heimdallfs_stat.nr_comp_pkg_blks, + "NR_COMP_PKG_SAVED_BLKS", sbi->sec_heimdallfs_stat.nr_comp_saved_blks); + } else if (!strcmp(a->attr.name, "sec_defrag_stat")) { + int len = 0; + + len = snprintf(buf, PAGE_SIZE, "\"%s\":\"%u\",\"%s\":\"%u\",\"%s\":\"%u\",\"%s\":\"%u\",\"%s\":\"%u\",\"%s\":\"%u\"\n", "BESTEXT", sbi->s_sec_part_best_extents, "CUREXT", sbi->s_sec_part_current_extents, @@ -604,8 +694,14 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, "DEFWRITE", sbi->s_sec_defrag_writes_kb, "NUMAPP", sbi->s_sec_num_apps, "CAPAPP", sbi->s_sec_capacity_apps_kb); + + if (!sbi->sec_hqm_preserve) + __sec_bigdata_init_value(sbi, a->attr.name); + + return len; } else if (!strcmp(a->attr.name, "sec_fua_mode")) { int len = 0, i; + for (i = 0; i < NR_F2FS_SEC_FUA_MODE; i++) { if (i == sbi->s_sec_cond_fua_mode) len += snprintf(buf, PAGE_SIZE, "[%s] ", @@ -614,6 +710,7 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, len += snprintf(buf, PAGE_SIZE, "%s ", sec_fua_mode_names[i]); } + return len; #ifdef CONFIG_F2FS_SEC_DEBUG_NODE } else if (!strcmp(a->attr.name, "sec_stats")) { @@ -634,7 +731,6 @@ static ssize_t __sbi_store(struct f2fs_attr *a, unsigned long t; unsigned int *ui; ssize_t ret; - unsigned int i = 0; ptr = __struct_ptr(sbi, a->struct_type); if (!ptr) @@ -674,60 +770,16 @@ static ssize_t __sbi_store(struct f2fs_attr *a, up_write(&sbi->sb_lock); return ret ? ret : count; } else if(!strcmp(a->attr.name, "sec_gc_stat")) { - sbi->sec_stat.gc_count[BG_GC] = 0; - sbi->sec_stat.gc_count[FG_GC] = 0; - sbi->sec_stat.gc_node_seg_count[BG_GC] = 0; - sbi->sec_stat.gc_node_seg_count[FG_GC] = 0; - sbi->sec_stat.gc_data_seg_count[BG_GC] = 0; - sbi->sec_stat.gc_data_seg_count[FG_GC] = 0; - sbi->sec_stat.gc_node_blk_count[BG_GC] = 0; - sbi->sec_stat.gc_node_blk_count[FG_GC] = 0; - sbi->sec_stat.gc_data_blk_count[BG_GC] = 0; - sbi->sec_stat.gc_data_blk_count[FG_GC] = 0; - sbi->sec_stat.gc_ttime[BG_GC] = 0; - sbi->sec_stat.gc_ttime[FG_GC] = 0; + __sec_bigdata_init_value(sbi, a->attr.name); return count; } else if (!strcmp(a->attr.name, "sec_io_stat")) { - sbi->sec_stat.cp_cnt[STAT_CP_ALL] = 0; - sbi->sec_stat.cp_cnt[STAT_CP_BG] = 0; - sbi->sec_stat.cp_cnt[STAT_CP_FSYNC] = 0; - for (i = 0; i < NR_CP_REASON; i++) - sbi->sec_stat.cpr_cnt[i] = 0; - sbi->sec_stat.cp_max_interval= 0; - sbi->sec_stat.alloc_seg_type[LFS] = 0; - sbi->sec_stat.alloc_seg_type[SSR] = 0; - sbi->sec_stat.alloc_blk_count[LFS] = 0; - sbi->sec_stat.alloc_blk_count[SSR] = 0; - atomic64_set(&sbi->sec_stat.inplace_count, 0); - sbi->sec_stat.fsync_count = 0; - sbi->sec_stat.fsync_dirty_pages = 0; - sbi->sec_stat.hot_file_written_blocks = 0; - sbi->sec_stat.cold_file_written_blocks = 0; - sbi->sec_stat.warm_file_written_blocks = 0; - sbi->sec_stat.max_inmem_pages = 0; - sbi->sec_stat.drop_inmem_all = 0; - sbi->sec_stat.drop_inmem_files = 0; - if (sbi->sb->s_bdev->bd_part) - sbi->sec_stat.kwritten_byte = BD_PART_WRITTEN(sbi); - sbi->sec_stat.fs_por_error = 0; - sbi->sec_stat.fs_error = 0; - sbi->sec_stat.max_undiscard_blks = 0; + __sec_bigdata_init_value(sbi, a->attr.name); return count; } else if (!strcmp(a->attr.name, "sec_fsck_stat")) { - sbi->sec_fsck_stat.fsck_read_bytes = 0; - sbi->sec_fsck_stat.fsck_written_bytes = 0; - sbi->sec_fsck_stat.fsck_elapsed_time = 0; - sbi->sec_fsck_stat.fsck_exit_code = 0; - sbi->sec_fsck_stat.valid_node_count = 0; - sbi->sec_fsck_stat.valid_inode_count = 0; + __sec_bigdata_init_value(sbi, a->attr.name); return count; } else if (!strcmp(a->attr.name, "sec_defrag_stat")) { - sbi->s_sec_part_best_extents = 0; - sbi->s_sec_part_current_extents = 0; - sbi->s_sec_part_score = 0; - sbi->s_sec_defrag_writes_kb = 0; - sbi->s_sec_num_apps = 0; - sbi->s_sec_capacity_apps_kb = 0; + __sec_bigdata_init_value(sbi, a->attr.name); return count; } else if (!strcmp(a->attr.name, "sec_fua_mode")) { const char *mode= strim((char *)buf); @@ -920,6 +972,11 @@ static struct f2fs_attr f2fs_attr_##_name = { \ f2fs_sbi_show, f2fs_sbi_store, \ offsetof(struct struct_name, elname)) +#define F2FS_RW_ATTR_640(struct_type, struct_name, name, elname) \ + F2FS_ATTR_OFFSET(struct_type, name, 0640, \ + f2fs_sbi_show, f2fs_sbi_store, \ + offsetof(struct struct_name, elname)) + #define F2FS_GENERAL_RO_ATTR(name) \ static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) @@ -978,20 +1035,22 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_super_block, extension_list, extension_list); F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); #endif -F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_gc_stat, sec_stat); -F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_io_stat, sec_stat); +F2FS_RW_ATTR_640(F2FS_SBI, f2fs_sb_info, sec_gc_stat, sec_stat); +F2FS_RW_ATTR_640(F2FS_SBI, f2fs_sb_info, sec_io_stat, sec_stat); #ifdef CONFIG_F2FS_SEC_DEBUG_NODE F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_stats, stat_info); #endif -F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_fsck_stat, sec_fsck_stat); +F2FS_RW_ATTR_640(F2FS_SBI, f2fs_sb_info, sec_fsck_stat, sec_fsck_stat); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_heimdallfs_stat, sec_heimdallfs_stat); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_part_best_extents, s_sec_part_best_extents); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_part_current_extents, s_sec_part_current_extents); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_part_score, s_sec_part_score); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_defrag_writes_kb, s_sec_defrag_writes_kb); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_num_apps, s_sec_num_apps); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_capacity_apps_kb, s_sec_capacity_apps_kb); -F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_defrag_stat, s_sec_part_best_extents); +F2FS_RW_ATTR_640(F2FS_SBI, f2fs_sb_info, sec_defrag_stat, s_sec_part_best_extents); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_fua_mode, s_sec_cond_fua_mode); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, sec_hqm_preserve, sec_hqm_preserve); F2FS_GENERAL_RO_ATTR(dirty_segments); F2FS_GENERAL_RO_ATTR(free_segments); F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); @@ -1071,6 +1130,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(sec_stats), #endif ATTR_LIST(sec_fsck_stat), + ATTR_LIST(sec_heimdallfs_stat), ATTR_LIST(sec_part_best_extents), ATTR_LIST(sec_part_current_extents), ATTR_LIST(sec_part_score), @@ -1079,6 +1139,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(sec_capacity_apps_kb), ATTR_LIST(sec_defrag_stat), ATTR_LIST(sec_fua_mode), + ATTR_LIST(sec_hqm_preserve), #ifdef CONFIG_F2FS_FAULT_INJECTION ATTR_LIST(inject_rate), ATTR_LIST(inject_type), diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ba5e99d2d..98095a016 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1371,6 +1371,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) long nr_to_write = wbc->nr_to_write; unsigned dirty; int ret; + /* @fs.sec -- 62cf6bdd87a5c084b05e3bb9a11045a339d42a6b -- */ bool newly_dirty = false; WARN_ON(!(inode->i_state & I_SYNC)); diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 479f2fc46..3603f491a 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -153,6 +153,7 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, if (fuse_block_alloc(fc, for_background)) { err = -EINTR; + /* @fs.sec -- 9992f9e9ebd25b0dcc80951a9e4f4fc2e71a08c6 -- */ if (fuse_wait_event_killable_exclusive(fc->blocked_waitq, !fuse_block_alloc(fc, for_background))) goto out; @@ -2136,6 +2137,7 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort) { struct fuse_iqueue *fiq = &fc->iq; + /* @fs.sec -- d7bd5cc97a05d48e04defc719fbaffefdd4e6f22 -- */ ST_LOG("<%s> dev = %u:%u fuse abort all requests", __func__, MAJOR(fc->dev), MINOR(fc->dev)); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 98c2bcdc9..7a8c6afb0 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -325,6 +325,7 @@ static void fuse_dentry_release(struct dentry *dentry) kfree_rcu(fd, rcu); } +/* @fs.sec -- 63ff82f9216c9b6d003e7d45699d54b833344719 -- */ static int fuse_dentry_delete(const struct dentry *dentry) { struct fuse_inode *fi; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fd4da8cae..583608ed5 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1005,6 +1005,7 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) bdi_put(sb->s_bdi); sb->s_bdi = &noop_backing_dev_info; } + /* @fs.sec -- 9b4d962cc783453fc63e4302012c8e28e11e31a5 -- */ err = sec_super_setup_bdi_name(sb, "%u:%u%s", MAJOR(fc->dev), MINOR(fc->dev), suffix); if (err) diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index f87464412..28fac5038 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h @@ -283,11 +283,4 @@ enum drbg_prefixes { DRBG_PREFIX3 }; -extern int drbg_alloc_state(struct drbg_state *drbg); -extern void drbg_dealloc_state(struct drbg_state *drbg); -extern void drbg_convert_tfm_core(const char *cra_driver_name, int *coreref, - bool *pr); -extern const struct drbg_core drbg_cores[]; -extern unsigned short drbg_sec_strength(drbg_flag_t flags); - #endif /* _DRBG_H */ diff --git a/include/kunit/strerror.h b/include/kunit/strerror.h index d5f421dee..ee13de067 100644 --- a/include/kunit/strerror.h +++ b/include/kunit/strerror.h @@ -17,11 +17,7 @@ * EPERM, ENOENT, ESRCH, etc). For unsupported errors this function returns * NULL. */ -// FIXME: BUILD ERROR for UM -//#pragma GCC diagnostic push -//#pragma GCC diagnostic ignored "-Wincompatible-library-redeclaration" -const char *strerror(int errno); -//#pragma GCC diagnostic pop +const char *strerror_str(int errno); /** * strerror_r() - returns a string representation of the given error code. diff --git a/include/kunit/test.h b/include/kunit/test.h index e12f55555..8e9889c32 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -11,11 +11,7 @@ #include #include - #include -//#include -//#include - #include #include @@ -452,16 +448,16 @@ static inline void test_expect_end(struct test *test, typeof(expression) __result = (expression); \ char buf[64]; \ \ - if (result != 0) \ + if (__result != 0) \ __stream->add(__stream, \ "Expected " #expression " is not error, " \ "but is: %s.", \ - strerror_r(-result, buf, sizeof(buf))); \ - EXPECT_END(test, result != 0, __stream); \ + strerror_r(-__result, buf, sizeof(buf))); \ + EXPECT_END(test, __result == 0, __stream); \ } while (0) /** - * EXPECT_ERROR() - Causes a test failure when @expression evaluates to @errno. + * EXPECT_ERROR() - Causes a test failure when @expression does not evaluate to @errno. * @test: The test context object. * @expression: an arbitrary expression evaluating to an int error code. The * test fails when this does not evaluate to @errno. @@ -476,12 +472,12 @@ static inline void test_expect_end(struct test *test, char buf1[64]; \ char buf2[64]; \ \ - if (result != errno) \ + if (__result != errno) \ __stream->add(__stream, \ "Expected " #expression " is %s, but is: %s.", \ - strerror_t(-errno, buf1, sizeof(buf1)), \ - strerror_r(-result, buf2, sizeof(buf2))); \ - EXPECT_END(test, result == errno, __stream); \ + strerror_r(-errno, buf1, sizeof(buf1)), \ + strerror_r(-__result, buf2, sizeof(buf2))); \ + EXPECT_END(test, __result == errno, __stream); \ } while (0) static inline void test_expect_binary(struct test *test, @@ -753,12 +749,12 @@ static inline void test_assert_end(struct test *test, typeof(expression) __result = (expression); \ char buf[64]; \ \ - if (result != 0) \ + if (__result != 0) \ __stream->add(__stream, \ "Asserted " #expression " is not error, " \ "but is: %s.", \ - strerror_r(-result, buf, sizeof(buf))); \ - ASSERT_END(test, result != 0, __stream); \ + strerror_r(-__result, buf, sizeof(buf))); \ + ASSERT_END(test, __result == 0, __stream); \ } while (0) /** @@ -777,12 +773,12 @@ static inline void test_assert_end(struct test *test, char buf1[64]; \ char buf2[64]; \ \ - if (result != errno) \ + if (__result != errno) \ __stream->add(__stream, \ "Expected " #expression " is %s, but is: %s.", \ - strerror_t(-errno, buf1, sizeof(buf1)), \ - strerror_r(-result, buf2, sizeof(buf2))); \ - ASSERT_END(test, result == errno, __stream); \ + strerror_r(-errno, buf1, sizeof(buf1)), \ + strerror_r(-__result, buf2, sizeof(buf2))); \ + ASSERT_END(test, __result == errno, __stream); \ } while (0) static inline void test_assert_binary(struct test *test, diff --git a/include/linux/adsp/adsp_ft_common.h b/include/linux/adsp/adsp_ft_common.h index e059f6b15..63f96b766 100644 --- a/include/linux/adsp/adsp_ft_common.h +++ b/include/linux/adsp/adsp_ft_common.h @@ -129,11 +129,23 @@ enum { }; #endif +enum { + COMMON_DATA_SET_ABS_OFF, // 0x00 00 47 C1 + COMMON_DATA_SET_ABS_ON, // 0x01 00 47 C1 +#ifdef CONFIG_SUPPORT_VFOLD_FLEX + COMMON_DATA_SET_MAIN_ON, // 0x02 00 47 C1 + COMMON_DATA_SET_SUB_ON, // 0x03 00 47 C1 +#endif + COMMON_DATA_SET_LCD_INTENT_ON = 0xf1, // 0xf1 00 47 C1 + COMMON_DATA_SET_LCD_INTENT_OFF, // 0xf2 00 47 C1 +}; + // for ssc_core sensor type enum { OPTION_TYPE_SSC_CHARGING_STATE, // for pocket mode OPTION_TYPE_SSC_ABS_LCD_TYPE, // for pocket mode - OPTION_TYPE_SSC_LCD_TYPE, // for pocket mode + OPTION_TYPE_SSC_LCD_TYPE, // for pocket mode + auto roation + OPTION_TYPE_SSC_LCD_INTENT_TYPE, // for auto rotation OPTION_TYPE_SSC_DUMP_TYPE, // for pocket mode OPTION_TYPE_SSC_AOD_RECT, // for AOD OPTION_TYPE_SSC_AOD_LIGHT_CIRCLE, // for AOD diff --git a/include/linux/bluetooth-power.h b/include/linux/bluetooth-power.h index 04614d491..4e41cfd2b 100644 --- a/include/linux/bluetooth-power.h +++ b/include/linux/bluetooth-power.h @@ -52,6 +52,8 @@ struct bluetooth_power_platform_data { int bt_gpio_sys_rst; /* Bluetooth sw_ctrl gpio */ int bt_gpio_sw_ctrl; + /* Wlan reset gpio */ + int wl_gpio_sys_rst; /* Bluetooth debug gpio */ int bt_gpio_debug; struct device *slim_dev; diff --git a/include/linux/ccic/max77705C_pass2_PID03.h b/include/linux/ccic/max77705C_pass2_PID03.h index f252585ba..a760680ba 100644 --- a/include/linux/ccic/max77705C_pass2_PID03.h +++ b/include/linux/ccic/max77705C_pass2_PID03.h @@ -1,6634 +1,6634 @@ const uint8_t BOOT_FLASH_FW_PASS2[] = { -0xc1, 0x66, 0xf1, 0xce, 0x4e, 0x18, 0x15, 0x02, +0xc1, 0x66, 0xf1, 0xce, 0x59, 0x18, 0x15, 0x02, 0x01, 0x22, 0x21, 0x70, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, -0x0d, 0x0e, 0x0f, 0x00, 0x4e, 0x18, 0x15, 0x02, -0x03, 0x00, 0x00, 0x00, 0x7c, 0x7a, 0x22, 0x8c, -0xf9, 0xdc, 0x69, 0x6b, 0x03, 0x04, 0x51, 0x02, +0x0d, 0x0e, 0x0f, 0x00, 0x59, 0x18, 0x15, 0x02, +0x03, 0x00, 0x00, 0x00, 0x50, 0x7f, 0x79, 0x1a, +0x42, 0x37, 0x90, 0x26, 0x03, 0x04, 0x51, 0x02, 0x00, 0x01, 0x01, 0x22, 0x21, 0x20, 0xa9, 0xe8, 0x91, 0x2c, 0xdf, 0x69, 0xb7, 0x95, 0x9d, 0xa4, 0x69, 0x33, 0xed, 0x4a, 0x1d, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x07, -0x91, 0x9b, 0x62, 0xac, 0x4b, 0x1f, 0x03, 0x04, -0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0x45, -0x32, 0xe4, 0xf6, 0x76, 0x49, 0x63, 0x48, 0x5d, -0x8f, 0x53, 0xd5, 0xa6, 0x81, 0x51, 0xa1, 0xef, -0x56, 0xb8, 0x41, 0xb3, 0x2c, 0x07, 0xc2, 0xc8, -0xfe, 0xde, 0xb9, 0x1a, 0x64, 0xd2, 0xe1, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x4d, +0x9d, 0x9d, 0x7a, 0x48, 0xa8, 0x8e, 0x03, 0x04, +0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0x0d, +0xd9, 0x1f, 0x96, 0x3f, 0x6c, 0xc9, 0x68, 0xbe, +0x54, 0x6c, 0x04, 0xba, 0x7a, 0xb9, 0x30, 0x20, +0x46, 0x6b, 0xb7, 0xcc, 0x3d, 0x48, 0xc0, 0x94, +0xca, 0x90, 0x29, 0xb4, 0x3d, 0x69, 0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x03, 0x01, 0x22, -0x21, 0xe9, 0xa8, 0xa9, 0xc1, 0xd9, 0x2b, 0x8a, -0xe1, 0x18, 0x62, 0x01, 0x6f, 0xac, 0x94, 0x9f, -0x12, 0x29, 0xb6, 0xd6, 0xf4, 0x3b, 0x21, 0x33, -0x7f, 0x4c, 0x1d, 0x14, 0x8e, 0xfc, 0xd9, 0xf7, -0x90, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, -0x01, 0x22, 0x21, 0xf6, 0xae, 0x8d, 0xf3, 0xa9, -0xc0, 0xb6, 0xc4, 0xd3, 0xf6, 0x3a, 0x43, 0xda, -0x0c, 0x9b, 0xdb, 0x0b, 0xb1, 0x2b, 0xf3, 0x38, -0x2a, 0x2b, 0x6d, 0xf3, 0xcb, 0xf9, 0x22, 0x7c, -0x60, 0x0a, 0xf2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x05, 0x01, 0x22, 0x21, 0x14, 0xf5, 0xd0, -0x7a, 0x62, 0x13, 0xde, 0x4c, 0x73, 0xb6, 0xd1, -0x59, 0xd4, 0x95, 0xf1, 0xe2, 0xbc, 0xbc, 0xa2, -0xb1, 0xd6, 0x88, 0x4b, 0x26, 0x9d, 0x31, 0x18, -0x59, 0x55, 0xfe, 0xd5, 0x37, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0x70, -0x04, 0xa2, 0xb9, 0xb7, 0x45, 0x49, 0xda, 0xa0, -0xc5, 0x30, 0x7b, 0x47, 0x99, 0x69, 0x37, 0x4f, -0xdf, 0xee, 0xbf, 0x81, 0x05, 0x9b, 0xfd, 0xaf, -0x6b, 0x96, 0x17, 0xc2, 0xbb, 0x08, 0x70, 0x00, +0x21, 0x32, 0xb0, 0x50, 0x99, 0xbf, 0x35, 0x8e, +0x7a, 0x65, 0xa6, 0x3a, 0x05, 0x19, 0x55, 0x97, +0x36, 0x59, 0xd9, 0xb4, 0xaa, 0xd6, 0xcd, 0xa5, +0xc9, 0x79, 0x96, 0xab, 0x1f, 0xa4, 0xdf, 0x10, +0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, +0x01, 0x22, 0x21, 0xb6, 0x50, 0xf8, 0x18, 0xc7, +0x51, 0x5a, 0xc3, 0x09, 0xa2, 0x37, 0xc6, 0x17, +0x89, 0x36, 0x6e, 0x69, 0x62, 0x90, 0x2c, 0xfd, +0xa8, 0x6d, 0xbd, 0x17, 0x41, 0x25, 0xcb, 0x50, +0xa9, 0x67, 0x9f, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x05, 0x01, 0x22, 0x21, 0xfe, 0x0f, 0x9a, +0x33, 0x9b, 0xd4, 0x55, 0x2b, 0x54, 0x47, 0x56, +0xbd, 0xa9, 0xf2, 0xd5, 0xda, 0x0e, 0xd1, 0xd6, +0x98, 0x7b, 0xec, 0xae, 0xd8, 0xf6, 0x44, 0x18, +0x6a, 0x30, 0x23, 0x81, 0xc7, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0xfb, +0x8d, 0xf4, 0x22, 0xb4, 0x34, 0xfc, 0x87, 0x2b, +0xc0, 0x08, 0xd3, 0xcd, 0x1c, 0xd9, 0x1b, 0x70, +0xbe, 0xe6, 0xf3, 0x48, 0x9c, 0x31, 0x5f, 0x07, +0x3c, 0x58, 0x06, 0x97, 0xab, 0x71, 0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x07, 0x01, 0x22, -0x21, 0x09, 0xf3, 0x67, 0x25, 0xdc, 0xa0, 0xaa, -0xc9, 0x68, 0xe1, 0xd2, 0x1b, 0x51, 0xc6, 0x1d, -0x40, 0x51, 0x76, 0x9f, 0xec, 0xef, 0xa5, 0xf2, -0x5b, 0x33, 0xf3, 0xea, 0xec, 0xc3, 0x34, 0xd4, -0xf3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, -0x01, 0x22, 0x21, 0x26, 0xe1, 0xee, 0x8f, 0x7a, -0x49, 0xba, 0xce, 0x6d, 0x68, 0x5f, 0xa6, 0xf6, -0x20, 0xab, 0xa2, 0x5a, 0x92, 0x30, 0x43, 0x4c, -0x3f, 0x6f, 0xe5, 0x30, 0xad, 0x93, 0x5f, 0x00, -0x9d, 0xe8, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x09, 0x01, 0x22, 0x21, 0x53, 0x60, 0xc0, -0xed, 0x39, 0xf3, 0xc7, 0x25, 0x9d, 0xeb, 0x7d, -0x30, 0x85, 0x1c, 0xfe, 0xc7, 0xee, 0x23, 0x1e, -0x80, 0xcc, 0xb7, 0x91, 0xa1, 0x16, 0x49, 0x63, -0x06, 0xb2, 0x47, 0x32, 0x1b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0x4e, -0x5b, 0x82, 0xd9, 0xb5, 0xb7, 0xa1, 0xdf, 0xb8, -0x44, 0x9f, 0x37, 0x59, 0x91, 0x33, 0x3f, 0x85, -0x42, 0x69, 0xf3, 0x44, 0xbd, 0x4b, 0xca, 0x43, -0xb7, 0x1b, 0x66, 0xa2, 0x6f, 0xc0, 0x8e, 0x00, +0x21, 0xe2, 0xfa, 0xfc, 0x07, 0x65, 0xfa, 0xf9, +0x56, 0x8f, 0x30, 0xa3, 0xda, 0x3f, 0x3f, 0x94, +0xc9, 0x5b, 0xe8, 0xb4, 0x05, 0xf4, 0xb8, 0x49, +0xac, 0xeb, 0x77, 0xc1, 0xda, 0xdf, 0x70, 0x8f, +0x93, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, +0x01, 0x22, 0x21, 0xcd, 0x54, 0xfc, 0x08, 0xc3, +0x7c, 0x1b, 0x85, 0xab, 0xba, 0xa9, 0xd2, 0x70, +0xb1, 0x70, 0x77, 0xbf, 0xd9, 0x8d, 0xbd, 0x33, +0x15, 0xd8, 0x28, 0x66, 0xfb, 0x5f, 0x5a, 0x23, +0x98, 0xf3, 0x5c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x09, 0x01, 0x22, 0x21, 0x78, 0xab, 0x14, +0xac, 0xce, 0x9a, 0xc8, 0xda, 0x87, 0x96, 0x25, +0xcb, 0x58, 0xaa, 0x5f, 0xa4, 0x1f, 0x95, 0x2b, +0x5c, 0x08, 0x69, 0xd3, 0x84, 0xe7, 0x84, 0x39, +0xbb, 0x13, 0xb3, 0xfd, 0xc8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0x2b, +0x82, 0x90, 0x37, 0xce, 0x8e, 0xa7, 0xb2, 0xc7, +0xaf, 0x3b, 0x35, 0xb8, 0x16, 0xf9, 0xf9, 0xc7, +0xce, 0x3d, 0x76, 0xc4, 0xc6, 0x88, 0x4d, 0x37, +0x90, 0xbc, 0x6c, 0xe8, 0x0b, 0xac, 0x0e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0b, 0x01, 0x22, -0x21, 0x64, 0xf6, 0xe7, 0xe7, 0xab, 0xca, 0x13, -0xc0, 0x29, 0xbc, 0x4d, 0x21, 0x05, 0x18, 0xa1, -0xfe, 0x95, 0x0a, 0x98, 0xf0, 0x51, 0x06, 0xf2, -0xee, 0xf5, 0x8c, 0xb5, 0x98, 0xe1, 0x0e, 0x24, -0x6f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, -0x01, 0x22, 0x21, 0xb4, 0xc8, 0x03, 0xaa, 0x1e, -0x45, 0x69, 0x9c, 0xf4, 0x05, 0xbe, 0xd1, 0x6b, -0xc2, 0xfa, 0x40, 0x07, 0x8d, 0x7b, 0xf3, 0xe7, -0x5d, 0x77, 0x68, 0x3d, 0xd7, 0x30, 0x92, 0x49, -0x6b, 0x8c, 0xc3, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x0d, 0x01, 0x22, 0x21, 0x14, 0xe0, 0x40, -0x37, 0x13, 0x22, 0x5f, 0x53, 0x36, 0xf2, 0xc3, -0xb4, 0x20, 0xd6, 0x74, 0x79, 0x90, 0xec, 0x45, -0x14, 0x7e, 0xce, 0x64, 0x29, 0x66, 0x67, 0x7d, -0xb2, 0xbd, 0x60, 0xaa, 0x9b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0x11, -0x72, 0xf3, 0x6b, 0xff, 0xca, 0x45, 0x60, 0xd4, -0xae, 0x35, 0xa0, 0x62, 0x19, 0xd7, 0xc7, 0xe8, -0x0a, 0xdb, 0x92, 0x72, 0xca, 0xad, 0x47, 0x52, -0xb9, 0x44, 0xa8, 0x43, 0x1a, 0xb1, 0xb9, 0x00, +0x21, 0x38, 0x4b, 0xbc, 0xd2, 0xae, 0x0c, 0xb7, +0x9c, 0x74, 0x4a, 0x7f, 0x35, 0xad, 0xdf, 0x25, +0x4e, 0x95, 0xd1, 0xdb, 0x1a, 0x1e, 0x48, 0x77, +0xb6, 0x57, 0x0f, 0xc9, 0x77, 0xff, 0x19, 0xe4, +0x3d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, +0x01, 0x22, 0x21, 0x77, 0x5b, 0xf2, 0x0f, 0x1a, +0xc6, 0xc0, 0x93, 0x5b, 0x89, 0x8a, 0x98, 0xd7, +0xd0, 0x13, 0x45, 0x88, 0x77, 0xa8, 0xe0, 0x8f, +0xf6, 0xa9, 0xf8, 0x6e, 0xb2, 0x03, 0x03, 0xb9, +0x3b, 0xc0, 0x29, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x0d, 0x01, 0x22, 0x21, 0xf0, 0xf6, 0x58, +0x60, 0x12, 0x3c, 0x46, 0xc5, 0x7a, 0x92, 0x4b, +0xbe, 0x4d, 0x9b, 0x69, 0x21, 0x49, 0x02, 0x90, +0x68, 0x00, 0xf9, 0xad, 0xa6, 0xc8, 0xbb, 0x1a, +0xef, 0xf0, 0x4e, 0xb5, 0xac, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0x2f, +0x4e, 0x84, 0xa2, 0x11, 0x6d, 0x7e, 0x46, 0xc5, +0x69, 0x9f, 0x88, 0xe3, 0x71, 0x7a, 0x1e, 0xb1, +0x60, 0x88, 0x04, 0xee, 0x8d, 0x56, 0xa9, 0x16, +0x71, 0x37, 0x4d, 0xdb, 0x87, 0x5f, 0x77, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0f, 0x01, 0x22, -0x21, 0xf2, 0x20, 0x6f, 0xeb, 0x29, 0x20, 0x76, -0x46, 0x57, 0x55, 0x80, 0xfd, 0x1d, 0xcc, 0x84, -0x87, 0x25, 0x2a, 0x57, 0x1f, 0xeb, 0xb1, 0x5a, -0x9d, 0xaf, 0xac, 0x9b, 0xd7, 0x10, 0x97, 0xa7, -0x32, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, -0x01, 0x22, 0x21, 0xf0, 0x4f, 0xde, 0xed, 0x61, -0x72, 0x65, 0xa3, 0xfc, 0xb0, 0x02, 0xea, 0x05, -0x13, 0x6f, 0x7f, 0x56, 0xd1, 0x1d, 0xf2, 0xad, -0xa6, 0x8e, 0xef, 0xe8, 0xc9, 0xbd, 0x8a, 0x2c, -0x73, 0xa5, 0xfa, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x11, 0x01, 0x22, 0x21, 0xb9, 0x18, 0x75, -0x7f, 0x96, 0x5c, 0x33, 0x78, 0xe5, 0xaf, 0x4e, -0x3c, 0xe1, 0x36, 0xd1, 0x52, 0x70, 0xb3, 0xc4, -0x08, 0x51, 0x06, 0x2a, 0xfa, 0x56, 0xf6, 0xa3, -0x38, 0x78, 0x3b, 0x20, 0xa2, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0xa4, -0xb0, 0xf5, 0x48, 0xef, 0x60, 0xf5, 0x85, 0x83, -0x85, 0xb9, 0xe3, 0x02, 0x3f, 0x9f, 0xcf, 0x52, -0x6a, 0x39, 0xa5, 0x54, 0x1d, 0x47, 0x9e, 0x2b, -0x86, 0xf4, 0x1f, 0x32, 0xd5, 0x7a, 0x7c, 0x00, +0x21, 0x7e, 0x7c, 0x7f, 0x27, 0x0b, 0x9f, 0x31, +0xda, 0x04, 0x73, 0xc7, 0x8d, 0x1c, 0xd1, 0xcf, +0x4b, 0xea, 0x95, 0xdd, 0x53, 0xba, 0x61, 0xe2, +0xb5, 0x81, 0x6b, 0x3a, 0x7a, 0x45, 0xed, 0x20, +0x5c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, +0x01, 0x22, 0x21, 0x4c, 0x0c, 0xba, 0x70, 0x45, +0x09, 0xb4, 0xa1, 0x49, 0x20, 0x76, 0xad, 0xd5, +0x41, 0x19, 0x13, 0x48, 0x2a, 0x1a, 0x30, 0xc0, +0x6f, 0xd4, 0x08, 0x06, 0x10, 0x10, 0x39, 0xee, +0xee, 0x4e, 0x95, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x11, 0x01, 0x22, 0x21, 0x6f, 0x30, 0x68, +0x92, 0x42, 0x2e, 0x83, 0x56, 0x0d, 0xb1, 0xb8, +0xdc, 0xd4, 0x60, 0xa6, 0x3d, 0xfd, 0x80, 0xca, +0xff, 0xde, 0x36, 0x6a, 0x45, 0xa5, 0x33, 0x51, +0x45, 0x81, 0xb1, 0x0c, 0x08, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0x12, +0xc9, 0x24, 0x7b, 0xe9, 0xd2, 0xd3, 0x56, 0x62, +0x38, 0x8b, 0x39, 0x2d, 0xd2, 0x98, 0xde, 0x52, +0xbc, 0x31, 0x0e, 0xda, 0x2a, 0xd3, 0x89, 0x80, +0x2c, 0x91, 0xc8, 0x8f, 0x91, 0x78, 0x32, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x13, 0x01, 0x22, -0x21, 0xee, 0x5d, 0xd0, 0xf3, 0xc8, 0x7d, 0x97, -0x40, 0xdb, 0x1f, 0x1e, 0xf5, 0xcb, 0xc0, 0xd4, -0x94, 0xaa, 0xdf, 0x80, 0xdb, 0x70, 0xd6, 0x68, -0x83, 0x25, 0x93, 0xc4, 0x5a, 0x9b, 0xec, 0x5b, -0x77, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, -0x01, 0x22, 0x21, 0xb3, 0x63, 0x7d, 0xaa, 0xcc, -0x62, 0xf8, 0x99, 0x81, 0x4a, 0xaf, 0xf2, 0x5b, -0x10, 0x9f, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xb5, 0xd5, 0xac, 0x72, -0x68, 0xb7, 0x84, 0x7f, 0x03, 0x04, 0x51, 0x02, -0x00, 0x15, 0x01, 0x22, 0x21, 0xa5, 0x3f, 0xa0, -0xc3, 0x05, 0x01, 0xc1, 0xd7, 0x1e, 0x0f, 0x93, -0x56, 0x22, 0xf9, 0x48, 0x79, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0xac, -0x20, 0xca, 0xbf, 0xde, 0xf0, 0x41, 0x03, 0x04, -0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x0a, -0x01, 0x4b, 0x5f, 0x25, 0xe6, 0xe2, 0xbe, 0x70, -0x56, 0x56, 0x01, 0x74, 0x58, 0xfe, 0xf5, 0x14, -0xea, 0x41, 0x41, 0x0d, 0xcf, 0xde, 0x8c, 0xad, -0x01, 0xbd, 0xa8, 0x30, 0x3b, 0xec, 0xca, 0x00, +0x21, 0xdc, 0xb4, 0x95, 0x23, 0x55, 0x42, 0x83, +0x2b, 0x26, 0x86, 0xba, 0x8e, 0x68, 0xee, 0x7d, +0x0d, 0xf2, 0x4a, 0x22, 0x0e, 0x76, 0x95, 0x51, +0x65, 0x80, 0x66, 0x10, 0x33, 0x1f, 0x5b, 0x80, +0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, +0x01, 0x22, 0x21, 0x91, 0xe3, 0xc1, 0x00, 0x04, +0xe9, 0xd9, 0x27, 0xb6, 0x19, 0xbb, 0x38, 0xd4, +0x48, 0x6d, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x84, 0x8b, 0xd9, 0x35, +0x60, 0x4b, 0x02, 0x1f, 0x03, 0x04, 0x51, 0x02, +0x00, 0x15, 0x01, 0x22, 0x21, 0x0d, 0x9a, 0x77, +0xaf, 0xd8, 0xa2, 0xc5, 0xd5, 0x1d, 0x64, 0xcd, +0x22, 0x16, 0x0e, 0x06, 0x9f, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x39, +0x40, 0x85, 0x43, 0x2b, 0x50, 0x34, 0x03, 0x04, +0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x3c, +0x1b, 0xed, 0xa9, 0xa9, 0x16, 0x9a, 0x8f, 0x41, +0x19, 0x75, 0x91, 0x99, 0xb1, 0x68, 0x64, 0xa7, +0x5f, 0x39, 0xd3, 0xc3, 0xd0, 0xdc, 0x05, 0xd3, +0x33, 0x89, 0xc1, 0x7c, 0xbd, 0x33, 0x72, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x17, 0x01, 0x22, -0x21, 0x71, 0x36, 0x13, 0x90, 0x49, 0xd4, 0xfd, -0xf6, 0x37, 0xf5, 0xbd, 0xfe, 0x5c, 0x26, 0x45, -0x4f, 0x23, 0x51, 0x04, 0xda, 0x04, 0xe4, 0x7a, -0x1a, 0x79, 0xef, 0x71, 0x98, 0x23, 0xd5, 0x66, -0x16, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, -0x01, 0x22, 0x21, 0x25, 0xe8, 0x3f, 0xd9, 0x29, -0x75, 0xe3, 0xba, 0x9c, 0x36, 0x43, 0xc7, 0xe9, -0xa0, 0xc3, 0x10, 0x97, 0xfd, 0x19, 0x77, 0xfb, -0x24, 0x6e, 0xaa, 0xda, 0x6a, 0x3b, 0xc4, 0x7a, -0xfd, 0x82, 0x71, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x19, 0x01, 0x22, 0x21, 0x05, 0x6d, 0x1e, -0x32, 0x90, 0x28, 0xf1, 0x02, 0xe2, 0xcb, 0x01, -0xaa, 0x2c, 0xc0, 0x07, 0x0b, 0x7c, 0x33, 0x4e, -0xfe, 0x27, 0xb0, 0xac, 0x91, 0x4b, 0x3c, 0x98, -0x52, 0x38, 0x47, 0x71, 0x63, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0x88, -0xd4, 0x3e, 0xe4, 0x61, 0x1d, 0xe1, 0x2f, 0xf9, -0x6d, 0xce, 0xf9, 0x47, 0x59, 0x34, 0x45, 0xf5, -0xf0, 0xfa, 0x3d, 0x64, 0xd1, 0xcc, 0x01, 0xf6, -0xed, 0xc8, 0xb0, 0x1d, 0x9e, 0x49, 0x2c, 0x00, +0x21, 0x7f, 0x37, 0x27, 0x61, 0x08, 0xb6, 0x8b, +0x27, 0x83, 0x73, 0x5b, 0x56, 0xe4, 0xd7, 0xf3, +0xab, 0x4e, 0x52, 0xf2, 0xcb, 0x00, 0x68, 0x71, +0xce, 0x0b, 0xfa, 0xcc, 0x45, 0x21, 0x32, 0x35, +0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, +0x01, 0x22, 0x21, 0x04, 0x8f, 0xf1, 0x13, 0xa5, +0x67, 0x1c, 0xf8, 0xb9, 0xc8, 0x18, 0xec, 0xd5, +0xff, 0x2d, 0x1a, 0x86, 0x9c, 0xd5, 0x4b, 0x41, +0xe6, 0x82, 0x66, 0x63, 0x2a, 0x4d, 0xef, 0xdd, +0x5e, 0x7d, 0xa2, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x19, 0x01, 0x22, 0x21, 0x1c, 0xf1, 0xff, +0xac, 0x94, 0xaa, 0xd8, 0xac, 0x69, 0x91, 0x2e, +0x3f, 0xf3, 0x41, 0x71, 0x21, 0x62, 0x01, 0xf8, +0x60, 0xb7, 0x50, 0x5d, 0x3d, 0x12, 0x11, 0x09, +0xe9, 0x19, 0xa6, 0x14, 0xfb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0xb3, +0x63, 0x4e, 0x75, 0x80, 0x56, 0x56, 0xc5, 0xd3, +0x45, 0x3b, 0xf9, 0xa8, 0x3f, 0x09, 0x0f, 0x59, +0x9e, 0x05, 0xac, 0xce, 0x5c, 0xe9, 0x65, 0x85, +0x88, 0x68, 0x09, 0x43, 0x24, 0xb0, 0x10, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1b, 0x01, 0x22, -0x21, 0x55, 0xc0, 0xa9, 0xab, 0x5d, 0x2d, 0x68, -0x4b, 0x7a, 0x2d, 0x4d, 0xc2, 0xb6, 0x64, 0xc2, -0xd5, 0x4c, 0x68, 0xdb, 0xb7, 0x55, 0x2a, 0x35, -0x7b, 0xc7, 0x0c, 0xeb, 0x4b, 0x0e, 0x19, 0xcf, -0x08, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, -0x01, 0x22, 0x21, 0xbd, 0x65, 0xa3, 0x29, 0x17, -0x3c, 0x87, 0xa2, 0xed, 0xdd, 0xb0, 0xb8, 0x43, -0x18, 0x59, 0xd5, 0x80, 0xc7, 0x63, 0x44, 0x89, -0x60, 0xaf, 0x7d, 0x45, 0x7d, 0xb1, 0xbb, 0x17, -0x16, 0xc5, 0x7a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x1d, 0x01, 0x22, 0x21, 0x14, 0x2d, 0xa4, -0xee, 0x08, 0xd5, 0x37, 0x4f, 0xf1, 0x7f, 0xe1, -0x8e, 0x85, 0x87, 0x39, 0x9b, 0x28, 0x5a, 0x34, -0x05, 0x28, 0x80, 0x3b, 0x1f, 0xd2, 0xb9, 0xca, -0x12, 0x7e, 0xa4, 0x44, 0x8c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0x1a, -0xdf, 0x31, 0x4d, 0xb5, 0x50, 0x80, 0x8b, 0x30, -0x55, 0xab, 0xff, 0x56, 0x9d, 0x0e, 0xd9, 0xb4, -0x91, 0x38, 0x43, 0x0c, 0xa1, 0xf0, 0x93, 0xb2, -0x3f, 0xab, 0x42, 0x80, 0x4d, 0x96, 0xe6, 0x00, +0x21, 0xf1, 0x8b, 0x42, 0x39, 0xab, 0x8d, 0xba, +0xa5, 0x41, 0xb9, 0x77, 0x00, 0x97, 0x96, 0x80, +0x6e, 0x30, 0x41, 0xb0, 0x96, 0x3a, 0x5d, 0xca, +0xe0, 0x97, 0x3b, 0x60, 0x26, 0x37, 0x32, 0x7b, +0x6a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, +0x01, 0x22, 0x21, 0xa2, 0xee, 0x28, 0x04, 0x20, +0x34, 0xbb, 0x55, 0x1c, 0xd8, 0xf8, 0x92, 0x3c, +0x1f, 0x07, 0xac, 0xc7, 0x28, 0x0d, 0x2c, 0x06, +0xd7, 0x01, 0x26, 0xa1, 0x87, 0x9d, 0x90, 0x2d, +0xd8, 0x03, 0xa0, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x1d, 0x01, 0x22, 0x21, 0xb8, 0x5b, 0x20, +0x7c, 0xfd, 0x55, 0x21, 0x12, 0x50, 0xec, 0x5f, +0x12, 0x85, 0xbb, 0x3a, 0xaf, 0xa6, 0xc9, 0x56, +0x8e, 0x6e, 0x3c, 0x5a, 0x6d, 0x43, 0xf2, 0xde, +0x61, 0x12, 0x32, 0x4f, 0xfd, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0x99, +0xb2, 0x15, 0xdb, 0x67, 0xcd, 0x9e, 0x92, 0xe9, +0x54, 0x7b, 0x1f, 0xcc, 0xc6, 0xbd, 0xd8, 0xff, +0x1d, 0xc6, 0xa8, 0x3b, 0x1d, 0x6b, 0x9e, 0x68, +0xa8, 0x3a, 0x2d, 0x6a, 0xe4, 0x4b, 0x44, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1f, 0x01, 0x22, -0x21, 0xdb, 0x0c, 0x9d, 0xb0, 0x16, 0xad, 0xa5, -0xc2, 0x2d, 0x54, 0x4a, 0x03, 0x51, 0x57, 0xe9, -0xcd, 0x06, 0x99, 0x51, 0x40, 0x10, 0x55, 0xbf, -0x51, 0xbc, 0x8d, 0x57, 0x3b, 0x6a, 0x46, 0x27, -0x09, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, -0x01, 0x22, 0x21, 0x13, 0x58, 0x83, 0x68, 0x61, -0x90, 0x31, 0x33, 0x12, 0x86, 0x58, 0xb8, 0xdc, -0x84, 0x29, 0xcd, 0x00, 0xee, 0x8a, 0x87, 0x9a, -0x3d, 0x46, 0xa3, 0x45, 0x6a, 0x1b, 0xe3, 0x0f, -0x41, 0x8f, 0xdf, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x21, 0x01, 0x22, 0x21, 0x3e, 0x5a, 0xb8, -0x58, 0xf7, 0xe7, 0x49, 0xb3, 0x30, 0x6a, 0x7a, -0xbb, 0x26, 0x1c, 0x29, 0xfb, 0x93, 0x3c, 0x7e, -0x36, 0xb8, 0x4c, 0x47, 0x09, 0x0b, 0xb1, 0x40, -0xd8, 0xf3, 0x35, 0x9d, 0x1c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0x57, -0x1f, 0xb8, 0x77, 0x4a, 0xe9, 0xc4, 0x64, 0x8c, -0x93, 0xde, 0xee, 0x2c, 0x91, 0x4d, 0xc1, 0x6c, -0x9e, 0xca, 0x5b, 0x68, 0x43, 0x88, 0xbb, 0xae, -0x97, 0x95, 0xcf, 0xcf, 0xca, 0x66, 0x84, 0x00, +0x21, 0x2e, 0xe4, 0x86, 0x24, 0xa0, 0xe1, 0xb5, +0x43, 0x68, 0xa1, 0x6f, 0xa0, 0x98, 0xad, 0x60, +0x90, 0x4e, 0xdf, 0x24, 0x9c, 0x25, 0xd2, 0x76, +0x30, 0xae, 0xa6, 0xce, 0xfc, 0x72, 0x38, 0xa4, +0xe8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, +0x01, 0x22, 0x21, 0x20, 0x2e, 0x75, 0xd0, 0x63, +0x33, 0x3e, 0x58, 0x73, 0x5c, 0x82, 0x77, 0x53, +0x57, 0x6c, 0xd4, 0x06, 0xae, 0x67, 0xa3, 0x3e, +0x61, 0xc8, 0xbd, 0x62, 0xf4, 0x56, 0x96, 0x6e, +0x22, 0x8c, 0x6d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x21, 0x01, 0x22, 0x21, 0x48, 0xfe, 0x45, +0x47, 0x51, 0xf6, 0x0d, 0x88, 0x8d, 0x7d, 0x3c, +0x8a, 0xe4, 0x33, 0x6f, 0x6e, 0x44, 0x95, 0xc5, +0x48, 0xd3, 0xd7, 0x52, 0xed, 0x92, 0xf8, 0xd4, +0x06, 0xab, 0x13, 0x03, 0x30, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0xc0, +0xf9, 0x3d, 0x66, 0xc8, 0x7c, 0x71, 0xcf, 0x0f, +0xfc, 0x98, 0x1d, 0x06, 0xde, 0x0b, 0x5d, 0x7a, +0x50, 0xea, 0x10, 0x4f, 0x9a, 0xcc, 0xa4, 0xe6, +0xf1, 0xe1, 0x05, 0xc5, 0x57, 0x42, 0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x23, 0x01, 0x22, -0x21, 0xc7, 0x78, 0x7a, 0x3b, 0xd3, 0xfb, 0xf7, -0x82, 0xbe, 0x67, 0x0f, 0xa4, 0x59, 0x0a, 0x5a, -0xd3, 0xb4, 0x6b, 0x2c, 0xae, 0x31, 0x4c, 0x41, -0x7c, 0x96, 0x0a, 0xc1, 0x80, 0x28, 0xdf, 0x78, -0xe6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, -0x01, 0x22, 0x21, 0x39, 0x99, 0x41, 0x8b, 0x7d, -0x56, 0xd1, 0x25, 0x2d, 0x02, 0x7e, 0xb0, 0x30, -0xf0, 0xc7, 0xfe, 0xd7, 0x9f, 0xdb, 0x2e, 0xbc, -0xdb, 0xea, 0xfa, 0x9d, 0xee, 0x59, 0x0d, 0x99, -0x34, 0x3b, 0xcf, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x25, 0x01, 0x22, 0x21, 0x6f, 0xfc, 0x8d, -0x4d, 0x02, 0xae, 0xf8, 0xbc, 0xc5, 0x2a, 0x6e, -0xdd, 0x1a, 0x9a, 0x3f, 0x8a, 0x45, 0x2b, 0xd7, -0x28, 0xe3, 0x35, 0xc7, 0x9c, 0x2f, 0x8c, 0x73, -0x36, 0x92, 0xa3, 0xb5, 0x95, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0xbd, -0xf9, 0x35, 0x1e, 0xb6, 0xc2, 0xb3, 0xa1, 0x85, -0x04, 0x62, 0x09, 0x39, 0xaf, 0xbb, 0x3b, 0x36, -0x63, 0x08, 0x02, 0x9b, 0x9e, 0xd1, 0xec, 0xa5, -0x42, 0x13, 0xb5, 0xb4, 0xf1, 0x0d, 0x38, 0x00, +0x21, 0x9d, 0xc3, 0x01, 0xa9, 0x55, 0xb9, 0xe2, +0x5c, 0x0e, 0x16, 0xd3, 0xa4, 0x55, 0xf2, 0x8a, +0x72, 0x2d, 0x8e, 0x00, 0x82, 0x74, 0x21, 0x51, +0x17, 0x72, 0xbe, 0xa6, 0x1e, 0x35, 0x3c, 0xfd, +0x64, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, +0x01, 0x22, 0x21, 0x19, 0x3b, 0x69, 0xad, 0x75, +0x49, 0x54, 0x85, 0x99, 0xba, 0x4f, 0x92, 0xb6, +0x32, 0x1d, 0x95, 0xcb, 0x87, 0x79, 0xf8, 0x51, +0xcc, 0x1f, 0x5a, 0xd9, 0x68, 0x6c, 0xaf, 0xa1, +0x62, 0x29, 0x22, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x25, 0x01, 0x22, 0x21, 0x82, 0x07, 0x29, +0xaf, 0xa3, 0xe6, 0xbd, 0x8b, 0xbe, 0xae, 0x0d, +0xdd, 0x68, 0x6a, 0xe5, 0x07, 0x0d, 0x5d, 0x67, +0xe1, 0x82, 0xc2, 0x6f, 0xd2, 0xd1, 0x04, 0x35, +0xa8, 0x50, 0x3c, 0x15, 0x6c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0xb5, +0x8d, 0xaf, 0xe6, 0x8e, 0xc0, 0x41, 0x4a, 0xf9, +0x0c, 0xf4, 0xe3, 0x2f, 0x1c, 0x1e, 0x1d, 0x39, +0x4b, 0x28, 0x02, 0xb2, 0x22, 0x65, 0x16, 0x80, +0xb8, 0x61, 0x1c, 0xa5, 0x67, 0x24, 0xd1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x27, 0x01, 0x22, -0x21, 0xdf, 0x7e, 0x2c, 0xee, 0x2d, 0x1a, 0xe9, -0x07, 0x04, 0xfc, 0x8d, 0xac, 0x18, 0xba, 0xad, -0x00, 0x4d, 0x20, 0xd1, 0x05, 0x9b, 0xf7, 0x18, -0x8a, 0x20, 0x83, 0xad, 0xff, 0x04, 0x3d, 0x9a, +0x21, 0xf2, 0xf7, 0xad, 0xfd, 0x86, 0x93, 0xf8, +0x0b, 0x06, 0x4b, 0xcb, 0x1d, 0xe7, 0xcb, 0x28, +0xb8, 0x10, 0xed, 0x67, 0xdd, 0x84, 0x3b, 0xb5, +0xfb, 0x34, 0xf3, 0x36, 0xce, 0x83, 0x29, 0x91, 0x56, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, -0x01, 0x22, 0x21, 0x43, 0x49, 0x17, 0x75, 0xae, -0xdd, 0x3c, 0x59, 0xcb, 0xb4, 0xea, 0xa2, 0x71, -0x66, 0x65, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x9e, 0xfd, 0xb7, 0x6e, -0x85, 0xfc, 0x3d, 0xd6, 0x03, 0x04, 0x51, 0x02, -0x00, 0x29, 0x01, 0x22, 0x21, 0x1b, 0x31, 0x77, -0x94, 0x7c, 0x89, 0x40, 0xd6, 0xcd, 0x9c, 0x95, -0x9d, 0x8b, 0xfc, 0x67, 0xd5, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x58, -0xe8, 0x31, 0x8b, 0x01, 0xa9, 0x3a, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x41, -0xf5, 0x20, 0x20, 0x46, 0xb2, 0x7d, 0x7d, 0xe8, -0x1b, 0x02, 0x81, 0x32, 0xc3, 0x1d, 0xe0, 0x3c, -0x6e, 0x20, 0x93, 0x31, 0xaf, 0x3f, 0xd9, 0x3b, -0x23, 0xff, 0x50, 0x40, 0xe9, 0xb7, 0x61, 0x00, +0x01, 0x22, 0x21, 0xc6, 0xf7, 0x8d, 0xb4, 0xc3, +0xc7, 0x8e, 0x26, 0xd3, 0xca, 0x29, 0x76, 0x21, +0x09, 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xf5, 0xd0, 0x11, 0x64, +0x1c, 0x14, 0x2a, 0x0b, 0x03, 0x04, 0x51, 0x02, +0x00, 0x29, 0x01, 0x22, 0x21, 0x23, 0x86, 0x8b, +0xea, 0x25, 0xcb, 0xca, 0x9a, 0x53, 0x08, 0x0c, +0x8a, 0x0e, 0x4f, 0xe3, 0x05, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x0d, +0x72, 0xde, 0x23, 0x0b, 0xc5, 0x12, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x6c, +0x30, 0x74, 0x0f, 0x2d, 0x39, 0x3d, 0x1d, 0x44, +0xe5, 0x61, 0x1e, 0xd8, 0xd2, 0x15, 0x75, 0x3e, +0x7e, 0x9f, 0x3d, 0x3f, 0xde, 0x4f, 0x14, 0x63, +0x0c, 0xaa, 0xfa, 0x93, 0x12, 0x9f, 0xd3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2b, 0x01, 0x22, -0x21, 0x75, 0x7d, 0xe4, 0x4c, 0x7f, 0xd7, 0xcc, -0x4c, 0x3e, 0x97, 0x43, 0x9a, 0x1d, 0xbb, 0x4f, -0x11, 0x94, 0x48, 0x7f, 0x6c, 0x56, 0x0a, 0xaf, -0x44, 0x13, 0x67, 0xf5, 0xd1, 0xcb, 0x8c, 0xb4, -0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, -0x01, 0x22, 0x21, 0x0f, 0x48, 0x90, 0xcf, 0x80, -0x0e, 0xcf, 0xcf, 0x10, 0x51, 0x33, 0x08, 0x6c, -0x52, 0xff, 0xf0, 0x9a, 0x84, 0x16, 0x19, 0xe7, -0xf1, 0x1a, 0x9c, 0xf7, 0xff, 0x11, 0xab, 0x2e, -0x35, 0x94, 0xd1, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x2d, 0x01, 0x22, 0x21, 0x62, 0xd8, 0xf9, -0x23, 0x9c, 0x88, 0x29, 0xa0, 0x1d, 0xc8, 0x47, -0x5e, 0xea, 0x7d, 0x82, 0xf5, 0x64, 0x1c, 0x48, -0x1c, 0x6d, 0xf9, 0xbc, 0x19, 0x35, 0x4d, 0x90, -0x30, 0x75, 0x5b, 0x71, 0xf8, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0x1b, -0x23, 0xb0, 0xe5, 0x17, 0x7f, 0x2f, 0x93, 0xcc, -0x80, 0xab, 0xae, 0xed, 0xe8, 0x1b, 0x2c, 0x59, -0x0f, 0x6e, 0xbe, 0x47, 0x32, 0x30, 0xc8, 0xae, -0x0e, 0x9d, 0xe0, 0x84, 0xe5, 0x35, 0xbb, 0x00, +0x21, 0x03, 0x04, 0x77, 0x15, 0xbc, 0x39, 0x8f, +0x5e, 0x7d, 0x38, 0x41, 0x42, 0x3c, 0x26, 0xba, +0x26, 0xe0, 0xbd, 0x9b, 0x55, 0xd5, 0x6e, 0x20, +0x8e, 0x12, 0x86, 0x4a, 0x1c, 0xcc, 0x59, 0x0a, +0xfc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, +0x01, 0x22, 0x21, 0x08, 0x9d, 0xc9, 0xc2, 0x80, +0xb2, 0xc6, 0x8a, 0x9e, 0x26, 0x41, 0xd6, 0x28, +0x9a, 0x22, 0xf4, 0xc9, 0x8f, 0x3e, 0x86, 0x2f, +0x32, 0x44, 0xed, 0xe0, 0xaa, 0xff, 0x57, 0xcd, +0xd6, 0x73, 0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x2d, 0x01, 0x22, 0x21, 0xfc, 0xa8, 0xac, +0x88, 0x60, 0x40, 0x87, 0x34, 0x4e, 0x79, 0x59, +0xcf, 0x05, 0x8d, 0x9c, 0xc0, 0x9b, 0x31, 0x7f, +0xf4, 0x05, 0x5a, 0x0e, 0x49, 0x2a, 0x5a, 0x5d, +0xdc, 0x34, 0x9f, 0xdd, 0x28, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0xb4, +0x8a, 0xf0, 0x37, 0x21, 0xe5, 0x35, 0x8c, 0x89, +0xf9, 0x21, 0xa3, 0x29, 0x52, 0xb9, 0xe1, 0x17, +0x26, 0xb8, 0x49, 0xb3, 0x3e, 0xa3, 0xcd, 0xb9, +0x57, 0xee, 0xd3, 0x7e, 0x35, 0x5f, 0x00, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2f, 0x01, 0x22, -0x21, 0xdc, 0xee, 0x52, 0x2d, 0xd0, 0xbe, 0x2a, -0x0f, 0x3f, 0x21, 0x74, 0xc0, 0xdc, 0x6a, 0xa1, -0x6d, 0xe3, 0x60, 0xaf, 0xfe, 0xab, 0xfc, 0x10, -0xc9, 0x3d, 0x24, 0x1c, 0x6a, 0xca, 0x1f, 0xa6, -0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, -0x01, 0x22, 0x21, 0x09, 0xe3, 0x77, 0x59, 0x6c, -0xbe, 0x32, 0x8a, 0x94, 0x4f, 0xb2, 0xa2, 0x94, -0xd7, 0xdc, 0x34, 0xe9, 0x09, 0x68, 0xb1, 0x22, -0x88, 0xbe, 0x31, 0x91, 0x20, 0x11, 0x0d, 0xcd, -0x2c, 0x55, 0x39, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x31, 0x01, 0x22, 0x21, 0x92, 0xdd, 0x2a, -0x43, 0x8b, 0x09, 0x3e, 0xec, 0x4d, 0xa9, 0x3f, -0xb1, 0xfd, 0xd7, 0x5d, 0x54, 0xec, 0x41, 0x0b, -0x67, 0x8d, 0xb3, 0x27, 0xe3, 0x6f, 0x66, 0x21, -0x4a, 0x87, 0xa0, 0xc7, 0x78, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0x04, -0x9d, 0xbc, 0x87, 0x70, 0xe9, 0x34, 0x83, 0x02, -0x7e, 0x29, 0x37, 0x54, 0xdd, 0x68, 0xa6, 0x7a, -0xdd, 0xc7, 0xf5, 0x4f, 0x90, 0x83, 0x5c, 0xc0, -0x76, 0x73, 0x75, 0xff, 0x82, 0x2d, 0xe3, 0x00, +0x21, 0x74, 0x55, 0x7b, 0x6c, 0xb4, 0xb9, 0x53, +0x0a, 0xdd, 0x68, 0x76, 0x28, 0xe4, 0xe6, 0x81, +0xc3, 0x2a, 0xa7, 0x52, 0x0d, 0x6d, 0x76, 0xa8, +0xf7, 0x23, 0xd1, 0x9f, 0x28, 0x0c, 0xc4, 0x8f, +0xdc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, +0x01, 0x22, 0x21, 0x56, 0xfb, 0x9f, 0x73, 0xd9, +0x31, 0x43, 0x76, 0x80, 0x4d, 0x9d, 0x65, 0xa5, +0x3b, 0xa2, 0xf1, 0xd4, 0x32, 0xa8, 0x32, 0x93, +0x61, 0xa7, 0x3f, 0x31, 0x8a, 0x0f, 0xdd, 0x66, +0xee, 0x29, 0xdc, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x31, 0x01, 0x22, 0x21, 0x02, 0x0d, 0x98, +0xe3, 0xc8, 0xed, 0xc6, 0x9b, 0x13, 0x5b, 0xf3, +0x59, 0xb9, 0x55, 0xfc, 0x1d, 0xfd, 0x06, 0xa9, +0xd2, 0x11, 0xc0, 0x3c, 0xe3, 0x75, 0xad, 0x1f, +0x54, 0xfd, 0xb9, 0x8e, 0x2e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0xb4, +0xf7, 0xd7, 0x5e, 0x9f, 0x5a, 0x72, 0xd3, 0x42, +0xe3, 0x6e, 0xaf, 0x6c, 0x90, 0xd8, 0x6e, 0xd0, +0xd2, 0x51, 0xfc, 0xe4, 0xdc, 0x54, 0xda, 0x5f, +0xeb, 0xb8, 0x56, 0x75, 0x38, 0x6c, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x33, 0x01, 0x22, -0x21, 0x8a, 0x12, 0x0f, 0x61, 0xd7, 0x6f, 0xf8, -0x3d, 0xb4, 0xa4, 0xc7, 0x7b, 0x47, 0xba, 0xb4, -0x39, 0x1c, 0xe5, 0x16, 0x2e, 0x56, 0xa4, 0x76, -0x2c, 0x86, 0xaa, 0xfa, 0xa1, 0x5e, 0x3b, 0x15, -0xa8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, -0x01, 0x22, 0x21, 0xd3, 0xfd, 0x99, 0xb2, 0xd5, -0xe6, 0x13, 0xeb, 0xf9, 0xbf, 0xcd, 0x79, 0x05, -0xce, 0x8e, 0xa9, 0xbb, 0x82, 0xa5, 0x07, 0xc7, -0x9b, 0xb4, 0x20, 0xd8, 0x00, 0xe3, 0x6f, 0x20, -0xe0, 0xa1, 0x0b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x35, 0x01, 0x22, 0x21, 0x06, 0x35, 0x6d, -0x13, 0x62, 0x94, 0x80, 0x0a, 0xdf, 0xe8, 0x83, -0x47, 0x50, 0x06, 0xf1, 0xe1, 0xe1, 0xf0, 0x32, -0xd2, 0x59, 0xc1, 0x64, 0x12, 0x38, 0xa2, 0xba, -0x2c, 0x28, 0xe4, 0xad, 0x80, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0x03, -0x40, 0x6a, 0xcf, 0x52, 0xae, 0x72, 0x8b, 0xa0, -0x77, 0xb1, 0x40, 0x7a, 0x40, 0xcd, 0x3d, 0x48, -0x7a, 0x43, 0x56, 0xe1, 0x2a, 0x67, 0x70, 0x02, -0x1a, 0xab, 0x7d, 0x2a, 0xb2, 0xee, 0x73, 0x00, +0x21, 0xda, 0x04, 0xbc, 0xd5, 0x04, 0xb5, 0x96, +0xe6, 0x66, 0x96, 0xb7, 0xcf, 0x41, 0x85, 0x2f, +0x88, 0xba, 0x8e, 0x07, 0x8a, 0x43, 0xda, 0x8c, +0x93, 0x65, 0x94, 0xd2, 0x21, 0xd9, 0xa7, 0x8f, +0x2f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, +0x01, 0x22, 0x21, 0x04, 0x46, 0xf9, 0x17, 0x12, +0xb0, 0x0d, 0xb1, 0xdf, 0xc4, 0x87, 0xe4, 0x9c, +0x42, 0x30, 0x94, 0xd2, 0xd0, 0x78, 0xf7, 0xa1, +0x33, 0xc1, 0xfe, 0xce, 0x8a, 0x97, 0x98, 0x9c, +0x2e, 0xaa, 0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x35, 0x01, 0x22, 0x21, 0xf7, 0x45, 0xe1, +0xbb, 0xdc, 0x19, 0x11, 0x44, 0xc2, 0x9b, 0x53, +0x48, 0xfe, 0x1e, 0x94, 0xd5, 0x68, 0xbe, 0x04, +0xaf, 0x75, 0xae, 0xea, 0x51, 0x49, 0x50, 0x4f, +0x71, 0xe3, 0xb5, 0xa1, 0x36, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0x99, +0x9f, 0x51, 0x90, 0x62, 0xe6, 0x19, 0xcf, 0xe2, +0x32, 0x47, 0x34, 0xcb, 0xbe, 0x61, 0xb4, 0xbc, +0xf0, 0x31, 0x1e, 0xd4, 0x2f, 0x62, 0xdb, 0x8c, +0x77, 0x45, 0x53, 0x47, 0xd0, 0x44, 0x47, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x37, 0x01, 0x22, -0x21, 0x6b, 0x47, 0x6d, 0xb4, 0xfa, 0x1f, 0x32, -0x45, 0xb0, 0xaf, 0x65, 0xf4, 0xff, 0x77, 0xe6, -0xc5, 0x1e, 0xd9, 0x23, 0xcd, 0x05, 0xa7, 0xd2, -0x46, 0xb9, 0x66, 0x89, 0xb3, 0x53, 0x9f, 0xa5, -0xb4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, -0x01, 0x22, 0x21, 0x35, 0x88, 0x34, 0x92, 0xeb, -0x0c, 0xe1, 0x26, 0x0c, 0x5a, 0x30, 0x10, 0x34, -0xac, 0x27, 0xc3, 0x98, 0x82, 0x2a, 0xcc, 0x85, -0x73, 0xbd, 0x8e, 0x48, 0x71, 0x72, 0xe8, 0x74, -0x40, 0x2b, 0x43, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x39, 0x01, 0x22, 0x21, 0xf9, 0x7b, 0x0a, -0xf7, 0xc4, 0xb5, 0x3d, 0x0e, 0x5e, 0x70, 0x07, -0xa1, 0xf5, 0xd0, 0x69, 0x5c, 0xb1, 0x1c, 0xc0, -0x1f, 0xa0, 0x41, 0xd1, 0xa9, 0xb0, 0x50, 0x6e, -0xbd, 0x04, 0x61, 0xec, 0x85, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0xeb, -0x13, 0xca, 0x43, 0x54, 0xb3, 0xde, 0xb9, 0x81, -0x8c, 0x31, 0x5e, 0x9f, 0xb0, 0x8c, 0x28, 0x8b, -0xf7, 0xe5, 0x2b, 0xfa, 0x43, 0xde, 0x4e, 0xb8, -0x7a, 0x12, 0x93, 0xa5, 0x76, 0x69, 0x41, 0x00, +0x21, 0xcc, 0x29, 0x62, 0x36, 0xcd, 0xf2, 0x2b, +0x3a, 0x50, 0xad, 0x13, 0xae, 0xd7, 0xea, 0xc5, +0x27, 0xa0, 0xf1, 0x83, 0xd4, 0xe7, 0x41, 0x0d, +0x59, 0x63, 0xf2, 0x56, 0xa1, 0x3d, 0x34, 0x4f, +0xd8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, +0x01, 0x22, 0x21, 0x7d, 0x7a, 0xb5, 0xdd, 0x1b, +0x6a, 0xd1, 0xe8, 0xfb, 0xfa, 0x24, 0x74, 0x60, +0x94, 0xdb, 0x38, 0xfa, 0xc2, 0x98, 0x45, 0x37, +0x13, 0xde, 0x24, 0xbc, 0x2c, 0x3c, 0x82, 0x0f, +0x33, 0x50, 0xf0, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x39, 0x01, 0x22, 0x21, 0xf7, 0x33, 0x66, +0xe1, 0x92, 0x25, 0x55, 0x67, 0x32, 0x7c, 0x03, +0x09, 0x7b, 0xaa, 0x10, 0x1e, 0x11, 0x45, 0xa9, +0x93, 0xdb, 0x4f, 0x37, 0xb3, 0xf2, 0xf2, 0x15, +0x0e, 0xe5, 0x3a, 0xa0, 0xfa, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0x95, +0x79, 0x8d, 0x05, 0xda, 0x3d, 0x23, 0xec, 0xe5, +0x54, 0x9c, 0x6c, 0xea, 0x7d, 0x5b, 0x4e, 0x1d, +0x4d, 0xb1, 0x90, 0x47, 0xc0, 0xa2, 0x86, 0xbb, +0x0f, 0xad, 0x56, 0xe7, 0xc3, 0x17, 0x6c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3b, 0x01, 0x22, -0x21, 0x14, 0xda, 0x1e, 0x85, 0x58, 0x1c, 0x8f, -0xd0, 0x1a, 0x14, 0xa8, 0xae, 0x57, 0x9c, 0x6b, -0xbe, 0xd4, 0xe0, 0x4c, 0x6f, 0x40, 0x00, 0x8a, -0x75, 0xe1, 0xcb, 0xff, 0xf5, 0x7e, 0x61, 0x9f, -0x82, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, -0x01, 0x22, 0x21, 0x2b, 0x8c, 0x94, 0x7c, 0x8b, -0x75, 0x88, 0x81, 0x3c, 0x1b, 0x28, 0x17, 0x29, -0xe0, 0x61, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x3b, 0xbf, 0x3a, 0xe6, -0x6a, 0x54, 0x62, 0xae, 0x03, 0x04, 0x51, 0x02, -0x00, 0x3d, 0x01, 0x22, 0x21, 0xa7, 0x58, 0x72, -0x68, 0x09, 0x9f, 0xbf, 0x90, 0xcb, 0x24, 0x3b, -0x70, 0xac, 0xfd, 0x7e, 0xc7, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xbf, -0xa0, 0xba, 0x17, 0xf3, 0xe7, 0x93, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0x5d, -0x30, 0xb9, 0xea, 0xfa, 0xf1, 0x90, 0x5c, 0x53, -0x03, 0x3c, 0xa8, 0x91, 0xc0, 0x15, 0x34, 0x51, -0x9a, 0x42, 0x28, 0x4a, 0x05, 0x29, 0x05, 0xca, -0xa2, 0xa1, 0xc1, 0x23, 0x4d, 0x34, 0x19, 0x00, +0x21, 0x36, 0x84, 0x27, 0x89, 0xd7, 0x60, 0x1c, +0xae, 0xf1, 0xd3, 0x0c, 0x15, 0x82, 0x45, 0x41, +0x4d, 0x63, 0xbe, 0xbd, 0x65, 0x39, 0x74, 0x56, +0x12, 0x08, 0xde, 0xd3, 0x8c, 0x06, 0x88, 0x04, +0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, +0x01, 0x22, 0x21, 0x00, 0xf6, 0xb5, 0xd0, 0xaa, +0x8f, 0x85, 0xee, 0x34, 0x2f, 0xb9, 0xcf, 0x02, +0xed, 0xd4, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xf8, 0x35, 0x55, 0x26, +0xba, 0xb2, 0x7b, 0x0e, 0x03, 0x04, 0x51, 0x02, +0x00, 0x3d, 0x01, 0x22, 0x21, 0x7c, 0xd8, 0x78, +0x90, 0x72, 0x20, 0x32, 0x38, 0x82, 0x37, 0x02, +0x8e, 0x52, 0xf8, 0x5f, 0xd0, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xdd, +0xeb, 0x74, 0x79, 0x9c, 0xf6, 0x6c, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0xd2, +0xaf, 0xa1, 0xd4, 0x1c, 0xce, 0x27, 0x30, 0xbb, +0x71, 0x7d, 0x18, 0x35, 0x7e, 0xef, 0xb0, 0x60, +0x08, 0x54, 0x00, 0x4a, 0xd1, 0x4f, 0x6e, 0x4d, +0x91, 0x45, 0xa6, 0xa6, 0xdf, 0x2f, 0x86, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3f, 0x01, 0x22, -0x21, 0x47, 0x5a, 0x20, 0x18, 0x03, 0x24, 0xf9, -0x25, 0x9e, 0x1b, 0xd1, 0x4d, 0x96, 0x47, 0x81, -0xa3, 0xdd, 0x42, 0x41, 0x65, 0xe6, 0xc3, 0xee, -0xeb, 0xc7, 0x27, 0x59, 0xe7, 0xf3, 0xfb, 0xa9, -0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, -0x01, 0x22, 0x21, 0xbf, 0x92, 0x11, 0x6c, 0x5b, -0xa6, 0xc2, 0xe7, 0x43, 0x95, 0x12, 0x24, 0x66, -0xe1, 0xa3, 0x0f, 0x72, 0xfd, 0x3e, 0xbc, 0x42, -0x3f, 0xd2, 0x5f, 0x0f, 0xcb, 0x9f, 0x13, 0x14, -0xe0, 0xca, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x41, 0x01, 0x22, 0x21, 0x04, 0xe4, 0x1d, -0xc1, 0x54, 0x42, 0x85, 0x94, 0x4d, 0x53, 0x95, -0x7e, 0xcd, 0x37, 0xc4, 0x77, 0x02, 0xca, 0xb7, -0x69, 0x4c, 0xb2, 0x1e, 0xfe, 0x48, 0x86, 0xa8, -0xf1, 0x3f, 0x1c, 0xf7, 0x14, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0x47, -0xff, 0xce, 0x94, 0xd0, 0xe7, 0x35, 0xa7, 0x8a, -0x64, 0xfa, 0x50, 0x5a, 0x1a, 0xb8, 0xfd, 0xba, -0x55, 0xca, 0xfa, 0xcf, 0x70, 0x01, 0xe6, 0xb5, -0xfb, 0x6b, 0x9a, 0xbc, 0x27, 0x13, 0xee, 0x00, +0x21, 0xb6, 0x1c, 0x1d, 0x2b, 0x48, 0x77, 0xc6, +0x94, 0xab, 0xc3, 0x12, 0x3d, 0x0d, 0x3b, 0x68, +0x5a, 0x9e, 0x5a, 0x1c, 0x73, 0xe5, 0x20, 0x17, +0x20, 0xe7, 0x86, 0x79, 0x0a, 0x20, 0xdf, 0x4e, +0x35, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, +0x01, 0x22, 0x21, 0xb7, 0xb1, 0x2b, 0x7d, 0x71, +0x38, 0xc5, 0x1e, 0x88, 0x54, 0xd9, 0x44, 0x11, +0xdd, 0x70, 0x87, 0x80, 0x81, 0xe7, 0xe4, 0x76, +0x0d, 0x43, 0x0e, 0x5e, 0x32, 0x5b, 0x40, 0x70, +0x72, 0xeb, 0xd1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x41, 0x01, 0x22, 0x21, 0x86, 0x42, 0x42, +0x50, 0x1a, 0xc7, 0x42, 0x2a, 0x63, 0x80, 0xaf, +0x8b, 0xa1, 0x97, 0xec, 0x0e, 0x14, 0x2a, 0xe0, +0x79, 0x63, 0x8d, 0x32, 0xd4, 0xaa, 0x6a, 0x25, +0x76, 0x7d, 0x64, 0x5b, 0x38, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0x4f, +0xa7, 0xd8, 0x53, 0x8f, 0x2e, 0xa5, 0x2d, 0xfd, +0xdf, 0x0d, 0x4f, 0xaa, 0x63, 0x89, 0x82, 0x09, +0x0f, 0x6c, 0xff, 0x1d, 0x7e, 0xcb, 0x4c, 0xa6, +0x73, 0xdc, 0xb2, 0xa1, 0x64, 0x51, 0xc5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x43, 0x01, 0x22, -0x21, 0x63, 0x0b, 0x46, 0xc3, 0xad, 0xd7, 0x28, -0x21, 0xc2, 0xd3, 0x4d, 0x95, 0xeb, 0xfb, 0x44, -0xf4, 0x3e, 0x87, 0xdb, 0x43, 0x1b, 0xc2, 0x61, -0x36, 0xf1, 0xba, 0x61, 0x0d, 0xed, 0xf7, 0xf2, -0x3a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, -0x01, 0x22, 0x21, 0xbf, 0xf0, 0x3b, 0xb3, 0x3f, -0x66, 0x3d, 0x61, 0x33, 0x47, 0x58, 0x5a, 0x2d, -0x6e, 0xfd, 0x83, 0x41, 0x5c, 0x73, 0x5c, 0x41, -0x21, 0x5e, 0x6a, 0x0f, 0x1c, 0x7d, 0x8d, 0xaf, -0x14, 0x38, 0x4f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x45, 0x01, 0x22, 0x21, 0x23, 0x5a, 0x6c, -0x4f, 0x4c, 0x55, 0x41, 0x7c, 0xc6, 0xf8, 0x5e, -0xf2, 0x4a, 0x45, 0x4f, 0x4b, 0x0d, 0x51, 0x3b, -0xbb, 0xe5, 0x5b, 0x74, 0x67, 0x9b, 0xa2, 0xf6, -0x5a, 0xc3, 0x17, 0xe3, 0x65, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0xec, -0x76, 0x32, 0x27, 0x05, 0xbd, 0x23, 0xc1, 0xcd, -0xe0, 0x93, 0x2f, 0xda, 0x30, 0x43, 0x3a, 0x3c, -0xdc, 0x1d, 0xcd, 0xd9, 0x0b, 0x98, 0xc1, 0x63, -0x1e, 0xd7, 0x9c, 0x24, 0x98, 0xda, 0xf5, 0x00, +0x21, 0x32, 0x5b, 0xd6, 0x5d, 0x35, 0x1c, 0xc7, +0xdd, 0x0e, 0x5e, 0x79, 0x06, 0xf6, 0x2b, 0x08, +0xc3, 0x49, 0xe2, 0x3e, 0x11, 0x3c, 0xa7, 0x2f, +0x6f, 0xd7, 0x3e, 0xac, 0x1d, 0x90, 0xe1, 0x70, +0x4a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, +0x01, 0x22, 0x21, 0x85, 0x0c, 0x4f, 0xe4, 0x51, +0xd5, 0x6c, 0xa6, 0x47, 0x9b, 0x11, 0x81, 0xca, +0x3c, 0x7b, 0xef, 0x13, 0x57, 0x7a, 0xc2, 0xa6, +0x1d, 0x32, 0xc3, 0x4e, 0x9a, 0xfe, 0x34, 0x57, +0x0b, 0x21, 0x47, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x45, 0x01, 0x22, 0x21, 0x33, 0x5f, 0x5d, +0xd6, 0x8e, 0x8e, 0x04, 0x0e, 0xe9, 0xc5, 0x2f, +0xef, 0xa0, 0xdd, 0x9a, 0x32, 0x1a, 0xbf, 0x2d, +0x2a, 0xde, 0x14, 0x5e, 0x54, 0x3f, 0x36, 0x28, +0x79, 0xea, 0xcd, 0x20, 0x59, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0xc8, +0x42, 0xe4, 0x60, 0x9c, 0x4a, 0xa1, 0x5e, 0x7f, +0x4b, 0x07, 0xce, 0x11, 0x55, 0x7a, 0x75, 0xbf, +0xc4, 0x09, 0x14, 0xc0, 0xf6, 0xac, 0xba, 0xd9, +0x9e, 0x31, 0xdc, 0xa6, 0x68, 0x03, 0x66, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x47, 0x01, 0x22, -0x21, 0xc3, 0x53, 0x0f, 0x97, 0x2c, 0x6e, 0x24, -0x1b, 0xa3, 0x51, 0x80, 0x8c, 0xc5, 0x86, 0xd2, -0x44, 0x83, 0x19, 0x7b, 0x47, 0x30, 0xda, 0x8e, -0x71, 0xdc, 0x10, 0xbf, 0x68, 0xe5, 0x09, 0x95, -0x67, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, -0x01, 0x22, 0x21, 0xa6, 0x29, 0x37, 0x38, 0x7c, -0xc3, 0x2a, 0x69, 0xad, 0xf1, 0x10, 0xc8, 0x49, -0xb6, 0x45, 0xc6, 0xba, 0xcd, 0xda, 0x21, 0xa8, -0x97, 0x82, 0xca, 0xab, 0x36, 0x60, 0xd8, 0x59, -0xa8, 0xe0, 0xad, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x49, 0x01, 0x22, 0x21, 0x8e, 0xe0, 0x03, -0x8a, 0x93, 0x64, 0x60, 0xda, 0x75, 0x8c, 0xfa, -0xa2, 0x8b, 0x23, 0x58, 0x7c, 0x44, 0x57, 0xbf, -0x0f, 0x1d, 0x90, 0xb4, 0x40, 0xd7, 0xd3, 0x6f, -0x81, 0xf4, 0x32, 0x97, 0xf1, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0x9b, -0x00, 0x45, 0x9f, 0xed, 0x80, 0x29, 0x99, 0xfa, -0x3f, 0x07, 0x68, 0xaa, 0x8f, 0xd0, 0x02, 0x25, -0x09, 0x17, 0xcb, 0xfc, 0x35, 0xc7, 0x80, 0xfc, -0x6c, 0xac, 0x89, 0x92, 0x7b, 0xe8, 0x58, 0x00, +0x21, 0xf3, 0xa0, 0x43, 0x19, 0x8c, 0x28, 0x8c, +0x95, 0xdb, 0xc4, 0xb5, 0xea, 0x18, 0xa8, 0xb1, +0xb7, 0x61, 0x1c, 0x30, 0x68, 0x0f, 0x7e, 0x13, +0x3d, 0x8a, 0xa9, 0x82, 0x8d, 0x9b, 0x83, 0x18, +0x09, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, +0x01, 0x22, 0x21, 0x6e, 0x60, 0xaa, 0xae, 0xc1, +0x18, 0xac, 0xc2, 0x4f, 0xa2, 0xa5, 0xb2, 0xc3, +0x44, 0x2b, 0xd0, 0xc5, 0x0e, 0x2d, 0x17, 0x05, +0x04, 0x5d, 0xe3, 0x9b, 0x48, 0x4b, 0x29, 0x15, +0xdf, 0xc3, 0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x49, 0x01, 0x22, 0x21, 0xfe, 0x32, 0xc9, +0x72, 0x00, 0x42, 0x0e, 0xae, 0x8f, 0xbd, 0xfe, +0xe4, 0x63, 0x65, 0xaf, 0x5e, 0x6a, 0x21, 0x63, +0x00, 0xea, 0x40, 0xbf, 0x57, 0x2b, 0x50, 0xd9, +0xcb, 0x3d, 0x2a, 0x12, 0xaa, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0x71, +0x16, 0x92, 0x62, 0xef, 0x12, 0xf5, 0x1c, 0x13, +0x49, 0x45, 0x7e, 0x42, 0x0a, 0xc0, 0x46, 0x47, +0xa9, 0xef, 0xe9, 0xda, 0x99, 0x96, 0x68, 0x46, +0xc1, 0x50, 0xe0, 0xff, 0x48, 0x11, 0x67, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4b, 0x01, 0x22, -0x21, 0xf5, 0x4d, 0x51, 0x15, 0x29, 0xe2, 0x13, -0x48, 0x98, 0xbf, 0x3e, 0x90, 0x85, 0x79, 0x46, -0xe3, 0x7b, 0xa7, 0x66, 0xb2, 0xd4, 0x7c, 0x11, -0x9b, 0xde, 0x9c, 0xfb, 0x53, 0x3d, 0x30, 0x09, -0x48, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, -0x01, 0x22, 0x21, 0xb8, 0xcc, 0xd3, 0x5f, 0x5a, -0xb4, 0x9c, 0x8a, 0x3b, 0x03, 0xc3, 0xf0, 0xed, -0xd8, 0x12, 0x22, 0xb8, 0xf5, 0xe0, 0xa5, 0x1b, -0x99, 0xc6, 0x23, 0x28, 0x87, 0x7a, 0xb2, 0x18, -0x59, 0x57, 0x6f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x4d, 0x01, 0x22, 0x21, 0x3a, 0xc8, 0xa8, -0xce, 0xa6, 0xc2, 0xc5, 0x1d, 0x06, 0xbd, 0xc3, -0x2d, 0x5a, 0x75, 0x6b, 0xed, 0x48, 0x34, 0xcb, -0xd1, 0xe6, 0x0b, 0x8a, 0xa5, 0xce, 0xfd, 0x37, -0x7a, 0x80, 0xd8, 0xbf, 0x51, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x64, -0x7f, 0x6e, 0x6d, 0x28, 0x94, 0xe3, 0xd3, 0xb1, -0xe7, 0x80, 0xe3, 0x01, 0x4b, 0x61, 0x0a, 0x58, -0xae, 0x59, 0x7c, 0xd8, 0x4c, 0x18, 0x06, 0xa4, -0xbc, 0x36, 0x8c, 0x19, 0x61, 0x97, 0xd4, 0x00, +0x21, 0x3a, 0xe5, 0x08, 0xe4, 0xfb, 0xf8, 0x06, +0x28, 0xcd, 0x67, 0xe6, 0x90, 0x6a, 0x33, 0x58, +0x9e, 0x92, 0x18, 0x88, 0x37, 0x51, 0x89, 0x3b, +0xa8, 0xce, 0xf8, 0x6a, 0x07, 0xa9, 0x6a, 0xa3, +0xca, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, +0x01, 0x22, 0x21, 0x64, 0xce, 0xa5, 0x8f, 0x43, +0x68, 0xd8, 0xe5, 0x8b, 0xbb, 0x25, 0x89, 0xcb, +0xdd, 0xbb, 0xf9, 0x44, 0x85, 0x30, 0x75, 0x42, +0xac, 0xf2, 0x06, 0xd4, 0x1a, 0xe3, 0x33, 0xfa, +0x39, 0xf3, 0xa7, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x4d, 0x01, 0x22, 0x21, 0x30, 0x63, 0x59, +0x1d, 0x89, 0xff, 0xcd, 0x23, 0x5e, 0xec, 0xfb, +0xa2, 0x17, 0xb7, 0xc2, 0xc9, 0x84, 0x5b, 0xb0, +0x4e, 0x40, 0x45, 0x06, 0x4b, 0x50, 0xc8, 0xe3, +0x9b, 0x27, 0xd1, 0xd1, 0x48, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0xb7, +0xc0, 0x25, 0x69, 0xf9, 0x4f, 0x5f, 0x7a, 0x74, +0x2f, 0xcf, 0x71, 0xc8, 0x81, 0x11, 0xb9, 0xd5, +0x37, 0xf3, 0x6b, 0x33, 0x81, 0xfa, 0x45, 0xc9, +0x82, 0xac, 0xe2, 0x74, 0x77, 0x3b, 0xdc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4f, 0x01, 0x22, -0x21, 0x0b, 0x76, 0x12, 0x5c, 0xd6, 0xd9, 0xbd, -0xd5, 0x23, 0x52, 0xc8, 0xc6, 0xb1, 0x25, 0x6c, -0xb3, 0xe6, 0x6c, 0xb1, 0x0a, 0x8f, 0xde, 0xb0, -0x50, 0xde, 0xb0, 0x23, 0xb2, 0x1b, 0x9c, 0xe7, -0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, -0x01, 0x22, 0x21, 0xd5, 0xd6, 0x2f, 0x1f, 0x8c, -0xaf, 0xdc, 0xd2, 0x72, 0x7a, 0xa3, 0x7f, 0x3d, -0x11, 0xf1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x44, 0x3e, 0x43, 0x17, -0x58, 0x66, 0xbf, 0x9e, 0x03, 0x04, 0x51, 0x02, -0x00, 0x51, 0x01, 0x22, 0x21, 0x8c, 0xcd, 0x0b, -0x1d, 0xd5, 0x9e, 0x0b, 0xd3, 0xb4, 0xfa, 0xa5, -0x83, 0xb3, 0x4a, 0xaf, 0x73, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x3a, -0x01, 0x27, 0x91, 0xe5, 0xfa, 0x0b, 0x03, 0x04, -0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0x64, -0xe5, 0x55, 0xa0, 0xea, 0x43, 0xe3, 0x82, 0x98, -0xe3, 0x88, 0x15, 0x0d, 0xea, 0x56, 0x9b, 0x0f, -0xf2, 0xa7, 0xab, 0x8b, 0x3b, 0x13, 0xa0, 0xf9, -0x8b, 0xfb, 0xbf, 0xb7, 0xce, 0xa5, 0x7a, 0x00, +0x21, 0x65, 0xa3, 0xb7, 0xef, 0xd1, 0xbd, 0xcd, +0x51, 0xcc, 0xee, 0x0e, 0xb9, 0xa1, 0xd0, 0xa4, +0x39, 0x7e, 0xba, 0xdf, 0x15, 0xb8, 0x60, 0xe4, +0x49, 0xd8, 0x17, 0x06, 0x71, 0x2a, 0x33, 0x73, +0x20, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, +0x01, 0x22, 0x21, 0x3c, 0x59, 0x43, 0x7b, 0xca, +0x15, 0xdb, 0x4a, 0xb4, 0xb0, 0x54, 0x7e, 0x71, +0x7a, 0x85, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0x73, 0x7c, +0x47, 0x27, 0x56, 0xd8, 0x03, 0x04, 0x51, 0x02, +0x00, 0x51, 0x01, 0x22, 0x21, 0x34, 0x48, 0x38, +0x9a, 0x1b, 0xb3, 0x9f, 0x67, 0x89, 0x34, 0xb9, +0xce, 0xd8, 0xfe, 0xe3, 0x58, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xbd, +0x38, 0x5c, 0x5c, 0xcc, 0x14, 0x1a, 0x03, 0x04, +0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0xa9, +0x40, 0x66, 0x48, 0xd6, 0xed, 0x92, 0x72, 0xe5, +0xc7, 0x34, 0x6b, 0x79, 0xec, 0xfb, 0xce, 0x22, +0xef, 0xa3, 0xdb, 0xe0, 0x38, 0xf4, 0xcc, 0xbc, +0x65, 0xa4, 0xc4, 0x8e, 0x60, 0xed, 0x82, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x53, 0x01, 0x22, -0x21, 0x2a, 0x9f, 0xdc, 0x48, 0x6f, 0x16, 0xa6, -0xaf, 0xa2, 0x62, 0x90, 0xc3, 0x4f, 0xa6, 0x10, -0x24, 0x9d, 0xc5, 0xc4, 0xa3, 0xd8, 0x34, 0xf6, -0x0d, 0x92, 0x5f, 0x49, 0x17, 0xf7, 0xf3, 0x63, -0xaf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, -0x01, 0x22, 0x21, 0x0d, 0xa4, 0x55, 0x39, 0xe6, -0x1e, 0xb8, 0xc8, 0x6c, 0x5c, 0xbd, 0xc0, 0x8f, -0xcb, 0xb1, 0xbc, 0xf8, 0xc3, 0xf7, 0xc0, 0xc8, -0x77, 0xd9, 0x4a, 0x75, 0xec, 0x7a, 0xcb, 0xb6, -0x7a, 0xeb, 0xee, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x55, 0x01, 0x22, 0x21, 0x53, 0xd7, 0x73, -0x30, 0x32, 0x18, 0xb1, 0x1a, 0xac, 0x55, 0x1a, -0xf8, 0x0b, 0x2f, 0xf0, 0x4f, 0x19, 0x95, 0x5d, -0x98, 0x73, 0x68, 0x8d, 0xea, 0xb6, 0xf6, 0x3f, -0x72, 0x25, 0x31, 0x15, 0x86, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x87, -0x5b, 0x2e, 0x33, 0x75, 0xcc, 0xc8, 0xab, 0x66, -0x57, 0x12, 0x46, 0x58, 0x0f, 0x33, 0x36, 0xbe, -0x86, 0x42, 0xf1, 0xcb, 0x2e, 0x1f, 0x9b, 0x23, -0xa1, 0x0d, 0xe2, 0x49, 0xdd, 0x64, 0x7e, 0x00, +0x21, 0x9b, 0x67, 0x4e, 0x48, 0xc4, 0xa9, 0xab, +0x01, 0xb4, 0xfd, 0x78, 0xdb, 0x25, 0x2c, 0xd6, +0x06, 0x47, 0x87, 0x8d, 0xf0, 0x3d, 0xbc, 0xc9, +0xb1, 0xbd, 0x27, 0x71, 0xff, 0xe7, 0xfc, 0x18, +0x5a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, +0x01, 0x22, 0x21, 0xef, 0x1f, 0x24, 0x1b, 0x96, +0xce, 0x10, 0x60, 0x7f, 0xd0, 0x40, 0xbc, 0x15, +0x00, 0xc2, 0x2a, 0xec, 0xc1, 0xde, 0xce, 0x9b, +0x87, 0x47, 0x02, 0x1d, 0x40, 0xd0, 0x60, 0xb1, +0x1f, 0x31, 0x29, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x55, 0x01, 0x22, 0x21, 0xdb, 0x88, 0x28, +0x83, 0x47, 0xdd, 0x52, 0xd0, 0xb1, 0xa2, 0x27, +0xa7, 0x4b, 0x72, 0xb2, 0x27, 0xc1, 0x9d, 0xf1, +0xbc, 0x13, 0xd3, 0xc5, 0x9f, 0x24, 0x71, 0xd7, +0x60, 0x57, 0x1a, 0x06, 0x2d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x90, +0x42, 0xcf, 0x1d, 0x23, 0x7f, 0x29, 0x67, 0x6c, +0x7a, 0xb9, 0x82, 0x32, 0xd9, 0x02, 0x04, 0x5c, +0x83, 0x3c, 0x23, 0xb3, 0x6e, 0xcf, 0x78, 0x1c, +0x7c, 0x56, 0x8a, 0x66, 0x2d, 0x58, 0xf4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x57, 0x01, 0x22, -0x21, 0xf2, 0xbf, 0xd8, 0x93, 0x1e, 0x96, 0x45, -0x7b, 0xe8, 0x00, 0x7d, 0xa0, 0xe3, 0xfd, 0xbb, -0xbc, 0x6b, 0xb3, 0x9b, 0x7e, 0xc0, 0x81, 0x7a, -0xd3, 0x6b, 0xf3, 0x2b, 0xf7, 0x08, 0x67, 0x03, -0xc8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, -0x01, 0x22, 0x21, 0xdc, 0xf3, 0x7f, 0x1a, 0x0b, -0x34, 0x8f, 0xee, 0x45, 0x23, 0x56, 0x88, 0xf9, -0x82, 0xa8, 0x9c, 0x31, 0x46, 0xe0, 0xe9, 0x38, -0x9d, 0x34, 0x99, 0x48, 0x1a, 0x9f, 0x49, 0xe2, -0xf0, 0xd5, 0xa7, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x59, 0x01, 0x22, 0x21, 0x42, 0xe2, 0xdb, -0x2f, 0xc7, 0x32, 0x00, 0xef, 0x5e, 0xf5, 0x3b, -0xda, 0x19, 0xb9, 0x80, 0x4b, 0x42, 0xf1, 0x21, -0xc0, 0x0a, 0xf0, 0x7c, 0xb4, 0xda, 0x55, 0x39, -0x0c, 0x98, 0x1f, 0x21, 0x90, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0xdd, -0x04, 0xc8, 0x0d, 0x26, 0x0f, 0x57, 0x68, 0x4d, -0xcb, 0x07, 0x30, 0x17, 0x25, 0x39, 0x81, 0xfb, -0x5b, 0x09, 0x2a, 0xff, 0xc7, 0x55, 0xe7, 0x03, -0x2e, 0x87, 0xe8, 0x00, 0x24, 0x81, 0x12, 0x00, +0x21, 0x7c, 0x6a, 0xe4, 0x33, 0x33, 0x60, 0xe9, +0xa7, 0x8f, 0xc5, 0xa8, 0x38, 0x97, 0xd7, 0x09, +0x86, 0x78, 0x69, 0x53, 0xe7, 0xbc, 0x9a, 0x2c, +0x0d, 0xcf, 0xf3, 0x63, 0xbd, 0x51, 0x71, 0x6f, +0x98, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, +0x01, 0x22, 0x21, 0x11, 0x48, 0xc2, 0x22, 0x5d, +0xfb, 0x86, 0x34, 0x44, 0x61, 0x6a, 0xed, 0x9f, +0xd3, 0x6c, 0x5a, 0x35, 0xb5, 0x4f, 0x30, 0x14, +0xfd, 0x01, 0x3f, 0x9e, 0x7a, 0xbc, 0x4e, 0x1b, +0x47, 0x02, 0x92, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x59, 0x01, 0x22, 0x21, 0x1b, 0x02, 0x13, +0xc0, 0x50, 0xc4, 0xb5, 0x1d, 0xbd, 0xb0, 0xfd, +0x80, 0x37, 0xb3, 0x94, 0xdd, 0x1c, 0x93, 0x01, +0xca, 0xb3, 0x81, 0xbb, 0xfc, 0x1b, 0xec, 0xf1, +0x6e, 0xf1, 0xef, 0x10, 0x17, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0x96, +0x1a, 0x02, 0x47, 0xcc, 0xa0, 0xff, 0x76, 0x1b, +0x65, 0x89, 0x49, 0xfa, 0x25, 0x5e, 0xb0, 0x57, +0xb9, 0x5a, 0x01, 0xf8, 0xb2, 0xd4, 0xca, 0x8b, +0x2d, 0x83, 0x3b, 0x06, 0x02, 0x90, 0xd2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5b, 0x01, 0x22, -0x21, 0x8a, 0x99, 0x59, 0x3c, 0xc6, 0xf6, 0x05, -0x3c, 0x4d, 0xba, 0xf4, 0x0b, 0x68, 0x1a, 0x57, -0x04, 0x4b, 0x7f, 0x1d, 0xaa, 0x4d, 0xc2, 0x70, -0x92, 0x43, 0xf7, 0xa0, 0x34, 0x17, 0x42, 0x68, -0xfc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, -0x01, 0x22, 0x21, 0x86, 0x06, 0x00, 0x94, 0x2d, -0x45, 0xd2, 0xa4, 0xc9, 0xb8, 0x56, 0x4b, 0x65, -0x0e, 0x8b, 0xfc, 0x5f, 0xa2, 0xcf, 0x41, 0xa3, -0xca, 0x74, 0xb5, 0x28, 0x2e, 0x37, 0xf9, 0x5f, -0x12, 0x7c, 0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x5d, 0x01, 0x22, 0x21, 0x2a, 0xb7, 0x86, -0x34, 0x2c, 0x76, 0xea, 0x35, 0xd5, 0x1f, 0x65, -0x32, 0x9c, 0x24, 0x3e, 0xfe, 0xae, 0x45, 0xb9, -0x60, 0xf8, 0x58, 0x43, 0x82, 0x10, 0x88, 0xba, -0x57, 0xeb, 0xb0, 0xce, 0xa6, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0xfd, -0xdb, 0x85, 0x3a, 0x52, 0xc6, 0xb8, 0x28, 0x73, -0x1a, 0x17, 0x68, 0x14, 0x8f, 0x86, 0x06, 0xab, -0x19, 0x78, 0x29, 0xfe, 0x46, 0xa7, 0x76, 0x35, -0x51, 0xe9, 0x21, 0xfd, 0x93, 0xe3, 0x1d, 0x00, +0x21, 0x70, 0xb0, 0x0c, 0x92, 0x8c, 0x89, 0x48, +0x86, 0xe0, 0x6c, 0x49, 0x3b, 0xc8, 0x5f, 0xa1, +0xe6, 0xd8, 0xba, 0x63, 0x61, 0x99, 0xf5, 0xea, +0x7d, 0xd7, 0x2d, 0x03, 0x98, 0x48, 0xc9, 0xc5, +0x2c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, +0x01, 0x22, 0x21, 0x76, 0xfe, 0xd3, 0x92, 0x8a, +0x6e, 0x96, 0x59, 0x7d, 0x47, 0xd4, 0x9c, 0x9e, +0xc0, 0xdf, 0xa2, 0xca, 0x94, 0xf9, 0xab, 0x89, +0x0c, 0x31, 0x47, 0xd0, 0x5c, 0x27, 0x71, 0x85, +0xa4, 0xee, 0xf4, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x5d, 0x01, 0x22, 0x21, 0xa7, 0xf0, 0x63, +0x89, 0xfe, 0x16, 0xca, 0x01, 0xc4, 0x60, 0xf7, +0x4d, 0xf3, 0xa8, 0x81, 0xe9, 0xe2, 0xca, 0xff, +0x07, 0xea, 0xbb, 0x13, 0x4e, 0x2a, 0xa6, 0x51, +0x5c, 0xc5, 0xf0, 0xe8, 0xc0, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0x15, +0x1e, 0x03, 0x36, 0x49, 0xfc, 0xfa, 0x5c, 0x95, +0xf7, 0x66, 0xc9, 0xf6, 0x59, 0x1b, 0x3d, 0xa4, +0x95, 0x2b, 0x97, 0xab, 0x22, 0x45, 0xe0, 0xd9, +0x6e, 0xa0, 0x8a, 0x80, 0x33, 0x5f, 0xd4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5f, 0x01, 0x22, -0x21, 0x3d, 0x2e, 0xe8, 0xc9, 0xe5, 0xda, 0xb0, -0x3a, 0x21, 0x82, 0xd8, 0xc6, 0x08, 0xa3, 0x3a, -0xe6, 0x22, 0x60, 0xed, 0x40, 0xe5, 0x0f, 0xf1, -0x95, 0xd1, 0x1f, 0xf8, 0xba, 0xdd, 0xc8, 0x69, -0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, -0x01, 0x22, 0x21, 0x74, 0xe7, 0xbd, 0x6d, 0xe1, -0x50, 0x22, 0x5c, 0x8f, 0xb6, 0x16, 0xc2, 0x71, -0x5a, 0x88, 0x2a, 0x4b, 0xb2, 0xb0, 0x00, 0xe8, -0x94, 0x7e, 0xe9, 0x58, 0x73, 0x15, 0x2b, 0xfc, -0x52, 0x28, 0xf3, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x61, 0x01, 0x22, 0x21, 0x2a, 0x2f, 0x7a, -0xa1, 0x33, 0xb3, 0x16, 0xf9, 0xc7, 0xd8, 0xce, -0x03, 0x1f, 0xa8, 0x68, 0x81, 0x01, 0x57, 0x6e, -0x5d, 0xde, 0x6e, 0x2f, 0xbd, 0x94, 0xc3, 0x0f, -0xcc, 0xac, 0x16, 0xc6, 0x87, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0x88, -0x75, 0x5d, 0xf0, 0x8f, 0x1a, 0x61, 0xf0, 0xc5, -0x18, 0x49, 0x69, 0x3d, 0x70, 0x3c, 0x88, 0x44, -0x37, 0x13, 0x64, 0x08, 0xb6, 0x40, 0xd0, 0xf9, -0x56, 0xc0, 0x79, 0xc4, 0xfd, 0xf5, 0xe4, 0x00, +0x21, 0x0a, 0xbc, 0x6c, 0xf7, 0x6e, 0xb4, 0xc4, +0xd2, 0x40, 0x9c, 0x22, 0xae, 0x74, 0x6e, 0xf6, +0xb1, 0x1d, 0x1c, 0xa2, 0xef, 0xe3, 0x5d, 0xc8, +0xa5, 0xb1, 0x8b, 0x47, 0x10, 0x8a, 0xa4, 0xe8, +0xea, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, +0x01, 0x22, 0x21, 0x5e, 0xea, 0xde, 0xc1, 0x3b, +0x34, 0xc4, 0xee, 0x7a, 0x9c, 0x58, 0xfb, 0x74, +0x28, 0x8e, 0x46, 0x25, 0x4c, 0x9b, 0x0c, 0xa7, +0xcb, 0x1d, 0x04, 0x00, 0x9f, 0xc8, 0xd4, 0xce, +0x9b, 0x8f, 0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x61, 0x01, 0x22, 0x21, 0xcf, 0x31, 0x0c, +0x68, 0x0c, 0xfc, 0x4a, 0x2e, 0x90, 0xae, 0xc5, +0x86, 0x52, 0x8b, 0x3d, 0x71, 0xed, 0xfc, 0x61, +0x60, 0xce, 0x78, 0xec, 0xf6, 0x93, 0x50, 0x4a, +0x8d, 0x65, 0xc1, 0x14, 0xb5, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0xe8, +0x69, 0x4e, 0x8a, 0x22, 0x9d, 0x4d, 0xf8, 0xc1, +0x45, 0xc4, 0x19, 0x44, 0xee, 0x63, 0x35, 0x60, +0x1d, 0xff, 0xef, 0xce, 0x30, 0x18, 0x78, 0x1d, +0x67, 0xf3, 0x40, 0x9f, 0xc1, 0xe2, 0x45, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x63, 0x01, 0x22, -0x21, 0x95, 0x05, 0x68, 0xa1, 0x82, 0x46, 0x66, -0xde, 0xb6, 0x21, 0xc3, 0xa7, 0x59, 0x5f, 0xce, -0x2a, 0x1c, 0xda, 0x67, 0x04, 0xe3, 0x24, 0x1f, -0x35, 0xc7, 0xa4, 0xe2, 0x9d, 0x0c, 0x85, 0x81, -0x85, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, -0x01, 0x22, 0x21, 0x28, 0xcc, 0x23, 0x2c, 0xfc, -0x67, 0x63, 0x0b, 0x2d, 0xf1, 0x2e, 0xf1, 0x2e, -0xfd, 0xc0, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x0a, 0x9f, 0xcc, 0x3a, -0x25, 0xb3, 0xf7, 0x88, 0x03, 0x04, 0x51, 0x02, -0x00, 0x65, 0x01, 0x22, 0x21, 0xbb, 0x98, 0x42, -0xf9, 0x90, 0x83, 0x76, 0x8e, 0xb6, 0x01, 0x2e, -0x99, 0xc7, 0x31, 0x48, 0x0b, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x4b, -0x92, 0x25, 0xae, 0xa8, 0xfe, 0x51, 0x03, 0x04, -0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0xa5, -0x74, 0xb8, 0x12, 0x0f, 0x4d, 0xbc, 0x94, 0xfa, -0xaf, 0x76, 0x51, 0x57, 0xb7, 0x1b, 0x89, 0xb1, -0xaa, 0x23, 0xee, 0x55, 0xf9, 0x27, 0xbd, 0x8a, -0x01, 0xe1, 0x02, 0xc4, 0x4d, 0x32, 0xed, 0x00, +0x21, 0x76, 0x66, 0x0a, 0x45, 0x72, 0x92, 0x87, +0x72, 0xdb, 0x35, 0x4f, 0xa6, 0x51, 0x5c, 0xa3, +0xba, 0x63, 0x7c, 0xc5, 0x31, 0xdc, 0x71, 0x6f, +0x8b, 0x3c, 0xc0, 0x6f, 0x6d, 0x12, 0x44, 0xfd, +0x20, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, +0x01, 0x22, 0x21, 0xb2, 0x83, 0x74, 0x19, 0xc8, +0x3c, 0x3e, 0x01, 0x4f, 0xbc, 0x0f, 0xcb, 0xa9, +0xaa, 0x85, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x15, 0xe1, 0x0a, 0x87, +0x64, 0x36, 0x6d, 0xb8, 0x03, 0x04, 0x51, 0x02, +0x00, 0x65, 0x01, 0x22, 0x21, 0x93, 0x3a, 0x66, +0x02, 0x65, 0x77, 0x72, 0xbc, 0x64, 0xb4, 0xf9, +0x53, 0x93, 0x58, 0x35, 0xf9, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, +0xb6, 0x35, 0xb0, 0x10, 0xf5, 0x39, 0x03, 0x04, +0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0x22, +0x24, 0xb1, 0xaa, 0xd3, 0x9f, 0x60, 0x41, 0x11, +0xe6, 0x64, 0xe8, 0x93, 0x67, 0x07, 0xf4, 0x46, +0x19, 0xf6, 0xc1, 0xf9, 0x9e, 0x79, 0xe2, 0x96, +0xf9, 0xe8, 0x39, 0xeb, 0x55, 0x35, 0x30, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x67, 0x01, 0x22, -0x21, 0x76, 0xf4, 0x4c, 0xe0, 0xb7, 0x30, 0x8e, -0xb1, 0x82, 0x3a, 0xd3, 0x21, 0x21, 0xba, 0x98, -0xb4, 0x15, 0xea, 0x63, 0x27, 0xbf, 0x4c, 0x72, -0x93, 0x34, 0x4e, 0x69, 0x87, 0xa9, 0x18, 0x84, -0xc2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, -0x01, 0x22, 0x21, 0xf4, 0x99, 0x1c, 0xd3, 0x0c, -0x25, 0xc6, 0x51, 0xa8, 0xbd, 0xe9, 0xc8, 0xd1, -0xff, 0x35, 0x62, 0x63, 0x19, 0xf5, 0x7f, 0x0b, -0x0f, 0x62, 0xaf, 0x7b, 0x58, 0xf8, 0xbf, 0x95, -0x10, 0x63, 0xbe, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x69, 0x01, 0x22, 0x21, 0x25, 0x86, 0x10, -0x0d, 0x70, 0x95, 0x58, 0x8f, 0x45, 0xd9, 0x67, -0x45, 0x21, 0x92, 0x01, 0xcc, 0x30, 0xd7, 0x78, -0x0f, 0x6a, 0xfe, 0xc9, 0xfa, 0x38, 0x11, 0xd0, -0x5d, 0x25, 0xf1, 0x87, 0xb3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0x2a, -0x99, 0xb9, 0x1e, 0xac, 0x1f, 0x87, 0xc9, 0x2b, -0x5c, 0x9c, 0xce, 0xe7, 0x72, 0x67, 0x5e, 0xdc, -0x80, 0xb1, 0x29, 0x92, 0xbc, 0x6f, 0x39, 0x36, -0xab, 0x6e, 0xb0, 0xe8, 0xa8, 0xd7, 0x19, 0x00, +0x21, 0x26, 0xf8, 0xe3, 0x42, 0xaf, 0xf2, 0xa2, +0x9e, 0xd8, 0x13, 0x20, 0xa3, 0x75, 0x78, 0xfc, +0xd2, 0x80, 0xf8, 0x8e, 0x33, 0x0c, 0x40, 0x23, +0xe7, 0xca, 0xb5, 0x6f, 0xe9, 0xe9, 0xd8, 0x9f, +0x72, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, +0x01, 0x22, 0x21, 0x4f, 0xf7, 0xbf, 0x57, 0x59, +0x44, 0xfe, 0x48, 0x81, 0xc1, 0xcb, 0xea, 0xd8, +0xe8, 0x79, 0x8a, 0x79, 0xf5, 0xca, 0x80, 0x79, +0x6d, 0x4d, 0x10, 0xc2, 0x29, 0x98, 0x2e, 0x5a, +0x70, 0xca, 0x6c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x69, 0x01, 0x22, 0x21, 0x3d, 0xf7, 0x34, +0x17, 0x1a, 0x0f, 0x41, 0x73, 0x77, 0x99, 0xe5, +0x2b, 0x44, 0x1b, 0x8f, 0xf6, 0xd8, 0x9a, 0x34, +0xe1, 0x5a, 0x44, 0xa1, 0x29, 0xe5, 0x1c, 0xd4, +0xf0, 0x9b, 0x49, 0x5e, 0xac, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0xa0, +0x0d, 0xd2, 0x1b, 0x5a, 0x04, 0xb8, 0x83, 0x3f, +0xbe, 0xa4, 0x6b, 0x8f, 0x4d, 0x0a, 0x99, 0xf0, +0x47, 0xc0, 0x63, 0x99, 0xcc, 0xfc, 0x7b, 0xe0, +0x8d, 0xc1, 0x19, 0xe2, 0xd0, 0xb3, 0xfe, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6b, 0x01, 0x22, -0x21, 0x1e, 0x49, 0x60, 0x27, 0x02, 0x80, 0x80, -0x80, 0xaa, 0x85, 0x55, 0x68, 0x7d, 0x19, 0x15, -0xa0, 0x3f, 0xb1, 0xd7, 0x09, 0x66, 0x90, 0x56, -0x70, 0xf2, 0xe1, 0x84, 0xc3, 0x59, 0x42, 0x4c, -0x29, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, -0x01, 0x22, 0x21, 0x16, 0xcb, 0x32, 0xc0, 0xe3, -0x6f, 0x2f, 0x3b, 0xbb, 0x8d, 0x7f, 0xf8, 0xe4, -0xc0, 0xcc, 0xcc, 0x58, 0x18, 0x38, 0x14, 0x90, -0xcd, 0x0e, 0x04, 0xe2, 0x9d, 0x20, 0x69, 0x4b, -0x48, 0xaf, 0x1a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x6d, 0x01, 0x22, 0x21, 0xc9, 0x87, 0x3c, -0x41, 0x5b, 0xa6, 0xef, 0x0e, 0x13, 0x71, 0x2b, -0xf3, 0xa8, 0xff, 0x55, 0x82, 0x19, 0x3a, 0xfb, -0x69, 0x5b, 0x99, 0xbb, 0x86, 0x11, 0x96, 0x27, -0x41, 0xc2, 0x41, 0x8a, 0x20, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0x36, -0x1c, 0xc6, 0x21, 0xe1, 0xee, 0x1b, 0x9f, 0x30, -0xf3, 0x0a, 0x02, 0x78, 0x20, 0x7a, 0x41, 0xb3, -0x6d, 0xb2, 0x9c, 0x59, 0x26, 0xfa, 0xed, 0x9b, -0x0d, 0xfe, 0x76, 0xca, 0x56, 0x47, 0xaa, 0x00, +0x21, 0x8e, 0x5c, 0xd6, 0x22, 0x2d, 0x5f, 0xce, +0x08, 0xee, 0x72, 0xdd, 0x5b, 0x2d, 0xb1, 0x8b, +0xa0, 0xa1, 0x00, 0x6d, 0xa8, 0xda, 0xb5, 0x42, +0xe1, 0xed, 0x51, 0x30, 0x43, 0x50, 0xf7, 0xf4, +0xf5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, +0x01, 0x22, 0x21, 0x35, 0x76, 0xf6, 0xc2, 0xb8, +0xe4, 0x29, 0xd3, 0x61, 0x44, 0x96, 0x34, 0x8c, +0x54, 0xcb, 0x75, 0xd8, 0xcf, 0x61, 0xf6, 0x45, +0xa6, 0xbb, 0x0e, 0x1a, 0xf5, 0xd9, 0x57, 0x95, +0x3e, 0x8d, 0x55, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x6d, 0x01, 0x22, 0x21, 0xe3, 0xeb, 0x52, +0x4b, 0xa6, 0x83, 0x69, 0x4c, 0xcf, 0x8b, 0x02, +0xb7, 0x8a, 0x22, 0xf9, 0xf7, 0x8f, 0x35, 0x91, +0xa4, 0x02, 0xef, 0x36, 0x80, 0x05, 0x3f, 0xc9, +0xf4, 0xf3, 0xad, 0xb7, 0xe6, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0x52, +0x3f, 0x45, 0x9d, 0x3e, 0x0a, 0x70, 0x97, 0x5e, +0x81, 0xe1, 0xe6, 0x61, 0xef, 0x4c, 0x5d, 0xe9, +0x0b, 0x48, 0x51, 0x83, 0x14, 0xe6, 0xec, 0x17, +0x24, 0xb3, 0x8e, 0xd6, 0xfc, 0x5b, 0x0d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6f, 0x01, 0x22, -0x21, 0x25, 0xe1, 0xe7, 0xeb, 0x3f, 0x14, 0x18, -0xf1, 0x5a, 0x34, 0x53, 0x12, 0x96, 0xa2, 0x74, -0xa7, 0x97, 0x97, 0x62, 0xa9, 0x2f, 0xe0, 0x65, -0x56, 0x76, 0xcf, 0x41, 0xc7, 0x03, 0xc5, 0x01, -0xce, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, -0x01, 0x22, 0x21, 0x80, 0x80, 0x7d, 0x86, 0x0e, -0x7b, 0x48, 0x6d, 0x9a, 0x50, 0x04, 0x83, 0x6a, -0x2d, 0x22, 0x51, 0x78, 0x34, 0xf5, 0x6f, 0x62, -0x3b, 0xeb, 0xaa, 0x2d, 0xf0, 0x7e, 0x90, 0xc4, -0xc3, 0xfa, 0xc1, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x71, 0x01, 0x22, 0x21, 0xc5, 0x7d, 0x2a, -0x16, 0x2e, 0x91, 0x4d, 0xb0, 0xa6, 0x0e, 0x9b, -0xff, 0x83, 0x0f, 0x9c, 0x9f, 0xf3, 0x82, 0x94, -0x38, 0xc9, 0xbd, 0x93, 0x06, 0x36, 0xda, 0xe9, -0x04, 0x8b, 0x2a, 0x13, 0xde, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0xf2, -0xa4, 0xd9, 0xbd, 0xd3, 0x66, 0x61, 0xd4, 0xd1, -0xf5, 0x02, 0x35, 0x96, 0x7f, 0xea, 0xd9, 0x29, -0xfe, 0x65, 0x61, 0x71, 0x3d, 0xae, 0x87, 0x70, -0x79, 0xd1, 0x18, 0x4d, 0x02, 0xa6, 0x43, 0x00, +0x21, 0x19, 0x40, 0x96, 0x54, 0xa4, 0x36, 0x66, +0x32, 0x66, 0x44, 0x9d, 0x16, 0x57, 0xf3, 0x9b, +0xf1, 0x79, 0xd6, 0xe3, 0xb3, 0x03, 0x5c, 0xc3, +0x91, 0x92, 0xa9, 0x7d, 0x51, 0x99, 0x90, 0x8d, +0x89, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, +0x01, 0x22, 0x21, 0xd3, 0xae, 0x25, 0x85, 0x3c, +0xc9, 0x34, 0xc1, 0x13, 0x65, 0x0e, 0x58, 0x3c, +0xed, 0x75, 0xb9, 0x9a, 0x45, 0xd7, 0x0f, 0x46, +0x19, 0x07, 0x49, 0x8f, 0x44, 0xff, 0x95, 0xcb, +0xa4, 0x79, 0x59, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x71, 0x01, 0x22, 0x21, 0xfa, 0xda, 0x83, +0x5c, 0x71, 0x80, 0x32, 0x9b, 0x7f, 0xbd, 0x99, +0x79, 0xbc, 0xa1, 0xe2, 0x4b, 0x1a, 0x15, 0xa8, +0xd8, 0x70, 0xdc, 0x1a, 0x5e, 0x8b, 0x65, 0x3c, +0x95, 0x79, 0xfd, 0x49, 0x4e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0xe7, +0x62, 0x05, 0x7e, 0x7c, 0x13, 0x19, 0xb7, 0x4b, +0xfb, 0x5f, 0x5f, 0x25, 0x8b, 0xe6, 0x71, 0xe5, +0x9d, 0x9b, 0x26, 0x7d, 0xb1, 0xc5, 0xba, 0x88, +0x80, 0x8e, 0x74, 0xe0, 0x66, 0xeb, 0x3b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x73, 0x01, 0x22, -0x21, 0x35, 0xbb, 0x15, 0xd7, 0x52, 0x8a, 0xce, -0x2c, 0xd6, 0x8a, 0x11, 0xdd, 0x87, 0x2c, 0xab, -0x91, 0xb5, 0xb9, 0xf0, 0xe1, 0xbe, 0x40, 0xb2, -0x99, 0xa2, 0x0d, 0xf7, 0x82, 0xc4, 0x2e, 0x9f, -0x36, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, -0x01, 0x22, 0x21, 0x64, 0xbc, 0x56, 0x58, 0xfe, -0xde, 0x50, 0x08, 0xe3, 0x51, 0xc1, 0x19, 0x29, -0xaa, 0x1e, 0xfb, 0xea, 0xfa, 0xe4, 0x4f, 0xbb, -0xd2, 0x29, 0x50, 0x6c, 0xed, 0x7b, 0x3f, 0xa5, -0x09, 0x89, 0xdf, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x75, 0x01, 0x22, 0x21, 0x50, 0x85, 0xd2, -0x8e, 0x14, 0x7a, 0xb5, 0x69, 0xba, 0xfc, 0x7e, -0xe3, 0xdd, 0xf6, 0x92, 0x00, 0xe3, 0xf5, 0x81, -0x52, 0x93, 0x6f, 0xbe, 0xd8, 0x0c, 0x66, 0xc2, -0x5b, 0xa0, 0x00, 0x62, 0x9e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0xe6, -0x3d, 0xc5, 0x03, 0x9d, 0xce, 0xa9, 0x71, 0xf7, -0x71, 0xce, 0xad, 0x27, 0xb7, 0x9d, 0x5b, 0xea, -0x88, 0xe2, 0x27, 0xfa, 0x55, 0xb7, 0x09, 0x42, -0xb9, 0x7a, 0x4a, 0xd6, 0x4d, 0x85, 0xa7, 0x00, +0x21, 0xee, 0xf3, 0xa3, 0x06, 0x75, 0x47, 0x83, +0x36, 0x5a, 0x72, 0x42, 0x73, 0xd4, 0x50, 0x2f, +0xc8, 0xa4, 0xa0, 0xa7, 0x24, 0x69, 0x1b, 0x9d, +0x19, 0x23, 0xdf, 0xb8, 0x66, 0x0c, 0x87, 0xbd, +0x5f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, +0x01, 0x22, 0x21, 0xf3, 0x43, 0xba, 0x92, 0xa5, +0x89, 0x57, 0x07, 0x59, 0x43, 0x02, 0x12, 0xfa, +0xce, 0x70, 0xed, 0x15, 0x26, 0xb8, 0xbc, 0x95, +0x30, 0x63, 0x2c, 0x07, 0x69, 0x5c, 0x85, 0x45, +0x7c, 0xf2, 0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x75, 0x01, 0x22, 0x21, 0x79, 0xa5, 0xe5, +0xe6, 0x20, 0x65, 0xaa, 0x2e, 0x05, 0x29, 0xad, +0x3e, 0xeb, 0x26, 0x85, 0xe2, 0xc3, 0x08, 0xba, +0x34, 0x20, 0xc5, 0xfb, 0x18, 0x6a, 0xc0, 0x78, +0xd8, 0x29, 0x1e, 0xa2, 0x86, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0x1a, +0x13, 0xa3, 0xf0, 0x6d, 0xe0, 0x67, 0xad, 0x3c, +0x18, 0xbc, 0x78, 0xb3, 0x77, 0xd8, 0x5f, 0xaa, +0x0c, 0x44, 0x16, 0x49, 0xed, 0xa3, 0x83, 0x27, +0x4f, 0x9d, 0xae, 0x9f, 0x03, 0xeb, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x77, 0x01, 0x22, -0x21, 0x5d, 0xd0, 0x11, 0x55, 0x0b, 0x96, 0xd8, -0x25, 0x11, 0x94, 0x9d, 0x90, 0x58, 0x7b, 0xd4, -0x41, 0x69, 0xfd, 0x4d, 0xc0, 0x45, 0xd8, 0x63, -0x93, 0xd2, 0x92, 0x98, 0x64, 0x5b, 0x30, 0x2f, -0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, -0x01, 0x22, 0x21, 0x40, 0x0b, 0x22, 0xe6, 0xd0, -0x6b, 0x8b, 0x71, 0x35, 0x56, 0x15, 0xeb, 0x39, -0xe4, 0x5c, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x26, 0xca, 0xa7, 0x06, -0x8f, 0x47, 0xec, 0x30, 0x03, 0x04, 0x51, 0x02, -0x00, 0x79, 0x01, 0x22, 0x21, 0x04, 0x13, 0xf3, -0x41, 0x7d, 0xd4, 0xbd, 0xbb, 0x55, 0x6a, 0x88, -0x5b, 0x32, 0x1e, 0x3b, 0x21, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x9c, -0x25, 0x82, 0xa2, 0x2b, 0xa6, 0x7f, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0xe1, -0x56, 0x16, 0x78, 0x08, 0x42, 0x07, 0xd4, 0x6d, -0x36, 0x6a, 0x5d, 0x46, 0xa9, 0xe0, 0x53, 0xbe, -0x79, 0xae, 0xe5, 0xde, 0xc0, 0x0d, 0xa1, 0xe1, -0x64, 0x6e, 0x8f, 0x9e, 0xd5, 0x38, 0xf8, 0x00, +0x21, 0x7c, 0xf5, 0xeb, 0x62, 0x65, 0xca, 0x54, +0xd3, 0x3f, 0x94, 0x8e, 0x42, 0x90, 0x8e, 0xa8, +0xf7, 0x15, 0x30, 0x56, 0x38, 0x59, 0xf1, 0x9d, +0x56, 0x09, 0x37, 0x5b, 0x8b, 0x80, 0xe8, 0x3e, +0xae, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, +0x01, 0x22, 0x21, 0x6c, 0xd6, 0x4e, 0x3c, 0x1f, +0x78, 0x45, 0xe4, 0xaf, 0xf9, 0x65, 0xd3, 0xa7, +0xda, 0x27, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xfc, 0x51, 0x8f, 0x2e, +0x5d, 0xda, 0x17, 0x2e, 0x03, 0x04, 0x51, 0x02, +0x00, 0x79, 0x01, 0x22, 0x21, 0xfc, 0x0b, 0xfa, +0xd9, 0x01, 0xae, 0x9f, 0xec, 0x68, 0xa6, 0xcb, +0xea, 0xa2, 0xf6, 0x22, 0x94, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xcf, +0xf9, 0x36, 0xdd, 0xdf, 0x4d, 0x60, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0x94, +0xe8, 0x27, 0x41, 0xb0, 0x6c, 0xea, 0x3f, 0x68, +0x35, 0x78, 0x02, 0x61, 0x5a, 0xc6, 0xaa, 0x63, +0x1d, 0xb0, 0x21, 0x98, 0x84, 0xb3, 0xa8, 0xcb, +0x71, 0xa3, 0xe7, 0x0c, 0x74, 0xb0, 0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7b, 0x01, 0x22, -0x21, 0xaa, 0xab, 0x58, 0xc0, 0x79, 0x0c, 0x5d, -0x5b, 0x82, 0x4a, 0x23, 0xfc, 0x83, 0x97, 0xac, -0x36, 0xc6, 0x88, 0x55, 0x1f, 0xf6, 0x55, 0x6c, -0x40, 0xd6, 0x4b, 0xff, 0xdf, 0xf1, 0xdc, 0x4c, -0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, -0x01, 0x22, 0x21, 0x13, 0xdd, 0x6e, 0xe0, 0x3f, -0x20, 0x9a, 0xe5, 0x96, 0xa4, 0xcc, 0x68, 0xb2, -0xc4, 0x44, 0xc3, 0x75, 0x77, 0x8f, 0x95, 0x29, -0x52, 0xb2, 0xc0, 0xb1, 0xfa, 0xa6, 0x50, 0x77, -0x90, 0x2e, 0x5d, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x7d, 0x01, 0x22, 0x21, 0xd5, 0x44, 0xf6, -0x2a, 0xad, 0x4b, 0x1c, 0x82, 0x23, 0x0d, 0x01, -0x7f, 0xa2, 0x75, 0xf1, 0x72, 0xe7, 0x8c, 0x20, -0xe6, 0x9b, 0x2f, 0x8b, 0x1a, 0xd9, 0x0e, 0xf7, -0x60, 0xaf, 0x8d, 0xb2, 0xf3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0xed, -0xcd, 0x61, 0xe7, 0x8d, 0x3e, 0xa1, 0x1e, 0x7e, -0x41, 0x44, 0x3f, 0x11, 0xb7, 0xa5, 0xc7, 0x35, -0xc5, 0xf2, 0x13, 0x78, 0x1f, 0xe9, 0xa9, 0xb2, -0x16, 0x33, 0x5b, 0x3b, 0xbc, 0x8c, 0x59, 0x00, +0x21, 0x49, 0x51, 0x04, 0xfd, 0x9c, 0x8e, 0x4a, +0x38, 0x44, 0xc9, 0xd8, 0x92, 0x21, 0x26, 0x60, +0xc2, 0x0f, 0xb5, 0xf8, 0x77, 0x76, 0x1d, 0xe0, +0xe9, 0x82, 0x15, 0xe9, 0x44, 0x16, 0xd4, 0x34, +0x05, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, +0x01, 0x22, 0x21, 0x10, 0xb3, 0xda, 0x65, 0x2e, +0x65, 0x8f, 0x0f, 0xef, 0x7e, 0x78, 0xe3, 0x4b, +0x26, 0x50, 0xc9, 0x90, 0xb6, 0x3d, 0x0a, 0x36, +0xef, 0xb0, 0xc5, 0x64, 0xcb, 0xaa, 0xe1, 0x5c, +0x21, 0x1d, 0x79, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x7d, 0x01, 0x22, 0x21, 0x5e, 0xc8, 0x42, +0x7e, 0x99, 0x30, 0x12, 0x25, 0x4c, 0x91, 0xce, +0xdb, 0xc2, 0xf6, 0x81, 0x18, 0xac, 0x59, 0x4f, +0xbe, 0x21, 0xd9, 0xc0, 0x8c, 0x44, 0x5f, 0x26, +0xe2, 0xcd, 0x0c, 0x99, 0x94, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0xbc, +0xed, 0xad, 0xd1, 0x3f, 0x51, 0xb4, 0xa1, 0xc3, +0x99, 0xf5, 0x88, 0x89, 0x9c, 0xd0, 0x74, 0x48, +0xf1, 0x5f, 0x30, 0x9b, 0x92, 0x66, 0xf5, 0x2d, +0xd7, 0x31, 0xd6, 0x06, 0x7d, 0x1c, 0x9e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7f, 0x01, 0x22, -0x21, 0x6f, 0x0d, 0xb4, 0x13, 0xb3, 0xe2, 0x30, -0x0b, 0x62, 0x69, 0x3d, 0xb4, 0xb2, 0x6a, 0x1d, -0x30, 0x84, 0x99, 0x33, 0xa5, 0x18, 0x48, 0xae, -0x8c, 0xe8, 0xe4, 0xad, 0xc5, 0xcb, 0xc9, 0x23, -0x69, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, -0x01, 0x22, 0x21, 0x88, 0x45, 0x4c, 0x17, 0x6b, -0xb2, 0x4b, 0xfb, 0xad, 0xbc, 0x93, 0x47, 0xe4, -0x33, 0x68, 0x32, 0x3a, 0xdd, 0x7c, 0xa5, 0xaf, -0x1e, 0x74, 0xa4, 0xe3, 0x71, 0x82, 0xfc, 0xb2, -0x06, 0x76, 0xe7, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x81, 0x01, 0x22, 0x21, 0xf6, 0xb1, 0x0a, -0x06, 0x73, 0x0f, 0x1e, 0x16, 0x65, 0x73, 0xcd, -0x53, 0x5b, 0x32, 0xf7, 0x46, 0x53, 0xd5, 0xba, -0xa7, 0x7e, 0xea, 0x75, 0x99, 0x8e, 0xff, 0x54, -0xb6, 0x73, 0xb2, 0x78, 0xa6, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0xb8, -0x77, 0xd5, 0x46, 0xd4, 0x2f, 0x82, 0x49, 0xdf, -0xf4, 0xe5, 0x7b, 0x40, 0x23, 0x1c, 0x4a, 0xe5, -0x43, 0x47, 0x06, 0x25, 0x33, 0x1d, 0x0f, 0x6c, -0x86, 0x75, 0x6f, 0xb1, 0xfa, 0x68, 0xe2, 0x00, +0x21, 0x59, 0xde, 0x2e, 0x77, 0x44, 0xcf, 0xbf, +0xb5, 0x52, 0xed, 0x35, 0x7a, 0x51, 0x84, 0x75, +0x08, 0x73, 0xef, 0xf3, 0x91, 0xe1, 0x71, 0xb8, +0x62, 0x12, 0xde, 0x2b, 0x7f, 0xd5, 0x56, 0x58, +0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, +0x01, 0x22, 0x21, 0xff, 0x8d, 0xde, 0x2e, 0x87, +0x65, 0xa1, 0x80, 0x56, 0x1c, 0xf5, 0x0e, 0xab, +0xff, 0x7b, 0xb9, 0xdf, 0x27, 0x9d, 0x8a, 0x19, +0xd2, 0x14, 0x9c, 0xed, 0x01, 0x8f, 0x56, 0x4f, +0xd0, 0x3b, 0xbc, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x81, 0x01, 0x22, 0x21, 0x2f, 0xb6, 0x11, +0xd3, 0x14, 0xe0, 0x41, 0x37, 0x53, 0xa9, 0x28, +0x40, 0x6c, 0xc5, 0x1e, 0x7b, 0x29, 0x6f, 0x57, +0x95, 0xc9, 0x45, 0xf0, 0xc2, 0x7b, 0x88, 0xe1, +0x17, 0x22, 0x22, 0x51, 0xb2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0x9f, +0x41, 0xd4, 0x43, 0x71, 0x13, 0xb3, 0xf1, 0x90, +0xcd, 0x3f, 0x42, 0xea, 0xb6, 0xe1, 0xe7, 0x69, +0x09, 0x68, 0x0c, 0x6f, 0xd0, 0xe1, 0xd1, 0x53, +0x3c, 0xf3, 0xfb, 0xa4, 0xfe, 0x0d, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x83, 0x01, 0x22, -0x21, 0xb8, 0x93, 0xc1, 0x30, 0x9e, 0x1a, 0xc4, -0xcc, 0x7e, 0x75, 0xb6, 0xa1, 0x1a, 0x65, 0x0e, -0xe3, 0x15, 0xc8, 0x26, 0x37, 0x82, 0xf2, 0x0d, -0x33, 0x63, 0x7c, 0xa9, 0x12, 0x2b, 0xd8, 0xa6, -0x50, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, -0x01, 0x22, 0x21, 0x96, 0xa9, 0x2a, 0xfe, 0x5c, -0xd2, 0xe8, 0xc3, 0x63, 0xde, 0x92, 0x7d, 0x1a, -0x5f, 0x04, 0xc6, 0x3f, 0xd9, 0xb3, 0x17, 0xb2, -0x17, 0xef, 0xf8, 0xf9, 0x52, 0x50, 0x3e, 0x01, -0xe5, 0xb9, 0xc9, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x85, 0x01, 0x22, 0x21, 0x6c, 0x36, 0xaa, -0x04, 0x57, 0x66, 0x41, 0xf5, 0x87, 0x6d, 0x14, -0x49, 0x06, 0x66, 0x58, 0x3a, 0xd0, 0x6d, 0xcb, -0x64, 0xc4, 0xdb, 0xfa, 0x7d, 0x7c, 0x5a, 0x4b, -0xe8, 0x9e, 0x0a, 0xca, 0x6f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0x75, -0xa3, 0x18, 0xdd, 0xa4, 0xc4, 0x72, 0x8b, 0xee, -0x9a, 0x83, 0x5a, 0xa1, 0xbb, 0x96, 0xfa, 0xbf, -0x62, 0x22, 0x68, 0x6b, 0x90, 0x05, 0xae, 0x9c, -0x28, 0x84, 0xdd, 0xc4, 0xbd, 0x25, 0x42, 0x00, +0x21, 0x5d, 0xd1, 0xfd, 0x22, 0x46, 0x94, 0xdb, +0x91, 0xb9, 0xc3, 0x7c, 0xc2, 0x8c, 0x13, 0xe7, +0xd7, 0xfa, 0x44, 0xf7, 0x49, 0x49, 0x79, 0xc5, +0x31, 0xe7, 0x14, 0xee, 0x9c, 0x68, 0xdd, 0x95, +0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, +0x01, 0x22, 0x21, 0x2d, 0x6c, 0x01, 0x17, 0xcb, +0x42, 0xe6, 0x19, 0xc5, 0x07, 0x12, 0x01, 0x6e, +0x67, 0x4b, 0x44, 0x26, 0xae, 0x99, 0x56, 0x5f, +0x5d, 0x84, 0x87, 0xf3, 0x6b, 0x0f, 0x26, 0x4b, +0xd9, 0xd8, 0x27, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x85, 0x01, 0x22, 0x21, 0xe0, 0x8a, 0x8b, +0x97, 0x33, 0x93, 0xb2, 0xa5, 0xc7, 0xd5, 0xf5, +0xc0, 0xf5, 0xea, 0x1b, 0xca, 0x54, 0xb8, 0xd0, +0x62, 0x14, 0xf0, 0xa6, 0x2c, 0x61, 0x37, 0x17, +0x4e, 0xa3, 0x94, 0x9e, 0xd9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0xa9, +0xf6, 0x62, 0x98, 0x3f, 0x4f, 0xc9, 0x86, 0x63, +0x30, 0x2c, 0xba, 0xb5, 0x27, 0x21, 0xd6, 0x02, +0xeb, 0x7c, 0x12, 0x24, 0x31, 0x9f, 0x88, 0xf2, +0xa4, 0x34, 0x94, 0xe3, 0x97, 0xf4, 0xf8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x87, 0x01, 0x22, -0x21, 0x57, 0x65, 0x8b, 0xf2, 0xb7, 0xf3, 0x64, -0x32, 0xa5, 0x21, 0x8e, 0x70, 0x17, 0x1c, 0xcd, -0x76, 0xe0, 0x6a, 0x57, 0x82, 0xd9, 0xdc, 0xb9, -0x23, 0x56, 0x73, 0x90, 0xd7, 0xff, 0xf6, 0xc1, -0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, -0x01, 0x22, 0x21, 0x60, 0x59, 0xb6, 0x03, 0x24, -0xdc, 0x97, 0xda, 0x37, 0x7a, 0x28, 0xe5, 0xd7, -0x6b, 0xca, 0x4c, 0x19, 0x1f, 0x3b, 0x51, 0x52, -0xec, 0x80, 0x7a, 0x1d, 0xee, 0x78, 0x52, 0x9d, -0xc7, 0xc1, 0x01, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x89, 0x01, 0x22, 0x21, 0xec, 0x9a, 0x0a, -0x9b, 0x92, 0x8e, 0x1b, 0x09, 0x68, 0x29, 0xb6, -0x17, 0x44, 0xb8, 0xf5, 0x37, 0x32, 0xae, 0x6a, -0x20, 0xf0, 0xc1, 0x14, 0x86, 0x49, 0x99, 0x3f, -0x78, 0xfb, 0x62, 0x6e, 0xd5, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0x61, -0x81, 0x21, 0xa0, 0xaa, 0x71, 0xb0, 0x78, 0x54, -0x99, 0x79, 0xdb, 0xc2, 0xe3, 0x9a, 0xed, 0xe7, -0x91, 0xc4, 0x18, 0xed, 0x71, 0x6d, 0x37, 0xaa, -0xc9, 0x8a, 0xb2, 0xe9, 0xcb, 0x67, 0x94, 0x00, +0x21, 0x5e, 0x8c, 0x0d, 0xc5, 0x60, 0x79, 0xe7, +0x1c, 0xb2, 0x3b, 0xfd, 0x05, 0x7d, 0x2d, 0x9f, +0x90, 0xde, 0xab, 0x40, 0xab, 0x90, 0x91, 0x78, +0x31, 0x5a, 0x03, 0x69, 0xdb, 0x6a, 0xff, 0x56, +0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, +0x01, 0x22, 0x21, 0xc8, 0x6f, 0x8c, 0xd4, 0x7f, +0x2a, 0x3b, 0x3f, 0x2b, 0xdb, 0x97, 0xf2, 0xf8, +0xc8, 0x73, 0xf6, 0xe7, 0x0e, 0x78, 0x01, 0x58, +0xc2, 0x0d, 0xe1, 0x8b, 0xcd, 0x57, 0x0b, 0xf4, +0x0c, 0x86, 0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x89, 0x01, 0x22, 0x21, 0x7a, 0x40, 0x93, +0x84, 0xa3, 0x55, 0x45, 0x7c, 0x49, 0x72, 0x9f, +0xa4, 0x62, 0x23, 0x81, 0x11, 0x7a, 0x83, 0xb7, +0x89, 0xdb, 0x71, 0xa9, 0x64, 0x57, 0xdc, 0x69, +0xdd, 0xce, 0x81, 0x3d, 0x70, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0x13, +0xe7, 0xbc, 0x1d, 0x2c, 0x1a, 0x90, 0x04, 0xb9, +0xbf, 0xfc, 0x03, 0x82, 0xf3, 0x89, 0xa3, 0xa8, +0xa4, 0x04, 0xc2, 0xfb, 0xeb, 0x8a, 0x84, 0xc8, +0x41, 0x76, 0x92, 0x8e, 0x65, 0xee, 0xed, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8b, 0x01, 0x22, -0x21, 0x6f, 0xb2, 0xa3, 0x85, 0x64, 0xd6, 0xce, -0x5e, 0x14, 0x22, 0x4d, 0x3d, 0xcc, 0x01, 0x9c, -0xbf, 0xbb, 0x10, 0xd8, 0xb8, 0xb1, 0x9b, 0x2e, -0x8a, 0x71, 0x15, 0x08, 0x2f, 0x2a, 0xeb, 0x99, -0x84, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, -0x01, 0x22, 0x21, 0x65, 0xa1, 0x6f, 0xfd, 0x2d, -0x8f, 0xb8, 0x13, 0x62, 0x7a, 0xa8, 0x61, 0x35, -0x78, 0x17, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xbc, 0x4d, 0xba, 0xf2, -0xe9, 0x4f, 0x63, 0x88, 0x03, 0x04, 0x51, 0x02, -0x00, 0x8d, 0x01, 0x22, 0x21, 0xff, 0x4a, 0xbb, -0xe3, 0x83, 0xea, 0xe0, 0x3c, 0xd4, 0xaa, 0x9f, -0x18, 0xbb, 0xb9, 0x35, 0x38, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x2a, -0x82, 0x35, 0xc2, 0xd7, 0x34, 0x38, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0xa4, -0x59, 0xb4, 0x7b, 0x20, 0x33, 0x38, 0x9c, 0xb8, -0x90, 0xb5, 0xcb, 0x8a, 0x8a, 0xf5, 0x0c, 0xc8, -0x68, 0xe3, 0xcb, 0x87, 0x87, 0xf3, 0xd4, 0x9d, -0xd7, 0x78, 0x10, 0x54, 0x6a, 0x2d, 0xa0, 0x00, +0x21, 0xdc, 0x28, 0x79, 0x99, 0x3b, 0x3c, 0xc8, +0x72, 0x2c, 0x47, 0xad, 0xef, 0x17, 0x53, 0x5f, +0x68, 0x20, 0x27, 0x79, 0x5b, 0x3c, 0x51, 0x8a, +0xa2, 0x0c, 0x03, 0xd7, 0x7c, 0x99, 0xaa, 0x3f, +0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, +0x01, 0x22, 0x21, 0x1b, 0x71, 0xbe, 0x5f, 0x51, +0xaa, 0xfc, 0x55, 0xb3, 0x08, 0x60, 0x20, 0xb2, +0x83, 0x80, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x26, 0xc4, 0x0e, 0xfa, +0xee, 0xb4, 0x3b, 0x93, 0x03, 0x04, 0x51, 0x02, +0x00, 0x8d, 0x01, 0x22, 0x21, 0x35, 0xc7, 0x37, +0xfc, 0xd6, 0x8c, 0x67, 0xcd, 0xeb, 0x83, 0xbe, +0x1a, 0x50, 0x07, 0x37, 0x99, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x51, +0xc0, 0x3a, 0x79, 0xb7, 0xdc, 0xdd, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x9a, +0x69, 0x17, 0x2a, 0x56, 0x7d, 0xb6, 0x45, 0xe4, +0xb3, 0x65, 0x08, 0xaf, 0xc8, 0x68, 0x47, 0xb7, +0xbc, 0x69, 0xab, 0xa2, 0x40, 0xd1, 0xdd, 0x87, +0xab, 0xd6, 0x20, 0xd4, 0xc5, 0x09, 0x19, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8f, 0x01, 0x22, -0x21, 0xba, 0xbc, 0xd0, 0xf2, 0x11, 0x14, 0x7d, -0x1c, 0x32, 0x6a, 0x9f, 0xa9, 0x21, 0x30, 0x3b, -0xa0, 0xa8, 0x4c, 0xb2, 0xc1, 0x42, 0x79, 0x46, -0xa6, 0x57, 0x7e, 0xa5, 0xb0, 0x03, 0x2e, 0xf6, -0x54, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, -0x01, 0x22, 0x21, 0xfa, 0x50, 0x73, 0xa7, 0x60, -0x62, 0x71, 0x62, 0x7a, 0x35, 0x12, 0xaa, 0x08, -0x12, 0x77, 0x94, 0x55, 0x6f, 0xb4, 0xcf, 0xd8, -0x4c, 0x57, 0x0b, 0x32, 0x74, 0xff, 0xd4, 0x9b, -0xc0, 0xaf, 0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x91, 0x01, 0x22, 0x21, 0x4f, 0x1b, 0xd6, -0xb5, 0xd1, 0x14, 0xa4, 0xaf, 0x11, 0x7a, 0x5a, -0x9a, 0xd4, 0x1f, 0xb8, 0xc8, 0xbb, 0xcd, 0xc0, -0x12, 0x47, 0x51, 0x51, 0x6c, 0xb5, 0x27, 0xce, -0xb7, 0x58, 0xb8, 0x9f, 0x90, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0xd5, -0xe2, 0x33, 0xc6, 0x0c, 0x31, 0x0b, 0xe5, 0x63, -0xc4, 0x25, 0x9a, 0x68, 0x75, 0x91, 0x31, 0x1b, -0x2e, 0x51, 0xb2, 0xa9, 0xf1, 0x31, 0xa6, 0xfe, -0x91, 0x89, 0x4d, 0x12, 0xfd, 0x0a, 0x5e, 0x00, +0x21, 0xda, 0x65, 0x32, 0x3c, 0xd7, 0xf4, 0xab, +0xaf, 0x8c, 0x83, 0x9c, 0x04, 0xc2, 0x65, 0xd9, +0x43, 0x54, 0xe5, 0xd8, 0x5e, 0x20, 0xe9, 0xdc, +0x2c, 0xb6, 0x40, 0xc8, 0x80, 0xd9, 0x23, 0x5c, +0x99, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, +0x01, 0x22, 0x21, 0xd4, 0x08, 0xd2, 0x8a, 0xd8, +0x56, 0x5c, 0x73, 0x6e, 0x54, 0x02, 0x23, 0x7b, +0x61, 0x3a, 0x5f, 0x12, 0x8a, 0x91, 0xfd, 0x65, +0x95, 0x51, 0xb2, 0xbd, 0x70, 0x6c, 0x69, 0x06, +0xfb, 0x7a, 0x43, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x91, 0x01, 0x22, 0x21, 0xde, 0x4e, 0x63, +0xd5, 0xd7, 0x08, 0xdf, 0xbb, 0xc3, 0x9f, 0x39, +0x6b, 0xfd, 0xb0, 0x49, 0x39, 0x1e, 0xe2, 0xd1, +0x2a, 0x6b, 0xaf, 0x1d, 0x70, 0xff, 0x4c, 0xe5, +0x85, 0x08, 0x2b, 0xb2, 0xcf, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0xc9, +0x9a, 0xbf, 0x67, 0x80, 0x62, 0x88, 0x1c, 0xd8, +0x4c, 0xf2, 0x70, 0x54, 0xd5, 0xa2, 0x9f, 0x36, +0x49, 0xb2, 0xa4, 0x22, 0x22, 0x1a, 0x84, 0x9d, +0xdd, 0xb6, 0xf9, 0xca, 0xe1, 0x46, 0x50, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x93, 0x01, 0x22, -0x21, 0x55, 0xd1, 0x21, 0x72, 0x3e, 0x67, 0xd6, -0x1f, 0x0e, 0x1a, 0xed, 0x9d, 0x4e, 0xbc, 0x35, -0x05, 0xd7, 0x0f, 0x1c, 0x84, 0xbb, 0x87, 0xf2, -0x9d, 0x44, 0x2a, 0x2f, 0xe1, 0x43, 0xce, 0x4c, -0x25, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, -0x01, 0x22, 0x21, 0x03, 0xe0, 0x26, 0xf7, 0xc7, -0x5b, 0x68, 0xa2, 0x1f, 0x1d, 0xcb, 0x0d, 0x2f, -0x75, 0x28, 0xcc, 0x1b, 0xe3, 0x6f, 0x96, 0x63, -0x7f, 0xcc, 0x53, 0x43, 0xd6, 0x6d, 0x31, 0x5d, -0xc2, 0x59, 0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x95, 0x01, 0x22, 0x21, 0xdc, 0x2f, 0x20, -0x24, 0xa1, 0xb9, 0x56, 0x6a, 0x6e, 0x80, 0x98, -0x6a, 0x09, 0x37, 0x33, 0x0d, 0x37, 0xd8, 0x5f, -0xa9, 0x1e, 0xff, 0x6a, 0xb3, 0x62, 0x84, 0x1c, -0xc7, 0x99, 0x5c, 0x69, 0x91, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0x2d, -0x48, 0xe7, 0xe5, 0x58, 0x05, 0xb9, 0x0c, 0x24, -0xcf, 0x75, 0x1b, 0x2b, 0x85, 0xd5, 0xab, 0x97, -0x0f, 0x94, 0xd7, 0x76, 0x84, 0x83, 0xbd, 0x84, -0xee, 0x58, 0x29, 0x0b, 0x13, 0x57, 0xa0, 0x00, +0x21, 0xf3, 0x61, 0xe9, 0x40, 0x14, 0x88, 0x8e, +0x2d, 0xad, 0x27, 0x84, 0xcd, 0xca, 0x77, 0x74, +0x84, 0xd7, 0x7e, 0x93, 0xcf, 0x5f, 0x85, 0xdd, +0xf7, 0x49, 0xc9, 0xcf, 0x5e, 0x01, 0x93, 0xcc, +0xab, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, +0x01, 0x22, 0x21, 0x09, 0x1e, 0xba, 0x7d, 0x33, +0xcd, 0x6f, 0xd1, 0x5c, 0xa0, 0x32, 0x96, 0x11, +0xa8, 0x66, 0xe9, 0x76, 0x96, 0xc0, 0x6f, 0xeb, +0x2c, 0xee, 0x9e, 0x96, 0xb3, 0x97, 0x06, 0xd5, +0x89, 0xb2, 0xf7, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x95, 0x01, 0x22, 0x21, 0x52, 0x90, 0x7b, +0x7d, 0xbe, 0xea, 0x52, 0xe0, 0x2c, 0xf1, 0x2d, +0x3c, 0x36, 0x1e, 0xbe, 0xe9, 0x70, 0xed, 0x6a, +0xbe, 0xea, 0x5d, 0x4d, 0xff, 0x86, 0x61, 0xeb, +0x3f, 0x36, 0x12, 0x02, 0x91, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0x0f, +0x85, 0x02, 0xf3, 0x92, 0xc3, 0x00, 0xce, 0x70, +0x09, 0x63, 0x5c, 0x1a, 0xb8, 0x7a, 0xf7, 0x07, +0xaf, 0x46, 0xcc, 0x0c, 0x43, 0x91, 0xf7, 0x16, +0x45, 0xa7, 0x0c, 0x4c, 0x7b, 0x19, 0xfd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x97, 0x01, 0x22, -0x21, 0x53, 0x4d, 0xfb, 0x4b, 0x24, 0xea, 0x76, -0x7c, 0xf2, 0xe8, 0x29, 0x93, 0xda, 0xc9, 0xce, -0x7a, 0x75, 0xa7, 0xfa, 0x79, 0xaa, 0xc7, 0xb7, -0x20, 0xbd, 0xac, 0xe0, 0x6d, 0x40, 0xc5, 0x1d, -0xea, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, -0x01, 0x22, 0x21, 0x11, 0x68, 0x56, 0xd2, 0xd3, -0x40, 0x9d, 0x0b, 0x41, 0x07, 0x02, 0x26, 0x19, -0xba, 0xc6, 0xbd, 0x39, 0x88, 0x2a, 0xee, 0xf4, -0x64, 0x9e, 0x47, 0x60, 0xfc, 0xa9, 0xcc, 0x7e, -0x95, 0xe4, 0x06, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x99, 0x01, 0x22, 0x21, 0x13, 0x44, 0x0d, -0xb2, 0x37, 0x4e, 0x51, 0x66, 0x2b, 0x84, 0x59, -0x67, 0x2d, 0x95, 0x33, 0x0e, 0xc8, 0x89, 0xb8, -0x31, 0x81, 0x82, 0xff, 0x53, 0x7a, 0x34, 0x0a, -0x76, 0xb4, 0x7a, 0xa3, 0xe3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0xb9, -0x23, 0x9e, 0x20, 0x05, 0xa9, 0x60, 0x8d, 0x5a, -0x13, 0x2a, 0xe9, 0x14, 0x84, 0x05, 0x1a, 0x3d, -0xa7, 0xdb, 0xea, 0x49, 0x63, 0x37, 0xc5, 0x20, -0x44, 0xe8, 0x11, 0x53, 0x9b, 0x63, 0xe8, 0x00, +0x21, 0x65, 0xd7, 0xe1, 0x40, 0xa6, 0x12, 0x11, +0x0b, 0xe3, 0xc9, 0x67, 0x03, 0x57, 0x56, 0x40, +0x5d, 0x8c, 0x40, 0x8d, 0x5a, 0x84, 0xe1, 0xb5, +0xe8, 0xa7, 0x82, 0x17, 0xb7, 0xd6, 0x07, 0xf2, +0x6f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, +0x01, 0x22, 0x21, 0x4d, 0x09, 0xdc, 0xac, 0xac, +0x44, 0x24, 0xc9, 0x62, 0xce, 0x86, 0x47, 0x54, +0x57, 0xe8, 0x7c, 0x77, 0x2a, 0x15, 0xcc, 0x4d, +0xa3, 0x9f, 0xc0, 0xf6, 0x9d, 0xa2, 0x74, 0xcd, +0x78, 0xd8, 0x70, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x99, 0x01, 0x22, 0x21, 0xd3, 0x98, 0x8a, +0x02, 0x3e, 0xa1, 0xbc, 0x82, 0x7e, 0xb3, 0x16, +0xbb, 0x56, 0x68, 0xa6, 0x05, 0x53, 0x14, 0x85, +0x5f, 0xed, 0xd4, 0xd9, 0xde, 0x34, 0xb0, 0x11, +0x18, 0xf1, 0x59, 0x4a, 0xb8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0xb3, +0xb5, 0xbd, 0xe2, 0x51, 0x7a, 0x00, 0x6d, 0x18, +0x87, 0xa4, 0x1a, 0x67, 0x7d, 0xb6, 0x3f, 0x50, +0xe6, 0xab, 0x3b, 0x6d, 0x1f, 0x3f, 0x06, 0x82, +0x94, 0x7d, 0xf1, 0x89, 0xbb, 0x0b, 0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9b, 0x01, 0x22, -0x21, 0x7b, 0x75, 0x90, 0xd1, 0xb5, 0x0f, 0x8b, -0x2d, 0xe9, 0xa5, 0xa7, 0xd6, 0x6d, 0x75, 0xde, -0xcc, 0xce, 0x0e, 0xfc, 0xc9, 0x1a, 0x23, 0xbf, -0x43, 0x88, 0xa0, 0x0f, 0x9a, 0xc4, 0x53, 0x26, -0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, -0x01, 0x22, 0x21, 0x4c, 0xdb, 0x2c, 0xec, 0x6e, -0x84, 0x31, 0x56, 0x25, 0x31, 0xf5, 0x7e, 0x9b, -0x2c, 0x81, 0xec, 0xcc, 0xc6, 0x21, 0x81, 0xba, -0x96, 0x09, 0x08, 0xfc, 0xa6, 0x33, 0x12, 0x99, -0x60, 0xe1, 0x27, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x9d, 0x01, 0x22, 0x21, 0x1f, 0x7f, 0xf3, -0x22, 0xc6, 0x82, 0x19, 0x95, 0x7d, 0xa8, 0x96, -0x6a, 0xec, 0xc1, 0x4a, 0x5c, 0x9c, 0x7f, 0xef, -0x2b, 0xe5, 0xae, 0x40, 0x5c, 0x7c, 0xde, 0xe2, -0x7c, 0x5c, 0x54, 0x4f, 0x97, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0x74, -0xec, 0xcc, 0x15, 0x6a, 0xf5, 0x6f, 0xea, 0xc3, -0xa5, 0xb5, 0x16, 0x7e, 0x97, 0xf0, 0x3e, 0x34, -0x32, 0x77, 0x4d, 0x56, 0x1a, 0x9e, 0xf5, 0x9c, -0xf6, 0x78, 0x33, 0xae, 0x23, 0xb2, 0x9f, 0x00, +0x21, 0xfc, 0xbc, 0xe3, 0x4b, 0xc2, 0xbf, 0x57, +0xdf, 0xa6, 0x14, 0xee, 0x43, 0x2f, 0x50, 0xc0, +0xf0, 0xda, 0xc1, 0xaf, 0x96, 0x42, 0x04, 0x09, +0x4c, 0xe1, 0x65, 0x95, 0xa9, 0xfc, 0x46, 0x43, +0x22, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, +0x01, 0x22, 0x21, 0xaa, 0x98, 0x7a, 0xeb, 0xb1, +0xab, 0x9b, 0xc1, 0x2c, 0xfb, 0x1c, 0xf7, 0x46, +0x17, 0x4d, 0x60, 0x88, 0x2c, 0xdf, 0x4f, 0x46, +0x49, 0x7c, 0x59, 0xee, 0x5e, 0x76, 0x2c, 0xba, +0x0a, 0x75, 0xb9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x9d, 0x01, 0x22, 0x21, 0x7a, 0x08, 0xd1, +0x98, 0xfd, 0x52, 0xcb, 0xc8, 0x62, 0x13, 0xd7, +0xd0, 0xf4, 0x40, 0xca, 0xc0, 0xda, 0x58, 0x92, +0xff, 0x33, 0xfb, 0xf7, 0xf7, 0x85, 0x72, 0x87, +0xff, 0x08, 0x9b, 0xcd, 0xc7, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0xd6, +0xe4, 0x9e, 0x8b, 0x2d, 0x39, 0xac, 0xf6, 0x6d, +0x6c, 0x1a, 0xac, 0xeb, 0x9c, 0x8b, 0x2f, 0xdb, +0x5f, 0xfc, 0x09, 0x75, 0xb8, 0xad, 0x48, 0x99, +0x44, 0x7e, 0x5b, 0x10, 0x56, 0x0b, 0xae, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9f, 0x01, 0x22, -0x21, 0x90, 0x38, 0xd4, 0xbc, 0x9f, 0x7a, 0xef, -0x08, 0x36, 0x11, 0xb6, 0x27, 0x8f, 0x5a, 0x0f, -0x67, 0x59, 0xfe, 0x49, 0xbb, 0x7c, 0x77, 0x1a, -0x75, 0x5a, 0xb4, 0xc6, 0x2e, 0x44, 0xdf, 0x05, -0xac, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, -0x01, 0x22, 0x21, 0x3f, 0x36, 0xe8, 0x60, 0x8b, -0x81, 0x02, 0x70, 0x97, 0x20, 0x71, 0x41, 0x5f, -0x59, 0xe8, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x31, 0xb2, 0x4b, 0xcb, -0xee, 0x54, 0x94, 0xb7, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa1, 0x01, 0x22, 0x21, 0xf0, 0xae, 0x4a, -0x26, 0x09, 0xd0, 0xc7, 0x38, 0x04, 0x36, 0x9b, -0x4a, 0xe3, 0x27, 0x99, 0xaf, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xa2, -0xa1, 0x44, 0x06, 0x4e, 0x23, 0x61, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xe7, -0x98, 0xb3, 0x70, 0x76, 0xf3, 0x10, 0x0f, 0x49, -0x6c, 0x4e, 0x8d, 0xb5, 0xd2, 0xf4, 0xb1, 0x20, -0xe8, 0xf1, 0x14, 0xdb, 0x40, 0xd6, 0xfe, 0xb7, -0xb8, 0xab, 0x74, 0x89, 0x37, 0xcf, 0xcb, 0x00, +0x21, 0x8d, 0x35, 0x85, 0x46, 0x8f, 0x30, 0x3b, +0xef, 0x61, 0x06, 0xf1, 0x98, 0xb7, 0x05, 0xf5, +0x8b, 0x5b, 0x2b, 0x7c, 0xa4, 0xd0, 0x47, 0x80, +0x0a, 0x5c, 0x71, 0xff, 0x3c, 0x92, 0xe6, 0x25, +0xab, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, +0x01, 0x22, 0x21, 0x67, 0x51, 0xe7, 0xe5, 0x47, +0x9f, 0x8c, 0x59, 0x6f, 0x1a, 0x36, 0x11, 0x52, +0xbb, 0x57, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7e, 0xf3, 0x8c, 0x61, +0xc3, 0xc3, 0xa4, 0xf8, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa1, 0x01, 0x22, 0x21, 0x6a, 0x95, 0x01, +0xf4, 0xcf, 0xdb, 0x49, 0xc2, 0xa7, 0xc0, 0xcc, +0xa5, 0x91, 0xa7, 0xfc, 0x1b, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xc2, +0x78, 0x06, 0x40, 0xbd, 0x04, 0xb4, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xd9, +0x0f, 0x6d, 0x89, 0x44, 0x64, 0x06, 0xa0, 0xae, +0x77, 0x88, 0xfc, 0x0e, 0x34, 0xe2, 0x17, 0x01, +0xbe, 0xc0, 0xb3, 0xec, 0x43, 0xbe, 0xbc, 0x35, +0xb9, 0xe0, 0xa5, 0xd9, 0x6b, 0xe6, 0xc3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa3, 0x01, 0x22, -0x21, 0x6a, 0x5d, 0x8a, 0xe8, 0x0b, 0x83, 0x39, -0xf3, 0x66, 0x90, 0xd2, 0xe7, 0x86, 0xc6, 0xd4, -0xc5, 0xe7, 0x50, 0x03, 0x21, 0x2b, 0xc4, 0xf9, -0x2d, 0x1a, 0x43, 0xd9, 0x39, 0xb7, 0xfc, 0x38, -0xba, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, -0x01, 0x22, 0x21, 0xdb, 0x01, 0x15, 0xc4, 0x4c, -0x4f, 0xab, 0x87, 0x81, 0xfa, 0x29, 0x57, 0xf2, -0xb2, 0xe9, 0x68, 0x1a, 0xdf, 0x23, 0x63, 0x9f, -0x15, 0x72, 0x30, 0x8e, 0x4d, 0x41, 0xd4, 0x46, -0x77, 0x6a, 0x78, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa5, 0x01, 0x22, 0x21, 0xd0, 0x94, 0xde, -0xe8, 0xa3, 0x6a, 0xde, 0x32, 0xa4, 0x3f, 0xdd, -0xc2, 0xd3, 0x38, 0x68, 0xb1, 0x3b, 0x9a, 0xac, -0xc9, 0x98, 0x97, 0x22, 0xe3, 0x6f, 0x15, 0x24, -0x65, 0x8d, 0xf5, 0xb7, 0x32, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0x59, -0x3c, 0x36, 0x82, 0x24, 0x07, 0x23, 0xee, 0xb2, -0x4e, 0x56, 0xd0, 0x01, 0xcb, 0x0b, 0x6f, 0xdc, -0x68, 0x36, 0x32, 0xbc, 0xe2, 0x01, 0x1b, 0x46, -0xbd, 0x9d, 0x7a, 0x15, 0x78, 0xd9, 0xad, 0x00, +0x21, 0xd4, 0xdc, 0x45, 0xdd, 0x36, 0xf2, 0x52, +0x10, 0x31, 0x60, 0xd3, 0x49, 0x58, 0xc5, 0xcc, +0xe6, 0xea, 0x33, 0x06, 0xc7, 0xf0, 0x05, 0x7d, +0xe8, 0xf9, 0x78, 0xd6, 0x88, 0x6d, 0x63, 0xee, +0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, +0x01, 0x22, 0x21, 0x7b, 0x88, 0x80, 0xbd, 0xcb, +0x1c, 0x8c, 0xf1, 0xe1, 0x71, 0x61, 0xed, 0x6a, +0x69, 0xf3, 0x93, 0xae, 0x77, 0xda, 0x62, 0x85, +0x1e, 0x92, 0x7b, 0x2f, 0x03, 0x1a, 0x56, 0x53, +0x5b, 0xe9, 0xec, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa5, 0x01, 0x22, 0x21, 0xe0, 0x5b, 0xb5, +0x31, 0x2f, 0xe2, 0x71, 0x35, 0x30, 0xc1, 0xba, +0xb0, 0x01, 0xb2, 0xf3, 0x5a, 0x5f, 0x3e, 0x25, +0x6b, 0x0b, 0x97, 0x47, 0x59, 0x6f, 0x04, 0xd3, +0xd9, 0x99, 0x44, 0x81, 0x44, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0x5a, +0x70, 0x86, 0x0c, 0xaa, 0xa3, 0x8c, 0x65, 0x4b, +0xeb, 0x75, 0xe0, 0xd8, 0xdd, 0x4b, 0xce, 0x9a, +0xee, 0x97, 0x1f, 0x01, 0xc6, 0xf1, 0x6b, 0x3d, +0x68, 0xb4, 0x9a, 0x24, 0x8b, 0x53, 0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa7, 0x01, 0x22, -0x21, 0xf0, 0x51, 0x05, 0xfe, 0x01, 0xa4, 0x87, -0xc3, 0xfc, 0xcc, 0xff, 0x6d, 0x4e, 0xe5, 0x43, -0xfa, 0xb8, 0xe3, 0x68, 0xca, 0x4a, 0xbc, 0x84, -0x32, 0x1b, 0x54, 0x91, 0x3c, 0x35, 0x67, 0xc5, -0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, -0x01, 0x22, 0x21, 0x55, 0x1e, 0xe2, 0xc1, 0xd6, -0x8e, 0x5b, 0x0d, 0xfd, 0xb6, 0xc7, 0x3f, 0xe1, -0x53, 0x10, 0x6d, 0x04, 0xfd, 0x02, 0xb4, 0x4d, -0x83, 0x94, 0xea, 0x91, 0x86, 0x1f, 0x84, 0xfe, -0xab, 0x6c, 0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa9, 0x01, 0x22, 0x21, 0xc5, 0x60, 0x1c, -0xb5, 0xdd, 0xcd, 0x03, 0x95, 0xc8, 0x5b, 0xb0, -0xa9, 0x67, 0xfa, 0xbb, 0x74, 0xfb, 0x28, 0x37, -0xe7, 0x3a, 0xd9, 0xa0, 0x5a, 0xb6, 0x4a, 0xe4, -0x08, 0xb5, 0x89, 0x15, 0x91, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0xb7, -0x71, 0xba, 0x27, 0xb4, 0x77, 0x8b, 0x09, 0x25, -0x58, 0x2b, 0x2b, 0x81, 0x91, 0x47, 0xe6, 0x5f, -0xe2, 0x75, 0x48, 0x34, 0x16, 0xd4, 0x8b, 0xb5, -0x2d, 0x6d, 0xa6, 0x0a, 0x4c, 0xe5, 0x05, 0x00, +0x21, 0x36, 0x73, 0x97, 0xec, 0xfd, 0xba, 0x21, +0x4b, 0x3c, 0xca, 0x07, 0xba, 0x95, 0x5b, 0xf3, +0x9f, 0x40, 0xc8, 0x9e, 0x48, 0x44, 0xfc, 0x70, +0x39, 0xda, 0xf0, 0x08, 0x2a, 0xf0, 0x31, 0xac, +0x73, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, +0x01, 0x22, 0x21, 0xe4, 0x47, 0x5c, 0xb8, 0x64, +0x9f, 0x23, 0x16, 0xc9, 0x07, 0xb6, 0x5d, 0x6b, +0x24, 0x2f, 0x3f, 0x3d, 0xe0, 0x6d, 0xec, 0xf2, +0xbf, 0x9c, 0x8f, 0x10, 0xd1, 0x7b, 0xdb, 0x4e, +0xa1, 0x02, 0x9c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa9, 0x01, 0x22, 0x21, 0x73, 0x95, 0x15, +0x06, 0xba, 0x2b, 0x6b, 0xfd, 0xcb, 0x4f, 0x6e, +0x66, 0x35, 0x58, 0xd3, 0x8b, 0xd6, 0x13, 0x02, +0x1a, 0xed, 0x43, 0x6d, 0x79, 0xaa, 0x7f, 0x78, +0x2b, 0xba, 0xf9, 0xd7, 0xc8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x96, +0x42, 0x33, 0x82, 0xda, 0xb9, 0x10, 0xea, 0x56, +0xce, 0x1c, 0xe5, 0xfc, 0x30, 0x67, 0x37, 0x6b, +0x34, 0xe5, 0x57, 0x56, 0xd5, 0x5e, 0x3c, 0x10, +0x90, 0x64, 0x5f, 0xb9, 0x84, 0x66, 0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xab, 0x01, 0x22, -0x21, 0x1d, 0xc3, 0x0d, 0x3f, 0xd7, 0x60, 0xde, -0x9b, 0xca, 0x29, 0x70, 0x66, 0x80, 0x67, 0x96, -0x99, 0x56, 0x10, 0x47, 0x35, 0xe5, 0x7d, 0x9d, -0x02, 0x18, 0xd2, 0xa3, 0x18, 0xc2, 0xe8, 0x49, -0x4e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, -0x01, 0x22, 0x21, 0x56, 0xb8, 0xad, 0x39, 0x9e, -0xfc, 0xe4, 0x9e, 0x4a, 0xdd, 0xdc, 0x6f, 0x60, -0xb4, 0xce, 0x7f, 0xbf, 0x0c, 0xdf, 0x1b, 0x90, -0x3b, 0x0e, 0x9f, 0xdd, 0x88, 0xc5, 0x97, 0xdc, -0xd4, 0x15, 0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xad, 0x01, 0x22, 0x21, 0x05, 0x22, 0x73, -0x1f, 0x0d, 0x38, 0x6c, 0xc8, 0xf6, 0xf9, 0x1b, -0x97, 0x5f, 0x07, 0xa4, 0x84, 0x12, 0xb7, 0xb1, -0x84, 0xde, 0x0e, 0x19, 0xcf, 0xa5, 0xf4, 0x63, -0xf7, 0x1f, 0x53, 0x45, 0x8c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0xe6, -0xa2, 0xaa, 0x08, 0x6b, 0x2a, 0xbe, 0xcb, 0x0a, -0xd7, 0x39, 0x22, 0x7c, 0xfe, 0x00, 0xa0, 0x67, -0x0f, 0x14, 0xaf, 0x00, 0x46, 0xd6, 0x0b, 0xc1, -0x89, 0x27, 0x59, 0x36, 0x54, 0x5b, 0xf3, 0x00, +0x21, 0x00, 0xd0, 0x09, 0xde, 0xb1, 0x69, 0xef, +0x13, 0x22, 0xf7, 0x82, 0x54, 0x14, 0xc1, 0x88, +0xaf, 0xfe, 0xe0, 0xa7, 0x7d, 0xfd, 0x43, 0xb2, +0x48, 0xa7, 0x67, 0x3c, 0x1e, 0x68, 0x81, 0x3e, +0xa0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, +0x01, 0x22, 0x21, 0xb6, 0xaf, 0x4e, 0x77, 0xcb, +0xdd, 0x56, 0x86, 0xbc, 0x68, 0xbd, 0xd6, 0xf6, +0x71, 0x87, 0x0b, 0x21, 0x1f, 0xc6, 0xee, 0x60, +0xb3, 0x13, 0xd0, 0xd6, 0x03, 0xeb, 0xfe, 0x4f, +0x1f, 0xf6, 0x1f, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xad, 0x01, 0x22, 0x21, 0xbb, 0xcf, 0xc9, +0xf0, 0xee, 0x40, 0x23, 0x4e, 0xc6, 0x2e, 0xe4, +0xf1, 0xc5, 0x02, 0x11, 0x38, 0x9f, 0x37, 0xbc, +0xa2, 0x7e, 0x5a, 0xe4, 0x08, 0xce, 0x5d, 0x9d, +0x7b, 0xcc, 0xde, 0x17, 0x41, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0x62, +0x98, 0x67, 0xd1, 0x44, 0xc0, 0xc2, 0x6f, 0xa8, +0x4b, 0xb2, 0x07, 0xb9, 0x8a, 0x83, 0x8d, 0xc6, +0x2e, 0x10, 0x97, 0xcb, 0x63, 0x88, 0x7a, 0xf0, +0x3e, 0x8b, 0x8b, 0x81, 0x92, 0xf6, 0xbf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xaf, 0x01, 0x22, -0x21, 0x83, 0xca, 0xef, 0x4f, 0xc6, 0x77, 0x5a, -0x45, 0x92, 0x3d, 0x5d, 0x6a, 0xb9, 0xa8, 0xa0, -0xc6, 0x7b, 0xc1, 0xa5, 0xe1, 0x9a, 0x49, 0x64, -0x46, 0x50, 0xe1, 0x5f, 0x00, 0xdd, 0x82, 0x05, -0x03, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, -0x01, 0x22, 0x21, 0x01, 0x4f, 0xa9, 0x23, 0x35, -0x94, 0x11, 0x8a, 0xc5, 0xd7, 0xc4, 0x27, 0x51, -0x70, 0xb1, 0xa7, 0x32, 0x8a, 0x77, 0x8b, 0x91, -0x8b, 0x51, 0xdf, 0xc4, 0x2b, 0x28, 0x2d, 0xf4, -0xf6, 0x38, 0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb1, 0x01, 0x22, 0x21, 0xbd, 0x35, 0x61, -0x2f, 0xb7, 0x60, 0xd1, 0x27, 0x4f, 0xf8, 0x04, -0xee, 0x3b, 0xdd, 0xf5, 0x58, 0x41, 0xce, 0x6b, -0x3b, 0x09, 0x77, 0x03, 0x45, 0x4f, 0x25, 0x84, -0x07, 0x2a, 0x09, 0x6f, 0x03, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0xd8, -0x7c, 0xf8, 0xca, 0x2d, 0x0f, 0x53, 0xdd, 0xf2, -0x00, 0x1c, 0xab, 0x55, 0x94, 0x62, 0xf9, 0x66, -0x67, 0xc4, 0x3f, 0x93, 0xb1, 0xea, 0xdb, 0x02, -0x3f, 0x3f, 0x05, 0x67, 0x31, 0x28, 0xce, 0x00, +0x21, 0x76, 0x1f, 0xc1, 0x81, 0xf5, 0xe3, 0x6c, +0x97, 0x6f, 0x2a, 0x83, 0x6a, 0x98, 0xa8, 0x47, +0x08, 0x93, 0x4a, 0x25, 0xcd, 0xfc, 0x2e, 0x4f, +0x1d, 0xf1, 0x81, 0xd8, 0x45, 0xf9, 0x00, 0x7e, +0x27, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, +0x01, 0x22, 0x21, 0xd5, 0x60, 0xf9, 0x2a, 0x0e, +0x80, 0x01, 0x9b, 0x26, 0xf7, 0x82, 0x68, 0x02, +0x80, 0x9a, 0x0d, 0xee, 0x8f, 0x0a, 0x2c, 0xca, +0x6d, 0xef, 0xfe, 0x63, 0x5f, 0xbf, 0xd8, 0x08, +0xbb, 0xd1, 0x29, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb1, 0x01, 0x22, 0x21, 0x29, 0x8b, 0x7f, +0xe0, 0xf3, 0xf1, 0x44, 0xc3, 0xc5, 0xb5, 0x50, +0x39, 0xdf, 0x38, 0xf6, 0x7d, 0xd6, 0x72, 0xaf, +0x9f, 0x76, 0x71, 0xbf, 0x63, 0xa9, 0x16, 0xd6, +0x94, 0x31, 0x40, 0x25, 0xe5, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0x5c, +0x37, 0x5c, 0xae, 0x4f, 0x12, 0xdf, 0x06, 0xae, +0x63, 0xed, 0xc7, 0x6e, 0xc6, 0xb8, 0x8e, 0x16, +0xfc, 0x80, 0x1d, 0x70, 0xc6, 0xdf, 0x07, 0xcf, +0x50, 0xee, 0x14, 0x0e, 0x86, 0x58, 0x77, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb3, 0x01, 0x22, -0x21, 0xc4, 0x7e, 0x98, 0x2f, 0xa1, 0x08, 0x68, -0x0b, 0x8e, 0x8e, 0x16, 0xd7, 0xe1, 0x17, 0x63, -0x37, 0xf9, 0xe8, 0xf2, 0x3f, 0x9a, 0x74, 0x92, -0x67, 0xe2, 0x0e, 0x3f, 0xc1, 0x6f, 0xca, 0x35, -0xe7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, -0x01, 0x22, 0x21, 0xda, 0x64, 0x8a, 0xe4, 0xce, -0xf5, 0x12, 0x5d, 0xe0, 0x15, 0xfd, 0x8c, 0xed, -0x5f, 0x02, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xcc, 0x17, 0x0b, 0x33, -0xbc, 0x63, 0xca, 0x5a, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb5, 0x01, 0x22, 0x21, 0xdc, 0xd7, 0x01, -0xba, 0x74, 0x8b, 0xa2, 0xe8, 0x06, 0x75, 0x74, -0x11, 0x91, 0xc7, 0xa5, 0xc9, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x26, -0x48, 0x1d, 0x97, 0x9c, 0xcc, 0x8b, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0x5b, -0x6a, 0x16, 0x15, 0x55, 0xd6, 0x60, 0xe5, 0xa7, -0x64, 0x46, 0xf2, 0x9e, 0x87, 0x40, 0xcb, 0x7f, -0xc3, 0x9e, 0xce, 0x82, 0x15, 0xe5, 0x35, 0x68, -0xa5, 0x11, 0xf2, 0x5d, 0x7f, 0xd2, 0x63, 0x00, +0x21, 0xf5, 0x39, 0xe3, 0x53, 0xa1, 0xd8, 0x4f, +0xc6, 0xf1, 0x9b, 0xd0, 0xc2, 0xf6, 0x28, 0xb9, +0x68, 0xb8, 0xd5, 0x85, 0x08, 0x68, 0xed, 0x8e, +0x9a, 0xe4, 0x4b, 0xb0, 0x7b, 0xce, 0x2c, 0x79, +0x2f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, +0x01, 0x22, 0x21, 0xcd, 0x46, 0x3b, 0x54, 0xbd, +0x27, 0x4f, 0xa6, 0x75, 0x7e, 0x9e, 0x9d, 0x93, +0x13, 0x43, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x4a, 0x65, 0x61, 0x48, +0x33, 0x83, 0xc2, 0x09, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb5, 0x01, 0x22, 0x21, 0x96, 0x45, 0x5a, +0x57, 0x0a, 0x6a, 0x3f, 0xa2, 0x20, 0xcd, 0xa2, +0x70, 0x37, 0x1b, 0x2e, 0xa1, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0xf7, +0xde, 0xcb, 0x79, 0x42, 0x87, 0xa9, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0xe4, +0xbc, 0x7b, 0x97, 0xee, 0x94, 0xf6, 0x00, 0xb4, +0x9b, 0xa9, 0xa6, 0x20, 0x4f, 0x20, 0x3c, 0xc5, +0x35, 0x85, 0xee, 0x92, 0x4c, 0x96, 0x65, 0x10, +0x9b, 0x90, 0xae, 0x0b, 0xe6, 0x4b, 0xad, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb7, 0x01, 0x22, -0x21, 0xed, 0x51, 0x17, 0x60, 0x84, 0xcd, 0x41, -0x38, 0x69, 0xb6, 0x15, 0x5e, 0x5e, 0xd5, 0xad, -0xd7, 0xa8, 0xa8, 0x89, 0x2b, 0x99, 0x9b, 0xa8, -0xad, 0xd9, 0x21, 0x54, 0x2a, 0x68, 0xd7, 0x8a, -0x02, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, -0x01, 0x22, 0x21, 0xd7, 0xfb, 0x9a, 0xe6, 0x28, -0x96, 0xa5, 0x97, 0xf2, 0x65, 0xf2, 0x2c, 0x30, -0x34, 0xb2, 0x59, 0xa7, 0xcd, 0x7d, 0xb2, 0xc4, -0x88, 0x58, 0x46, 0x2c, 0x96, 0xfe, 0x22, 0x32, -0x3d, 0x9c, 0x67, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb9, 0x01, 0x22, 0x21, 0x2e, 0xca, 0x86, -0x9e, 0x6a, 0xf5, 0x59, 0xb7, 0x96, 0x7e, 0x69, -0xc2, 0x13, 0xd5, 0xc8, 0x49, 0x77, 0xc9, 0x5c, -0xe6, 0xae, 0xa6, 0x34, 0xac, 0x75, 0x2f, 0x24, -0x94, 0x1e, 0xee, 0x13, 0x40, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0xa1, -0xe2, 0x90, 0xa8, 0xd0, 0x97, 0xd4, 0xfe, 0xc4, -0x8d, 0x44, 0x68, 0x0a, 0xa9, 0xb1, 0xb2, 0x39, -0xeb, 0xb7, 0x15, 0x0e, 0xb8, 0x14, 0x1f, 0x8d, -0x30, 0x05, 0xe2, 0xda, 0xf3, 0x6a, 0xb1, 0x00, +0x21, 0xb4, 0xb2, 0x75, 0x4c, 0x08, 0x9c, 0xc8, +0x00, 0x4c, 0x0f, 0xde, 0x82, 0xc4, 0x7c, 0x06, +0x98, 0x79, 0xd7, 0x0b, 0xfa, 0x3a, 0x32, 0x7c, +0xc0, 0x66, 0x1e, 0x27, 0xe3, 0x6e, 0x8d, 0xe7, +0xdb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, +0x01, 0x22, 0x21, 0xd4, 0x1c, 0xe3, 0xf0, 0xaa, +0xab, 0x77, 0xae, 0x45, 0x07, 0x73, 0x66, 0xd2, +0x2c, 0x32, 0xc2, 0xc5, 0x56, 0xc9, 0x09, 0x7a, +0x41, 0xb6, 0x85, 0x0e, 0x88, 0x2a, 0xb0, 0x2b, +0xfc, 0x6d, 0x5a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb9, 0x01, 0x22, 0x21, 0x8d, 0x0a, 0x75, +0x78, 0x08, 0x09, 0x1c, 0xc0, 0xf8, 0xbc, 0x0f, +0x54, 0x2c, 0x3d, 0x9b, 0x2c, 0xda, 0xcc, 0x98, +0x99, 0x0b, 0xd3, 0xba, 0xe6, 0x77, 0x35, 0x08, +0x83, 0x57, 0x83, 0xd1, 0xdc, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0x9d, +0x81, 0x17, 0xed, 0xba, 0x13, 0xfa, 0x1c, 0x70, +0x83, 0x6a, 0x9c, 0x77, 0x3f, 0xfa, 0x22, 0xd2, +0x93, 0x20, 0x68, 0x3e, 0x1a, 0x38, 0x01, 0x9f, +0xd5, 0xbe, 0x5a, 0x03, 0x67, 0x10, 0xe3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbb, 0x01, 0x22, -0x21, 0xeb, 0xb0, 0x1d, 0x8c, 0x53, 0xfa, 0xce, -0x1b, 0x80, 0x59, 0xe1, 0x6e, 0x21, 0xae, 0xac, -0x86, 0x2a, 0xdf, 0xd4, 0x22, 0xa5, 0xce, 0x36, -0xec, 0x3c, 0x83, 0xcc, 0xb6, 0xdb, 0x1b, 0x6b, -0xeb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, -0x01, 0x22, 0x21, 0xee, 0x87, 0xa3, 0x51, 0x43, -0x5f, 0x1d, 0x02, 0x45, 0xd8, 0x97, 0xe7, 0x12, -0xfc, 0xdf, 0xe2, 0x9a, 0x0d, 0x03, 0x00, 0x7d, -0xd8, 0x3d, 0x30, 0xc6, 0x49, 0xcc, 0x46, 0xb5, -0x23, 0x47, 0x01, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xbd, 0x01, 0x22, 0x21, 0x2a, 0xe0, 0xa6, -0x1a, 0x1a, 0x49, 0xdc, 0x65, 0x7f, 0xdd, 0x33, -0x16, 0x14, 0x35, 0xa8, 0xab, 0x3d, 0x0c, 0x04, -0x0f, 0xa6, 0x8b, 0x3d, 0x41, 0x64, 0xaa, 0x1c, -0x30, 0xfd, 0xb2, 0xf2, 0x61, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0xdf, -0x0c, 0x6d, 0xad, 0x39, 0xb9, 0x19, 0xa1, 0x65, -0x6b, 0xec, 0x38, 0x07, 0x1f, 0xb1, 0xdd, 0x95, -0x4c, 0x21, 0xa4, 0x2c, 0xb7, 0x2a, 0x9e, 0x79, -0x09, 0x9c, 0xcd, 0x73, 0x0b, 0x5e, 0x02, 0x00, +0x21, 0xd2, 0xfd, 0x96, 0x05, 0xcc, 0xe2, 0x99, +0x31, 0xb0, 0xd3, 0xca, 0x54, 0x6c, 0x33, 0xda, +0xd8, 0xd2, 0x28, 0x5d, 0x26, 0x91, 0x03, 0xa5, +0xb9, 0x63, 0x59, 0x70, 0xcb, 0x1b, 0xe2, 0x92, +0x4e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, +0x01, 0x22, 0x21, 0x75, 0x0e, 0xfc, 0x55, 0x46, +0x71, 0x47, 0x58, 0x57, 0x31, 0x01, 0xa9, 0x7f, +0xda, 0x3c, 0x1d, 0x61, 0x24, 0x91, 0xaf, 0x90, +0x89, 0xf3, 0x17, 0x90, 0x09, 0xec, 0x5b, 0xda, +0x1b, 0x48, 0x0d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xbd, 0x01, 0x22, 0x21, 0x7e, 0x1d, 0x93, +0xca, 0x24, 0x41, 0x04, 0x27, 0x78, 0x81, 0xaf, +0x69, 0xc9, 0xe8, 0x6a, 0xc1, 0x8a, 0xa4, 0x99, +0xa6, 0x6a, 0xc9, 0xa4, 0x2f, 0x32, 0xdb, 0xb6, +0xc7, 0x67, 0x45, 0x3d, 0x54, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0x92, +0x7d, 0x08, 0xa2, 0x5b, 0x75, 0x97, 0xc5, 0xa5, +0xff, 0x93, 0x9a, 0x58, 0x5a, 0x05, 0x45, 0x38, +0x13, 0xb2, 0x67, 0x59, 0xfe, 0xa9, 0x4f, 0x15, +0x82, 0x30, 0x70, 0x0a, 0x36, 0x5d, 0x3d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbf, 0x01, 0x22, -0x21, 0x46, 0x6e, 0x38, 0x8e, 0xa1, 0x05, 0xaf, -0x70, 0xad, 0xb3, 0xe8, 0x82, 0x36, 0xa7, 0x5d, -0xe3, 0x79, 0xca, 0x0f, 0xca, 0xd3, 0x79, 0xaf, -0x2d, 0x7d, 0xa9, 0xe3, 0x94, 0x1b, 0x80, 0x83, -0x22, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, -0x01, 0x22, 0x21, 0x31, 0xef, 0x06, 0xf8, 0xa1, -0x2c, 0xdc, 0x99, 0x24, 0x02, 0x7f, 0x8a, 0xdd, -0x00, 0xa5, 0x35, 0xcb, 0x6a, 0xad, 0xd9, 0x5b, -0x6c, 0xe1, 0xc3, 0xe4, 0x2b, 0x98, 0x56, 0x2d, -0x58, 0x99, 0x0b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc1, 0x01, 0x22, 0x21, 0x41, 0x1c, 0x4b, -0x9a, 0x39, 0xf0, 0x16, 0x0e, 0x59, 0xa1, 0x3b, -0xe5, 0xb4, 0x13, 0x38, 0xc7, 0x44, 0xa5, 0xf7, -0x9a, 0x42, 0x87, 0x96, 0x93, 0xe0, 0x40, 0xc1, -0x6e, 0xd4, 0x3c, 0x38, 0x62, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0x88, -0xaa, 0xe8, 0x33, 0x25, 0x50, 0xca, 0xdc, 0x61, -0x68, 0x7b, 0x4e, 0xf3, 0x7f, 0x1c, 0x32, 0x4f, -0x35, 0xcf, 0x1f, 0xce, 0x3a, 0x99, 0x24, 0x82, -0xff, 0x5e, 0x89, 0xf5, 0x8c, 0xe7, 0xa3, 0x00, +0x21, 0x9e, 0x5c, 0x76, 0x48, 0x39, 0x44, 0x7d, +0xa4, 0x4d, 0x4e, 0x86, 0x9c, 0xaa, 0x13, 0xe5, +0x66, 0xf1, 0xc1, 0x71, 0xdb, 0xdc, 0x6d, 0xfe, +0x10, 0x23, 0x10, 0x1e, 0xd7, 0x93, 0xf7, 0xd7, +0x96, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, +0x01, 0x22, 0x21, 0x52, 0x72, 0x56, 0xc1, 0xb9, +0x0c, 0xe0, 0xdd, 0x70, 0xb8, 0xbd, 0xd0, 0x18, +0x96, 0x32, 0xdf, 0xb3, 0xde, 0x67, 0xa6, 0x8e, +0x13, 0x10, 0x1c, 0x47, 0xd5, 0x2b, 0xd9, 0x6e, +0xdf, 0x9c, 0xea, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc1, 0x01, 0x22, 0x21, 0xda, 0x9b, 0xb6, +0x90, 0xe8, 0x41, 0x0a, 0xe4, 0x4d, 0x7e, 0xa6, +0x64, 0x10, 0xc9, 0x78, 0x45, 0x25, 0x64, 0x64, +0x14, 0x89, 0x80, 0x20, 0x63, 0xc2, 0x4c, 0xfc, +0x11, 0x6c, 0x4b, 0x3f, 0x2d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0x1c, +0xfc, 0xc1, 0x33, 0x8a, 0x09, 0x92, 0xa6, 0xb0, +0x0f, 0x7f, 0xe3, 0x23, 0x08, 0xd8, 0x75, 0x5c, +0xf7, 0x6c, 0xf3, 0x38, 0x36, 0xb4, 0x88, 0x00, +0x66, 0x7e, 0xdd, 0xac, 0xf6, 0x15, 0xde, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc3, 0x01, 0x22, -0x21, 0xb8, 0xef, 0x9b, 0x48, 0x98, 0x98, 0x57, -0x87, 0x34, 0x97, 0x6f, 0xe9, 0x04, 0xa0, 0xc3, -0xa4, 0xcd, 0x7e, 0x91, 0xb1, 0xc6, 0xa2, 0x8f, -0x83, 0x3b, 0xb3, 0xca, 0x34, 0xbc, 0x7d, 0xce, -0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, -0x01, 0x22, 0x21, 0xea, 0x0e, 0xbd, 0xe9, 0x6f, -0x74, 0x8b, 0x0e, 0xe5, 0x9e, 0xb2, 0x58, 0x30, -0x8e, 0xdb, 0xe3, 0x3d, 0x07, 0xb1, 0x08, 0xb1, -0x48, 0x9c, 0x1b, 0x2c, 0x76, 0xcd, 0xfb, 0x1e, -0x24, 0xa4, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc5, 0x01, 0x22, 0x21, 0x92, 0x52, 0xb4, -0x67, 0x4e, 0xd4, 0x04, 0x16, 0x2b, 0xda, 0x35, -0xf9, 0x87, 0xda, 0x13, 0xc7, 0xef, 0xc5, 0xcd, -0x55, 0x3a, 0x05, 0x03, 0xa8, 0x46, 0x56, 0x49, -0x27, 0x91, 0x10, 0x56, 0x4b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0xd4, -0xb6, 0x7e, 0x59, 0x58, 0xa9, 0x60, 0xe7, 0xdc, -0xb0, 0xbb, 0x4b, 0x2d, 0xd8, 0x0d, 0x81, 0x48, -0xfe, 0xb3, 0xeb, 0xe9, 0xd4, 0x8d, 0xa2, 0x3e, -0xe7, 0xde, 0x90, 0x3b, 0x62, 0xb6, 0x70, 0x00, +0x21, 0x39, 0x1c, 0x48, 0xaf, 0x97, 0xb6, 0x8d, +0x11, 0xb2, 0x22, 0x5b, 0xbc, 0xb9, 0x82, 0x47, +0x06, 0xcd, 0x02, 0x5a, 0x70, 0xa4, 0xc5, 0xce, +0x02, 0x30, 0x4e, 0xdd, 0x8c, 0xe8, 0xa9, 0x8c, +0x20, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, +0x01, 0x22, 0x21, 0x6d, 0xb8, 0xbe, 0x87, 0x6d, +0x87, 0xd0, 0x8a, 0x06, 0xab, 0x3f, 0x72, 0x28, +0x00, 0x00, 0xd5, 0x86, 0x6d, 0xa9, 0x08, 0x7f, +0x81, 0x39, 0x4b, 0x2a, 0xfe, 0x55, 0x05, 0xc8, +0xd5, 0x1a, 0xeb, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc5, 0x01, 0x22, 0x21, 0x15, 0x06, 0xd8, +0x1e, 0x7e, 0xf7, 0xef, 0xb0, 0x2d, 0xe8, 0x14, +0x0f, 0x56, 0x10, 0x45, 0xe7, 0x6c, 0x7d, 0x5a, +0xa9, 0xa2, 0xb8, 0x2a, 0x87, 0x6c, 0x74, 0x9e, +0x64, 0x81, 0x1d, 0xa4, 0x23, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0x21, +0x87, 0xe3, 0x3d, 0x69, 0x76, 0x6c, 0x1c, 0x54, +0x6e, 0x87, 0x34, 0xef, 0xa8, 0x69, 0x1c, 0x61, +0xa9, 0x48, 0xdb, 0x28, 0x2f, 0x04, 0x28, 0x6a, +0x4e, 0x66, 0xef, 0x90, 0x14, 0xa2, 0xd5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc7, 0x01, 0x22, -0x21, 0xe1, 0xb6, 0x23, 0xda, 0xf7, 0xae, 0x8a, -0xed, 0x7c, 0xc0, 0x2d, 0x93, 0x48, 0xdd, 0x0d, -0xe0, 0xb9, 0x9f, 0x61, 0x33, 0xae, 0xf5, 0x8c, -0x6d, 0x71, 0xe2, 0x36, 0x91, 0xa8, 0xb4, 0x8a, -0x92, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, -0x01, 0x22, 0x21, 0xf6, 0xe7, 0xd5, 0x71, 0x3b, -0xcd, 0xb1, 0x49, 0xcf, 0x35, 0xa5, 0x06, 0x82, -0xcf, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x90, 0x46, 0x06, 0x91, -0xa7, 0x8e, 0x8b, 0xbb, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc9, 0x01, 0x22, 0x21, 0xd5, 0x11, 0xff, -0xfe, 0xfb, 0xbe, 0xe1, 0x90, 0xfe, 0x52, 0x45, -0xff, 0x89, 0x94, 0xcb, 0x20, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x5c, -0x28, 0xaa, 0x3c, 0xf6, 0x26, 0xbe, 0x03, 0x04, -0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0x95, -0x47, 0x16, 0x67, 0xc4, 0x05, 0x5b, 0x65, 0xf8, -0xd9, 0xb4, 0x5f, 0xf8, 0x33, 0x44, 0x4e, 0x0e, -0x4a, 0x34, 0x96, 0x12, 0xc0, 0x73, 0x01, 0xd9, -0x0a, 0x4f, 0xf8, 0x51, 0x7a, 0x12, 0x4c, 0x00, +0x21, 0xde, 0x88, 0x5f, 0x7e, 0x11, 0xb4, 0xfd, +0x85, 0x6f, 0x25, 0x6e, 0x38, 0x51, 0xb2, 0xf6, +0x3b, 0x31, 0x55, 0x58, 0x83, 0x7a, 0xfd, 0x26, +0x9f, 0x5a, 0x85, 0x84, 0xe0, 0x56, 0x32, 0x8b, +0x11, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, +0x01, 0x22, 0x21, 0x30, 0xd4, 0x85, 0x38, 0x65, +0x46, 0xa1, 0x9f, 0xfd, 0xe0, 0x8a, 0x42, 0x72, +0x05, 0x14, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0x7c, 0xab, +0x82, 0xa1, 0x24, 0xaf, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc9, 0x01, 0x22, 0x21, 0x6b, 0x1b, 0xc3, +0xf8, 0xf6, 0xf4, 0x50, 0x68, 0x7d, 0x15, 0xe1, +0x57, 0x7a, 0x0b, 0x87, 0x77, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x0d, +0x1f, 0x00, 0x04, 0xf9, 0x09, 0x7a, 0x03, 0x04, +0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0x8f, +0x29, 0xbf, 0xd2, 0x6d, 0x47, 0x5e, 0x52, 0x8a, +0x2e, 0xa6, 0x0a, 0xb7, 0x77, 0x4e, 0x5b, 0x91, +0x22, 0xde, 0x90, 0x41, 0xac, 0x48, 0x37, 0x73, +0x71, 0x77, 0x29, 0xd5, 0xe7, 0x3f, 0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcb, 0x01, 0x22, -0x21, 0x4c, 0x6e, 0x8d, 0x82, 0x47, 0xef, 0xd8, -0xb4, 0x15, 0x40, 0x69, 0x3e, 0xb3, 0x74, 0x73, -0xe6, 0xd6, 0xf6, 0x6f, 0x4d, 0x48, 0xc6, 0x24, -0xa6, 0xd5, 0x66, 0x1c, 0xea, 0x2d, 0x1d, 0x6a, -0x0f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, -0x01, 0x22, 0x21, 0xe2, 0xc9, 0x66, 0x6b, 0xfa, -0x16, 0xc3, 0x15, 0x29, 0xd1, 0x9d, 0x22, 0xfc, -0x52, 0xf3, 0xd2, 0x34, 0x1f, 0xcd, 0x93, 0xfe, -0xce, 0x09, 0xf4, 0xbf, 0x1c, 0x42, 0x3b, 0x70, -0x18, 0x22, 0x71, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xcd, 0x01, 0x22, 0x21, 0x15, 0xac, 0x26, -0xe3, 0x0a, 0xc3, 0x88, 0x2e, 0x64, 0x6f, 0x9f, -0x80, 0x53, 0x43, 0x23, 0x9f, 0xcf, 0xa6, 0x59, -0x38, 0xb1, 0x0b, 0xf5, 0x73, 0x93, 0xad, 0xeb, -0x06, 0xed, 0x5f, 0xe8, 0xa3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0x1c, -0x69, 0xec, 0x0a, 0xbd, 0x9a, 0x93, 0xba, 0x67, -0xc1, 0x18, 0x58, 0x14, 0x1e, 0xf9, 0xf6, 0x9e, -0xf7, 0x32, 0xdb, 0x71, 0x42, 0x9e, 0x4d, 0x4c, -0x81, 0x01, 0xff, 0xdd, 0x7a, 0x49, 0xda, 0x00, +0x21, 0xb5, 0xa1, 0xaa, 0xcc, 0x1e, 0x8a, 0xb9, +0x7d, 0xc1, 0x2d, 0x5b, 0x89, 0x25, 0x93, 0x00, +0xab, 0x34, 0xc3, 0x08, 0x96, 0x29, 0x0b, 0xbc, +0xfd, 0xa2, 0x12, 0xe7, 0x64, 0x30, 0x53, 0xc1, +0x17, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, +0x01, 0x22, 0x21, 0xc7, 0xec, 0x8b, 0x9c, 0x64, +0x81, 0x97, 0xe4, 0x68, 0xea, 0x1b, 0x26, 0x9b, +0x53, 0x6b, 0x71, 0xa6, 0x72, 0x79, 0x3f, 0x0d, +0x50, 0x93, 0xd2, 0x7e, 0x3d, 0xb0, 0xd2, 0xc3, +0x99, 0xf2, 0xef, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xcd, 0x01, 0x22, 0x21, 0xf3, 0x2a, 0x86, +0xf0, 0x8c, 0xf0, 0x31, 0xa3, 0x4c, 0x1c, 0x14, +0x83, 0xa7, 0x77, 0xa9, 0x57, 0x9b, 0x81, 0xae, +0x53, 0x48, 0xb8, 0xfa, 0xd9, 0x47, 0x10, 0xd4, +0xc9, 0x3c, 0x71, 0x6f, 0xa8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0x0d, +0xbb, 0x81, 0x15, 0x80, 0x28, 0xaa, 0xce, 0xbd, +0x44, 0x8f, 0x69, 0xac, 0xa3, 0xb6, 0x72, 0xc0, +0x63, 0xf5, 0x12, 0xcc, 0xc8, 0xa3, 0xd4, 0x0d, +0x5e, 0xa3, 0xbe, 0x31, 0xbe, 0xeb, 0xd2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcf, 0x01, 0x22, -0x21, 0x38, 0x26, 0x3d, 0x5a, 0xa0, 0xcb, 0x9a, -0x43, 0xbe, 0x90, 0xcb, 0x48, 0xb2, 0x39, 0xa2, -0x37, 0x0f, 0x3a, 0x53, 0xbd, 0xa3, 0x55, 0xaf, -0xd8, 0xdc, 0x4b, 0xba, 0x1d, 0x99, 0x62, 0x94, -0xe2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, -0x01, 0x22, 0x21, 0xcd, 0x69, 0xaa, 0x6d, 0xa0, -0x5f, 0x3b, 0xd3, 0x15, 0x12, 0x6d, 0x66, 0xe5, -0x63, 0xdf, 0x97, 0xc7, 0x71, 0xa7, 0x95, 0x4b, -0x46, 0x94, 0xeb, 0x41, 0x45, 0x8f, 0x4a, 0x5e, -0x0e, 0x82, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd1, 0x01, 0x22, 0x21, 0x0b, 0xfb, 0xa8, -0x20, 0xf6, 0x78, 0x1f, 0xb6, 0x3a, 0x60, 0x3b, -0x18, 0xb1, 0x11, 0x8c, 0x60, 0x92, 0xd4, 0x5c, -0xd9, 0x82, 0x6d, 0xef, 0x33, 0xb1, 0xa2, 0x93, -0xbf, 0x5e, 0x14, 0xcc, 0x2b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0xec, -0xf4, 0x0f, 0x50, 0x0d, 0xab, 0x66, 0xa1, 0xe5, -0xc0, 0xd5, 0x8c, 0xad, 0xb8, 0xb5, 0x8b, 0xd1, -0x76, 0x93, 0x9c, 0x13, 0x96, 0xe1, 0x99, 0x25, -0x0c, 0x76, 0x0f, 0xd3, 0x7f, 0x60, 0x6f, 0x00, +0x21, 0xae, 0xff, 0xba, 0x36, 0xc4, 0x82, 0x15, +0x44, 0xc2, 0x47, 0x90, 0x56, 0x06, 0x03, 0x76, +0x63, 0x8d, 0x54, 0x17, 0x6f, 0xd5, 0xc6, 0xb5, +0x6f, 0xd4, 0xf0, 0x53, 0x13, 0x50, 0x9b, 0xf3, +0x2a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, +0x01, 0x22, 0x21, 0xe0, 0xfb, 0x73, 0x29, 0xf0, +0xde, 0xe4, 0xb4, 0xd2, 0xb5, 0x9b, 0xdf, 0x98, +0x32, 0x57, 0x94, 0x71, 0xd5, 0xfd, 0x58, 0xd0, +0x19, 0x3a, 0xdd, 0x50, 0xf7, 0x22, 0x13, 0x3f, +0x77, 0xcf, 0x42, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd1, 0x01, 0x22, 0x21, 0x42, 0x5e, 0xc5, +0x85, 0x88, 0x52, 0xdc, 0x69, 0x5d, 0x40, 0xe2, +0xc0, 0x7f, 0xd2, 0xb7, 0x8c, 0x7f, 0x13, 0x84, +0xaa, 0x29, 0x1f, 0xa4, 0x83, 0x11, 0x8b, 0xca, +0xaf, 0x23, 0x94, 0xf9, 0xdd, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x36, +0x94, 0xe6, 0x2e, 0x9a, 0xfe, 0x25, 0x11, 0x01, +0xf7, 0xa7, 0x88, 0x5f, 0xc8, 0x84, 0x96, 0x6f, +0x48, 0x78, 0xdd, 0xb0, 0x1e, 0x79, 0x94, 0x5d, +0x51, 0x55, 0x1c, 0x75, 0x18, 0x86, 0x2f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd3, 0x01, 0x22, -0x21, 0xa8, 0xbf, 0xe2, 0xb7, 0xec, 0x21, 0x61, -0x06, 0xa7, 0xee, 0x8d, 0xaa, 0x1b, 0x19, 0x19, -0x7b, 0xf7, 0x09, 0x70, 0xed, 0x2f, 0xcf, 0x6f, -0x57, 0x4d, 0x39, 0xc6, 0x98, 0x10, 0x6a, 0xe0, -0x02, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, -0x01, 0x22, 0x21, 0x8a, 0xf1, 0xc5, 0xdf, 0x46, -0x28, 0x9d, 0x2f, 0x77, 0xa7, 0x44, 0x9e, 0x2f, -0xc7, 0x3b, 0xa4, 0x1a, 0xcd, 0xde, 0xf1, 0x78, -0xe2, 0xb0, 0x15, 0xd8, 0xc4, 0x98, 0x52, 0x57, -0xbe, 0xab, 0xef, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd5, 0x01, 0x22, 0x21, 0x62, 0xea, 0xbb, -0xfc, 0xa5, 0x73, 0xac, 0x17, 0x8c, 0x2c, 0xd1, -0xe7, 0x7d, 0x51, 0xa7, 0x2e, 0x53, 0x8d, 0xcf, -0x8a, 0x7b, 0x97, 0xfd, 0x9a, 0xd6, 0x23, 0xb1, -0xed, 0xda, 0x15, 0x86, 0x46, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0xef, -0x48, 0x07, 0xd1, 0x52, 0xfc, 0xd8, 0x8a, 0x68, -0xe5, 0xb6, 0x09, 0x6b, 0xc6, 0x17, 0x03, 0x5b, -0xf4, 0xf1, 0xc7, 0x94, 0xdf, 0x7e, 0xce, 0x64, -0xfb, 0x10, 0x26, 0xa8, 0xd8, 0x95, 0x2a, 0x00, +0x21, 0x59, 0x6b, 0xa2, 0x54, 0x54, 0x4c, 0x79, +0x39, 0x8a, 0x94, 0x59, 0x02, 0xdb, 0xd8, 0xdc, +0x24, 0x03, 0x3f, 0x23, 0x4a, 0xb4, 0x7c, 0x3d, +0x72, 0xc6, 0x18, 0xe5, 0x7d, 0x19, 0x27, 0x65, +0x61, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, +0x01, 0x22, 0x21, 0xbf, 0x34, 0xbf, 0xf5, 0xe1, +0x08, 0xd3, 0x27, 0x3f, 0x59, 0x79, 0xce, 0x67, +0x87, 0x47, 0x78, 0x36, 0xe8, 0xfd, 0x56, 0x5f, +0xf0, 0xd3, 0xe9, 0x55, 0x0d, 0xcc, 0x4c, 0x45, +0x38, 0x7c, 0x4a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd5, 0x01, 0x22, 0x21, 0x7a, 0x8a, 0x15, +0x1c, 0x1d, 0xca, 0x3b, 0x12, 0xf1, 0x0a, 0x93, +0x76, 0x19, 0xb3, 0xc0, 0x2e, 0x2a, 0x45, 0x15, +0x60, 0x3f, 0x67, 0xd0, 0xa7, 0xd0, 0x0a, 0x63, +0xcf, 0x71, 0x82, 0x73, 0x51, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0xff, +0x7a, 0x54, 0xbe, 0xcd, 0xd6, 0x31, 0xd0, 0xce, +0xc9, 0x2a, 0x63, 0x21, 0xfb, 0xdc, 0x64, 0x66, +0x2f, 0xe6, 0xbb, 0x22, 0x8a, 0x16, 0xd3, 0x22, +0x9c, 0xe4, 0x92, 0x35, 0xc1, 0xda, 0x51, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd7, 0x01, 0x22, -0x21, 0x85, 0xfa, 0x3f, 0x78, 0xab, 0x21, 0x2f, -0x51, 0xa0, 0xa1, 0x5d, 0xd1, 0x64, 0x98, 0x1e, -0xa5, 0x5c, 0x5e, 0xb3, 0x37, 0xdf, 0x25, 0xb4, -0x0b, 0x31, 0xb9, 0x5d, 0x06, 0x5c, 0xd0, 0x0a, -0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, -0x01, 0x22, 0x21, 0x9e, 0x63, 0xd2, 0xe2, 0x98, -0xd3, 0xaa, 0x73, 0x56, 0x4b, 0xd7, 0x5f, 0x2d, -0x88, 0xea, 0x22, 0x50, 0xf4, 0x1e, 0x0b, 0x79, -0xa1, 0x89, 0x9f, 0xe4, 0xb2, 0xe0, 0xde, 0x51, -0xba, 0xff, 0x6a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd9, 0x01, 0x22, 0x21, 0x5d, 0x04, 0xa1, -0x71, 0x6d, 0x60, 0x14, 0x4a, 0x0e, 0x74, 0x12, -0x0b, 0x40, 0x0e, 0x88, 0xba, 0x92, 0xa3, 0x4b, -0x77, 0x3f, 0x6c, 0x7b, 0x5f, 0xcd, 0x97, 0xf8, -0xec, 0x29, 0xa2, 0xf4, 0x9a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0x1d, -0x9c, 0x9a, 0x96, 0x4e, 0xad, 0x2c, 0x76, 0x37, -0x22, 0xae, 0x2f, 0xfb, 0x85, 0x72, 0x58, 0xb9, -0xa0, 0x3f, 0x64, 0xbf, 0xe2, 0xd4, 0x5d, 0xbb, -0x40, 0xe2, 0x22, 0xfc, 0x6b, 0x18, 0x6a, 0x00, +0x21, 0x95, 0xc3, 0x0a, 0xf0, 0xc5, 0x15, 0x68, +0x6d, 0x3b, 0xff, 0x4d, 0xb7, 0x67, 0x7f, 0xb4, +0x62, 0x79, 0xc3, 0x95, 0x6c, 0xf2, 0xdf, 0xd5, +0x9e, 0xa4, 0xbe, 0x6f, 0x41, 0x0e, 0xc7, 0x27, +0xce, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, +0x01, 0x22, 0x21, 0x6c, 0x23, 0xab, 0x2c, 0x7b, +0x7e, 0x4d, 0xba, 0xcb, 0xa1, 0xbe, 0x79, 0xf0, +0x1f, 0x8e, 0x5c, 0xfb, 0xa4, 0x9b, 0x51, 0x76, +0x3e, 0x84, 0xc8, 0x53, 0xd2, 0xd1, 0xf7, 0x78, +0xa3, 0xaf, 0x72, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd9, 0x01, 0x22, 0x21, 0x5e, 0xf8, 0x75, +0x80, 0x31, 0x07, 0x28, 0x90, 0xc4, 0x92, 0x0c, +0x9b, 0xfe, 0x76, 0x6a, 0x30, 0x0e, 0x62, 0xb7, +0x32, 0x9f, 0xf8, 0xb9, 0xde, 0x02, 0xdf, 0xf4, +0x6e, 0x42, 0xb6, 0x68, 0x4d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0xcc, +0xb7, 0x34, 0x14, 0xc9, 0xc5, 0x25, 0xa6, 0x79, +0x77, 0xe2, 0x60, 0xe4, 0x3a, 0x32, 0xfb, 0xb3, +0x87, 0x62, 0xd6, 0x29, 0xda, 0x22, 0x72, 0xab, +0x35, 0xfd, 0x0c, 0x46, 0x64, 0x52, 0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdb, 0x01, 0x22, -0x21, 0xcb, 0x1e, 0x50, 0xc3, 0x3a, 0xf7, 0xc5, -0x71, 0xfd, 0xda, 0xe0, 0x44, 0x04, 0xac, 0x32, -0x6d, 0x25, 0xd2, 0x35, 0xfb, 0xee, 0x98, 0x0e, -0xb5, 0x05, 0x8a, 0xda, 0xe0, 0x0f, 0x1a, 0x62, -0xc7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, -0x01, 0x22, 0x21, 0xe2, 0x92, 0x6e, 0xef, 0xaf, -0x4b, 0xf2, 0xf5, 0xbf, 0x79, 0x20, 0x3d, 0x72, -0x05, 0xf7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x58, 0x0b, 0x7f, 0xda, -0xe2, 0x99, 0x79, 0xb4, 0x03, 0x04, 0x51, 0x02, -0x00, 0xdd, 0x01, 0x22, 0x21, 0x6f, 0xba, 0x73, -0x0b, 0xa6, 0x8b, 0x6a, 0xa5, 0xa5, 0xb2, 0x56, -0x71, 0x9b, 0xee, 0x2f, 0x4d, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x6a, -0x4f, 0x6f, 0xc7, 0x41, 0xb4, 0x6c, 0x03, 0x04, -0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0xcf, -0x46, 0x62, 0x15, 0x34, 0xa6, 0x9c, 0x8e, 0x7a, -0x9c, 0x72, 0x29, 0xd2, 0x5a, 0x5e, 0x4c, 0xe9, -0xf4, 0x30, 0x71, 0x6e, 0x99, 0x2f, 0xf7, 0xba, -0x85, 0x00, 0xd0, 0x9f, 0xc3, 0x47, 0x6f, 0x00, +0x21, 0x60, 0x91, 0xcc, 0x96, 0x07, 0xe3, 0xa3, +0xd1, 0x70, 0xb3, 0x38, 0xde, 0xd4, 0x36, 0x12, +0x55, 0xc5, 0xca, 0xb4, 0xbc, 0xd8, 0xd0, 0x30, +0x29, 0x59, 0x7d, 0xbd, 0xc2, 0xc8, 0x77, 0x2d, +0x55, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, +0x01, 0x22, 0x21, 0x74, 0x33, 0xeb, 0xbb, 0x32, +0x65, 0xc4, 0x6c, 0xf5, 0x82, 0x27, 0xc7, 0x9c, +0x8f, 0x1a, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xe1, 0x5d, 0x35, 0xe1, +0xf9, 0x24, 0x6f, 0x29, 0x03, 0x04, 0x51, 0x02, +0x00, 0xdd, 0x01, 0x22, 0x21, 0x11, 0x22, 0xb4, +0x84, 0x48, 0x4a, 0x39, 0x46, 0x7a, 0x9b, 0x8a, +0xf0, 0x3a, 0xc4, 0x7d, 0xaf, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x5d, +0xb4, 0xd7, 0xff, 0x27, 0x49, 0x59, 0x03, 0x04, +0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0x8d, +0x69, 0x07, 0x4c, 0x12, 0xa9, 0x4b, 0x9d, 0x97, +0x5d, 0x38, 0x1d, 0x1d, 0x86, 0x55, 0x7b, 0xd6, +0x0b, 0xc4, 0x8f, 0xed, 0x31, 0xb0, 0x8c, 0xc5, +0xd0, 0x91, 0x53, 0x43, 0x43, 0x9d, 0x87, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdf, 0x01, 0x22, -0x21, 0x69, 0xde, 0x1f, 0xf1, 0xed, 0xc4, 0xd4, -0x59, 0x47, 0x81, 0x37, 0xad, 0x1d, 0x9d, 0x71, -0x4b, 0x72, 0xd7, 0xe1, 0x9f, 0x0b, 0x5f, 0xe6, -0xbb, 0x75, 0x45, 0x8f, 0x6d, 0x5a, 0xd0, 0x3e, -0x87, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, -0x01, 0x22, 0x21, 0x8c, 0x1d, 0x95, 0x9a, 0x48, -0x25, 0x7f, 0xee, 0x4d, 0x24, 0x11, 0x6d, 0xa0, -0x78, 0x6a, 0x25, 0x34, 0x64, 0x1e, 0x31, 0xcc, -0xb2, 0xe6, 0x7a, 0x26, 0xcd, 0x70, 0x51, 0xdb, -0xbe, 0x6b, 0x42, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe1, 0x01, 0x22, 0x21, 0x73, 0x36, 0x95, -0xad, 0x1f, 0x76, 0x30, 0xa9, 0x22, 0x4d, 0x7f, -0x21, 0xce, 0x6a, 0x72, 0xc5, 0x4f, 0x82, 0x3c, -0x43, 0xfa, 0xa3, 0x0b, 0x45, 0xb2, 0x1c, 0x7a, -0x3f, 0x2b, 0x51, 0x01, 0x41, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0x3a, -0xfc, 0xee, 0x2d, 0xac, 0x9b, 0x5b, 0x85, 0x00, -0x98, 0x10, 0x83, 0xed, 0xd2, 0x62, 0x4f, 0x66, -0x96, 0xde, 0x33, 0xaa, 0xb8, 0x47, 0xd2, 0xe6, -0xbc, 0x11, 0x38, 0x2e, 0x40, 0xc3, 0x59, 0x00, +0x21, 0x2b, 0xa7, 0xcf, 0x38, 0x8b, 0x56, 0xd2, +0x0a, 0xc5, 0x8f, 0x4d, 0x68, 0xa9, 0xf5, 0x11, +0x33, 0x74, 0xf1, 0x8b, 0x74, 0xc9, 0xbc, 0xb8, +0x53, 0xab, 0x89, 0x08, 0x0b, 0x28, 0x88, 0x63, +0x79, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, +0x01, 0x22, 0x21, 0xab, 0x41, 0x1f, 0x35, 0xe6, +0xf4, 0x99, 0x5d, 0x6e, 0x64, 0xee, 0x88, 0x32, +0xa1, 0x00, 0x5e, 0x83, 0xa0, 0x21, 0xc8, 0x49, +0x3f, 0xa1, 0xa2, 0x10, 0xd3, 0xdf, 0x26, 0xca, +0x3e, 0xe9, 0x01, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe1, 0x01, 0x22, 0x21, 0xdc, 0xcc, 0x90, +0x29, 0x4e, 0x70, 0x2d, 0x96, 0x9a, 0x82, 0xda, +0x9d, 0xe0, 0x07, 0x36, 0x41, 0x78, 0xa3, 0x53, +0x6c, 0x62, 0xe5, 0x31, 0x6a, 0x6a, 0x6f, 0xc7, +0x23, 0xe5, 0xff, 0x6b, 0x98, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0xb9, +0x74, 0x38, 0x8c, 0x21, 0xcc, 0x79, 0xc7, 0x8e, +0x99, 0x6b, 0xa3, 0x5e, 0xb3, 0x20, 0x91, 0xb1, +0xdc, 0x14, 0xc3, 0x09, 0x69, 0xbf, 0xc5, 0x40, +0x8a, 0x8f, 0x60, 0xee, 0xe8, 0x77, 0x97, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe3, 0x01, 0x22, -0x21, 0x3f, 0xff, 0xd6, 0xbc, 0xb8, 0xdb, 0xd6, -0xf1, 0x88, 0xc7, 0x4d, 0xf7, 0x67, 0xe6, 0x3e, -0x04, 0x2b, 0xa9, 0xf2, 0xc4, 0xd9, 0x28, 0xdf, -0x17, 0x42, 0x45, 0xf1, 0xbf, 0x24, 0xa0, 0xcc, -0xe6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, -0x01, 0x22, 0x21, 0x32, 0xe9, 0x29, 0xa0, 0x52, -0xb7, 0x74, 0x7a, 0x8f, 0x21, 0xbf, 0xd6, 0x49, -0x68, 0xb1, 0x51, 0x9d, 0x1b, 0xa5, 0x4d, 0x33, -0xa1, 0xdc, 0xe5, 0xe6, 0x10, 0x1b, 0x56, 0x3f, -0x99, 0x00, 0x5e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe5, 0x01, 0x22, 0x21, 0x87, 0x69, 0x8f, -0xbc, 0x15, 0x1f, 0xb8, 0x54, 0x95, 0x12, 0xcb, -0xaa, 0xb1, 0x04, 0xab, 0xab, 0xa7, 0xf2, 0x52, -0xa9, 0x2b, 0xcc, 0x70, 0xb2, 0x3c, 0x38, 0x11, -0x15, 0xc2, 0xbf, 0x6e, 0x64, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x42, -0x92, 0x21, 0x33, 0x1f, 0xb2, 0xbf, 0xe0, 0xee, -0xe1, 0x3f, 0x1d, 0x06, 0x84, 0xb8, 0x4d, 0x3b, -0x49, 0x66, 0x1c, 0xeb, 0x7d, 0xa7, 0xa5, 0x7a, -0x5c, 0x5a, 0x1e, 0x2f, 0xcf, 0x21, 0xc4, 0x00, +0x21, 0x75, 0x07, 0xeb, 0x94, 0xbc, 0xe3, 0x8f, +0x4a, 0xc7, 0x0d, 0x0d, 0xbe, 0x69, 0x87, 0x38, +0x07, 0x2c, 0x0f, 0x9b, 0xc9, 0x62, 0x9e, 0x6b, +0x38, 0x51, 0x6a, 0x8d, 0x80, 0x21, 0x25, 0x5f, +0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, +0x01, 0x22, 0x21, 0x30, 0xf2, 0x6e, 0x51, 0x47, +0x0c, 0x6c, 0xf8, 0x2d, 0x41, 0xf7, 0x2e, 0x07, +0x70, 0xe7, 0xe3, 0x2a, 0x19, 0xea, 0x84, 0x9d, +0x8f, 0xd9, 0x46, 0x4a, 0xf0, 0x4c, 0x7c, 0xbb, +0x03, 0xd1, 0xf4, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe5, 0x01, 0x22, 0x21, 0x7b, 0xce, 0x71, +0x31, 0xb8, 0xae, 0x1d, 0xfc, 0x16, 0x69, 0xe0, +0x6d, 0x8e, 0x6a, 0xb3, 0x34, 0x91, 0x1c, 0x0f, +0xff, 0xbc, 0x6c, 0xa7, 0x81, 0x9d, 0x81, 0x28, +0x31, 0x00, 0xbb, 0x4e, 0x00, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x72, +0x81, 0x05, 0xcb, 0x3a, 0xd4, 0x66, 0x11, 0xe2, +0x43, 0x19, 0x63, 0x1a, 0xa1, 0x7a, 0x3b, 0xa8, +0x16, 0x8d, 0x65, 0x3f, 0x85, 0x15, 0xf8, 0x90, +0x96, 0x4c, 0x66, 0x62, 0x4d, 0xc5, 0xb6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe7, 0x01, 0x22, -0x21, 0x92, 0x94, 0x3b, 0x20, 0x84, 0x7d, 0x0d, -0x39, 0xe0, 0x4c, 0x10, 0x84, 0xdb, 0xa5, 0xc8, -0xe8, 0xf4, 0xd2, 0x1e, 0x35, 0xbe, 0x20, 0x30, -0x67, 0x0e, 0x3b, 0x54, 0xdd, 0x16, 0xe2, 0xe2, -0xb8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, -0x01, 0x22, 0x21, 0x7a, 0xc6, 0x6f, 0xff, 0x20, -0xca, 0x07, 0xcc, 0xe2, 0x45, 0x42, 0x8c, 0x62, -0x14, 0xf4, 0x61, 0x89, 0x83, 0x40, 0xb0, 0x7d, -0x15, 0xc2, 0xf2, 0x7e, 0x22, 0xba, 0xe0, 0xf0, -0x13, 0xa9, 0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe9, 0x01, 0x22, 0x21, 0xe3, 0x39, 0xc1, -0x50, 0x56, 0x60, 0x39, 0x67, 0xa8, 0x84, 0x10, -0x2c, 0x5f, 0x38, 0x02, 0x90, 0xa0, 0xf6, 0x31, -0x94, 0x1a, 0x86, 0x66, 0x2c, 0xf8, 0x29, 0x4f, -0xc6, 0xcb, 0x82, 0x5e, 0x54, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0xab, -0x9c, 0x7a, 0x45, 0x1c, 0x2a, 0x8f, 0xed, 0xbd, -0x27, 0x74, 0xb1, 0xbe, 0x85, 0x50, 0x84, 0x03, -0x30, 0x13, 0x2f, 0xa6, 0x40, 0x84, 0xe7, 0x7b, -0xed, 0x21, 0xca, 0x4d, 0xa8, 0x6d, 0x4e, 0x00, +0x21, 0x8c, 0xf0, 0x95, 0x9e, 0x6c, 0xec, 0x6b, +0x7b, 0x1b, 0xae, 0x6b, 0x5b, 0x6f, 0x1f, 0x78, +0x8f, 0x14, 0x6d, 0x1f, 0x65, 0x60, 0xbc, 0x8d, +0xe8, 0x94, 0x40, 0xe9, 0x65, 0xa6, 0x09, 0x35, +0xab, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, +0x01, 0x22, 0x21, 0x22, 0x83, 0x9b, 0x42, 0x67, +0xd3, 0xa3, 0x2d, 0x3d, 0xac, 0xbd, 0x52, 0xb8, +0x8b, 0xd2, 0xd8, 0xb2, 0x17, 0x0c, 0xef, 0x3f, +0x86, 0xb1, 0x63, 0xb4, 0x9a, 0x2f, 0x78, 0x11, +0xfc, 0x33, 0x85, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe9, 0x01, 0x22, 0x21, 0x82, 0x8f, 0x99, +0x75, 0x09, 0x63, 0x60, 0x53, 0xed, 0x40, 0x11, +0xc7, 0xb4, 0x52, 0x19, 0xb4, 0x67, 0x6e, 0x03, +0xdf, 0x0c, 0x06, 0xde, 0x32, 0x41, 0x35, 0x06, +0x31, 0x39, 0xb1, 0x32, 0xd2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0x18, +0x93, 0x92, 0x7c, 0x02, 0x4d, 0x20, 0xd6, 0x75, +0xdf, 0x80, 0xe9, 0x55, 0x5e, 0xff, 0x60, 0x99, +0xe3, 0xe3, 0xac, 0x00, 0xa1, 0x48, 0x22, 0xca, +0xe3, 0x01, 0x29, 0x87, 0xa4, 0xf0, 0x0e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xeb, 0x01, 0x22, -0x21, 0x8c, 0xba, 0x3a, 0x3d, 0x19, 0x6c, 0x35, -0x00, 0xcb, 0x3b, 0x97, 0x1d, 0x99, 0xfe, 0x8b, -0xb4, 0xaa, 0x4e, 0x81, 0xce, 0xd6, 0x73, 0xc9, -0x2f, 0xe1, 0x41, 0x0f, 0xf6, 0x76, 0xc1, 0x76, -0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, -0x01, 0x22, 0x21, 0xce, 0x9d, 0xf0, 0x88, 0xf7, -0x7e, 0x50, 0xfb, 0x33, 0xd5, 0x03, 0xfb, 0xbf, -0xae, 0x13, 0x68, 0xca, 0x1e, 0x1d, 0x3c, 0x59, -0x5d, 0xa2, 0x05, 0x5e, 0xd0, 0xc0, 0x76, 0xf3, -0xe3, 0x13, 0x58, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xed, 0x01, 0x22, 0x21, 0x67, 0xb6, 0xfb, -0x64, 0x61, 0x24, 0x6a, 0xbb, 0x86, 0x08, 0x48, -0xe4, 0x00, 0xff, 0x82, 0x65, 0xdc, 0x59, 0x2e, -0x85, 0x9b, 0xcb, 0xea, 0x40, 0xcc, 0xae, 0x80, -0xe9, 0x30, 0x3a, 0x7b, 0xfa, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0xf7, -0x07, 0xd5, 0x14, 0x0f, 0x12, 0x44, 0x16, 0x67, -0x46, 0x44, 0xe8, 0xe8, 0xbe, 0x0e, 0xd0, 0x32, -0x51, 0x28, 0x85, 0xa8, 0x2a, 0x3c, 0x59, 0x45, -0xe2, 0xca, 0x83, 0xe9, 0xfe, 0x0d, 0x95, 0x00, +0x21, 0xc2, 0x00, 0x71, 0x6c, 0xdf, 0x1f, 0x41, +0xd4, 0xc8, 0x3c, 0xdf, 0x18, 0x45, 0x38, 0xbb, +0x4e, 0x03, 0x4c, 0xb4, 0xd5, 0xa0, 0x51, 0xc7, +0xf8, 0x24, 0xf7, 0x4e, 0xfe, 0x8c, 0xc5, 0xa3, +0x24, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, +0x01, 0x22, 0x21, 0x81, 0x2f, 0x27, 0xc1, 0xd4, +0xc4, 0x09, 0x71, 0x92, 0xe7, 0xa7, 0x25, 0x05, +0x49, 0x1c, 0xfd, 0x17, 0x45, 0x0c, 0x48, 0x2a, +0xe9, 0x47, 0xdf, 0x57, 0xeb, 0xcd, 0x91, 0x70, +0xb7, 0x9d, 0xb1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xed, 0x01, 0x22, 0x21, 0xe4, 0xb4, 0x23, +0x01, 0x37, 0x9f, 0xea, 0x7a, 0xd6, 0x5a, 0xc8, +0x9a, 0x5b, 0xc8, 0x60, 0xd2, 0xde, 0x18, 0xa8, +0xc9, 0xbe, 0x02, 0x12, 0x4e, 0x8b, 0x34, 0x3b, +0xbc, 0x87, 0x30, 0x6d, 0xb1, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0x70, +0xf7, 0x74, 0x26, 0xa3, 0x70, 0x4a, 0xad, 0xaa, +0x9e, 0x41, 0x21, 0x94, 0x89, 0xfe, 0x1a, 0x6e, +0xee, 0x24, 0x78, 0x5d, 0x65, 0x4c, 0xeb, 0x33, +0xa7, 0x3e, 0x72, 0x7b, 0x80, 0xdc, 0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xef, 0x01, 0x22, -0x21, 0x8b, 0x8c, 0x83, 0xe9, 0x88, 0x9f, 0x55, -0x41, 0x09, 0x0b, 0x7b, 0x57, 0x8c, 0x60, 0x4a, -0x4f, 0xae, 0x55, 0xab, 0x8a, 0x5d, 0x9c, 0xb0, -0x77, 0x75, 0x04, 0x14, 0x53, 0x31, 0x1e, 0x91, -0xd0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, -0x01, 0x22, 0x21, 0x6b, 0x74, 0xcd, 0xc9, 0x24, -0xff, 0x5d, 0xf0, 0x09, 0x8e, 0x19, 0x71, 0xab, -0x1a, 0x2d, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x29, 0xfc, 0xcf, 0x21, -0x9e, 0x1b, 0xbe, 0x3b, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf1, 0x01, 0x22, 0x21, 0x3f, 0x0c, 0x71, -0x6d, 0xc7, 0x4e, 0xba, 0x31, 0xf8, 0x84, 0x80, -0x61, 0xa8, 0x96, 0x69, 0x70, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf9, -0xbb, 0xf0, 0xa0, 0x09, 0x95, 0xeb, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0x60, -0xaf, 0xf4, 0x9b, 0x0a, 0x66, 0x9b, 0x6a, 0xab, -0x35, 0x51, 0x95, 0xd2, 0xf4, 0x15, 0x3c, 0x78, -0xdc, 0xd0, 0x79, 0x1d, 0x05, 0xf5, 0x38, 0xdc, -0xbf, 0x79, 0xe9, 0x49, 0x4c, 0xb3, 0xe0, 0x00, +0x21, 0xd9, 0xed, 0x10, 0x00, 0x67, 0x2f, 0xd3, +0xaa, 0xd7, 0xd1, 0xd0, 0x00, 0x5a, 0x4a, 0x00, +0xc0, 0xd1, 0x39, 0xd4, 0x57, 0x8a, 0xc0, 0xa8, +0xa2, 0xa0, 0xb6, 0xce, 0x96, 0x21, 0x8e, 0xf8, +0x46, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, +0x01, 0x22, 0x21, 0x29, 0x7b, 0xf2, 0x13, 0xb8, +0xe3, 0x1d, 0xf4, 0x9d, 0x82, 0x91, 0x3e, 0x87, +0x08, 0x60, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x0f, 0xd2, +0x2f, 0xe4, 0x10, 0xab, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf1, 0x01, 0x22, 0x21, 0x1c, 0x40, 0x0f, +0xce, 0x7a, 0xdc, 0x51, 0x5e, 0xc7, 0x01, 0x0f, +0xf2, 0x0c, 0xfb, 0x85, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xad, +0x4c, 0xaa, 0x84, 0xc8, 0xb0, 0x53, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0x2f, +0xbc, 0xfb, 0xf8, 0xd6, 0xed, 0x89, 0x3b, 0x0b, +0xf9, 0x93, 0x52, 0x13, 0xf9, 0x90, 0x78, 0xb3, +0xa9, 0xb8, 0x57, 0x23, 0xff, 0xa7, 0x9d, 0xc5, +0x03, 0xb0, 0xde, 0x6a, 0xeb, 0xcf, 0xf4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf3, 0x01, 0x22, -0x21, 0x04, 0x4b, 0x38, 0x93, 0x3a, 0x6f, 0xa2, -0x6d, 0x89, 0x4b, 0x49, 0x57, 0xa5, 0x3c, 0x63, -0xa6, 0x05, 0x0b, 0x4e, 0x9f, 0xc8, 0x2d, 0x7c, -0x88, 0x35, 0x04, 0x4e, 0xcd, 0xd3, 0x66, 0xbe, -0x88, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, -0x01, 0x22, 0x21, 0x3e, 0xed, 0x6b, 0xdb, 0x1c, -0xc6, 0xfe, 0x1a, 0x5c, 0x03, 0x72, 0x8b, 0xa2, -0x6f, 0x24, 0x40, 0x27, 0x30, 0x80, 0x34, 0x35, -0x46, 0x8f, 0xff, 0x31, 0x7c, 0x52, 0xd9, 0x25, -0x57, 0x44, 0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf5, 0x01, 0x22, 0x21, 0x53, 0xe7, 0x75, -0x4d, 0x0c, 0xdf, 0x0a, 0x9f, 0x4e, 0xe2, 0x2c, -0xd4, 0x83, 0xff, 0x59, 0x12, 0xd0, 0x42, 0x87, -0xba, 0x18, 0x60, 0x98, 0xcd, 0xcb, 0x68, 0x54, -0xc2, 0xa3, 0x0b, 0xcc, 0x3a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0x14, -0xad, 0x85, 0x90, 0x46, 0xf9, 0xe9, 0xfb, 0x06, -0xee, 0x44, 0x92, 0x69, 0xed, 0x0f, 0x94, 0xca, -0x2b, 0x72, 0xd2, 0x72, 0x6d, 0x84, 0xb0, 0xe9, -0x66, 0x11, 0x0f, 0xbe, 0xf7, 0x58, 0xeb, 0x00, +0x21, 0x91, 0xac, 0x25, 0xaa, 0x93, 0x7b, 0xa5, +0x86, 0x3a, 0x86, 0x81, 0xc0, 0xce, 0x7d, 0x02, +0xcf, 0x99, 0xfd, 0xd0, 0x2f, 0x5f, 0xf3, 0x3e, +0xe1, 0x05, 0x94, 0x71, 0x8b, 0x1e, 0x95, 0x0a, +0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, +0x01, 0x22, 0x21, 0x5c, 0x79, 0x7f, 0x19, 0x29, +0xbf, 0xfa, 0x76, 0xd0, 0x6c, 0xb0, 0x03, 0x53, +0x86, 0x84, 0xd3, 0xb8, 0x3e, 0xc6, 0x9d, 0x58, +0xe3, 0xe6, 0xa7, 0xad, 0x45, 0xdc, 0xe2, 0xe9, +0xe3, 0x06, 0x37, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf5, 0x01, 0x22, 0x21, 0xca, 0xb3, 0xad, +0xac, 0x28, 0xe9, 0xc0, 0x1e, 0x45, 0x47, 0xb8, +0x19, 0xce, 0xff, 0xd3, 0x01, 0x4e, 0xc9, 0x0c, +0x96, 0xd6, 0xf1, 0xba, 0xca, 0xc2, 0xe7, 0x50, +0x25, 0x20, 0x61, 0x55, 0x4e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0x44, +0x34, 0xeb, 0x2e, 0x5b, 0x07, 0x2f, 0x5e, 0x6b, +0x37, 0xbc, 0x0e, 0x56, 0xed, 0x5a, 0x9b, 0x28, +0xe2, 0xe5, 0x04, 0x69, 0x46, 0xf0, 0x7d, 0xda, +0x66, 0x29, 0xea, 0xdb, 0x3a, 0xba, 0x43, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf7, 0x01, 0x22, -0x21, 0x41, 0x5d, 0xc1, 0xcf, 0x7e, 0xcb, 0xa3, -0x75, 0xc8, 0xba, 0x22, 0x79, 0xe7, 0x41, 0xea, -0x8f, 0x82, 0x10, 0x54, 0x1f, 0x15, 0xe7, 0x52, -0xf1, 0xed, 0x04, 0x17, 0x99, 0x9b, 0x72, 0xa8, -0x88, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, -0x01, 0x22, 0x21, 0xe0, 0x7d, 0xf2, 0xbe, 0x12, -0xbc, 0xb6, 0x2e, 0x32, 0x01, 0x16, 0xbc, 0x7c, -0x59, 0x68, 0x1e, 0x96, 0xa0, 0x2f, 0xc2, 0xad, -0xdb, 0x94, 0xee, 0x02, 0x88, 0x88, 0x97, 0x67, -0xb3, 0xfe, 0xcc, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf9, 0x01, 0x22, 0x21, 0xa2, 0x50, 0x77, -0x4a, 0x8f, 0xff, 0x48, 0x61, 0xaa, 0x2e, 0x12, -0xad, 0xe7, 0x9e, 0xdc, 0x50, 0xba, 0xd8, 0x6c, -0x23, 0x51, 0x5d, 0x6f, 0x4f, 0x3e, 0x6c, 0xcd, -0x7c, 0x96, 0x05, 0xc4, 0x15, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0x12, -0xc2, 0x06, 0x5f, 0x94, 0x60, 0x3b, 0x70, 0xff, -0x54, 0xd6, 0xac, 0x16, 0x2e, 0xc9, 0xda, 0x46, -0xe0, 0xe9, 0x72, 0x28, 0x83, 0xd9, 0xa0, 0x77, -0x43, 0x73, 0x29, 0x2f, 0x13, 0x4c, 0xbb, 0x00, +0x21, 0xdf, 0xd8, 0xb6, 0x76, 0x4f, 0x85, 0xe4, +0x3b, 0xe5, 0x6c, 0x9c, 0xb1, 0xf5, 0xeb, 0x0a, +0xe7, 0x8a, 0xb7, 0x0e, 0x72, 0x7e, 0x23, 0x9b, +0x39, 0x2c, 0x7b, 0x0a, 0x19, 0xa9, 0x5f, 0x21, +0xd7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, +0x01, 0x22, 0x21, 0xb9, 0x75, 0x46, 0x71, 0xbd, +0x2f, 0x0a, 0x47, 0xa7, 0x57, 0x38, 0x32, 0xd4, +0x78, 0xd3, 0x2e, 0xc6, 0x4d, 0xa2, 0x29, 0x58, +0x5e, 0x32, 0x96, 0x7e, 0x59, 0x4b, 0x47, 0x04, +0x09, 0xec, 0x62, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf9, 0x01, 0x22, 0x21, 0xdf, 0xf6, 0x39, +0xee, 0x10, 0xca, 0x14, 0x7a, 0x3b, 0xac, 0x7d, +0xbe, 0xf7, 0x1a, 0x34, 0xaa, 0x9a, 0xb1, 0x02, +0x6f, 0x28, 0x51, 0x0c, 0x96, 0x61, 0x19, 0xb2, +0x77, 0x73, 0x41, 0x51, 0x0f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0x11, +0x3d, 0xf6, 0x7b, 0xc9, 0xa0, 0x05, 0xe1, 0xd6, +0xe5, 0x47, 0xdb, 0x91, 0xf6, 0xb7, 0x7d, 0x18, +0x2a, 0xc8, 0xb8, 0xcf, 0x04, 0x2e, 0xfe, 0xb0, +0xe4, 0xe7, 0x04, 0x64, 0xa9, 0x9e, 0x58, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfb, 0x01, 0x22, -0x21, 0x66, 0x81, 0xef, 0x00, 0x06, 0x19, 0x08, -0x00, 0x1f, 0xf2, 0x7f, 0x30, 0x0d, 0x70, 0x40, -0x3b, 0x1a, 0x58, 0x39, 0x56, 0x0a, 0x14, 0x8d, -0xa7, 0x55, 0x37, 0xe7, 0xf3, 0x39, 0xd2, 0xe2, -0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, -0x01, 0x22, 0x21, 0xa7, 0xf3, 0x01, 0x29, 0x81, -0x34, 0xa1, 0xc9, 0x75, 0x7f, 0xe7, 0xff, 0xfc, -0x55, 0x9e, 0x0e, 0xfa, 0x62, 0xdd, 0xc3, 0x3c, -0x7a, 0x7f, 0xf2, 0x84, 0x53, 0x67, 0x2d, 0x10, -0x29, 0x01, 0x90, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xfd, 0x01, 0x22, 0x21, 0xbb, 0x20, 0x68, -0x74, 0x3a, 0xcd, 0x9a, 0xd3, 0x12, 0x22, 0x91, -0x8a, 0x7e, 0x0b, 0x92, 0x95, 0xb9, 0xcb, 0x5a, -0x0e, 0xc9, 0xce, 0xda, 0x3d, 0x9b, 0x69, 0x4e, -0x77, 0xc5, 0x94, 0x07, 0x73, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0xb0, -0xbd, 0x64, 0x49, 0xed, 0x7d, 0xcd, 0x01, 0x37, -0x75, 0xcc, 0x7c, 0x2f, 0xff, 0x34, 0x67, 0x19, -0x00, 0x27, 0x62, 0xdc, 0x12, 0xa4, 0xa2, 0xc9, -0xdf, 0xa8, 0x09, 0x5b, 0x62, 0xa3, 0xd9, 0x00, +0x21, 0x44, 0x00, 0x60, 0xea, 0xd9, 0xc3, 0xab, +0x73, 0x54, 0x46, 0x41, 0x43, 0x8f, 0x33, 0x79, +0xa7, 0x43, 0xeb, 0x5b, 0x23, 0x2c, 0x69, 0x1e, +0x8c, 0x4e, 0xed, 0xc3, 0xa3, 0x93, 0x0a, 0xc9, +0x62, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, +0x01, 0x22, 0x21, 0xf2, 0x99, 0x6a, 0xb7, 0xaf, +0x6c, 0x8c, 0x65, 0xc8, 0xea, 0x0b, 0x2e, 0x1b, +0x8a, 0xae, 0xee, 0x00, 0xa5, 0x75, 0xaa, 0x45, +0x60, 0x2e, 0x08, 0x2a, 0xde, 0x50, 0x40, 0x8c, +0x71, 0x11, 0x89, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xfd, 0x01, 0x22, 0x21, 0xbf, 0x8c, 0xd6, +0xcf, 0xc8, 0x4a, 0xd7, 0x9c, 0x4e, 0x41, 0xc7, +0xc0, 0xd2, 0x28, 0x25, 0xf4, 0x22, 0xd8, 0xa7, +0x10, 0xd4, 0xf8, 0x77, 0x45, 0x40, 0x50, 0x05, +0xce, 0x64, 0xb9, 0x88, 0xca, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0xff, +0x94, 0x07, 0x61, 0x1e, 0x2c, 0x14, 0xd0, 0x9f, +0xa0, 0xca, 0x3d, 0x22, 0xee, 0x76, 0x5d, 0xc7, +0xa0, 0xf6, 0x6c, 0x9a, 0x8e, 0x49, 0x19, 0xe4, +0xbc, 0x74, 0xa5, 0x17, 0xfb, 0xcd, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xff, 0x01, 0x22, -0x21, 0x6e, 0x2b, 0x10, 0xf4, 0x5b, 0xda, 0x80, -0x6d, 0xf7, 0x8f, 0x03, 0x71, 0xcb, 0xf6, 0x01, -0xcf, 0x7b, 0xdb, 0x9b, 0x45, 0x8c, 0xd6, 0xae, -0x44, 0x63, 0xdd, 0xc8, 0x4e, 0xf0, 0x8f, 0xd7, -0x62, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, -0x01, 0x22, 0x21, 0x7d, 0xff, 0x95, 0x7e, 0xcb, -0xdc, 0xff, 0x7a, 0x92, 0x65, 0x59, 0x26, 0x4c, -0xc0, 0x36, 0x39, 0xa9, 0x4a, 0xb7, 0xfa, 0xed, -0xb7, 0xa1, 0xf5, 0x92, 0x8c, 0x52, 0xc2, 0xeb, -0xf0, 0xf9, 0x66, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x01, 0x01, 0x22, 0x21, 0x19, 0x36, 0x71, -0xcd, 0x3d, 0x21, 0xc1, 0x36, 0x9b, 0x27, 0x33, -0x10, 0x2a, 0x5b, 0xea, 0x08, 0xf7, 0x80, 0x53, -0x48, 0x11, 0xc4, 0xe1, 0xa2, 0x5d, 0xf4, 0xf2, -0x40, 0x7b, 0x0f, 0xc5, 0x80, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0xf0, -0x3a, 0x67, 0xbe, 0x5b, 0xc1, 0x7d, 0x33, 0x09, -0xc6, 0xf1, 0xf0, 0x31, 0x68, 0x6f, 0xe9, 0x78, -0x5a, 0x5f, 0x87, 0xff, 0x9b, 0x39, 0x1c, 0x9d, -0x6c, 0x00, 0xbd, 0x82, 0xe9, 0x02, 0xdc, 0x00, +0x21, 0x9a, 0x12, 0x58, 0xd7, 0x65, 0xa6, 0xec, +0xaa, 0xdc, 0x67, 0x9d, 0x61, 0xba, 0x08, 0xa2, +0x45, 0x11, 0x6b, 0x4e, 0xfa, 0xa5, 0xd1, 0x74, +0xe2, 0xb7, 0x0f, 0x5c, 0x3f, 0x9d, 0x98, 0x32, +0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, +0x01, 0x22, 0x21, 0xc6, 0xaf, 0xec, 0xe5, 0xb0, +0x30, 0xf4, 0x32, 0x2d, 0x62, 0xdd, 0xee, 0xf9, +0xca, 0x35, 0xbd, 0x08, 0xaf, 0x93, 0x7b, 0x71, +0x73, 0xf6, 0xe9, 0x1b, 0x8c, 0xd0, 0x27, 0x64, +0xad, 0xff, 0xe5, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x01, 0x01, 0x22, 0x21, 0x68, 0xbe, 0x25, +0xcb, 0xad, 0x16, 0x39, 0x9f, 0x98, 0x41, 0x25, +0x32, 0xd1, 0x27, 0xd1, 0x46, 0x3f, 0xd2, 0x04, +0x60, 0x82, 0x66, 0x3b, 0x13, 0x18, 0xba, 0x77, +0x0a, 0xe5, 0x99, 0x71, 0x1e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0xe3, +0x7e, 0x9e, 0x07, 0x37, 0xd6, 0x8c, 0x91, 0x52, +0x81, 0x40, 0x2c, 0x82, 0x4e, 0x4d, 0xd9, 0x6a, +0x52, 0xbb, 0x65, 0x6d, 0xd4, 0xb8, 0x3b, 0x34, +0xf2, 0x6f, 0x79, 0x81, 0xf3, 0xb4, 0x43, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x03, 0x01, 0x22, -0x21, 0xe2, 0xe4, 0x23, 0x2e, 0xc9, 0xc7, 0x27, -0x29, 0x59, 0xaf, 0xa8, 0x93, 0x81, 0x1c, 0xbe, -0xc6, 0x1b, 0xdd, 0x9c, 0x0a, 0xfc, 0xbb, 0x86, -0x06, 0x9c, 0x11, 0xc3, 0xca, 0xaa, 0x14, 0x33, -0x08, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, -0x01, 0x22, 0x21, 0x03, 0x17, 0xef, 0x44, 0x70, -0xb1, 0x84, 0xc6, 0x18, 0x3e, 0x6b, 0xf5, 0xbb, -0x88, 0x6e, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x7a, 0xd7, 0x99, -0x5e, 0x92, 0xc4, 0x12, 0x03, 0x04, 0x51, 0x02, -0x00, 0x05, 0x01, 0x22, 0x21, 0xb6, 0xae, 0xd8, -0xa3, 0x5b, 0x69, 0x15, 0x6b, 0xa9, 0x5e, 0x83, -0x95, 0x5e, 0xa8, 0x07, 0x4c, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0xb2, -0x84, 0xf6, 0x19, 0x79, 0xd4, 0x6e, 0x03, 0x04, -0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0x67, -0xa7, 0xb6, 0xed, 0xd2, 0x9c, 0xc8, 0x98, 0x69, -0xb8, 0x24, 0x67, 0xdf, 0xc9, 0x8f, 0xd5, 0x2c, -0xb6, 0x98, 0x02, 0x2a, 0x65, 0xe0, 0x97, 0xd2, -0x4d, 0x52, 0xee, 0xbc, 0xb8, 0xab, 0xc8, 0x00, +0x21, 0x2a, 0xe6, 0x51, 0xd0, 0x83, 0x9b, 0xf9, +0x20, 0xcc, 0x42, 0xc3, 0xff, 0x45, 0xae, 0xe5, +0x87, 0x79, 0x78, 0xcb, 0xcb, 0xb1, 0xd9, 0x03, +0x78, 0x5c, 0x2a, 0x4d, 0x25, 0x74, 0x09, 0x0e, +0x03, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, +0x01, 0x22, 0x21, 0x0d, 0x7e, 0xc6, 0x0d, 0xc0, +0x2d, 0xb1, 0x1f, 0xb1, 0x2f, 0x12, 0x3b, 0x13, +0x60, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xac, 0x85, 0x38, 0x70, +0x3a, 0x00, 0xcd, 0x06, 0x03, 0x04, 0x51, 0x02, +0x00, 0x05, 0x01, 0x22, 0x21, 0x4b, 0x83, 0x6f, +0xf3, 0x73, 0x48, 0x6e, 0x6b, 0x4e, 0x0c, 0xf9, +0xec, 0x46, 0x67, 0x9a, 0x06, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xca, +0xfc, 0x99, 0x35, 0xea, 0x7d, 0xee, 0x03, 0x04, +0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0xf6, +0xaa, 0xbb, 0x02, 0x67, 0xc9, 0x17, 0x4a, 0x99, +0x30, 0x65, 0x4e, 0x28, 0x41, 0xaa, 0x3e, 0xd5, +0x0a, 0xb8, 0x52, 0xc2, 0xdc, 0x2a, 0xa9, 0x0c, +0x01, 0x52, 0x80, 0x53, 0xbe, 0x4c, 0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x07, 0x01, 0x22, -0x21, 0x05, 0xc5, 0x5b, 0xe7, 0x71, 0x66, 0x06, -0x2b, 0xec, 0xa1, 0x2e, 0x18, 0x8f, 0x52, 0x7d, -0x52, 0xd2, 0x11, 0x47, 0x08, 0xe3, 0x62, 0xdf, -0x69, 0x6a, 0x52, 0xfe, 0x71, 0xeb, 0xa9, 0x85, -0x42, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, -0x01, 0x22, 0x21, 0x6f, 0x06, 0x1d, 0x0e, 0xe1, -0xac, 0x3c, 0xaa, 0xe4, 0x8f, 0xba, 0x85, 0x8c, -0x41, 0x7b, 0x26, 0xb3, 0xc1, 0x77, 0xc6, 0x10, -0x51, 0xb6, 0xdf, 0xd7, 0xbc, 0x50, 0x40, 0xd4, -0x16, 0xc5, 0x0f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x09, 0x01, 0x22, 0x21, 0xca, 0x86, 0xf1, -0xdc, 0x59, 0x6a, 0x5d, 0xa4, 0x9b, 0xb5, 0x12, -0x47, 0x96, 0x6c, 0xad, 0x94, 0x05, 0x81, 0xdb, -0x58, 0xf7, 0x77, 0xba, 0x0d, 0xe0, 0x37, 0xc2, -0xaa, 0x40, 0xf1, 0xef, 0xbc, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0x31, -0x7a, 0x9f, 0x61, 0x8d, 0x2b, 0x02, 0x51, 0xd8, -0xa1, 0x99, 0xc4, 0x01, 0x66, 0x39, 0x42, 0xae, -0xef, 0xb4, 0x67, 0x13, 0xfd, 0x49, 0xbe, 0xa8, -0x75, 0xe2, 0xb1, 0xf9, 0x8e, 0xb9, 0x77, 0x00, +0x21, 0xff, 0x90, 0xcd, 0x62, 0x93, 0xd9, 0x51, +0xcc, 0x6b, 0xc1, 0x1d, 0xa7, 0xef, 0x25, 0x32, +0x2b, 0xe9, 0x7d, 0x60, 0xa4, 0xc2, 0x73, 0x76, +0x06, 0xd9, 0xb9, 0x6f, 0x47, 0x20, 0x85, 0xb3, +0xea, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, +0x01, 0x22, 0x21, 0x3c, 0x92, 0xf8, 0xc0, 0xc5, +0xb6, 0x80, 0xc5, 0x6a, 0xc7, 0x0b, 0x5f, 0xfb, +0xdd, 0xbc, 0x75, 0x71, 0xe8, 0xe6, 0x7b, 0x0d, +0x9a, 0xef, 0xd9, 0x45, 0x81, 0xcd, 0x6e, 0x1b, +0xd9, 0x6b, 0x04, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x09, 0x01, 0x22, 0x21, 0x89, 0x9b, 0x35, +0xe3, 0xce, 0xc5, 0x92, 0x87, 0xdd, 0x6c, 0x00, +0xb1, 0x9a, 0xa4, 0xe2, 0xf0, 0x47, 0x6a, 0x2b, +0xdd, 0x3f, 0x8d, 0x90, 0x50, 0x44, 0x0b, 0x20, +0xbb, 0x87, 0x93, 0x61, 0x1d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0x33, +0xa9, 0xd8, 0x48, 0xc2, 0x6b, 0xae, 0xbf, 0x54, +0x2a, 0x34, 0xf2, 0xb8, 0xfa, 0x5f, 0xab, 0xfb, +0x15, 0x98, 0x1b, 0x15, 0x7f, 0x01, 0x78, 0xec, +0x31, 0x31, 0x94, 0x34, 0x68, 0x2b, 0x9a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0b, 0x01, 0x22, -0x21, 0x48, 0x63, 0x1a, 0x0c, 0x4b, 0x88, 0x35, -0xca, 0x9d, 0x71, 0xa1, 0x8e, 0xde, 0x67, 0xd7, -0xa9, 0xf4, 0x9a, 0xa2, 0x44, 0xa0, 0xd7, 0xd4, -0x13, 0x58, 0x6a, 0x28, 0x01, 0xba, 0xbe, 0xbc, -0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, -0x01, 0x22, 0x21, 0x66, 0xbd, 0x63, 0xbe, 0x27, -0x66, 0x95, 0x64, 0xe6, 0x1a, 0x87, 0x27, 0xec, -0xb5, 0x60, 0x11, 0x5a, 0x96, 0x35, 0x50, 0xb8, -0xd1, 0x41, 0x8b, 0x0c, 0xd9, 0x82, 0x32, 0x96, -0x37, 0xcf, 0xdb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x0d, 0x01, 0x22, 0x21, 0x66, 0x20, 0xdb, -0x9e, 0x46, 0x05, 0x9b, 0xaf, 0xfd, 0xc1, 0xa2, -0x38, 0x32, 0x64, 0xee, 0xf6, 0xb4, 0x14, 0xc4, -0xcb, 0x57, 0x88, 0x9e, 0x09, 0x51, 0x33, 0x61, -0x7f, 0xd8, 0x71, 0xfb, 0xa2, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0x37, -0x2a, 0x38, 0xc4, 0x60, 0x56, 0x67, 0x54, 0x16, -0x3f, 0x2e, 0xaa, 0x90, 0xc3, 0xa1, 0xa1, 0x88, -0xda, 0x1d, 0xa5, 0xe9, 0xbd, 0xeb, 0x8a, 0xeb, -0xe9, 0x34, 0xc7, 0xfd, 0xfd, 0x8e, 0x8d, 0x00, +0x21, 0x29, 0x54, 0xf5, 0x8b, 0x73, 0x93, 0x66, +0xeb, 0xf3, 0x45, 0x61, 0x2f, 0xf0, 0x5e, 0x8a, +0x6b, 0xea, 0xe3, 0x5b, 0xd2, 0x3c, 0xfd, 0xd4, +0x13, 0x7b, 0x34, 0x1f, 0xbd, 0x6e, 0x89, 0xb9, +0x76, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, +0x01, 0x22, 0x21, 0x7b, 0xe3, 0x3c, 0x9b, 0x95, +0x35, 0x58, 0x0f, 0xbf, 0x61, 0x63, 0xa9, 0xaa, +0xec, 0xc1, 0xdd, 0x19, 0xd9, 0x9e, 0x7b, 0x04, +0x1b, 0xca, 0xec, 0xb7, 0xe5, 0xd2, 0xd8, 0xe7, +0x12, 0x90, 0x02, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x0d, 0x01, 0x22, 0x21, 0xb3, 0xbf, 0x8e, +0x8d, 0x1c, 0xa9, 0x8d, 0x9a, 0xe9, 0x55, 0x86, +0x17, 0x57, 0xbf, 0xb6, 0x1f, 0x33, 0x18, 0x2a, +0x8c, 0x3d, 0x0b, 0x31, 0xb5, 0x64, 0xcb, 0x42, +0xed, 0x6b, 0x52, 0x20, 0x9e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0xf5, +0x11, 0x48, 0xb7, 0x43, 0x28, 0xde, 0x4c, 0xc2, +0x25, 0x62, 0xa0, 0xff, 0xbc, 0xd9, 0xc2, 0x90, +0x16, 0x89, 0x93, 0xb0, 0x43, 0xa9, 0xdc, 0xbe, +0x29, 0xb6, 0xf5, 0x07, 0xe0, 0x65, 0x57, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0f, 0x01, 0x22, -0x21, 0xe3, 0xee, 0x33, 0x2f, 0x38, 0xb7, 0x93, -0x1d, 0x8f, 0x73, 0x64, 0xb4, 0x1a, 0xeb, 0x25, -0xdb, 0xea, 0x3e, 0xa8, 0xbd, 0x02, 0x26, 0xe7, -0x47, 0x6f, 0x5e, 0xaa, 0xe5, 0xa8, 0x9b, 0x89, -0x0e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, -0x01, 0x22, 0x21, 0x2d, 0x13, 0x16, 0xe7, 0x32, -0xdb, 0x1b, 0xf9, 0xe8, 0x59, 0xec, 0xb6, 0xbf, -0x4e, 0xc3, 0x68, 0x5f, 0x01, 0x2a, 0xe8, 0xac, -0xb0, 0x37, 0x6a, 0x6f, 0x36, 0xe0, 0xe2, 0x4c, -0x72, 0xe4, 0x3b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x11, 0x01, 0x22, 0x21, 0x84, 0x3e, 0xba, -0x35, 0x7b, 0xbf, 0xcf, 0x73, 0x56, 0xc6, 0x11, -0xb9, 0x97, 0xc7, 0xa1, 0x89, 0x26, 0x3c, 0x47, -0x05, 0x0e, 0xef, 0xa6, 0x5b, 0x95, 0x26, 0x27, -0x35, 0x6a, 0xae, 0x09, 0xa7, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0xfc, -0x06, 0x9f, 0x38, 0x29, 0x92, 0x71, 0xb1, 0x44, -0x31, 0x0d, 0x65, 0x6b, 0xf1, 0x00, 0x2a, 0x1f, -0xe8, 0x20, 0x28, 0xe7, 0x92, 0x28, 0x00, 0xe9, -0xf0, 0x6c, 0x95, 0xe8, 0x71, 0xa9, 0xe5, 0x00, +0x21, 0x60, 0xa2, 0x10, 0x5a, 0x3a, 0x6b, 0x36, +0xe9, 0x13, 0x0b, 0x71, 0xa5, 0xbd, 0x6c, 0xc1, +0x6d, 0xd0, 0xf3, 0x32, 0x96, 0xaf, 0x27, 0x51, +0xac, 0xa6, 0xc3, 0x87, 0x37, 0x50, 0xed, 0xeb, +0x92, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, +0x01, 0x22, 0x21, 0x49, 0xd7, 0x4f, 0x62, 0x80, +0xcd, 0xe8, 0x91, 0x4c, 0x00, 0x71, 0x14, 0x64, +0x85, 0xd5, 0x3c, 0xb5, 0xa9, 0x7b, 0x67, 0xdd, +0x64, 0xbe, 0x45, 0xaa, 0x3e, 0xe3, 0xfc, 0x0d, +0x6e, 0x3a, 0x03, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x11, 0x01, 0x22, 0x21, 0x17, 0xf4, 0x0f, +0x64, 0xf7, 0x32, 0xd6, 0x27, 0x65, 0x05, 0xf3, +0x6b, 0x9b, 0x5a, 0x61, 0xec, 0x95, 0x81, 0x87, +0x13, 0xe2, 0x41, 0x93, 0x35, 0x3f, 0x34, 0xff, +0x33, 0x31, 0xa5, 0x22, 0x1a, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0xbe, +0x10, 0x48, 0xc7, 0x53, 0x50, 0x33, 0xa6, 0x93, +0xd8, 0xf1, 0x35, 0x4b, 0x1d, 0xe4, 0x0d, 0x63, +0xdf, 0x88, 0x01, 0xb0, 0x0c, 0xda, 0x6c, 0x40, +0x82, 0x26, 0x82, 0xb4, 0x43, 0x5a, 0x9a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x13, 0x01, 0x22, -0x21, 0x1b, 0x62, 0xde, 0xea, 0x04, 0x17, 0xa0, -0x5e, 0x4b, 0x84, 0x46, 0x15, 0xd2, 0x92, 0x08, -0x2c, 0xf0, 0x5f, 0x31, 0xf6, 0xc7, 0x87, 0x3c, -0x5b, 0x09, 0x1c, 0x55, 0xc3, 0xd3, 0x88, 0x7a, -0x50, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, -0x01, 0x22, 0x21, 0x9a, 0x51, 0xf0, 0x82, 0x02, -0x98, 0xc8, 0x27, 0x56, 0x2f, 0xca, 0x46, 0xe2, -0x78, 0xf1, 0xf0, 0xef, 0x5f, 0x76, 0x2c, 0x14, -0xd1, 0xc3, 0x7c, 0x60, 0xb1, 0x11, 0xf8, 0xbe, -0xa3, 0xe7, 0xd7, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x15, 0x01, 0x22, 0x21, 0x82, 0x35, 0xa6, -0xab, 0xde, 0xe0, 0xb0, 0xf8, 0xc8, 0xd1, 0x54, -0x06, 0x3b, 0x71, 0x6a, 0xdf, 0x52, 0x37, 0x49, -0x87, 0x4c, 0x58, 0x86, 0x13, 0x02, 0x2b, 0x38, -0x2e, 0x6a, 0x7a, 0x61, 0x8e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0xbe, -0x2e, 0x91, 0x89, 0x82, 0x8b, 0x3e, 0xb6, 0x7f, -0xfd, 0xc9, 0xe3, 0x74, 0x8c, 0x99, 0xac, 0xeb, -0x78, 0x13, 0xa3, 0x4f, 0x0f, 0x3b, 0x88, 0x48, -0xfb, 0x93, 0xff, 0x0e, 0x91, 0x6d, 0x46, 0x00, +0x21, 0xe3, 0x56, 0x4e, 0xdb, 0xc7, 0x33, 0x85, +0x88, 0xd7, 0x38, 0xf2, 0x3a, 0x4c, 0xab, 0x5c, +0x51, 0x3d, 0xc5, 0x80, 0xbd, 0xc7, 0x62, 0x5d, +0xd2, 0xde, 0xf1, 0x94, 0x21, 0x63, 0x12, 0x55, +0x30, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, +0x01, 0x22, 0x21, 0xa4, 0x86, 0x12, 0x37, 0x20, +0x5d, 0x9c, 0x5c, 0xaf, 0xe8, 0x52, 0x5d, 0x7a, +0x84, 0xaf, 0x77, 0xa5, 0xd3, 0x3f, 0x84, 0x09, +0xa4, 0xb2, 0x11, 0xb2, 0x00, 0xcf, 0x78, 0xde, +0xde, 0xc8, 0x9c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x15, 0x01, 0x22, 0x21, 0x06, 0x13, 0x3e, +0xb6, 0x34, 0xd2, 0x07, 0x1a, 0xe1, 0x66, 0xfb, +0x83, 0x9c, 0x20, 0x4f, 0xe9, 0x2d, 0x01, 0xaf, +0xb2, 0xb4, 0xd8, 0x41, 0xc1, 0xdc, 0xab, 0xbe, +0x90, 0x2a, 0xdd, 0xf8, 0x9c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x80, +0x95, 0xff, 0x72, 0xb0, 0xf2, 0xd6, 0xdd, 0x5a, +0x65, 0xad, 0xf0, 0x21, 0x12, 0x71, 0x64, 0xa5, +0xf7, 0x3e, 0xff, 0xf5, 0x25, 0x42, 0x1e, 0x77, +0xc6, 0x8c, 0x0c, 0xe0, 0xed, 0xe1, 0xc2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x17, 0x01, 0x22, -0x21, 0x51, 0x5a, 0x07, 0x8b, 0xaa, 0x10, 0x9f, -0xd0, 0xe4, 0x0d, 0x81, 0x1a, 0x07, 0x7c, 0x55, -0x98, 0x41, 0xf5, 0x56, 0x4d, 0x53, 0xa6, 0xf0, -0x4f, 0x9c, 0xf3, 0x7e, 0xf6, 0x8b, 0x5a, 0xc4, -0x06, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, -0x01, 0x22, 0x21, 0x34, 0xd1, 0x7f, 0xf0, 0x55, -0x56, 0x4c, 0xa8, 0x07, 0x57, 0x46, 0xbc, 0x19, -0x9c, 0x7b, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xa6, 0x14, 0xf3, 0x56, -0x3d, 0x12, 0xf8, 0xdc, 0x03, 0x04, 0x51, 0x02, -0x00, 0x19, 0x01, 0x22, 0x21, 0x96, 0x48, 0x9d, -0x2c, 0x49, 0x0e, 0xd0, 0x9b, 0xb3, 0x7e, 0x14, -0xd2, 0x1c, 0xe6, 0x95, 0x96, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x34, -0x0a, 0x8d, 0xc7, 0x95, 0xfc, 0x5a, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0x20, -0x5e, 0x26, 0x51, 0x86, 0x87, 0xcc, 0x89, 0x54, -0x23, 0x50, 0xa5, 0xad, 0xb5, 0x96, 0x9d, 0xa1, -0x7c, 0x65, 0xd2, 0x78, 0x60, 0x3d, 0x22, 0xa2, -0x93, 0x61, 0xf4, 0xd4, 0xa5, 0x26, 0x44, 0x00, +0x21, 0x3f, 0x00, 0xb6, 0xd7, 0xfb, 0x54, 0xc9, +0xae, 0x97, 0x3a, 0x4c, 0x78, 0x67, 0x21, 0x6e, +0x8b, 0xd6, 0x55, 0x2c, 0x88, 0xe8, 0xb4, 0xb1, +0x9a, 0xb4, 0xab, 0x88, 0x71, 0xf0, 0x1f, 0x8a, +0xda, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, +0x01, 0x22, 0x21, 0xa2, 0x11, 0xfa, 0x8b, 0x7b, +0xd7, 0x45, 0xfd, 0xda, 0x46, 0x69, 0x53, 0x6d, +0xe5, 0xbd, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x75, 0xc6, 0xa3, 0xc5, +0xc2, 0xb5, 0x8a, 0x8b, 0x03, 0x04, 0x51, 0x02, +0x00, 0x19, 0x01, 0x22, 0x21, 0xfc, 0x98, 0x77, +0x68, 0x80, 0x9a, 0xed, 0x69, 0xa7, 0x15, 0x6f, +0x11, 0x5d, 0x90, 0xff, 0xee, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0xe6, +0x12, 0xf8, 0x82, 0x0b, 0xf2, 0xba, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0x98, +0x9f, 0x08, 0x57, 0x4d, 0x09, 0xba, 0x82, 0x2c, +0x5a, 0x53, 0xb5, 0x20, 0x9a, 0xa6, 0x0f, 0x46, +0x19, 0x71, 0xd5, 0xd0, 0xb6, 0xb2, 0x6b, 0xcc, +0xfa, 0x3f, 0x9a, 0xce, 0xfc, 0x76, 0x85, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1b, 0x01, 0x22, -0x21, 0x4e, 0x60, 0x0a, 0x53, 0xa4, 0xfa, 0x5c, -0x67, 0xa3, 0xd7, 0xbd, 0xea, 0x98, 0x94, 0x96, -0x44, 0x9a, 0xb2, 0x82, 0xd3, 0x50, 0xa0, 0x03, -0x60, 0x08, 0xcb, 0x6c, 0xd3, 0xf4, 0xc5, 0x3a, -0xdc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, -0x01, 0x22, 0x21, 0xf5, 0xb4, 0xcf, 0xc1, 0x11, -0x57, 0xfd, 0x59, 0x48, 0x69, 0x80, 0xda, 0xee, -0xd0, 0x0f, 0x36, 0x02, 0xa8, 0xdd, 0x3c, 0x85, -0x61, 0xbb, 0xb2, 0x51, 0x63, 0x2d, 0x08, 0xf7, -0xa8, 0x75, 0xd2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x1d, 0x01, 0x22, 0x21, 0x9e, 0x55, 0x2b, -0x77, 0x40, 0xf8, 0x71, 0xce, 0x40, 0x12, 0xe3, -0x54, 0xd3, 0x2c, 0xa8, 0xe6, 0x2b, 0x9e, 0x0b, -0x5f, 0x29, 0xe4, 0xf7, 0x2a, 0x34, 0x70, 0x8e, -0xcb, 0xf4, 0x8d, 0x21, 0xa2, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0x4c, -0x73, 0xc9, 0xd7, 0x32, 0xfa, 0x4a, 0xb5, 0x5c, -0xdc, 0x65, 0x3f, 0x6e, 0xad, 0x81, 0xbd, 0x12, -0x6d, 0x1f, 0x3d, 0xb4, 0xad, 0xbf, 0xd4, 0xee, -0x5d, 0xf5, 0xc0, 0x62, 0x29, 0x36, 0xc2, 0x00, +0x21, 0x95, 0x90, 0x6b, 0xa9, 0x5d, 0x20, 0x81, +0xc8, 0x28, 0x76, 0xbe, 0x2c, 0xee, 0x13, 0x64, +0x58, 0xc3, 0x87, 0x14, 0x4a, 0x95, 0x57, 0x6e, +0x8d, 0xe4, 0x41, 0xea, 0x53, 0xf2, 0x77, 0x9f, +0x58, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, +0x01, 0x22, 0x21, 0x5d, 0x94, 0xef, 0x90, 0x57, +0xbe, 0x2d, 0xec, 0xf4, 0x47, 0xdf, 0x05, 0x68, +0x36, 0x39, 0x6c, 0x72, 0x8d, 0x5d, 0x5e, 0x61, +0xe8, 0x2c, 0xb2, 0xc4, 0xd4, 0xac, 0x2a, 0x8f, +0xf5, 0xe7, 0x61, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x1d, 0x01, 0x22, 0x21, 0x84, 0x28, 0x87, +0x77, 0x12, 0xa3, 0x2a, 0xa1, 0x64, 0x51, 0x16, +0x78, 0x6a, 0xa0, 0x4b, 0xcd, 0x69, 0xe0, 0x74, +0x53, 0xec, 0xed, 0x24, 0x18, 0xf8, 0x4a, 0x66, +0x87, 0x21, 0x37, 0xf2, 0x0f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0x97, +0x52, 0x04, 0xa8, 0x56, 0x24, 0x55, 0x8e, 0x39, +0xfe, 0x40, 0x99, 0xd1, 0x62, 0x69, 0xd4, 0x34, +0x25, 0xe6, 0xf2, 0x31, 0x67, 0x95, 0x5a, 0x9a, +0xf1, 0xf5, 0xd1, 0xc8, 0x0b, 0x42, 0x3a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1f, 0x01, 0x22, -0x21, 0x15, 0xc2, 0x3e, 0xac, 0xfd, 0xa4, 0xf4, -0x24, 0x24, 0x35, 0x56, 0x65, 0xf9, 0xb2, 0xb4, -0xfe, 0x55, 0xa4, 0xe4, 0x55, 0xc4, 0x2e, 0x7e, -0x70, 0xd1, 0x48, 0x7a, 0x0d, 0x24, 0x84, 0x53, -0xd7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, -0x01, 0x22, 0x21, 0x7f, 0x0b, 0xc5, 0x28, 0xb4, -0xef, 0x45, 0x80, 0x22, 0xde, 0xac, 0x15, 0xa2, -0x53, 0x41, 0x6d, 0xf6, 0x70, 0xdf, 0x64, 0xfe, -0xd8, 0x7c, 0x8f, 0x03, 0x9f, 0x42, 0xa8, 0xb3, -0xb5, 0x95, 0x03, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x21, 0x01, 0x22, 0x21, 0x66, 0x7a, 0x61, -0x1c, 0x5e, 0x1d, 0x8b, 0xec, 0xa1, 0x07, 0x8c, -0x16, 0x2c, 0xa0, 0x85, 0x9d, 0xa1, 0xe6, 0xda, -0xc3, 0x98, 0xed, 0x3f, 0x19, 0xa7, 0x2a, 0x50, -0x7f, 0x81, 0xf9, 0x65, 0x7c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0x6c, -0xa7, 0x0c, 0x9b, 0x4d, 0xf9, 0x6c, 0x43, 0xcb, -0xe7, 0x94, 0x0c, 0x1d, 0xc8, 0x85, 0x8b, 0x58, -0xcf, 0x52, 0xc6, 0x3f, 0x3c, 0x3f, 0x0d, 0x10, -0x4c, 0xa0, 0xa8, 0xeb, 0x8a, 0xb5, 0x22, 0x00, +0x21, 0xc8, 0x9f, 0x76, 0x6e, 0xe4, 0x54, 0x96, +0xd4, 0x88, 0xa1, 0xf1, 0x5a, 0xb4, 0x59, 0x18, +0xa7, 0x6d, 0xb6, 0x4f, 0xd6, 0x30, 0x77, 0x1c, +0xf1, 0x87, 0x40, 0x08, 0x64, 0x97, 0x19, 0x86, +0x8d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, +0x01, 0x22, 0x21, 0xe5, 0x8d, 0x2e, 0x29, 0x2a, +0x03, 0x66, 0x16, 0x14, 0x00, 0xc4, 0x38, 0x74, +0x26, 0xbd, 0xc9, 0x10, 0xec, 0x73, 0xf1, 0xe7, +0xf5, 0x97, 0xd5, 0x02, 0xb0, 0x05, 0xb1, 0x25, +0x0e, 0x35, 0x2c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x21, 0x01, 0x22, 0x21, 0xc3, 0x05, 0xda, +0xb6, 0x1d, 0xef, 0xb5, 0x68, 0xbe, 0xdd, 0x61, +0x8f, 0xf6, 0xc9, 0x61, 0x3b, 0x99, 0xa3, 0x39, +0x71, 0x52, 0xf5, 0xc4, 0xae, 0x7b, 0x1c, 0x96, +0x42, 0x90, 0xe2, 0x32, 0x85, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0x7e, +0x06, 0x85, 0x6b, 0xa2, 0x30, 0x30, 0x10, 0x62, +0x7f, 0x60, 0xfa, 0x84, 0x31, 0x12, 0x9a, 0x23, +0xbc, 0x56, 0x6e, 0x0c, 0xab, 0xf9, 0x40, 0xae, +0xdb, 0x75, 0xe7, 0x65, 0xbf, 0x7a, 0xdb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x23, 0x01, 0x22, -0x21, 0x87, 0xcc, 0xa2, 0x25, 0x07, 0xd9, 0xfa, -0x92, 0x87, 0x3c, 0x95, 0x56, 0x7f, 0x40, 0xd7, -0x7c, 0x9c, 0x16, 0x75, 0xc3, 0xee, 0x43, 0x20, -0x64, 0xc6, 0x51, 0x6a, 0xfd, 0x5c, 0x32, 0xf4, -0xcc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, -0x01, 0x22, 0x21, 0x7f, 0xc0, 0x85, 0x30, 0x52, -0x8e, 0xd5, 0x70, 0xc1, 0xfa, 0x80, 0x8e, 0xc0, -0xd9, 0xe5, 0x04, 0xd0, 0xad, 0x05, 0xf5, 0x8c, -0xad, 0x7b, 0x0e, 0x0c, 0xa3, 0xbf, 0xbe, 0xa0, -0xfe, 0xe6, 0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x25, 0x01, 0x22, 0x21, 0x3a, 0x7b, 0x8c, -0x19, 0x08, 0x96, 0x95, 0x1f, 0x38, 0x1e, 0x8e, -0x78, 0x74, 0x05, 0x74, 0x9b, 0x21, 0xb7, 0x6e, -0x3a, 0xaa, 0xdc, 0x8d, 0x16, 0x34, 0x6f, 0x07, -0xf7, 0xf7, 0xb7, 0x98, 0x31, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0x73, -0xc1, 0x10, 0xed, 0x5f, 0x2c, 0x62, 0xff, 0x02, -0x23, 0xda, 0x2a, 0x3e, 0xe3, 0x3a, 0x20, 0xfe, -0x00, 0x25, 0xf8, 0x66, 0x70, 0x7b, 0xa5, 0xd1, -0x55, 0x4b, 0xb4, 0xdb, 0x4a, 0x62, 0x36, 0x00, +0x21, 0x53, 0x91, 0xcb, 0x14, 0x65, 0x57, 0x1e, +0xaa, 0xa3, 0xe3, 0x7c, 0x9f, 0x88, 0x72, 0x3f, +0xa4, 0xf0, 0x40, 0x5c, 0x74, 0xfc, 0xf3, 0xb9, +0x40, 0xa1, 0x73, 0x5b, 0x6f, 0x04, 0x1e, 0x92, +0xf3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, +0x01, 0x22, 0x21, 0xeb, 0xdd, 0xdb, 0xca, 0xc0, +0x41, 0xfd, 0x08, 0xc3, 0x32, 0x7f, 0x66, 0x67, +0x74, 0xcb, 0x00, 0x6e, 0xb0, 0x2f, 0x79, 0x00, +0x2b, 0x61, 0x6c, 0x3e, 0x11, 0xb2, 0x0a, 0x91, +0x1b, 0xbb, 0x93, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x25, 0x01, 0x22, 0x21, 0xd1, 0x16, 0x3f, +0x22, 0xb4, 0x85, 0xa2, 0x51, 0x2f, 0x1d, 0x3b, +0xd7, 0x3a, 0x40, 0xe6, 0xfb, 0x8a, 0x6d, 0x20, +0xe2, 0x60, 0xa6, 0x29, 0x75, 0x31, 0x0c, 0x19, +0x4f, 0xac, 0x19, 0xc0, 0xc2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0x2a, +0x1e, 0x05, 0x26, 0xb2, 0x85, 0x07, 0x29, 0x43, +0x1e, 0x06, 0xba, 0x33, 0x70, 0xc5, 0x90, 0x26, +0xf6, 0xf2, 0x86, 0xaa, 0x3e, 0xbc, 0x2a, 0x9e, +0x72, 0x4c, 0x62, 0xe7, 0x34, 0xd1, 0x95, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x27, 0x01, 0x22, -0x21, 0xfd, 0xd3, 0x43, 0xde, 0xa7, 0x66, 0x98, -0x2c, 0xd2, 0x59, 0x8c, 0x65, 0x88, 0xcc, 0x39, -0xac, 0x55, 0x80, 0xa4, 0x56, 0x0a, 0x7a, 0xcf, -0x5a, 0x90, 0x85, 0x67, 0x0e, 0xd1, 0x49, 0x0c, -0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, -0x01, 0x22, 0x21, 0x4d, 0x3a, 0x4c, 0x1b, 0x22, -0x1a, 0x80, 0xcc, 0x9b, 0x04, 0x88, 0xa5, 0x73, -0xb8, 0x85, 0xcb, 0xd3, 0x3e, 0x74, 0x35, 0x3f, -0x9f, 0xc2, 0xcd, 0xb5, 0x78, 0xcb, 0xb3, 0x87, -0x69, 0xef, 0xe2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x29, 0x01, 0x22, 0x21, 0x70, 0x65, 0x02, -0x52, 0xbf, 0xd6, 0x84, 0x0b, 0x4b, 0xe1, 0x8a, -0x4a, 0x88, 0xb5, 0xb3, 0x3d, 0xa7, 0x88, 0xf2, -0x15, 0x63, 0xcb, 0x2c, 0x7d, 0xf3, 0x76, 0x2c, -0x64, 0xc9, 0xfb, 0x63, 0x23, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x55, -0x65, 0xc0, 0x29, 0x4b, 0x22, 0x23, 0xae, 0xea, -0x57, 0x94, 0xa2, 0xbc, 0xa4, 0x8f, 0xb7, 0xb3, -0x24, 0x55, 0x6a, 0x09, 0x34, 0xb2, 0xe4, 0x8b, -0xd4, 0x0c, 0x3e, 0x34, 0xd0, 0xb7, 0x44, 0x00, +0x21, 0xcf, 0x94, 0x35, 0xa9, 0xf3, 0x0c, 0xfe, +0x64, 0x2f, 0x80, 0xc5, 0xe5, 0xc0, 0x87, 0x5b, +0x78, 0xc6, 0xd1, 0x52, 0xbf, 0x9c, 0x74, 0xcc, +0x50, 0x93, 0x8d, 0x1d, 0xd8, 0x53, 0xb9, 0xa4, +0x57, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, +0x01, 0x22, 0x21, 0x86, 0x7b, 0x17, 0xa0, 0x6a, +0x3f, 0x69, 0x71, 0x5e, 0x60, 0x2b, 0x63, 0x72, +0x99, 0x62, 0x41, 0x19, 0x9a, 0xf9, 0xb7, 0x6f, +0x1d, 0x5d, 0x6b, 0xfb, 0x67, 0xe8, 0xf2, 0x4d, +0xeb, 0x52, 0xd8, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x29, 0x01, 0x22, 0x21, 0x72, 0x4a, 0xea, +0xa5, 0x10, 0x03, 0x3b, 0xcb, 0x42, 0x19, 0xc9, +0x10, 0xbb, 0x5a, 0xc9, 0xb4, 0x9b, 0x89, 0x5e, +0xba, 0x10, 0x01, 0x08, 0x5e, 0x69, 0x8c, 0x31, +0x91, 0x9e, 0xa5, 0x91, 0x57, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0xd6, +0x18, 0xfc, 0xb7, 0x1c, 0xa6, 0xd8, 0x09, 0x05, +0x94, 0xb4, 0x00, 0xee, 0x56, 0xf4, 0xc0, 0xfe, +0xc6, 0x53, 0x74, 0xa4, 0xb1, 0x55, 0x3d, 0x8d, +0xa8, 0x98, 0xcd, 0x31, 0x17, 0xc4, 0x52, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2b, 0x01, 0x22, -0x21, 0x42, 0xea, 0xa9, 0xea, 0xb9, 0x19, 0xbd, -0x79, 0x7b, 0xea, 0x77, 0xd4, 0xf9, 0x27, 0xd6, -0xbb, 0x8a, 0x5e, 0x79, 0x78, 0xa7, 0x92, 0xc9, -0xe0, 0xf9, 0x8f, 0xa3, 0x52, 0x52, 0x47, 0xa4, -0xd3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, -0x01, 0x22, 0x21, 0x03, 0x06, 0x4f, 0xf0, 0x14, -0xf4, 0xdf, 0xcc, 0x6c, 0xac, 0xc9, 0xd0, 0x0a, -0xc2, 0x29, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x2b, 0xcb, 0x83, 0x97, -0x18, 0x29, 0x98, 0xb9, 0x03, 0x04, 0x51, 0x02, -0x00, 0x2d, 0x01, 0x22, 0x21, 0x8f, 0x4c, 0xa2, -0x04, 0x48, 0x6d, 0xeb, 0xaf, 0x6b, 0xb3, 0x92, -0xcb, 0x40, 0x6e, 0x2d, 0xff, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x94, -0xc3, 0x78, 0x2c, 0xaf, 0x3a, 0x13, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0x54, -0x04, 0xf0, 0xbe, 0x43, 0x36, 0x3c, 0x63, 0x30, -0xfe, 0xb4, 0x11, 0xfe, 0x44, 0xc1, 0xdc, 0x26, -0x72, 0xcc, 0x70, 0xce, 0xaa, 0xf2, 0x96, 0x53, -0xff, 0xd7, 0xa7, 0x8a, 0xb7, 0xb1, 0xc0, 0x00, +0x21, 0x89, 0x8a, 0x10, 0xe3, 0x3a, 0xc0, 0xd7, +0xdf, 0x65, 0x6e, 0xcd, 0x6b, 0xa1, 0x12, 0x7f, +0x4f, 0xbd, 0x52, 0x6d, 0x56, 0x49, 0x71, 0x96, +0xb5, 0xe8, 0x7d, 0xa4, 0x22, 0xae, 0xd3, 0xc2, +0x07, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, +0x01, 0x22, 0x21, 0xdf, 0x90, 0xea, 0x6e, 0xa0, +0x52, 0x32, 0x65, 0x44, 0xe3, 0xf5, 0xc7, 0xa3, +0x86, 0x08, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x06, 0xbd, 0x8c, 0xa2, +0xf1, 0xb2, 0x05, 0x31, 0x03, 0x04, 0x51, 0x02, +0x00, 0x2d, 0x01, 0x22, 0x21, 0x22, 0xb7, 0x7d, +0xcc, 0x85, 0x1e, 0xae, 0x70, 0xf8, 0xa9, 0x41, +0xaf, 0x03, 0x9e, 0xc0, 0x4b, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0xf3, +0xba, 0x26, 0x5c, 0x3e, 0x9f, 0x97, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0xe8, +0x32, 0xb9, 0x4d, 0x23, 0xa6, 0xbc, 0x59, 0x97, +0x92, 0xef, 0x43, 0xca, 0xb3, 0x30, 0xa5, 0xe3, +0xb6, 0x98, 0x2e, 0x4b, 0x0f, 0xee, 0x9c, 0x68, +0xf7, 0xbd, 0xd5, 0xf2, 0xa0, 0x47, 0x98, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2f, 0x01, 0x22, -0x21, 0x10, 0x15, 0x6f, 0x08, 0xd1, 0xfa, 0x9b, -0xbc, 0x80, 0xe1, 0x56, 0x5c, 0x09, 0x1e, 0xc6, -0xff, 0x94, 0xaf, 0xfc, 0x78, 0x77, 0x26, 0xa9, -0x15, 0x85, 0x76, 0x88, 0xc0, 0x01, 0x00, 0x37, -0x64, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, -0x01, 0x22, 0x21, 0xcd, 0x36, 0x86, 0x25, 0x21, -0xf3, 0xb9, 0x01, 0x6a, 0x77, 0xbf, 0x69, 0xce, -0xa4, 0x02, 0x34, 0xb7, 0xc2, 0x29, 0xff, 0xa2, -0x73, 0xfd, 0x9e, 0xe6, 0x46, 0x58, 0x7c, 0x54, -0x22, 0x93, 0x81, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x31, 0x01, 0x22, 0x21, 0xff, 0x65, 0x51, -0x7d, 0x6d, 0x02, 0x19, 0xcf, 0x7a, 0x70, 0xff, -0x37, 0x69, 0xd6, 0x99, 0x20, 0x3a, 0x7d, 0xfb, -0xe1, 0xc3, 0x84, 0x17, 0x90, 0xce, 0x68, 0x0e, -0x86, 0x86, 0x91, 0x06, 0x20, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0xdc, -0x5d, 0x1f, 0x36, 0x05, 0xef, 0x60, 0x72, 0x4e, -0x04, 0xd3, 0x8c, 0x83, 0x96, 0x41, 0xf6, 0xf3, -0x9b, 0x9c, 0xff, 0xbe, 0x99, 0x9a, 0x53, 0xee, -0x0b, 0xaf, 0xf8, 0xd8, 0x1b, 0xc9, 0xf4, 0x00, +0x21, 0xac, 0x08, 0x26, 0xc5, 0x40, 0xa3, 0x4b, +0x63, 0xdc, 0x95, 0xce, 0xdd, 0x51, 0x92, 0x65, +0x3a, 0x2b, 0x69, 0x77, 0xdf, 0xe4, 0x46, 0x0a, +0x1a, 0xa8, 0xc3, 0xa4, 0xae, 0xcd, 0x16, 0x46, +0x24, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, +0x01, 0x22, 0x21, 0x6b, 0xce, 0x4b, 0x4b, 0xe3, +0xf4, 0xc7, 0xfa, 0x4c, 0xee, 0x86, 0xa0, 0x3d, +0x1f, 0x8c, 0xa0, 0x51, 0xf0, 0xd5, 0x28, 0xf6, +0x0d, 0x06, 0xaa, 0xc0, 0x13, 0x12, 0x09, 0x5d, +0xf2, 0x01, 0x6a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x31, 0x01, 0x22, 0x21, 0x29, 0x41, 0x72, +0x3d, 0xb6, 0x5e, 0xee, 0xbb, 0x81, 0xbd, 0x7e, +0xb7, 0xd3, 0xa4, 0xcc, 0x6a, 0x11, 0xdd, 0x92, +0xeb, 0xae, 0x42, 0x67, 0x47, 0x44, 0xdb, 0xf4, +0x5f, 0xbd, 0xc4, 0xc5, 0x39, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0xc8, +0x8a, 0xde, 0x68, 0xdc, 0x7f, 0x80, 0xa2, 0x5b, +0x02, 0x7f, 0x1a, 0xfc, 0xf8, 0xa3, 0x90, 0x41, +0x63, 0xef, 0xcf, 0xae, 0x54, 0x6b, 0x80, 0x19, +0x4c, 0xf9, 0x4c, 0x89, 0x1b, 0x78, 0x58, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x33, 0x01, 0x22, -0x21, 0x9c, 0x1e, 0x7b, 0x8c, 0x70, 0xb2, 0x83, -0x95, 0xa7, 0x72, 0xcc, 0x00, 0xa1, 0xde, 0xd5, -0xa1, 0x43, 0x56, 0x38, 0x87, 0xb2, 0x1b, 0xc1, -0xbf, 0x1e, 0x3d, 0x35, 0x39, 0xeb, 0xd9, 0x36, -0xc3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, -0x01, 0x22, 0x21, 0x78, 0x50, 0x04, 0x46, 0xe4, -0xed, 0xab, 0x67, 0xee, 0x89, 0xcf, 0x21, 0x2f, -0x90, 0xa3, 0x64, 0x4d, 0x33, 0x8e, 0xf3, 0x67, -0x46, 0xc5, 0x70, 0xe6, 0x5b, 0x70, 0xc1, 0x7a, -0x19, 0x09, 0xb2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x35, 0x01, 0x22, 0x21, 0x0d, 0x95, 0x9d, -0x2a, 0x41, 0x30, 0xc3, 0x38, 0x91, 0xb6, 0x51, -0x74, 0xbf, 0xe0, 0xce, 0x62, 0xf8, 0x51, 0x56, -0x94, 0x7e, 0x91, 0xe2, 0x28, 0xa7, 0xd1, 0x81, -0x7e, 0x87, 0x86, 0x24, 0xc0, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0x75, -0x41, 0xf3, 0x71, 0x2c, 0x19, 0xc1, 0x02, 0x60, -0x4a, 0xe7, 0xc7, 0x88, 0x87, 0x34, 0x5c, 0x01, -0x6b, 0xaf, 0x5f, 0xf5, 0xa0, 0x7d, 0xba, 0xdd, -0x25, 0xfa, 0xfe, 0x2b, 0x08, 0x2b, 0x28, 0x00, +0x21, 0x4c, 0x88, 0xbd, 0xd5, 0x17, 0xe6, 0x5b, +0x7e, 0x4e, 0xc1, 0x91, 0x86, 0xe6, 0xeb, 0xc8, +0xca, 0x96, 0x94, 0xd3, 0x3b, 0xba, 0x6b, 0x7f, +0x92, 0xd5, 0xbf, 0x05, 0x33, 0x20, 0xa5, 0xa8, +0x05, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, +0x01, 0x22, 0x21, 0x9d, 0xf3, 0x76, 0x98, 0xd2, +0x31, 0xed, 0x71, 0xc0, 0xd3, 0x3a, 0x9e, 0xa7, +0x8d, 0xfc, 0xec, 0xcc, 0xa1, 0xbb, 0x43, 0xfe, +0xa3, 0x2c, 0x87, 0x38, 0x4f, 0xb5, 0x1a, 0xbc, +0x46, 0xff, 0x99, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x35, 0x01, 0x22, 0x21, 0xc0, 0x10, 0xac, +0x96, 0xbd, 0xba, 0x8f, 0x81, 0xcd, 0xbb, 0xfa, +0xc6, 0x64, 0x30, 0x51, 0xd7, 0x1b, 0x24, 0x4c, +0xae, 0x34, 0xe4, 0x2d, 0xad, 0x89, 0x1b, 0xdf, +0x00, 0x4c, 0xd2, 0x58, 0xb6, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0x84, +0xf2, 0xb5, 0x58, 0x9d, 0x0b, 0x8b, 0x0b, 0x6d, +0xe7, 0xd1, 0x8b, 0xd6, 0x92, 0xe5, 0xfe, 0x20, +0xee, 0x9d, 0xad, 0xcf, 0xc5, 0x9e, 0x3b, 0xe3, +0x47, 0x2e, 0x71, 0x4a, 0x62, 0x54, 0xa8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x37, 0x01, 0x22, -0x21, 0x91, 0xeb, 0x1c, 0x67, 0x33, 0x4c, 0x80, -0x82, 0xa6, 0x08, 0x54, 0xb4, 0xa5, 0x97, 0xe5, -0x95, 0xe1, 0x91, 0x89, 0x80, 0x68, 0xc5, 0x2b, -0xc9, 0xa1, 0x97, 0xb5, 0x09, 0x81, 0x7f, 0xfd, -0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, -0x01, 0x22, 0x21, 0x96, 0xa9, 0xb9, 0xff, 0xfc, -0x43, 0xd1, 0x95, 0xab, 0x7b, 0xf2, 0xfa, 0xe9, -0xc5, 0x14, 0x2a, 0x4f, 0xf5, 0x09, 0xee, 0x87, -0x83, 0xdf, 0x22, 0xcc, 0xa5, 0x7f, 0xe7, 0x87, -0xfb, 0xbb, 0xd2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x39, 0x01, 0x22, 0x21, 0x70, 0x41, 0xc4, -0x09, 0x6f, 0xed, 0x12, 0x69, 0x3e, 0x51, 0x90, -0x28, 0xed, 0xf2, 0xd5, 0x84, 0x4f, 0x75, 0xf5, -0x48, 0xf9, 0x30, 0x2c, 0x60, 0x3a, 0x07, 0xa5, -0x17, 0x41, 0xf4, 0xa2, 0x2c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0xa3, -0x92, 0x06, 0xa8, 0x93, 0x4b, 0x81, 0x2a, 0x0d, -0x3b, 0x6d, 0xc8, 0xb9, 0x47, 0x7e, 0x7a, 0x8a, -0x01, 0x10, 0x2d, 0xb2, 0xdf, 0x48, 0x9a, 0x43, -0x81, 0xd7, 0x77, 0xca, 0x38, 0xc0, 0x13, 0x00, +0x21, 0xe0, 0xf4, 0x3a, 0x39, 0x78, 0x37, 0x80, +0xd6, 0x1e, 0x4c, 0x7a, 0xdd, 0xc4, 0xc2, 0xf5, +0x03, 0xd9, 0xab, 0xe6, 0xa1, 0x10, 0x17, 0xe9, +0x6d, 0xd5, 0xa5, 0xec, 0x54, 0x7e, 0xcd, 0xb7, +0x3f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, +0x01, 0x22, 0x21, 0x3c, 0x58, 0x11, 0x3f, 0xa6, +0xbd, 0x5c, 0x2e, 0x4f, 0xdc, 0x67, 0x96, 0x96, +0x6c, 0x7b, 0x4d, 0x5c, 0xfe, 0x43, 0x2e, 0xb0, +0x9f, 0x79, 0x04, 0x09, 0xce, 0xd2, 0xbe, 0x61, +0x5d, 0x8e, 0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x39, 0x01, 0x22, 0x21, 0xe2, 0x75, 0x4d, +0x31, 0x04, 0x28, 0xa1, 0xc6, 0xca, 0x19, 0x04, +0x8c, 0xee, 0xa8, 0xf5, 0x71, 0x50, 0xcd, 0x33, +0x33, 0x7b, 0x3b, 0x2c, 0x23, 0x7f, 0xd7, 0xc4, +0xa2, 0x73, 0x77, 0x64, 0x8f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0x5a, +0xf4, 0x90, 0x28, 0xbc, 0xbb, 0x14, 0x30, 0x4d, +0xfa, 0x32, 0xf7, 0x16, 0xda, 0xfe, 0x77, 0x84, +0x5b, 0xe8, 0x40, 0xcb, 0x2e, 0xea, 0x78, 0xf0, +0x58, 0xde, 0x72, 0xc2, 0x1c, 0xf5, 0x72, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3b, 0x01, 0x22, -0x21, 0xfd, 0xae, 0x2d, 0x46, 0x0d, 0xad, 0xc1, -0x7e, 0xaf, 0x78, 0x8d, 0x1c, 0x3a, 0x4c, 0x0c, -0x39, 0x77, 0x3b, 0xeb, 0x7a, 0x17, 0x7a, 0x22, -0xeb, 0x83, 0x98, 0x2b, 0xb6, 0x85, 0x85, 0x64, -0x02, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, -0x01, 0x22, 0x21, 0x7e, 0x9a, 0x5b, 0xfb, 0x49, -0x8e, 0xe7, 0xae, 0xf2, 0x91, 0x44, 0xf2, 0x7c, -0xa2, 0x55, 0x59, 0x47, 0x77, 0x0f, 0xc0, 0xa4, -0xc6, 0xb8, 0xb3, 0x12, 0xda, 0x5a, 0x99, 0xfd, -0x71, 0xf4, 0xc1, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x3d, 0x01, 0x22, 0x21, 0x01, 0x11, 0x58, -0xae, 0xab, 0x25, 0xa9, 0x07, 0xb4, 0xe7, 0x53, -0x8f, 0x6f, 0x4a, 0xd7, 0x8c, 0x83, 0x2a, 0xd3, -0x5b, 0x16, 0x70, 0x99, 0x2f, 0x10, 0xc7, 0xb1, -0x7b, 0x9c, 0xfd, 0x92, 0x02, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0x71, -0xd2, 0xbf, 0xab, 0x58, 0x29, 0x7e, 0xe4, 0x10, -0x0b, 0x42, 0xe5, 0x35, 0xbe, 0x63, 0x95, 0xd8, -0xb1, 0xd7, 0x65, 0xf0, 0xa0, 0x1e, 0x8f, 0x04, -0xde, 0x77, 0x77, 0xc4, 0xf4, 0x17, 0xa4, 0x00, +0x21, 0xf9, 0xae, 0x13, 0xc7, 0x16, 0x7e, 0xe4, +0xf4, 0xa1, 0xb2, 0x6c, 0x53, 0xa4, 0x00, 0x5c, +0x0d, 0x84, 0x8a, 0xf3, 0x38, 0x4f, 0xb3, 0x53, +0x3a, 0x70, 0x16, 0xcd, 0x7e, 0xf4, 0x55, 0x2b, +0x30, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, +0x01, 0x22, 0x21, 0x49, 0x64, 0x41, 0xe9, 0xa8, +0xf2, 0x39, 0xa5, 0x6c, 0x83, 0x7e, 0x5e, 0x4a, +0xe4, 0xaf, 0xc8, 0x6d, 0xdc, 0x18, 0x20, 0xe2, +0xd0, 0xa3, 0x6c, 0xf0, 0x4f, 0x56, 0x7f, 0xfb, +0xfe, 0x0c, 0x00, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x3d, 0x01, 0x22, 0x21, 0x48, 0x68, 0xea, +0xe3, 0xfd, 0xc9, 0xde, 0x01, 0x16, 0x6f, 0x77, +0x17, 0x66, 0xda, 0x1b, 0x52, 0x24, 0x27, 0x66, +0x42, 0x92, 0xda, 0x25, 0x38, 0xa7, 0x8e, 0x89, +0x83, 0x60, 0x9b, 0x0b, 0x0d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0x4b, +0x34, 0xe0, 0xbb, 0xa0, 0x7a, 0xb6, 0x21, 0x0e, +0x0c, 0xdb, 0xd0, 0xf5, 0x04, 0x7d, 0xfc, 0x30, +0x87, 0x9b, 0xb8, 0x38, 0xf4, 0xb1, 0xba, 0x15, +0x5e, 0xed, 0x8f, 0x7c, 0x21, 0xed, 0x7a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3f, 0x01, 0x22, -0x21, 0xd1, 0x8b, 0xd3, 0x9b, 0x27, 0xf2, 0xe7, -0x0d, 0xcd, 0x04, 0x13, 0x31, 0x86, 0x48, 0x67, -0x81, 0xe1, 0x2b, 0x6d, 0xbe, 0x3c, 0x01, 0xe9, -0x56, 0xe0, 0x3a, 0x75, 0x41, 0x17, 0x86, 0xc6, -0xed, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, -0x01, 0x22, 0x21, 0x04, 0xbd, 0x3c, 0xf5, 0xe2, -0x06, 0x8e, 0xa8, 0xcb, 0xaa, 0xb6, 0x1f, 0x5a, -0x16, 0xe1, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x8d, 0x29, 0x6c, 0x14, -0xdc, 0x3c, 0xff, 0x7f, 0x03, 0x04, 0x51, 0x02, -0x00, 0x41, 0x01, 0x22, 0x21, 0xde, 0xea, 0x7d, -0x96, 0xe9, 0xb6, 0x7d, 0x7f, 0x96, 0x41, 0x6e, -0x98, 0x37, 0x90, 0x30, 0x78, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xa2, -0x50, 0xb7, 0xd7, 0xf1, 0x96, 0x01, 0x03, 0x04, -0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0xb3, -0xa9, 0xbf, 0x0b, 0xfb, 0xdd, 0xe3, 0x39, 0x0a, -0x98, 0xa6, 0xab, 0xc7, 0x19, 0xa9, 0x25, 0x41, -0x06, 0x33, 0xff, 0xe4, 0xaf, 0xad, 0x3b, 0xa2, -0x32, 0x10, 0x37, 0xe6, 0x1f, 0x06, 0x49, 0x00, +0x21, 0x1a, 0xa4, 0xeb, 0x8e, 0x2e, 0xbf, 0xa9, +0xc0, 0xe9, 0xb8, 0x50, 0xcb, 0xd0, 0x4e, 0xe1, +0x56, 0xa2, 0x18, 0xa7, 0x5b, 0x3c, 0x36, 0xe4, +0x1c, 0x14, 0x4a, 0xf1, 0xbb, 0xb2, 0x9f, 0xa9, +0xef, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, +0x01, 0x22, 0x21, 0x2c, 0x4f, 0x00, 0x48, 0x45, +0x4c, 0x81, 0x64, 0x55, 0x77, 0x4e, 0x0e, 0x99, +0x36, 0xac, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xab, 0x48, 0xf1, 0x97, +0xe3, 0xd2, 0x24, 0xfd, 0x03, 0x04, 0x51, 0x02, +0x00, 0x41, 0x01, 0x22, 0x21, 0x45, 0xf0, 0xdf, +0xe3, 0x20, 0xf9, 0xaf, 0x97, 0x1f, 0xb4, 0x68, +0x94, 0xe1, 0x54, 0x84, 0xad, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x15, +0x71, 0xec, 0xcd, 0x85, 0x83, 0xd0, 0x03, 0x04, +0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0xc7, +0x89, 0x2e, 0xa4, 0xfd, 0x2f, 0x40, 0x41, 0xd1, +0x41, 0x5b, 0x0c, 0x22, 0xb3, 0xbe, 0xc0, 0x32, +0xf4, 0xa8, 0x4e, 0x8d, 0x0e, 0x6d, 0x8d, 0x5a, +0x85, 0xdd, 0xda, 0x45, 0x18, 0x10, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x43, 0x01, 0x22, -0x21, 0x8b, 0xa1, 0xb3, 0xba, 0x9a, 0xd1, 0x95, -0xa6, 0xf2, 0x34, 0xd5, 0xe8, 0x73, 0x09, 0x28, -0x68, 0xec, 0x7f, 0x76, 0xac, 0xf4, 0x14, 0x08, -0x0b, 0x07, 0x26, 0xb9, 0x10, 0x31, 0x22, 0xa9, -0xee, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, -0x01, 0x22, 0x21, 0xa1, 0xa1, 0x02, 0xef, 0x1c, -0x0d, 0xe5, 0x7f, 0xa2, 0xdc, 0x9b, 0xf4, 0x95, -0xaa, 0x80, 0x08, 0xa8, 0xaa, 0x1c, 0x3b, 0xf9, -0x3d, 0x34, 0x0a, 0xf5, 0xfe, 0x9d, 0x07, 0x30, -0xe4, 0x39, 0xac, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x45, 0x01, 0x22, 0x21, 0xc7, 0x4d, 0x48, -0xfa, 0x6a, 0x46, 0x43, 0xa9, 0x8c, 0x3c, 0xad, -0x25, 0xc8, 0xa5, 0x04, 0x20, 0x2b, 0x1f, 0xd9, -0x1a, 0x31, 0x0d, 0xc2, 0x32, 0xb8, 0xed, 0x33, -0x64, 0x1d, 0xf5, 0x7b, 0x73, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0x0b, -0xc7, 0x83, 0xd5, 0x6d, 0xdf, 0x84, 0xdf, 0x79, -0x44, 0x81, 0x7e, 0xa3, 0x07, 0xca, 0xa6, 0xbf, -0x9f, 0xfe, 0x0a, 0x73, 0x24, 0xbd, 0x2c, 0x4a, -0x12, 0x90, 0x39, 0x4c, 0x21, 0xa9, 0xaf, 0x00, +0x21, 0xaa, 0x8a, 0x2b, 0xc6, 0x33, 0x95, 0xe4, +0xf3, 0xfa, 0xc0, 0x05, 0x92, 0x7e, 0x29, 0xf8, +0x40, 0x7d, 0x9d, 0xcd, 0x81, 0xfd, 0x94, 0x90, +0xd3, 0xee, 0x55, 0xbd, 0x33, 0x68, 0x6b, 0x64, +0xd9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, +0x01, 0x22, 0x21, 0x95, 0xde, 0x66, 0x9c, 0x49, +0x2a, 0x89, 0x96, 0xe6, 0x72, 0xc1, 0xd5, 0x3f, +0x46, 0x0b, 0x59, 0xc1, 0x6a, 0xc7, 0x2c, 0x21, +0x03, 0xa6, 0x71, 0x63, 0x25, 0x5e, 0x18, 0xd5, +0x13, 0x0f, 0x9a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x45, 0x01, 0x22, 0x21, 0x55, 0x3c, 0x43, +0x99, 0xbc, 0xc9, 0x8e, 0x80, 0x02, 0x1a, 0xda, +0xfb, 0x6f, 0xd2, 0x71, 0x94, 0x95, 0x0f, 0xa3, +0xbb, 0x95, 0xe9, 0x20, 0x42, 0x74, 0x34, 0x44, +0xe6, 0x29, 0xd4, 0x9f, 0x02, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0xcd, +0x7d, 0x53, 0x34, 0x44, 0x02, 0xfe, 0x45, 0x33, +0x71, 0x15, 0xc6, 0xb2, 0x2c, 0x7d, 0xb3, 0x98, +0xe2, 0xe8, 0x9b, 0x6a, 0x57, 0x04, 0xca, 0xa6, +0x53, 0x94, 0x9c, 0xe5, 0xd5, 0x48, 0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x47, 0x01, 0x22, -0x21, 0xf2, 0x53, 0xf7, 0x52, 0xe4, 0xa9, 0x0f, -0x44, 0x91, 0x8e, 0xa1, 0x3a, 0x6b, 0xd7, 0x3c, -0xbd, 0xb6, 0x1a, 0x2a, 0xce, 0x17, 0x70, 0x97, -0x43, 0x1b, 0x62, 0xef, 0x7f, 0x86, 0x59, 0x75, -0x24, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, -0x01, 0x22, 0x21, 0xc0, 0x03, 0x91, 0x6b, 0x29, -0x64, 0x38, 0xd4, 0xdb, 0x34, 0x9f, 0x48, 0x52, -0xa3, 0xde, 0xf8, 0x73, 0xeb, 0xe3, 0x92, 0x6b, -0xfe, 0xa5, 0xc0, 0x32, 0xbb, 0xa4, 0xbe, 0x0b, -0x94, 0xc2, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x49, 0x01, 0x22, 0x21, 0xa0, 0x6f, 0x97, -0x1f, 0x45, 0x5b, 0x7f, 0x4d, 0xec, 0x00, 0xc2, -0x2f, 0x44, 0x74, 0x27, 0x74, 0x48, 0x38, 0x1d, -0x0d, 0x45, 0x0c, 0xbc, 0xca, 0x1b, 0x7a, 0x8e, -0x21, 0xcc, 0x9e, 0x30, 0x73, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0x49, -0x0c, 0xf3, 0xca, 0x67, 0x9a, 0x4b, 0x0e, 0xcd, -0x03, 0x29, 0xc6, 0x70, 0x04, 0x6d, 0x25, 0xe5, -0x7e, 0xf7, 0x34, 0xeb, 0xac, 0xfd, 0xa9, 0x9f, -0x23, 0x3e, 0xfc, 0xf4, 0xcb, 0x05, 0x1e, 0x00, +0x21, 0xd0, 0x06, 0x31, 0x65, 0xec, 0xf0, 0x00, +0x13, 0x6b, 0x36, 0xcc, 0xfd, 0x78, 0xb8, 0xb5, +0x4e, 0xbf, 0x0f, 0x4c, 0x10, 0x4f, 0xb3, 0x1c, +0xf7, 0xe4, 0x65, 0x0d, 0x90, 0xd0, 0xe4, 0x88, +0x4b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, +0x01, 0x22, 0x21, 0xd4, 0x52, 0x8c, 0x0f, 0x83, +0xf7, 0xfe, 0x43, 0x88, 0xdf, 0xf1, 0xd6, 0x0a, +0xf4, 0x46, 0x43, 0xb3, 0x7b, 0x58, 0x30, 0xe1, +0x50, 0x1a, 0xea, 0x06, 0xf6, 0x9f, 0xe0, 0x57, +0x5d, 0xce, 0xe9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x49, 0x01, 0x22, 0x21, 0xb3, 0xc7, 0xcc, +0xf3, 0x77, 0x43, 0x92, 0x88, 0x4f, 0x97, 0x1e, +0xf7, 0xe0, 0xb4, 0x77, 0x34, 0xc4, 0xc1, 0x85, +0x38, 0xda, 0x40, 0x7c, 0xa7, 0x09, 0x75, 0x37, +0xa7, 0xad, 0xb9, 0x21, 0x66, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0xde, +0x74, 0x8f, 0x3c, 0x24, 0x7e, 0x5c, 0xb0, 0x3a, +0xf1, 0x7d, 0x8d, 0x77, 0xbc, 0x13, 0x80, 0x0f, +0xe4, 0x20, 0xf3, 0x94, 0x3d, 0x90, 0x6a, 0xbf, +0x7f, 0x72, 0x47, 0x1c, 0xd8, 0xf9, 0x04, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4b, 0x01, 0x22, -0x21, 0x03, 0x54, 0xdb, 0xed, 0xba, 0x7f, 0xca, -0xa4, 0x8c, 0x40, 0x8a, 0x6d, 0xa2, 0xac, 0xed, -0xb8, 0x03, 0xab, 0xba, 0x22, 0xa8, 0xe9, 0x02, -0x3f, 0x42, 0xeb, 0xb2, 0x27, 0x6d, 0xa1, 0x6c, -0x71, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, -0x01, 0x22, 0x21, 0xe0, 0x79, 0x35, 0x72, 0x32, -0xb9, 0xd9, 0xbf, 0x09, 0xfd, 0x9c, 0x33, 0xbf, -0xd7, 0x26, 0xc0, 0x06, 0x70, 0xd7, 0x80, 0x3e, -0x66, 0x25, 0x36, 0x14, 0x63, 0xbd, 0x1f, 0x20, -0x4b, 0xc4, 0x6d, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x4d, 0x01, 0x22, 0x21, 0x87, 0x83, 0xb3, -0xe2, 0x71, 0x89, 0xad, 0x7c, 0xbe, 0xc6, 0xdb, -0x40, 0x6a, 0x29, 0xef, 0xf3, 0x17, 0x5c, 0x6c, -0xf7, 0x68, 0xe7, 0x2f, 0x55, 0x43, 0xca, 0x02, -0x79, 0x79, 0x55, 0x4d, 0xd6, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x18, -0x92, 0x75, 0xff, 0x78, 0xaf, 0x90, 0x1e, 0x8b, -0xa1, 0x22, 0xe2, 0x6e, 0x0c, 0x91, 0x99, 0xa8, -0x08, 0x8d, 0xdf, 0xd9, 0xe6, 0xa0, 0xce, 0xb7, -0x37, 0x30, 0xd1, 0x8f, 0xd9, 0x03, 0x58, 0x00, +0x21, 0xaf, 0xbb, 0x58, 0x83, 0x94, 0x70, 0x28, +0xc8, 0x10, 0x76, 0xed, 0x3b, 0x67, 0x31, 0x33, +0xaa, 0xea, 0xdb, 0x32, 0x52, 0xd5, 0x16, 0xd2, +0xc9, 0xfd, 0x0e, 0xa4, 0xf3, 0x02, 0x19, 0x84, +0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, +0x01, 0x22, 0x21, 0x89, 0xf0, 0x9c, 0xbd, 0xd8, +0xa7, 0x72, 0xec, 0x07, 0xf9, 0x52, 0x31, 0x13, +0xd4, 0x2a, 0x32, 0x6f, 0xdf, 0x18, 0xda, 0xe1, +0xac, 0x1c, 0x94, 0x64, 0xa9, 0x34, 0x1f, 0x46, +0xbf, 0xd5, 0xd7, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x4d, 0x01, 0x22, 0x21, 0x93, 0xaa, 0x9d, +0x6d, 0x14, 0xab, 0x43, 0xa7, 0xb0, 0xc1, 0x45, +0xe8, 0x4e, 0x92, 0x38, 0xe2, 0x49, 0x63, 0x61, +0x29, 0x64, 0x5d, 0xc1, 0x1d, 0xc4, 0x59, 0x89, +0x6b, 0xd0, 0xa7, 0x52, 0x17, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x4c, +0x5c, 0xa6, 0x4d, 0x2f, 0xed, 0xa6, 0x2c, 0x8f, +0x42, 0xe1, 0x47, 0x26, 0x83, 0x07, 0xd8, 0x50, +0x9a, 0x60, 0xf2, 0x9e, 0x48, 0xd2, 0x86, 0x2d, +0x39, 0x6d, 0xf7, 0x30, 0xdc, 0x9a, 0x68, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4f, 0x01, 0x22, -0x21, 0xeb, 0xe7, 0xad, 0x99, 0x7f, 0xd3, 0xfe, -0x2f, 0x40, 0xd3, 0xbf, 0x7d, 0x5e, 0xca, 0x0b, -0x44, 0xc4, 0xf9, 0xa9, 0xaf, 0x4a, 0x96, 0xa2, -0xf5, 0xf7, 0x1a, 0xf4, 0x16, 0x84, 0x79, 0xdc, -0xe6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, -0x01, 0x22, 0x21, 0x62, 0xc4, 0x54, 0x52, 0xc3, -0xe6, 0x2e, 0xa1, 0xa6, 0xc6, 0x89, 0x3a, 0x8b, -0x53, 0xd8, 0x4d, 0x6c, 0xcc, 0x47, 0xef, 0x70, -0xe8, 0x13, 0x8d, 0x88, 0x3c, 0x0c, 0xc3, 0x91, -0x58, 0x70, 0x88, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x51, 0x01, 0x22, 0x21, 0x57, 0x83, 0x02, -0xb5, 0x42, 0xfa, 0x61, 0x9b, 0xe8, 0x38, 0x80, -0x99, 0x01, 0xbc, 0x48, 0xf5, 0x79, 0x76, 0xe4, -0x83, 0x70, 0x61, 0xd6, 0xc8, 0x0c, 0xd3, 0x55, -0x43, 0x24, 0xe6, 0x00, 0x8e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0x8f, -0x2a, 0x59, 0x22, 0xfb, 0x1e, 0xdc, 0xd1, 0xc1, -0x11, 0x55, 0xe0, 0x56, 0x3b, 0xb9, 0x16, 0x56, -0xbf, 0x62, 0x7d, 0x5b, 0x72, 0x6b, 0xfe, 0x9a, -0xd1, 0x75, 0x46, 0x35, 0xaf, 0x2b, 0x90, 0x00, +0x21, 0xd4, 0xbe, 0x14, 0x37, 0x45, 0xbe, 0xca, +0xfc, 0xe3, 0x6a, 0xae, 0xd6, 0xfe, 0xce, 0xac, +0xf6, 0x78, 0x40, 0x62, 0x54, 0x7d, 0x16, 0x70, +0x6a, 0xcb, 0x1c, 0x4b, 0x12, 0xe9, 0x9f, 0x04, +0x54, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, +0x01, 0x22, 0x21, 0xd0, 0x82, 0x60, 0xbb, 0xe7, +0x4d, 0x97, 0x89, 0xa0, 0xf0, 0xd4, 0x1d, 0x70, +0xf7, 0xd8, 0x93, 0xcb, 0xf6, 0x48, 0xb9, 0xb4, +0x18, 0xc6, 0x68, 0xf7, 0x7a, 0xcd, 0xc2, 0xc3, +0xa7, 0x20, 0x81, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x51, 0x01, 0x22, 0x21, 0x92, 0x76, 0xfa, +0xc9, 0xc0, 0x82, 0x5a, 0xe6, 0x08, 0xd4, 0x3a, +0xe3, 0xad, 0xbe, 0x39, 0x70, 0x32, 0x96, 0xf5, +0xf4, 0x67, 0xe6, 0x57, 0x8d, 0x7c, 0x85, 0x74, +0x23, 0xba, 0x3f, 0x02, 0xef, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0x13, +0x92, 0x11, 0x3c, 0x85, 0xe4, 0xc3, 0x1a, 0x45, +0xc0, 0x0d, 0xa3, 0x8c, 0x42, 0x30, 0x0d, 0x97, +0x14, 0x00, 0x8f, 0x57, 0xbd, 0xb0, 0xf9, 0x11, +0xa6, 0xb3, 0xea, 0x6a, 0x38, 0x0e, 0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x53, 0x01, 0x22, -0x21, 0x5b, 0xc3, 0x7f, 0x1f, 0xcb, 0x9e, 0x3c, -0x39, 0x0f, 0x4b, 0x3b, 0x60, 0xb3, 0x73, 0x5d, -0x55, 0x6a, 0x51, 0x15, 0x38, 0xb6, 0xca, 0xd7, -0x67, 0xe4, 0x98, 0x81, 0xa1, 0xc0, 0xa6, 0x7b, -0x81, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, -0x01, 0x22, 0x21, 0x8d, 0x5f, 0xcd, 0xe1, 0x7c, -0x70, 0xb8, 0xd3, 0x8b, 0xfc, 0x43, 0xb2, 0xb8, -0x24, 0xfe, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x5e, 0x57, 0x5a, 0xfc, -0x8f, 0x32, 0x6e, 0x88, 0x03, 0x04, 0x51, 0x02, -0x00, 0x55, 0x01, 0x22, 0x21, 0x15, 0xb2, 0x6c, -0xfa, 0x8e, 0xbd, 0x8b, 0x81, 0x6b, 0x55, 0xa1, -0xa3, 0x87, 0x80, 0xdf, 0x58, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x08, -0xb8, 0xec, 0xd1, 0x7e, 0x3e, 0x72, 0x03, 0x04, -0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x95, -0x75, 0x2f, 0x37, 0x92, 0x29, 0x91, 0x43, 0xd0, -0x7f, 0x83, 0x31, 0xae, 0x2b, 0x22, 0x3e, 0x25, -0xf5, 0x6f, 0xdf, 0xfd, 0x2f, 0xd9, 0x64, 0x64, -0x44, 0xd4, 0x24, 0x6e, 0x17, 0xf5, 0xb1, 0x00, +0x21, 0xd0, 0x62, 0xbf, 0xc2, 0xdd, 0x89, 0x77, +0x42, 0xdd, 0xc6, 0xa5, 0x2d, 0x48, 0xb2, 0x6f, +0xf4, 0x5e, 0x55, 0xec, 0xdf, 0x18, 0x56, 0x7e, +0x13, 0xfe, 0x57, 0x95, 0x3d, 0xc8, 0x70, 0x28, +0x99, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, +0x01, 0x22, 0x21, 0xf7, 0x43, 0x70, 0x14, 0xd6, +0x0d, 0xea, 0x72, 0x33, 0xfd, 0x87, 0x04, 0xd1, +0xa9, 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x91, 0xd4, 0xba, 0x2c, +0x3a, 0xa5, 0x46, 0x30, 0x03, 0x04, 0x51, 0x02, +0x00, 0x55, 0x01, 0x22, 0x21, 0x95, 0x8a, 0xe3, +0x8c, 0x7b, 0x4a, 0xbe, 0x99, 0x4e, 0x94, 0x86, +0xbc, 0xe3, 0x7f, 0xe4, 0x85, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x5b, +0x59, 0x9d, 0x14, 0xa7, 0x27, 0x51, 0x03, 0x04, +0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x49, +0x1f, 0x0b, 0x2b, 0xfe, 0x7c, 0xa0, 0x2b, 0x2b, +0x52, 0xbc, 0x6c, 0xf2, 0x14, 0xdc, 0x9f, 0xa9, +0x21, 0xc8, 0x31, 0xbe, 0x80, 0xf2, 0x07, 0x51, +0x2a, 0xe0, 0xfe, 0xe1, 0x5f, 0xe1, 0x19, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x57, 0x01, 0x22, -0x21, 0x92, 0x34, 0x84, 0x96, 0x1b, 0x8f, 0x30, -0x86, 0xf4, 0xe0, 0xa2, 0xf7, 0x81, 0xdb, 0x21, -0xe9, 0x54, 0x4f, 0x0e, 0xbd, 0x07, 0x27, 0x50, -0x92, 0x78, 0xd9, 0x85, 0x2e, 0xb3, 0xaf, 0xd0, -0x09, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, -0x01, 0x22, 0x21, 0x83, 0x53, 0xfc, 0x08, 0x4f, -0xe9, 0x1d, 0x3f, 0x7a, 0x60, 0xcb, 0xa5, 0xf2, -0x7c, 0x5d, 0x36, 0x22, 0x73, 0x21, 0xf9, 0xde, -0x84, 0x5c, 0x37, 0x9b, 0xfa, 0xfc, 0xdb, 0x63, -0xf0, 0x8c, 0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x59, 0x01, 0x22, 0x21, 0xc2, 0xd0, 0xb6, -0xf2, 0x8a, 0x01, 0x5e, 0xb1, 0xa1, 0x1e, 0x51, -0x3e, 0x8a, 0x1a, 0x8f, 0xce, 0x35, 0x5a, 0xdf, -0x67, 0xa3, 0x93, 0x37, 0xcc, 0x4d, 0xe1, 0xd4, -0x93, 0x08, 0xe9, 0xef, 0x36, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0xd1, -0xbd, 0xca, 0x41, 0xbb, 0x70, 0x25, 0xbd, 0x3b, -0x56, 0x42, 0xbf, 0x6b, 0xab, 0xe8, 0xa3, 0xf7, -0x34, 0x57, 0x33, 0x52, 0x2b, 0xc1, 0xe8, 0xef, -0xc5, 0xf2, 0xed, 0x12, 0xdd, 0x96, 0xd4, 0x00, +0x21, 0x2e, 0x3d, 0xe5, 0x85, 0x5c, 0x49, 0x30, +0x2c, 0xeb, 0xf0, 0x28, 0x62, 0xd6, 0xba, 0x16, +0xb8, 0x4a, 0xd9, 0xcf, 0x0e, 0x15, 0xb2, 0x90, +0xba, 0x97, 0xb2, 0xae, 0x2d, 0x16, 0x29, 0xf0, +0x73, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, +0x01, 0x22, 0x21, 0x97, 0x95, 0x64, 0xe4, 0x86, +0x99, 0x9a, 0xe1, 0xb5, 0x90, 0x59, 0xc4, 0x41, +0x7c, 0xc4, 0x01, 0x9e, 0x6d, 0xea, 0xaa, 0x97, +0x14, 0x58, 0xfd, 0x31, 0xfb, 0xdf, 0x5e, 0x22, +0x99, 0xa8, 0x68, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x59, 0x01, 0x22, 0x21, 0xee, 0xaf, 0x4c, +0x59, 0x3e, 0x14, 0x2a, 0x22, 0x83, 0x89, 0x80, +0x3f, 0x3c, 0xc0, 0x37, 0xef, 0xfb, 0xef, 0x17, +0x59, 0xb5, 0x1f, 0xf5, 0x46, 0xa6, 0x5d, 0x75, +0x74, 0x8c, 0xfc, 0x7d, 0xbb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0xb8, +0x19, 0xc2, 0x3a, 0xf2, 0x88, 0xb3, 0xdf, 0x16, +0xbf, 0xcc, 0x62, 0x92, 0xf6, 0x1b, 0x16, 0xfd, +0x67, 0x70, 0xbc, 0xac, 0x11, 0x10, 0x17, 0xf3, +0xcb, 0xc2, 0xd5, 0xa0, 0x65, 0x46, 0x9c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5b, 0x01, 0x22, -0x21, 0x7e, 0xd3, 0x83, 0xd1, 0x70, 0x8f, 0x41, -0x8e, 0x94, 0x21, 0xed, 0x9e, 0x44, 0xa6, 0xae, -0x82, 0xdd, 0x73, 0x2c, 0x80, 0x11, 0x02, 0x8c, -0xbf, 0xfc, 0x5f, 0x57, 0x70, 0x53, 0xed, 0x0c, -0x23, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, -0x01, 0x22, 0x21, 0x05, 0x01, 0x86, 0xc8, 0x91, -0x78, 0x16, 0xad, 0x38, 0x21, 0x74, 0x8f, 0x8f, -0x4f, 0x0a, 0x66, 0xd6, 0xe8, 0x95, 0xb9, 0xdd, -0x06, 0x69, 0x62, 0x56, 0xb1, 0xf1, 0xa4, 0xb8, -0x0a, 0x73, 0x5e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x5d, 0x01, 0x22, 0x21, 0x6b, 0x27, 0x61, -0xeb, 0xec, 0x04, 0x9e, 0xaa, 0x14, 0x5c, 0xa1, -0x96, 0x72, 0x16, 0x43, 0x42, 0x72, 0xb2, 0x7b, -0xf6, 0x06, 0x2f, 0x62, 0xa6, 0xc4, 0xdc, 0x07, -0x0c, 0x92, 0x46, 0xa4, 0x2c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0xca, -0x06, 0x7c, 0x7b, 0xb9, 0x2b, 0x1a, 0x4d, 0x0d, -0xf5, 0x60, 0xb1, 0x4f, 0xf3, 0xa9, 0xcc, 0x8b, -0x16, 0x12, 0x5a, 0x1d, 0xc3, 0xc3, 0xba, 0x20, -0xe6, 0x4e, 0xf4, 0x79, 0x37, 0x98, 0x86, 0x00, +0x21, 0x96, 0xd3, 0x53, 0xe9, 0x34, 0xe1, 0xbe, +0x95, 0x28, 0xcb, 0xf2, 0x63, 0x3e, 0x8c, 0xef, +0x8c, 0x8b, 0xf2, 0xcf, 0xe5, 0x34, 0x50, 0xc8, +0x49, 0xc5, 0x74, 0xfa, 0xfb, 0xc4, 0x97, 0x97, +0x88, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, +0x01, 0x22, 0x21, 0x8b, 0xce, 0xed, 0x65, 0x45, +0x54, 0x48, 0xac, 0x2d, 0x7c, 0xf7, 0x13, 0xa8, +0x5b, 0x8c, 0x34, 0x2a, 0xfe, 0xe5, 0x05, 0xed, +0x73, 0xf6, 0x62, 0x56, 0x6f, 0xbf, 0x92, 0xf9, +0xd2, 0xbf, 0x54, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x5d, 0x01, 0x22, 0x21, 0x53, 0xde, 0x05, +0x39, 0x71, 0xe9, 0xa8, 0x92, 0x6f, 0x44, 0xab, +0x55, 0x0e, 0xfa, 0xbd, 0xcc, 0xd7, 0xea, 0x9b, +0xbf, 0xae, 0x37, 0xcf, 0x05, 0xdb, 0x0e, 0xd1, +0x5b, 0xc1, 0x4b, 0xe3, 0x96, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0xa6, +0x0f, 0x41, 0xdf, 0xc3, 0xf5, 0xbd, 0x8d, 0x4c, +0x55, 0x84, 0xa5, 0xb9, 0xda, 0x69, 0xa1, 0x06, +0x27, 0x81, 0x8d, 0xf8, 0x8e, 0x53, 0xc7, 0xe8, +0x57, 0x63, 0xa8, 0xf3, 0xd9, 0x4e, 0x21, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5f, 0x01, 0x22, -0x21, 0xed, 0xe8, 0x34, 0x5e, 0x5d, 0x79, 0xa6, -0x92, 0x9b, 0xbc, 0x9e, 0x7a, 0x38, 0x1b, 0xa7, -0xfe, 0xde, 0x65, 0x65, 0x7e, 0x1a, 0x9b, 0x12, -0x53, 0x66, 0x74, 0x1e, 0x4b, 0x69, 0xb5, 0x70, -0xfe, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, -0x01, 0x22, 0x21, 0xf9, 0x4b, 0x02, 0xdb, 0x00, -0x32, 0x4d, 0x7e, 0x5f, 0x46, 0x0d, 0x35, 0x4c, -0xec, 0xd3, 0xed, 0x38, 0x94, 0xf0, 0x66, 0xcd, -0x58, 0x45, 0xef, 0xa9, 0xfe, 0x2f, 0x21, 0xa3, -0xe1, 0x06, 0x87, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x61, 0x01, 0x22, 0x21, 0x45, 0xcb, 0x01, -0x71, 0xd9, 0x81, 0xff, 0x35, 0x8c, 0x93, 0x35, -0xb8, 0xdf, 0xd2, 0x36, 0x3a, 0x98, 0xee, 0xba, -0x1b, 0x28, 0x4e, 0xc0, 0x66, 0x5b, 0xf5, 0x23, -0xd1, 0x73, 0xdc, 0x3a, 0xca, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0xc7, -0x2e, 0xb9, 0x69, 0xbf, 0x76, 0x3c, 0x7b, 0xaf, -0xd5, 0xdc, 0xc5, 0x01, 0xd7, 0xf8, 0xd2, 0x8d, -0x0e, 0x02, 0xed, 0xf1, 0xdd, 0xe3, 0x8b, 0x93, -0x9b, 0x69, 0x0b, 0x89, 0xa9, 0x35, 0xa7, 0x00, +0x21, 0xef, 0x52, 0x0f, 0xcd, 0x54, 0x98, 0x11, +0x70, 0x69, 0xf9, 0x39, 0xd4, 0x19, 0x9b, 0x26, +0x49, 0x07, 0x49, 0x9f, 0x28, 0xc8, 0xec, 0x50, +0xdb, 0xb8, 0x16, 0x83, 0x70, 0xe0, 0xcd, 0x6b, +0x70, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, +0x01, 0x22, 0x21, 0x71, 0xf3, 0xc8, 0x2b, 0x09, +0x84, 0xe1, 0xba, 0xab, 0x44, 0x7c, 0xed, 0xc7, +0x98, 0x8c, 0x5e, 0xe1, 0x2a, 0x03, 0x7c, 0x69, +0x07, 0x76, 0x94, 0x72, 0x54, 0x32, 0x5d, 0x38, +0xce, 0x68, 0xd6, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x61, 0x01, 0x22, 0x21, 0xa6, 0x7b, 0x00, +0xb1, 0x4a, 0x87, 0x41, 0xfa, 0xea, 0xf2, 0xb7, +0x48, 0xc3, 0xa2, 0xe6, 0x5f, 0x15, 0xd2, 0xcd, +0xea, 0x64, 0x00, 0xa7, 0x5e, 0x96, 0xa8, 0xab, +0xb2, 0x31, 0xaa, 0x1d, 0xed, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0xcf, +0x26, 0xc5, 0x7a, 0xd0, 0x10, 0x1c, 0xaf, 0x4d, +0x45, 0x6a, 0xb6, 0x2e, 0x35, 0x67, 0x73, 0xf8, +0x45, 0x6a, 0xae, 0xef, 0xa9, 0xd6, 0x8a, 0x0a, +0xf5, 0xbf, 0x6a, 0x6a, 0x02, 0x5a, 0xee, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x63, 0x01, 0x22, -0x21, 0x5a, 0x44, 0xae, 0xec, 0x05, 0xe9, 0x1f, -0xc9, 0xac, 0x55, 0x40, 0x5f, 0x3e, 0x9c, 0xb8, -0xfa, 0x86, 0xea, 0x22, 0x9f, 0xe9, 0x5e, 0x50, -0xc2, 0xf7, 0x4e, 0xb2, 0x3e, 0x60, 0x6b, 0x85, -0x44, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, -0x01, 0x22, 0x21, 0x9f, 0x8b, 0x83, 0x29, 0xe1, -0x61, 0x2f, 0x07, 0x39, 0x31, 0x9c, 0x8b, 0xf2, -0x9a, 0xa5, 0x94, 0xf2, 0xa0, 0x52, 0x62, 0xf8, -0x10, 0xc8, 0x31, 0x00, 0xaa, 0x9d, 0xed, 0x14, -0x98, 0x30, 0x52, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x65, 0x01, 0x22, 0x21, 0x8d, 0x65, 0x52, -0x40, 0xbb, 0x90, 0x81, 0x25, 0x8b, 0x85, 0x22, -0x55, 0x72, 0x61, 0xe4, 0x1d, 0x8c, 0xb7, 0xdb, -0x1c, 0x75, 0x95, 0x2f, 0xef, 0x95, 0xf5, 0xa1, -0xb3, 0xaa, 0x0c, 0x93, 0xc3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0xc6, -0xcc, 0xa3, 0xb2, 0x73, 0xd5, 0x1e, 0x6d, 0x0e, -0x13, 0xb6, 0x54, 0x8f, 0x32, 0xc7, 0x5c, 0x26, -0x39, 0x5d, 0xb2, 0xba, 0x2e, 0x9f, 0x9a, 0x01, -0xc8, 0xbd, 0xc1, 0xbf, 0x49, 0xf5, 0x92, 0x00, +0x21, 0x45, 0x01, 0xf2, 0x74, 0x6b, 0x38, 0x42, +0x34, 0xb6, 0x6c, 0xdd, 0xfd, 0x99, 0x0c, 0x69, +0xfe, 0x14, 0x37, 0x25, 0x27, 0xfb, 0xa3, 0xab, +0x9d, 0x44, 0xa8, 0x44, 0x64, 0x3c, 0xb5, 0x40, +0x24, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, +0x01, 0x22, 0x21, 0x26, 0xb0, 0xc0, 0x8e, 0xbd, +0xe1, 0x00, 0x18, 0x6b, 0x60, 0x78, 0x70, 0xe4, +0x9a, 0xb4, 0xa2, 0x9d, 0x68, 0xe8, 0xdf, 0xf2, +0x2f, 0xd2, 0x43, 0xa1, 0x3b, 0xff, 0xc9, 0x95, +0x00, 0x60, 0xa6, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x65, 0x01, 0x22, 0x21, 0x35, 0x01, 0x86, +0xc5, 0xb5, 0xf7, 0xd8, 0x64, 0x73, 0xad, 0x3d, +0xff, 0x6d, 0xe6, 0xb2, 0x7d, 0x57, 0x41, 0xa8, +0x08, 0x00, 0x4a, 0x7f, 0x4a, 0xbc, 0xfa, 0x38, +0xf8, 0xe1, 0x24, 0x6e, 0x96, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0x4f, +0x3b, 0xf4, 0x29, 0xe7, 0x0d, 0x88, 0xec, 0xf8, +0xb7, 0xba, 0x55, 0xe1, 0x69, 0x79, 0x35, 0xcd, +0x85, 0x70, 0xd9, 0x51, 0x40, 0xf0, 0xb6, 0x69, +0x55, 0x18, 0x36, 0x44, 0x16, 0x3d, 0xb0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x67, 0x01, 0x22, -0x21, 0x48, 0x94, 0x13, 0x9f, 0xdd, 0x70, 0xb2, -0x01, 0x18, 0x08, 0xa0, 0x60, 0xfc, 0x33, 0x0d, -0x66, 0x55, 0x00, 0xf8, 0x15, 0x6e, 0x6c, 0xcd, -0xdb, 0x7d, 0x28, 0xdc, 0x2d, 0xbe, 0xbd, 0x2e, -0x1e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, -0x01, 0x22, 0x21, 0x0e, 0xe1, 0xf4, 0x92, 0xd9, -0x72, 0xe7, 0xb8, 0xd4, 0x4d, 0xe1, 0x2d, 0x9e, -0x1f, 0x5c, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x56, 0xbf, 0x88, 0x19, -0xba, 0x44, 0x5c, 0x62, 0x03, 0x04, 0x51, 0x02, -0x00, 0x69, 0x01, 0x22, 0x21, 0xfc, 0x31, 0x35, -0xb4, 0xca, 0x9b, 0x71, 0x68, 0x58, 0x05, 0xaf, -0x36, 0xfe, 0x40, 0x60, 0x6b, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x43, -0x03, 0x1d, 0x7c, 0xf0, 0x67, 0xa5, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0x82, -0x7a, 0x05, 0x39, 0xb9, 0x14, 0x9f, 0x1e, 0x5f, -0x28, 0x48, 0x86, 0xe5, 0x3a, 0x46, 0xb7, 0xc3, -0xd0, 0xc4, 0x45, 0x0a, 0xfd, 0x50, 0x97, 0x05, -0xe3, 0x12, 0x74, 0xb7, 0x85, 0x3b, 0xf3, 0x00, +0x21, 0xc5, 0x0a, 0x20, 0x97, 0x28, 0xac, 0xd8, +0xd9, 0x47, 0x82, 0xd6, 0x24, 0x67, 0x7e, 0x93, +0x85, 0x56, 0x26, 0x94, 0xb1, 0x58, 0x83, 0x13, +0xed, 0x52, 0xfc, 0x3b, 0x8c, 0x0e, 0x35, 0x17, +0x70, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, +0x01, 0x22, 0x21, 0xaf, 0x23, 0xab, 0x97, 0xe2, +0x5f, 0x3b, 0x59, 0x65, 0xb5, 0x5a, 0x12, 0x82, +0x52, 0xe4, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x07, 0x2e, 0x96, 0x81, +0xf0, 0x40, 0x78, 0x3d, 0x03, 0x04, 0x51, 0x02, +0x00, 0x69, 0x01, 0x22, 0x21, 0x9c, 0x26, 0x7d, +0x52, 0xb0, 0x73, 0x7d, 0xf1, 0x77, 0x38, 0x14, +0xd3, 0x2d, 0x8f, 0xbd, 0x17, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x98, +0x99, 0x28, 0x1e, 0xf9, 0xde, 0xdd, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0x17, +0x71, 0xfd, 0x52, 0xf2, 0xca, 0x3f, 0xec, 0x5c, +0xc7, 0x5e, 0x90, 0xc5, 0x8d, 0xe4, 0x9a, 0x30, +0xde, 0x26, 0x20, 0xe2, 0x4c, 0x01, 0x95, 0xf7, +0x40, 0x0f, 0xba, 0x53, 0xbc, 0x80, 0x5b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6b, 0x01, 0x22, -0x21, 0x29, 0x0b, 0xee, 0x44, 0x3b, 0x0d, 0x94, -0x72, 0xd9, 0xbd, 0xa5, 0xcc, 0xf4, 0xa0, 0x18, -0x4c, 0xc9, 0x4d, 0x26, 0x24, 0x0c, 0x62, 0x96, -0x28, 0xb4, 0x3b, 0x9c, 0x38, 0xdf, 0x33, 0x99, -0x9d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, -0x01, 0x22, 0x21, 0xa0, 0x55, 0x63, 0x74, 0x95, -0x9a, 0x39, 0x39, 0xfc, 0xa2, 0xe0, 0x28, 0x83, -0x2d, 0x49, 0xce, 0xd6, 0xd8, 0xf0, 0x3c, 0x10, -0xcd, 0xe2, 0xc0, 0xb0, 0x5a, 0x55, 0xab, 0x42, -0x98, 0x3f, 0x67, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x6d, 0x01, 0x22, 0x21, 0xa1, 0xf5, 0xbd, -0xf3, 0x70, 0xff, 0x83, 0x81, 0xae, 0xf7, 0x79, -0x35, 0x1e, 0xf5, 0xe0, 0x12, 0xe7, 0xb1, 0x7e, -0x28, 0x0b, 0x8a, 0x85, 0xe4, 0x19, 0xde, 0x91, -0x4b, 0x5a, 0x4b, 0xf4, 0xf0, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0xa6, -0x74, 0x08, 0x76, 0xa8, 0x4d, 0xc0, 0x50, 0x92, -0xb0, 0x5b, 0x21, 0xbf, 0xde, 0x36, 0x27, 0x00, -0x2d, 0xa6, 0xa9, 0x7a, 0xef, 0xf7, 0x6c, 0x4e, -0x67, 0x88, 0xc4, 0x03, 0xbf, 0x8d, 0x9a, 0x00, +0x21, 0xc0, 0xa4, 0x98, 0x57, 0x35, 0xd7, 0x2f, +0xbc, 0x87, 0x62, 0xfe, 0xd3, 0x59, 0x7e, 0x49, +0xaa, 0x50, 0x61, 0xed, 0xdb, 0x6c, 0x0b, 0x2f, +0x6c, 0xa8, 0x7c, 0x54, 0xbf, 0x76, 0x80, 0xac, +0x00, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, +0x01, 0x22, 0x21, 0xb6, 0x8c, 0x43, 0x2a, 0xd4, +0x85, 0xaa, 0xc2, 0x56, 0x0b, 0xc0, 0x32, 0x0e, +0xca, 0xb6, 0x8a, 0xa7, 0x90, 0x68, 0xe9, 0xc0, +0xf1, 0x6f, 0x59, 0x9d, 0x4c, 0x0f, 0x59, 0xe0, +0xc9, 0x22, 0xdf, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x6d, 0x01, 0x22, 0x21, 0x69, 0x49, 0x07, +0x2b, 0x00, 0x98, 0x49, 0xe3, 0xa1, 0xfc, 0xab, +0x5a, 0x1d, 0xb8, 0x40, 0xe5, 0x22, 0x1a, 0x04, +0xea, 0x16, 0x29, 0xcd, 0x08, 0xa4, 0xfe, 0x28, +0x25, 0xa3, 0x72, 0x2a, 0xdf, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0x0a, +0x3a, 0xfd, 0x99, 0x1f, 0xae, 0x35, 0x5c, 0x94, +0x73, 0xe3, 0x08, 0x79, 0xd6, 0xf9, 0xc6, 0xe2, +0xff, 0xf3, 0xd6, 0x9a, 0x30, 0xc2, 0xf1, 0x20, +0x7c, 0x7d, 0x82, 0xb8, 0xbf, 0x2b, 0xe2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6f, 0x01, 0x22, -0x21, 0x75, 0xca, 0x2e, 0xaa, 0x57, 0x55, 0x76, -0xed, 0x86, 0x16, 0xbc, 0xd6, 0x82, 0x0a, 0xb4, -0x54, 0x2e, 0x0d, 0x93, 0x06, 0x28, 0x03, 0xc1, -0x02, 0xe3, 0x05, 0x38, 0x7f, 0xe0, 0xcb, 0x83, -0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, -0x01, 0x22, 0x21, 0x8c, 0x53, 0xca, 0x29, 0xc9, -0xc8, 0x58, 0xa0, 0x19, 0xe6, 0x62, 0xad, 0x51, -0x6e, 0xfa, 0x36, 0xeb, 0xd6, 0xa0, 0x36, 0xe6, -0xdd, 0x7f, 0x08, 0xa2, 0x9b, 0xde, 0x52, 0x85, -0x57, 0x21, 0x22, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x71, 0x01, 0x22, 0x21, 0x85, 0x45, 0x28, -0x12, 0xfd, 0x30, 0x5f, 0x3e, 0xdb, 0x8d, 0xd3, -0xf0, 0x0c, 0x26, 0x00, 0x3a, 0x6e, 0x67, 0x28, -0x97, 0x19, 0xa2, 0x7e, 0xca, 0xa6, 0x17, 0xaa, -0xbb, 0x31, 0xb7, 0x79, 0xc2, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0x15, -0x48, 0x0d, 0x7e, 0x52, 0x48, 0x77, 0xab, 0x20, -0x63, 0x25, 0xc0, 0xad, 0xc2, 0xd6, 0x2f, 0xe8, -0x22, 0xb5, 0x43, 0x1e, 0x4b, 0x71, 0x20, 0xa4, -0x5e, 0x48, 0xb8, 0xba, 0x8c, 0xfe, 0x25, 0x00, +0x21, 0xe1, 0xb2, 0x2b, 0x95, 0xeb, 0x1f, 0x9e, +0x18, 0x41, 0xa0, 0x78, 0xfe, 0xba, 0x5c, 0x2b, +0xb1, 0xef, 0x18, 0xa5, 0xe5, 0x33, 0xf8, 0xc1, +0xf7, 0xc7, 0x46, 0x7e, 0xcb, 0x7d, 0x2f, 0x40, +0x09, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, +0x01, 0x22, 0x21, 0xb9, 0x71, 0x1c, 0x75, 0xf4, +0xe0, 0x73, 0x26, 0xd9, 0x0f, 0x4c, 0x70, 0x95, +0x14, 0x59, 0x80, 0x27, 0x9c, 0x83, 0x04, 0x5e, +0x4b, 0x8a, 0xed, 0xcf, 0xcc, 0x81, 0xfb, 0x06, +0x1c, 0x9e, 0xbc, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x71, 0x01, 0x22, 0x21, 0x83, 0xc3, 0x26, +0x47, 0xff, 0xbd, 0xf5, 0x75, 0x2b, 0xdf, 0x2b, +0x76, 0xe1, 0x5c, 0xa7, 0xe5, 0x0f, 0xd2, 0x53, +0x9a, 0x1b, 0x24, 0xf9, 0x91, 0x76, 0x88, 0x3e, +0xc8, 0x84, 0x0b, 0xd7, 0x0b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0x37, +0x79, 0xbf, 0xe1, 0x2e, 0x2d, 0xf6, 0x6e, 0xb7, +0x2a, 0x81, 0x12, 0x55, 0x7d, 0xb6, 0x39, 0xc2, +0xdb, 0x4a, 0x0b, 0x76, 0x97, 0x7f, 0xee, 0x40, +0xe5, 0x8a, 0x20, 0x10, 0x4d, 0x9a, 0xb0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x73, 0x01, 0x22, -0x21, 0x2a, 0x60, 0x41, 0x2d, 0x48, 0x9b, 0xff, -0x82, 0x3d, 0x6b, 0x20, 0xfd, 0xc7, 0x2f, 0x02, -0xcf, 0x25, 0x20, 0x1e, 0x2a, 0x60, 0x94, 0x20, -0xc8, 0xc3, 0x7b, 0x0b, 0x5b, 0x89, 0x95, 0xc7, -0x0d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, -0x01, 0x22, 0x21, 0x2d, 0x64, 0x42, 0x3b, 0xb5, -0xa1, 0x9f, 0x4e, 0xee, 0x41, 0xde, 0xa2, 0xf2, -0x72, 0xd8, 0x26, 0xb9, 0x91, 0xd2, 0xa4, 0xd4, -0x16, 0x1e, 0xa8, 0x39, 0x77, 0x44, 0xfa, 0xa6, -0x90, 0x8c, 0x49, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x75, 0x01, 0x22, 0x21, 0x7a, 0x78, 0x32, -0x28, 0x2a, 0x66, 0xd7, 0xe7, 0x4d, 0xad, 0xfb, -0x6e, 0xe4, 0xe6, 0xa2, 0xb9, 0x08, 0x9b, 0xbb, -0x92, 0xb7, 0x13, 0x36, 0x53, 0x0d, 0xe0, 0x8f, -0x9c, 0x5b, 0xb8, 0xd2, 0x7d, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0x90, -0xa8, 0x53, 0x35, 0xd2, 0x10, 0x3a, 0xd2, 0xe1, -0xa1, 0x7f, 0x60, 0xbd, 0x75, 0x84, 0x07, 0xab, -0xd8, 0x26, 0x95, 0xd1, 0x07, 0x36, 0x0f, 0x5e, -0x57, 0x76, 0x26, 0x45, 0x60, 0x94, 0x48, 0x00, +0x21, 0xba, 0x3a, 0x4c, 0x11, 0x53, 0x20, 0xe0, +0xfe, 0x0a, 0xaa, 0x8a, 0x56, 0xed, 0xe2, 0x8a, +0xf8, 0x1c, 0x1b, 0xb0, 0x01, 0x5c, 0x99, 0x6f, +0x1f, 0x0a, 0xfa, 0x69, 0x3d, 0x04, 0x6a, 0x23, +0xe7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, +0x01, 0x22, 0x21, 0xed, 0xfd, 0xad, 0x36, 0x65, +0x16, 0x4e, 0x41, 0xfa, 0xe5, 0x4b, 0x80, 0x95, +0x50, 0x6a, 0xc8, 0x0c, 0xc5, 0xad, 0x67, 0x1a, +0x0f, 0x2b, 0xc0, 0x2c, 0x6d, 0xc4, 0x89, 0x65, +0xa4, 0x62, 0x07, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x75, 0x01, 0x22, 0x21, 0x6a, 0x2c, 0xc8, +0x56, 0x3a, 0x98, 0x42, 0xcf, 0xd9, 0x35, 0x06, +0x6d, 0xe4, 0xdd, 0x67, 0xd0, 0x9e, 0xc7, 0x29, +0x97, 0xfd, 0x02, 0x9d, 0x94, 0x51, 0xc7, 0x95, +0x79, 0xf8, 0x42, 0x30, 0xc9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0x1d, +0xe8, 0xbd, 0x1f, 0x62, 0xf6, 0x90, 0x7f, 0x20, +0xb3, 0xe0, 0x7e, 0x1b, 0x4e, 0x22, 0x3e, 0x35, +0x91, 0x6f, 0x9f, 0x6c, 0x0e, 0xaf, 0xbe, 0xaa, +0xcf, 0x54, 0xc8, 0xa3, 0x8a, 0x22, 0xa0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x77, 0x01, 0x22, -0x21, 0x37, 0xb5, 0x88, 0x05, 0x84, 0xed, 0x2b, -0xa7, 0xc9, 0x03, 0x21, 0xb6, 0x2d, 0x42, 0xf2, -0x11, 0x6b, 0xa7, 0x73, 0xb4, 0x15, 0xd4, 0x2c, -0x94, 0x9c, 0xd6, 0x62, 0x81, 0x4b, 0xd9, 0x8f, -0x37, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, -0x01, 0x22, 0x21, 0x9a, 0x0c, 0xdb, 0xaf, 0x91, -0x07, 0x36, 0x30, 0x85, 0xaf, 0xe2, 0x30, 0xdc, -0x3a, 0xa5, 0x60, 0xc8, 0x56, 0x34, 0x97, 0x57, -0x35, 0xda, 0x52, 0x42, 0x4a, 0x2c, 0x77, 0xbf, -0xa5, 0x65, 0x01, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x79, 0x01, 0x22, 0x21, 0xad, 0xa4, 0x86, -0xf5, 0x2f, 0x39, 0xc6, 0xe1, 0x94, 0x20, 0xf1, -0x69, 0xb0, 0x17, 0x83, 0x13, 0x12, 0xed, 0x24, -0xa8, 0x87, 0x8e, 0xaf, 0x5c, 0xe0, 0xf5, 0xc1, -0x0e, 0x62, 0xb1, 0x4c, 0x8e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0x61, -0xf2, 0x1a, 0x68, 0x28, 0x2b, 0x8f, 0x07, 0x7d, -0x25, 0xcc, 0x61, 0xce, 0xe7, 0x37, 0x1f, 0xab, -0xa0, 0xc7, 0xfb, 0x17, 0x7e, 0x4b, 0xbe, 0xa2, -0x28, 0xda, 0xab, 0xb7, 0xe8, 0xb8, 0x0c, 0x00, +0x21, 0x23, 0x90, 0xf1, 0x58, 0x8e, 0xbc, 0xba, +0x9e, 0x8a, 0x32, 0x53, 0xbc, 0xd1, 0x4c, 0xd4, +0xbe, 0x3a, 0x7d, 0x06, 0x7c, 0xab, 0xaa, 0x5a, +0x6d, 0x19, 0xcb, 0xfc, 0x70, 0xac, 0x3b, 0xca, +0x10, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, +0x01, 0x22, 0x21, 0x32, 0xf1, 0xb2, 0x5b, 0xef, +0xf4, 0x70, 0x2f, 0x6d, 0x95, 0x70, 0x71, 0x6b, +0xd9, 0xc3, 0x43, 0xdf, 0xf8, 0xd5, 0xbf, 0x5d, +0x65, 0xcb, 0x30, 0xc9, 0x1e, 0xe3, 0x65, 0x59, +0x82, 0x9e, 0x5c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x79, 0x01, 0x22, 0x21, 0xc0, 0xd3, 0xc8, +0x22, 0xff, 0xb2, 0x3f, 0xf0, 0x82, 0xa9, 0x6e, +0xa1, 0x67, 0x4a, 0x0e, 0xd4, 0x4e, 0xc0, 0x02, +0xa9, 0x5d, 0x5f, 0x02, 0x44, 0x10, 0xf6, 0x09, +0xf2, 0xbc, 0x6b, 0xfa, 0x30, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0xf6, +0xa3, 0xfd, 0x47, 0x0f, 0xf7, 0xa9, 0x6c, 0x77, +0x39, 0x82, 0x86, 0x54, 0x4b, 0xf0, 0x3f, 0xb6, +0x88, 0x28, 0x31, 0x71, 0x93, 0x3f, 0x0b, 0x2b, +0x69, 0xdb, 0xe3, 0x6e, 0xb7, 0xc8, 0x18, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7b, 0x01, 0x22, -0x21, 0xe4, 0x69, 0x49, 0x0f, 0xc8, 0x8a, 0xab, -0x33, 0xa0, 0x9a, 0x00, 0xbd, 0xf2, 0x1e, 0x6f, -0x48, 0xc7, 0x69, 0x9a, 0x77, 0xe0, 0xb4, 0xb4, -0x73, 0x8f, 0x24, 0x93, 0x75, 0x53, 0xee, 0xd4, -0x1a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, -0x01, 0x22, 0x21, 0xa2, 0xce, 0xd6, 0x91, 0xcb, -0x33, 0xa2, 0x50, 0x75, 0xfc, 0xcf, 0xff, 0x83, -0x57, 0x09, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x95, 0x5a, 0xf4, 0xbb, -0xfd, 0x9b, 0x0d, 0xb4, 0x03, 0x04, 0x51, 0x02, -0x00, 0x7d, 0x01, 0x22, 0x21, 0xfc, 0xd0, 0xee, -0xcc, 0x11, 0x38, 0xf6, 0x0a, 0x86, 0x82, 0x7f, -0x3d, 0xa3, 0xb0, 0x5c, 0x81, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x1b, -0xf5, 0x57, 0x96, 0xa8, 0x95, 0x23, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0x26, -0xb1, 0xd1, 0xcf, 0xf9, 0x67, 0x89, 0xe4, 0x01, -0xb5, 0x59, 0xf4, 0x52, 0x2d, 0x18, 0x3c, 0xbf, -0x56, 0xac, 0x46, 0x20, 0xd7, 0x93, 0x6f, 0x8e, -0xc7, 0x9e, 0xff, 0x42, 0xbf, 0xec, 0x02, 0x00, +0x21, 0xbc, 0xd8, 0x50, 0xeb, 0xfa, 0xc1, 0x09, +0x24, 0xde, 0x38, 0xe2, 0x23, 0x0f, 0xa9, 0xd6, +0xff, 0x69, 0x95, 0x55, 0x4d, 0x39, 0xc1, 0x37, +0x5c, 0x7e, 0xc5, 0x3b, 0x59, 0xeb, 0x4c, 0x62, +0xdb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, +0x01, 0x22, 0x21, 0xb2, 0x13, 0x9e, 0x60, 0x9c, +0x91, 0x27, 0x46, 0x3b, 0xf1, 0x92, 0x65, 0x2c, +0xc5, 0xe5, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x5d, 0x23, 0x21, 0x2e, +0x24, 0x9c, 0xa6, 0x57, 0x03, 0x04, 0x51, 0x02, +0x00, 0x7d, 0x01, 0x22, 0x21, 0x2b, 0xeb, 0xb1, +0x19, 0x29, 0x01, 0xba, 0xff, 0x91, 0x57, 0x64, +0x4e, 0x6a, 0x7b, 0x9b, 0x68, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xc4, +0xa0, 0x69, 0xaf, 0xce, 0x1f, 0x4c, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0x0b, +0x88, 0x5a, 0x28, 0xb2, 0x6f, 0x31, 0x89, 0x4a, +0xdb, 0xe7, 0xfe, 0xf7, 0x23, 0xf2, 0x59, 0x47, +0xf7, 0xe8, 0x4a, 0x6e, 0x8f, 0xa1, 0xf1, 0xbb, +0x1e, 0x03, 0xd8, 0xa9, 0x31, 0xac, 0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7f, 0x01, 0x22, -0x21, 0x45, 0xd0, 0xbe, 0x1b, 0xa7, 0x13, 0x49, -0x4b, 0xcf, 0xeb, 0x7e, 0x40, 0xed, 0xba, 0xbc, -0xd7, 0xd0, 0xfc, 0xef, 0xae, 0x4d, 0x38, 0x8b, -0xa6, 0x59, 0x87, 0x41, 0x87, 0x47, 0xed, 0x4b, -0x98, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, -0x01, 0x22, 0x21, 0x36, 0x4a, 0xb9, 0x84, 0x64, -0xbb, 0x3c, 0x3b, 0x93, 0xe2, 0xfe, 0x32, 0xe0, -0x2d, 0x0b, 0x15, 0x38, 0x1f, 0x9f, 0xfc, 0xe8, -0xa9, 0xda, 0x83, 0xe2, 0x67, 0x21, 0x56, 0x33, -0x8e, 0xa7, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x81, 0x01, 0x22, 0x21, 0xfb, 0x1e, 0x28, -0x22, 0xff, 0xb8, 0x7e, 0xd0, 0xa3, 0x36, 0x69, -0xde, 0xbe, 0x7e, 0x04, 0x86, 0x62, 0x0c, 0x17, -0x64, 0x9f, 0x47, 0xcb, 0xe7, 0xde, 0xb3, 0x8b, -0x7e, 0xd9, 0xef, 0x7d, 0x94, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0xfb, -0x46, 0x7a, 0x7d, 0x3e, 0xe9, 0xad, 0xaa, 0xc0, -0x39, 0x0e, 0x33, 0x64, 0x76, 0x76, 0xc4, 0x11, -0xc2, 0xc7, 0x72, 0x4a, 0xd2, 0x5e, 0xcb, 0xb7, -0x3f, 0x86, 0x07, 0x03, 0xaf, 0x73, 0xb7, 0x00, +0x21, 0xf5, 0xdd, 0xcf, 0x45, 0x7f, 0x8c, 0x99, +0xa8, 0x4f, 0xf3, 0x0f, 0xee, 0xf8, 0x0e, 0x56, +0xbb, 0x14, 0x5f, 0xb8, 0x3d, 0xfa, 0x57, 0xae, +0xf9, 0x0f, 0x18, 0x60, 0x0b, 0x47, 0xc6, 0x4a, +0x4f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, +0x01, 0x22, 0x21, 0x4b, 0x31, 0xb1, 0xe8, 0x9e, +0x7d, 0x4f, 0x7b, 0x1b, 0xce, 0xa2, 0x7f, 0x0e, +0xa6, 0x8b, 0xdf, 0x49, 0x59, 0x22, 0x47, 0x26, +0xbe, 0x51, 0xa0, 0x27, 0x6b, 0xf5, 0x73, 0x94, +0x6f, 0xc5, 0x4d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x81, 0x01, 0x22, 0x21, 0xd4, 0xaf, 0x5a, +0x83, 0xf8, 0x8e, 0xce, 0xb0, 0x6b, 0x33, 0x0b, +0x55, 0x5e, 0x1c, 0x93, 0x53, 0xf8, 0xff, 0xcb, +0xa5, 0xf6, 0x08, 0xdd, 0xb7, 0xba, 0x33, 0x3c, +0x3a, 0x6b, 0x60, 0xc7, 0xd3, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0xc2, +0xbb, 0x2a, 0x92, 0x00, 0x7b, 0xd7, 0x49, 0x44, +0x33, 0xf6, 0x6b, 0x8c, 0x85, 0xa3, 0x8d, 0x0a, +0x4d, 0x26, 0x33, 0x3d, 0x57, 0x6d, 0xf9, 0x37, +0x57, 0x44, 0x6a, 0xea, 0xf3, 0x47, 0x59, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x83, 0x01, 0x22, -0x21, 0x90, 0xf1, 0x45, 0xc9, 0xe1, 0xd9, 0x75, -0x18, 0xb4, 0x84, 0xe4, 0x81, 0x89, 0x87, 0x5f, -0x5f, 0xb6, 0x19, 0xe2, 0x2e, 0xf8, 0x44, 0x4b, -0x68, 0x3a, 0x99, 0x48, 0x06, 0xb0, 0x8a, 0xa0, -0x12, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, -0x01, 0x22, 0x21, 0xa0, 0x66, 0xbe, 0x73, 0xcc, -0xab, 0x22, 0x32, 0x0d, 0x22, 0x7d, 0xd2, 0xb7, -0x96, 0xd8, 0x1d, 0x6d, 0xbc, 0x2a, 0x29, 0xb2, -0x04, 0xf3, 0xac, 0x34, 0xab, 0x0f, 0x1a, 0x9f, -0xd5, 0x75, 0xdf, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x85, 0x01, 0x22, 0x21, 0xcc, 0xf8, 0x1c, -0x75, 0x83, 0x59, 0xca, 0x06, 0x9d, 0x27, 0x63, -0x8d, 0x65, 0xdb, 0x83, 0xa1, 0x73, 0xfe, 0xa5, -0x55, 0xa7, 0x0c, 0x7c, 0x99, 0x5d, 0xf7, 0xc1, -0x6f, 0x64, 0xa9, 0x44, 0x41, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0x47, -0xc5, 0x61, 0xf4, 0xbc, 0x23, 0x93, 0x0e, 0xc0, -0x90, 0x9d, 0xd9, 0xc9, 0xba, 0x88, 0x4c, 0xc5, -0xd1, 0xac, 0x9e, 0xa7, 0x17, 0x7f, 0xe6, 0x2a, -0xae, 0xa5, 0x55, 0x55, 0xa0, 0x0d, 0x15, 0x00, +0x21, 0xf6, 0x97, 0xdf, 0xbe, 0x75, 0xab, 0x65, +0x06, 0xf8, 0xd4, 0x33, 0x46, 0x39, 0x00, 0xdb, +0x56, 0x75, 0xdb, 0xb6, 0x20, 0x1c, 0x91, 0x6d, +0xd7, 0x7b, 0x06, 0x1c, 0x38, 0xd1, 0x87, 0x0f, +0xfb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, +0x01, 0x22, 0x21, 0x56, 0x95, 0x5c, 0x7a, 0xbd, +0x8e, 0x6f, 0x30, 0x73, 0xb5, 0x2a, 0x73, 0x25, +0x79, 0x08, 0x38, 0x0d, 0x22, 0xcb, 0x14, 0xf2, +0x30, 0xd2, 0x2b, 0x9e, 0x90, 0xff, 0xf3, 0xf8, +0x99, 0x7a, 0xb7, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x85, 0x01, 0x22, 0x21, 0xc6, 0x8b, 0xca, +0x7c, 0xcd, 0x5d, 0xe7, 0x73, 0x4f, 0x60, 0xb3, +0x15, 0x3f, 0xa9, 0x78, 0xb4, 0x14, 0x47, 0x27, +0xe0, 0xe5, 0x44, 0x15, 0x57, 0xcc, 0x7f, 0x33, +0x4c, 0x56, 0xe0, 0x8a, 0xc9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0x83, +0xf4, 0x61, 0x31, 0x51, 0xd8, 0x75, 0xa8, 0x12, +0xe5, 0x51, 0x36, 0xc6, 0xbe, 0x8e, 0x37, 0x05, +0x31, 0xe3, 0x65, 0x09, 0x53, 0x9a, 0x1e, 0x2f, +0x9c, 0xc9, 0xff, 0xc3, 0xc6, 0x15, 0x4d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x87, 0x01, 0x22, -0x21, 0x29, 0x52, 0x93, 0xf9, 0x65, 0xf4, 0x68, -0x1f, 0xca, 0x43, 0x17, 0x7f, 0xf8, 0x4a, 0xa3, -0x50, 0x56, 0xc8, 0xc5, 0x8e, 0x2c, 0xd9, 0x16, -0x06, 0x8e, 0x52, 0x60, 0x50, 0x53, 0x26, 0xd0, -0x64, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, -0x01, 0x22, 0x21, 0x8d, 0xd1, 0x14, 0xf4, 0xcc, -0x6a, 0x5a, 0x0e, 0x90, 0x9d, 0x54, 0x14, 0xe3, -0x3b, 0x4a, 0x3e, 0x0f, 0xe6, 0x5e, 0x51, 0xb8, -0x70, 0xbc, 0x58, 0x6e, 0x18, 0x5e, 0x4a, 0x09, -0xef, 0xc3, 0x55, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x89, 0x01, 0x22, 0x21, 0xc2, 0x1f, 0x5f, -0x52, 0xef, 0xc9, 0x5c, 0xd9, 0xaf, 0xdc, 0x03, -0x3e, 0x98, 0x3d, 0x3f, 0xae, 0x29, 0xdc, 0xaa, -0xfb, 0xb5, 0x97, 0x4b, 0xcb, 0x78, 0x6b, 0x77, -0x1e, 0x84, 0x93, 0x6a, 0x07, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0x9c, -0x96, 0x32, 0x35, 0x75, 0xeb, 0xdc, 0x56, 0x8d, -0x99, 0x74, 0x16, 0x4c, 0xa4, 0x85, 0x1d, 0x4b, -0x56, 0x7e, 0x12, 0x4c, 0xdd, 0x3d, 0x73, 0x02, -0x64, 0x17, 0x25, 0x35, 0x41, 0xc4, 0xce, 0x00, +0x21, 0xd1, 0x66, 0x13, 0xa9, 0x34, 0x96, 0xfa, +0xa2, 0x84, 0x83, 0xc1, 0x12, 0xb1, 0x82, 0x50, +0xa4, 0x76, 0x73, 0x84, 0x7a, 0x16, 0xbb, 0x58, +0x10, 0x48, 0x83, 0xb7, 0x33, 0x6e, 0x55, 0x47, +0x9f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, +0x01, 0x22, 0x21, 0x7b, 0xb8, 0x27, 0xf8, 0xda, +0xa5, 0x47, 0x7f, 0x80, 0x82, 0x58, 0x9f, 0xc4, +0xd8, 0x71, 0xe5, 0x4b, 0x48, 0x8c, 0x68, 0x31, +0xd8, 0x7e, 0x8f, 0x05, 0x1a, 0x56, 0xb7, 0xbc, +0x33, 0x43, 0x6a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x89, 0x01, 0x22, 0x21, 0xed, 0x58, 0xba, +0x81, 0x2a, 0x7a, 0x0b, 0x65, 0x12, 0x9e, 0xd6, +0xe6, 0x4e, 0xa5, 0xa7, 0x11, 0x7b, 0x0f, 0x8c, +0xd8, 0x8c, 0x24, 0x6a, 0xc5, 0xaa, 0x54, 0x84, +0x23, 0x8a, 0x69, 0xfe, 0xbb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0xa4, +0x0e, 0xd5, 0x37, 0x28, 0xbc, 0x2d, 0x88, 0xfe, +0x17, 0xcd, 0xf7, 0xd5, 0xee, 0xca, 0x36, 0xb5, +0x25, 0xa6, 0x7a, 0xe6, 0xb0, 0x44, 0x64, 0x9d, +0xef, 0xbd, 0xba, 0x0b, 0xdf, 0xb8, 0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8b, 0x01, 0x22, -0x21, 0x3b, 0x39, 0x4c, 0x6f, 0xff, 0x75, 0x58, -0x32, 0x76, 0x9c, 0xf4, 0x82, 0x86, 0x0b, 0xe5, -0x47, 0x33, 0x39, 0x89, 0xc1, 0x32, 0x1d, 0x88, -0x8b, 0xb0, 0xcc, 0xc0, 0x52, 0xc8, 0xaf, 0xf6, -0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, -0x01, 0x22, 0x21, 0xcb, 0xf5, 0xa8, 0xf1, 0xa5, -0xf3, 0xb9, 0xf1, 0xcd, 0xe2, 0x91, 0xc5, 0x37, -0x49, 0x61, 0x77, 0x60, 0xbe, 0x5b, 0x48, 0x9a, -0x8f, 0x3a, 0x8a, 0x1c, 0x39, 0xb8, 0x3a, 0x4b, -0xb6, 0xa7, 0x70, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x8d, 0x01, 0x22, 0x21, 0xf2, 0x50, 0x3e, -0x53, 0xd0, 0x18, 0x96, 0x2e, 0x35, 0x34, 0x1d, -0xb6, 0x26, 0xba, 0x91, 0x8c, 0xb4, 0xce, 0xb8, -0x49, 0xdb, 0x7c, 0x67, 0xd4, 0xac, 0x27, 0xbf, -0x83, 0x23, 0x64, 0x06, 0xd0, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x06, -0x9b, 0xa7, 0x7b, 0x6d, 0xab, 0x2f, 0x02, 0xfd, -0xfe, 0x1e, 0x5a, 0x18, 0x15, 0xaa, 0xa7, 0x9c, -0xf2, 0x1b, 0x1c, 0x68, 0x25, 0x80, 0x81, 0x59, -0x08, 0xcd, 0x39, 0x07, 0x7d, 0x1c, 0x10, 0x00, +0x21, 0x6b, 0xc8, 0xef, 0xf6, 0x5c, 0xdd, 0x7d, +0xdc, 0x33, 0xce, 0xc0, 0x02, 0xfc, 0xfa, 0xfe, +0x74, 0xc6, 0xaa, 0xea, 0x1f, 0x01, 0xda, 0xb8, +0x4a, 0x8c, 0xbb, 0x04, 0x50, 0x0f, 0x63, 0xcd, +0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, +0x01, 0x22, 0x21, 0x40, 0x5a, 0x8d, 0x97, 0x2f, +0x61, 0x7c, 0x42, 0xbe, 0xbe, 0xbc, 0x3c, 0xf0, +0x42, 0x77, 0xc0, 0x0e, 0x4e, 0x85, 0x2e, 0xae, +0x8b, 0xaf, 0xb9, 0xd5, 0xf0, 0x75, 0x02, 0x45, +0x39, 0x37, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x8d, 0x01, 0x22, 0x21, 0x6b, 0xf8, 0x58, +0xec, 0x5d, 0x20, 0xab, 0x28, 0xb0, 0x67, 0x86, +0x39, 0xb3, 0x65, 0x2b, 0x97, 0x40, 0x6b, 0x59, +0x3d, 0x23, 0xf5, 0x0f, 0x7e, 0xbb, 0x99, 0x33, +0x43, 0xfc, 0x95, 0xe3, 0x1b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x88, +0xd1, 0x67, 0xe4, 0xd0, 0x24, 0x2b, 0x59, 0x4c, +0x5a, 0xc4, 0xc6, 0x6b, 0xe8, 0x46, 0x90, 0xdf, +0x13, 0xff, 0x03, 0x0c, 0x7d, 0xa6, 0x65, 0x8b, +0x5e, 0x38, 0xc5, 0x25, 0x14, 0x2c, 0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8f, 0x01, 0x22, -0x21, 0x4f, 0xfe, 0xb4, 0xa7, 0xb9, 0xd2, 0x44, -0x38, 0xe7, 0x50, 0xac, 0x11, 0x03, 0xe0, 0x35, -0x36, 0x46, 0xba, 0x21, 0x72, 0x9f, 0xc2, 0x3c, -0xf6, 0x25, 0x8b, 0x34, 0x2b, 0xec, 0xaa, 0x4f, -0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, -0x01, 0x22, 0x21, 0x09, 0x3b, 0xf2, 0xc9, 0xfc, -0x4e, 0xc9, 0x24, 0xfc, 0xd1, 0xd4, 0x55, 0x60, -0x10, 0x5c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x81, 0xc4, 0x41, 0xd9, -0xed, 0xf8, 0xf2, 0x37, 0x03, 0x04, 0x51, 0x02, -0x00, 0x91, 0x01, 0x22, 0x21, 0xcd, 0x68, 0x22, -0xdb, 0x86, 0x60, 0xfa, 0xb9, 0xb4, 0x60, 0x48, -0xde, 0x06, 0x3f, 0x1f, 0x30, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, -0xca, 0x87, 0x8c, 0xe5, 0x54, 0x6b, 0x03, 0x04, -0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0xc6, -0xac, 0x4b, 0x35, 0x7c, 0xaa, 0x4c, 0x12, 0x80, -0x0d, 0xcb, 0x06, 0x75, 0xb3, 0x1a, 0x78, 0xf3, -0x97, 0xad, 0x0d, 0xd4, 0x9b, 0x09, 0x83, 0x19, -0xfa, 0x60, 0x61, 0xc1, 0x53, 0x84, 0xfd, 0x00, +0x21, 0xa7, 0x12, 0xff, 0xbe, 0x4f, 0x97, 0x2e, +0xee, 0xef, 0xc0, 0x6c, 0xcb, 0x06, 0x5b, 0x05, +0x70, 0x85, 0xc2, 0xcb, 0xff, 0x18, 0x95, 0x1e, +0x0b, 0xe9, 0xb5, 0x6c, 0xff, 0xd5, 0x3a, 0xa8, +0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, +0x01, 0x22, 0x21, 0xad, 0x23, 0x45, 0xdc, 0x56, +0x1a, 0x80, 0xc1, 0xeb, 0x22, 0xcc, 0xf2, 0x4a, +0x7f, 0x0f, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x64, 0x18, 0x68, 0xc1, +0x21, 0x03, 0x47, 0xac, 0x03, 0x04, 0x51, 0x02, +0x00, 0x91, 0x01, 0x22, 0x21, 0x8d, 0x7a, 0xd5, +0xe4, 0xe4, 0x1a, 0x76, 0x25, 0x65, 0x5d, 0x75, +0xa7, 0xf7, 0x8e, 0x53, 0xd7, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x8c, +0x27, 0xa6, 0x79, 0x6b, 0xce, 0x60, 0x03, 0x04, +0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0x3b, +0x8f, 0x8d, 0x5c, 0xd6, 0x92, 0x81, 0x0f, 0xf0, +0x2e, 0x36, 0xa6, 0x28, 0xff, 0x95, 0x10, 0x16, +0xdc, 0xa5, 0x5b, 0x38, 0xc6, 0x97, 0xb9, 0x4f, +0x7e, 0x29, 0x94, 0xf7, 0x7d, 0xd1, 0x69, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x93, 0x01, 0x22, -0x21, 0xa2, 0x43, 0xe9, 0x3e, 0xd6, 0xdf, 0x11, -0xec, 0x51, 0xb1, 0xbe, 0xb4, 0x1a, 0xe5, 0xda, -0x58, 0xe4, 0x38, 0x0c, 0xe3, 0x83, 0xfa, 0x2d, -0xc0, 0xe3, 0x33, 0x9c, 0x98, 0xba, 0xf9, 0xf9, -0x22, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, -0x01, 0x22, 0x21, 0xbc, 0x5f, 0x44, 0x8c, 0xd0, -0x4a, 0x0a, 0x6f, 0xaf, 0xda, 0x82, 0xaf, 0x4f, -0x16, 0x5b, 0x33, 0x03, 0xb5, 0x87, 0x6b, 0x72, -0x21, 0x36, 0xe7, 0xae, 0x0a, 0xd7, 0xad, 0xf4, -0xf8, 0x6f, 0x18, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x95, 0x01, 0x22, 0x21, 0xad, 0xba, 0xab, -0x8c, 0xe1, 0xa0, 0xaf, 0xf8, 0x44, 0x63, 0xc1, -0xf7, 0xb8, 0xa5, 0x95, 0x21, 0x8a, 0x05, 0x48, -0x06, 0x41, 0x3f, 0xc0, 0xc0, 0x10, 0x64, 0x4e, -0x3e, 0xf4, 0x0c, 0xb2, 0xff, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0xb0, -0xe4, 0xaf, 0xf4, 0x9c, 0xf9, 0xea, 0xaa, 0x20, -0x47, 0xe1, 0xf7, 0xbd, 0x9a, 0xc4, 0x6d, 0x65, -0xcf, 0x59, 0x9a, 0xb5, 0x6f, 0x62, 0xda, 0xfd, -0x2a, 0x0c, 0xaf, 0x3d, 0x8d, 0xae, 0x6e, 0x00, +0x21, 0xfe, 0xd5, 0xd4, 0xef, 0x15, 0x45, 0xe9, +0x77, 0x41, 0x2d, 0xb3, 0xcc, 0xa5, 0xe0, 0x96, +0xa1, 0x65, 0x82, 0x38, 0x08, 0x2b, 0x67, 0xaf, +0x13, 0x61, 0x20, 0xe7, 0xf6, 0x90, 0x67, 0x91, +0xc0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, +0x01, 0x22, 0x21, 0xf8, 0x26, 0xa6, 0x7e, 0x69, +0x7c, 0xf5, 0x25, 0x28, 0xf6, 0xf5, 0x11, 0x2d, +0xee, 0xd3, 0xe6, 0x79, 0x7d, 0x3f, 0x01, 0xf1, +0x2a, 0x2a, 0xd2, 0x8d, 0x5a, 0xd9, 0x14, 0x5e, +0x60, 0x53, 0x84, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x95, 0x01, 0x22, 0x21, 0xfc, 0xdc, 0x54, +0xb1, 0xc1, 0x0c, 0xea, 0x35, 0x0b, 0x95, 0x48, +0x98, 0x3f, 0xaf, 0x8e, 0x91, 0xd9, 0xf2, 0x3e, +0x17, 0xb7, 0x9e, 0x2a, 0xee, 0x8a, 0x6a, 0xa0, +0xbb, 0x9a, 0x9f, 0xe2, 0x2c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0xca, +0x24, 0x69, 0x69, 0xd8, 0xe4, 0x1e, 0x24, 0x29, +0xad, 0xc4, 0xd4, 0x0c, 0x9e, 0xad, 0xc4, 0x3f, +0x8d, 0x6c, 0xd8, 0x65, 0xde, 0xca, 0x16, 0x9e, +0xeb, 0xbb, 0x6b, 0xd8, 0x27, 0x00, 0x21, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x97, 0x01, 0x22, -0x21, 0x83, 0x90, 0xde, 0x51, 0xe1, 0x95, 0x11, -0x2a, 0x77, 0x44, 0xbf, 0xbc, 0xb9, 0xc5, 0x1f, -0x30, 0x63, 0xc5, 0xb2, 0x3f, 0x02, 0x33, 0xd8, -0x70, 0xd2, 0xa4, 0xeb, 0xe2, 0xf4, 0xb0, 0x62, -0x67, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, -0x01, 0x22, 0x21, 0x48, 0x4a, 0xc3, 0xcd, 0xdc, -0x66, 0x09, 0x5f, 0x84, 0x20, 0x5a, 0x46, 0x89, -0x7d, 0x2d, 0xfb, 0x6f, 0x44, 0x68, 0x7b, 0x03, -0x86, 0xc7, 0x1f, 0x91, 0xd2, 0x74, 0x82, 0xe9, -0xa3, 0xff, 0x96, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x99, 0x01, 0x22, 0x21, 0x46, 0x3c, 0xd7, -0x8e, 0xd5, 0xdc, 0x4f, 0x91, 0xf2, 0x65, 0xfd, -0x0c, 0xb9, 0x9a, 0x3b, 0x67, 0x57, 0x2f, 0x70, -0x56, 0x6b, 0xde, 0x74, 0xf5, 0x7b, 0x2c, 0xbd, -0x99, 0xd5, 0xb2, 0xd4, 0x23, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0xd2, -0xc7, 0x79, 0x7e, 0x36, 0xba, 0x62, 0x02, 0x85, -0xf4, 0x74, 0x47, 0xde, 0x57, 0x01, 0x51, 0x84, -0x0b, 0x23, 0x38, 0xf2, 0x5b, 0x21, 0xff, 0x8e, -0x83, 0x1d, 0xf1, 0x4b, 0x32, 0xca, 0x67, 0x00, +0x21, 0xb0, 0x67, 0xb8, 0xc6, 0xeb, 0xcd, 0x8e, +0x3b, 0xe8, 0xd1, 0x4f, 0xbe, 0xdc, 0x12, 0x41, +0x41, 0x18, 0xfd, 0x21, 0xa2, 0xe3, 0x6a, 0x73, +0x29, 0xcb, 0x47, 0x5a, 0x49, 0x89, 0x1d, 0xad, +0xdb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, +0x01, 0x22, 0x21, 0x51, 0xa9, 0xa0, 0xb3, 0x8c, +0x5a, 0xe1, 0xde, 0x93, 0xa5, 0xd5, 0xd1, 0xc8, +0x5a, 0xac, 0xfa, 0xa7, 0x46, 0x98, 0x01, 0xa5, +0x4f, 0x98, 0x69, 0x97, 0x77, 0xfb, 0xe0, 0x49, +0x43, 0x9e, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x99, 0x01, 0x22, 0x21, 0x68, 0xa6, 0xa7, +0x1e, 0x8f, 0x49, 0x94, 0x72, 0x68, 0x14, 0x17, +0xa9, 0x53, 0x14, 0xc7, 0xc1, 0x96, 0x89, 0x89, +0x55, 0xd3, 0xa2, 0x74, 0x2a, 0x22, 0xe2, 0x25, +0x16, 0x68, 0xc3, 0x2a, 0x50, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0x3e, +0x79, 0x33, 0xce, 0x1e, 0xd6, 0x6a, 0xf3, 0x16, +0x74, 0x4a, 0xa1, 0x46, 0x87, 0xa5, 0x8f, 0xc6, +0x0b, 0xd9, 0xcf, 0x01, 0x47, 0x03, 0xbf, 0xba, +0x6b, 0x71, 0x6b, 0x7b, 0xe4, 0x4f, 0x53, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9b, 0x01, 0x22, -0x21, 0xb4, 0x62, 0xf3, 0x78, 0x94, 0x71, 0xc0, -0xd8, 0x19, 0x2f, 0xc6, 0x36, 0x98, 0xab, 0xb6, -0x0c, 0x38, 0xe5, 0xba, 0x33, 0x83, 0xa5, 0x69, -0x6d, 0xcd, 0x5e, 0xc7, 0x15, 0xe1, 0xa7, 0xc8, -0x14, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, -0x01, 0x22, 0x21, 0xde, 0xd5, 0xc5, 0x06, 0xd6, -0x0b, 0x23, 0xa7, 0x0d, 0x5b, 0x6d, 0xc4, 0x39, -0x25, 0x25, 0x06, 0xdf, 0xde, 0xad, 0x79, 0xee, -0xe5, 0x31, 0x00, 0xf9, 0xa6, 0xb8, 0x4e, 0x08, -0x67, 0xca, 0x33, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x9d, 0x01, 0x22, 0x21, 0xc7, 0x60, 0xee, -0x56, 0x65, 0x5e, 0x7b, 0x07, 0x5e, 0x69, 0x04, -0x92, 0xb6, 0x98, 0x61, 0x3f, 0x69, 0xdd, 0x1b, -0x80, 0x8c, 0xd3, 0x25, 0x56, 0x67, 0xef, 0xdc, -0xab, 0x82, 0x2b, 0xdb, 0x5e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0x2a, -0x30, 0xe8, 0x82, 0xce, 0xab, 0x94, 0x10, 0xba, -0xbd, 0xd3, 0x9e, 0x51, 0xa4, 0xa2, 0x40, 0x07, -0x82, 0xda, 0x7e, 0x57, 0x58, 0xaf, 0x63, 0x27, -0x29, 0x7d, 0x3f, 0x0e, 0x47, 0x7c, 0x0a, 0x00, +0x21, 0x4d, 0x4b, 0xb9, 0x3f, 0x64, 0x80, 0xaa, +0xc1, 0xc8, 0xbb, 0x06, 0x95, 0xa6, 0xb9, 0x69, +0x17, 0x9c, 0x1f, 0xf6, 0xd9, 0x17, 0xd1, 0x96, +0x76, 0x3a, 0x23, 0x75, 0xee, 0x91, 0xac, 0x34, +0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, +0x01, 0x22, 0x21, 0x84, 0x57, 0xe0, 0xd0, 0xb9, +0xd7, 0x30, 0xc0, 0x13, 0x37, 0xd2, 0xa9, 0xac, +0x57, 0xb1, 0xa9, 0xee, 0x7b, 0x7c, 0x84, 0x8f, +0x66, 0x24, 0x1f, 0x06, 0xf1, 0x39, 0x01, 0xc3, +0x9b, 0x05, 0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x9d, 0x01, 0x22, 0x21, 0xc2, 0x9a, 0x46, +0x9c, 0xdb, 0xf8, 0xaf, 0x54, 0x1b, 0x1e, 0xff, +0xb0, 0x03, 0x73, 0x40, 0x52, 0x80, 0xdd, 0x00, +0x91, 0x70, 0xeb, 0x96, 0x3d, 0xa5, 0xb4, 0x50, +0xd1, 0x2d, 0xaa, 0xa2, 0x5b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0x16, +0x68, 0x7e, 0x33, 0xfe, 0xc7, 0x5f, 0x3b, 0x74, +0xfb, 0xde, 0xfa, 0xcd, 0xc9, 0xbd, 0x3b, 0x87, +0x06, 0x05, 0xb5, 0x14, 0x90, 0x4e, 0x0e, 0x42, +0xab, 0x9c, 0xbd, 0xba, 0xc0, 0x0d, 0x42, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9f, 0x01, 0x22, -0x21, 0xbb, 0x75, 0x95, 0xce, 0xd1, 0x0e, 0x69, -0xaf, 0x42, 0x34, 0xe8, 0xec, 0x63, 0x03, 0x26, -0xb7, 0x52, 0x2c, 0xc9, 0x2d, 0xb8, 0x0d, 0xbb, -0x16, 0xa7, 0x74, 0xd1, 0x4b, 0x93, 0x07, 0x53, -0xef, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, -0x01, 0x22, 0x21, 0x41, 0x74, 0x34, 0xa5, 0x75, -0x30, 0x22, 0x8d, 0xdb, 0xa4, 0x2e, 0x2b, 0x6c, -0xba, 0x7c, 0x8e, 0x65, 0xa6, 0xc0, 0x37, 0xff, -0x52, 0x8b, 0xf6, 0x23, 0x2d, 0xe4, 0x0c, 0x9a, -0x06, 0x90, 0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa1, 0x01, 0x22, 0x21, 0x0a, 0x5a, 0xbd, -0x9f, 0x64, 0x41, 0xe6, 0x7e, 0xe1, 0x47, 0xe8, -0x27, 0xb2, 0xda, 0x7b, 0x84, 0x14, 0x01, 0xd2, -0x09, 0xd9, 0x51, 0xe4, 0xe5, 0x1c, 0xed, 0x85, -0x5f, 0xa4, 0xa6, 0xd2, 0x4f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xf8, -0x63, 0xc4, 0xa8, 0x06, 0xc7, 0xc7, 0xb9, 0xe2, -0x71, 0xd3, 0x0f, 0x34, 0xb3, 0x5e, 0x27, 0x26, -0x7c, 0xf0, 0x7e, 0x20, 0x28, 0x58, 0x78, 0x08, -0x74, 0xe3, 0xbe, 0x51, 0xb1, 0x8c, 0x41, 0x00, +0x21, 0x79, 0x37, 0x97, 0x3c, 0xa1, 0xb3, 0x78, +0x51, 0x8b, 0xb5, 0xb2, 0x57, 0x5b, 0xd0, 0x60, +0x27, 0xad, 0x9b, 0x1d, 0x24, 0xfe, 0xcb, 0xe5, +0x43, 0xbd, 0x7d, 0x6c, 0x84, 0xfe, 0xa3, 0x94, +0x12, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, +0x01, 0x22, 0x21, 0xd4, 0xd1, 0x12, 0x70, 0x14, +0xe5, 0xf8, 0x20, 0x64, 0xaf, 0x4d, 0xde, 0x61, +0x07, 0x91, 0x3a, 0xb7, 0x9e, 0x3d, 0x32, 0x4b, +0xb1, 0x05, 0x7e, 0x80, 0x63, 0x5a, 0x04, 0x94, +0x64, 0x58, 0x33, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa1, 0x01, 0x22, 0x21, 0x8a, 0xd1, 0x04, +0xd5, 0xa0, 0xd4, 0x30, 0xdc, 0xd3, 0xeb, 0x48, +0x1b, 0x8b, 0xec, 0x5f, 0x2c, 0x03, 0xa5, 0x40, +0x79, 0x60, 0x42, 0x26, 0x73, 0x38, 0x9c, 0x81, +0xf2, 0x74, 0x08, 0xa0, 0x29, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xe5, +0x92, 0x4e, 0x6d, 0xbc, 0xd4, 0x19, 0xcd, 0x3c, +0x9a, 0x5b, 0x8e, 0xa2, 0xd9, 0x94, 0xb9, 0xc1, +0x7f, 0xee, 0xbd, 0x57, 0x65, 0xbb, 0x23, 0x43, +0x2d, 0xc9, 0xc9, 0x02, 0x81, 0x7d, 0x59, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa3, 0x01, 0x22, -0x21, 0xf8, 0x62, 0x4c, 0xf2, 0xbf, 0x63, 0x80, -0x21, 0xe9, 0xe8, 0x30, 0xd5, 0x20, 0x14, 0x7d, -0xbb, 0x68, 0x7a, 0x81, 0x47, 0x03, 0xd1, 0x55, -0x97, 0x4b, 0x9d, 0x32, 0xdf, 0xe5, 0x56, 0xd1, -0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, -0x01, 0x22, 0x21, 0xf0, 0xfa, 0x6b, 0xa5, 0xe8, -0x5d, 0x25, 0x7c, 0x7f, 0x95, 0x71, 0x3b, 0x40, -0x73, 0x9f, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x68, 0xcb, 0x83, 0x09, -0x29, 0x47, 0x93, 0x1c, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa5, 0x01, 0x22, 0x21, 0x71, 0xea, 0x9f, -0x89, 0x11, 0x03, 0xf0, 0x57, 0x98, 0x9d, 0xc9, -0x1c, 0x5e, 0x9f, 0x15, 0x69, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x8d, -0xb6, 0x00, 0x72, 0x33, 0x97, 0x59, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0xfa, -0x35, 0x44, 0x51, 0xa6, 0x48, 0x18, 0x68, 0x28, -0xde, 0xda, 0x9c, 0xfe, 0x8a, 0x39, 0x60, 0x65, -0x22, 0xc0, 0x44, 0x90, 0x75, 0x19, 0xc0, 0xe1, -0x54, 0x65, 0x4a, 0x73, 0xf3, 0x30, 0x7b, 0x00, +0x21, 0x95, 0x6b, 0x06, 0x94, 0x18, 0x60, 0xc0, +0xb2, 0xa1, 0x7e, 0xdc, 0xbd, 0x87, 0x54, 0x9d, +0x15, 0x0a, 0x0c, 0x60, 0xd4, 0xde, 0xfc, 0x06, +0x59, 0xc8, 0x52, 0x1b, 0x31, 0x93, 0xb8, 0xff, +0xef, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, +0x01, 0x22, 0x21, 0xaf, 0xd5, 0x47, 0x28, 0x2b, +0x41, 0x76, 0xd6, 0x6c, 0x7f, 0xb4, 0x12, 0x26, +0x27, 0xb7, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x16, 0xca, 0xc8, 0x3e, +0x6b, 0x70, 0xc0, 0xb4, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa5, 0x01, 0x22, 0x21, 0x91, 0xa0, 0x72, +0xf8, 0xe6, 0x35, 0xa1, 0x32, 0x5e, 0x5d, 0x49, +0xbe, 0x8d, 0x10, 0x23, 0x78, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x7a, +0xfa, 0x5a, 0xbe, 0xed, 0xb9, 0x09, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0x11, +0xbe, 0x14, 0x89, 0x48, 0x53, 0xfb, 0x2e, 0x33, +0x48, 0x19, 0xcb, 0xbf, 0xcb, 0xa8, 0x0c, 0x65, +0x10, 0xa1, 0xca, 0x76, 0xd9, 0x3d, 0x5c, 0xb6, +0x42, 0xf9, 0xa7, 0x0b, 0x49, 0x76, 0xce, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa7, 0x01, 0x22, -0x21, 0xad, 0x46, 0x91, 0x7d, 0xcd, 0x28, 0xb9, -0x60, 0x09, 0xec, 0x95, 0x1a, 0xd6, 0x57, 0x0d, -0x49, 0xe4, 0x4b, 0x2a, 0xc4, 0x43, 0xc0, 0x78, -0xa7, 0xb9, 0x77, 0x95, 0x01, 0xd0, 0xad, 0xab, -0xb8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, -0x01, 0x22, 0x21, 0xad, 0xf8, 0xf4, 0xfa, 0x61, -0x69, 0x6e, 0x58, 0x90, 0x1b, 0x8c, 0x37, 0x13, -0xc4, 0x80, 0x2f, 0x9b, 0xce, 0x35, 0x13, 0x2e, -0xc6, 0xfe, 0x69, 0x6c, 0x3e, 0x57, 0x9a, 0xb9, -0x11, 0xd7, 0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa9, 0x01, 0x22, 0x21, 0x8c, 0x8f, 0xbe, -0xca, 0x6b, 0x64, 0x65, 0x03, 0x82, 0xf3, 0x81, -0xa4, 0x3d, 0x33, 0xf8, 0xe8, 0xed, 0x03, 0xc8, -0x28, 0xc8, 0x59, 0x41, 0x04, 0x45, 0x60, 0x7f, -0xbd, 0xaf, 0x5b, 0xf4, 0x33, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0xcf, -0x75, 0xfe, 0x4c, 0xf0, 0x3d, 0x68, 0xb4, 0x18, -0xfe, 0xc3, 0xf3, 0xa1, 0x2b, 0x0d, 0x4e, 0x85, -0x35, 0x20, 0x99, 0x92, 0x5c, 0x83, 0x47, 0xcb, -0xb9, 0xb8, 0x3a, 0x02, 0x57, 0x65, 0x99, 0x00, +0x21, 0x72, 0xb7, 0x4d, 0xe2, 0xd3, 0xf4, 0x15, +0x39, 0x7b, 0x9e, 0x1c, 0xe1, 0xc9, 0x10, 0xc7, +0x3a, 0x8f, 0x1d, 0x6a, 0x41, 0x79, 0x38, 0x5b, +0xd3, 0xe5, 0xfb, 0xf2, 0x84, 0x9e, 0x71, 0xb4, +0xe2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, +0x01, 0x22, 0x21, 0x9f, 0xfa, 0x5f, 0x58, 0x03, +0xe1, 0xda, 0xa8, 0xdb, 0x5a, 0x48, 0x0b, 0x89, +0x10, 0x39, 0x80, 0x18, 0x68, 0xcb, 0x27, 0x14, +0x8c, 0x4e, 0x9b, 0x82, 0x95, 0x6b, 0xf2, 0x60, +0xea, 0xa0, 0x74, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa9, 0x01, 0x22, 0x21, 0x11, 0x18, 0x64, +0x1b, 0x10, 0x2e, 0xee, 0x2f, 0xf7, 0x87, 0x7f, +0xcb, 0x38, 0x06, 0x98, 0x17, 0xd9, 0x24, 0x32, +0x3d, 0x6c, 0x32, 0x1a, 0x58, 0x19, 0xe6, 0x4b, +0x72, 0x23, 0xf6, 0xf6, 0x18, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x25, +0xc2, 0xa2, 0x7e, 0x93, 0x60, 0xf0, 0x75, 0x5c, +0xf9, 0x06, 0xde, 0xd5, 0x6f, 0xb8, 0x7d, 0x8d, +0x18, 0x7a, 0x46, 0x64, 0x4d, 0xd8, 0x3c, 0x70, +0x30, 0xbb, 0x66, 0x51, 0x49, 0xa9, 0xb2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xab, 0x01, 0x22, -0x21, 0x69, 0x37, 0xac, 0x71, 0xda, 0x51, 0xd8, -0xbf, 0x7c, 0xc1, 0xdb, 0xf4, 0x70, 0x47, 0x33, -0x03, 0x34, 0xb4, 0x42, 0x20, 0xce, 0x2d, 0xf5, -0x08, 0x16, 0x08, 0x2b, 0x2b, 0x6e, 0x53, 0x1b, -0x96, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, -0x01, 0x22, 0x21, 0x8a, 0xe7, 0xf8, 0x11, 0xb9, -0x62, 0x65, 0x9f, 0x67, 0x4e, 0xbb, 0xcb, 0x2c, -0x4e, 0x42, 0x37, 0x9c, 0xd5, 0x4f, 0x77, 0xb2, -0x0c, 0x22, 0xf9, 0x75, 0x08, 0x35, 0xc6, 0xdb, -0xb4, 0x6d, 0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xad, 0x01, 0x22, 0x21, 0xd0, 0x01, 0x3d, -0x50, 0xfb, 0x49, 0xc8, 0xb2, 0xb7, 0x08, 0x49, -0x93, 0x21, 0x87, 0x4c, 0x61, 0xd1, 0x1b, 0x1e, -0x06, 0xbb, 0xac, 0x0c, 0x9e, 0x55, 0xb3, 0x08, -0x69, 0xeb, 0xd3, 0x1d, 0x51, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0xcb, -0x8b, 0x48, 0x16, 0x9c, 0x79, 0x17, 0x28, 0xd5, -0xc2, 0xd9, 0xfb, 0x7c, 0x3d, 0x62, 0xe3, 0x91, -0x28, 0x2a, 0x8e, 0x64, 0x5f, 0x79, 0x02, 0xcf, -0x82, 0x5d, 0x96, 0xb2, 0xd6, 0x5f, 0xa7, 0x00, +0x21, 0x3f, 0x60, 0xd0, 0x2f, 0x4c, 0x3d, 0x06, +0x31, 0x48, 0xee, 0x3e, 0xe1, 0x39, 0x2b, 0x4a, +0x79, 0x95, 0x94, 0x8b, 0xfa, 0x0c, 0xed, 0x28, +0x29, 0x73, 0x08, 0xa1, 0x4a, 0xdd, 0xcc, 0xf0, +0xed, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, +0x01, 0x22, 0x21, 0xf7, 0x8f, 0xa2, 0x8a, 0x9e, +0xf3, 0x41, 0x81, 0xa3, 0xe1, 0x4a, 0xfe, 0xfc, +0x55, 0xf9, 0x8f, 0x0a, 0xf3, 0x13, 0x7d, 0x06, +0xbd, 0xba, 0xcd, 0xda, 0xc0, 0xd1, 0x57, 0x5a, +0xc8, 0xc9, 0xa0, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xad, 0x01, 0x22, 0x21, 0xa7, 0x71, 0x50, +0xd6, 0xd9, 0x33, 0x99, 0xa1, 0x3e, 0x1d, 0x97, +0x5a, 0xc5, 0x7d, 0xc2, 0x63, 0x30, 0x04, 0xa4, +0x30, 0xf8, 0xf5, 0x34, 0x54, 0x44, 0x13, 0x02, +0xfe, 0xf2, 0xa1, 0xe5, 0x01, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0xcd, +0x00, 0xe6, 0x81, 0x09, 0xed, 0x24, 0x58, 0x63, +0xc0, 0xda, 0x3c, 0x5f, 0x1a, 0x00, 0xe9, 0x53, +0x84, 0xc2, 0xca, 0x46, 0xb1, 0x1f, 0xa3, 0xf1, +0x16, 0xd0, 0xaf, 0x88, 0x70, 0x8e, 0xd5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xaf, 0x01, 0x22, -0x21, 0x1a, 0x58, 0x13, 0x70, 0x84, 0x5f, 0xbd, -0x33, 0x39, 0x54, 0xa5, 0xc6, 0x15, 0x13, 0xf1, -0xcb, 0x22, 0x69, 0xaf, 0x88, 0x2d, 0xd4, 0x4c, -0x50, 0x48, 0xdb, 0x60, 0x5a, 0x3a, 0x73, 0x24, -0x74, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, -0x01, 0x22, 0x21, 0x02, 0x3b, 0xf5, 0x4e, 0x3b, -0x6b, 0xeb, 0x02, 0xcb, 0xcf, 0x87, 0xeb, 0xbe, -0x2f, 0xa0, 0xb7, 0x52, 0x61, 0x17, 0x7a, 0x51, -0x0f, 0x26, 0x39, 0x2a, 0x70, 0x32, 0x64, 0x10, -0x1a, 0x60, 0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb1, 0x01, 0x22, 0x21, 0xa7, 0xb0, 0xa2, -0x50, 0x30, 0x01, 0x5a, 0xf4, 0x56, 0xbb, 0x34, -0x28, 0x6a, 0x54, 0xb9, 0x8f, 0x46, 0x83, 0x38, -0xf0, 0xe5, 0x88, 0x3e, 0xc9, 0x0b, 0x94, 0x12, -0x5d, 0x21, 0xe0, 0xf1, 0x06, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0x4e, -0xd3, 0x13, 0x76, 0x30, 0x43, 0x70, 0x30, 0xeb, -0x6f, 0xaf, 0x3f, 0x98, 0x14, 0xcb, 0xab, 0x00, -0xf8, 0x7f, 0xe9, 0x4a, 0xc2, 0x70, 0xf7, 0x13, -0xc6, 0x91, 0x86, 0xad, 0xfe, 0x53, 0xfb, 0x00, +0x21, 0x94, 0xf7, 0x11, 0x95, 0xfb, 0xd1, 0xdf, +0x66, 0x6d, 0x4a, 0xb8, 0x9e, 0x03, 0xda, 0x55, +0xe5, 0xc8, 0x8b, 0x7f, 0x27, 0xd9, 0x5e, 0xdf, +0x2c, 0xd2, 0x7c, 0xc3, 0x00, 0x09, 0x8f, 0x7f, +0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, +0x01, 0x22, 0x21, 0xe6, 0x50, 0x64, 0x5a, 0x7d, +0xbb, 0x16, 0x48, 0xa3, 0xdb, 0xd2, 0x28, 0x04, +0x1a, 0x9e, 0xfb, 0xdd, 0x48, 0x68, 0xa3, 0x95, +0xbb, 0x45, 0xbd, 0x70, 0x7c, 0x35, 0x69, 0xdc, +0x0f, 0xa8, 0x95, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb1, 0x01, 0x22, 0x21, 0xe3, 0x6b, 0x49, +0x23, 0xe4, 0x38, 0xb7, 0x33, 0xe5, 0x57, 0x54, +0x35, 0xa0, 0x2f, 0x3e, 0x0e, 0xdb, 0x11, 0x73, +0x86, 0x44, 0xb9, 0xd4, 0x32, 0x45, 0x15, 0xa5, +0xca, 0xc5, 0xa8, 0x85, 0x59, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0x47, +0x32, 0x7e, 0x10, 0xc8, 0x3d, 0x4b, 0x07, 0x9f, +0x90, 0xa7, 0xc4, 0x7d, 0xd1, 0x38, 0x12, 0x6c, +0x59, 0x0f, 0xe5, 0x9f, 0x42, 0xb8, 0x73, 0x38, +0x1e, 0x3d, 0x65, 0x5f, 0x6a, 0x11, 0x04, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb3, 0x01, 0x22, -0x21, 0xa3, 0x9b, 0xdc, 0x10, 0xcf, 0x8b, 0x39, -0xd7, 0x87, 0xe8, 0x3c, 0x08, 0xef, 0x0c, 0xba, -0x2d, 0x7d, 0x3e, 0xb4, 0x68, 0x74, 0xe9, 0x5b, -0x0d, 0xd0, 0x46, 0xa5, 0x61, 0xf0, 0x28, 0x1f, -0x6c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, -0x01, 0x22, 0x21, 0x32, 0xfd, 0x8c, 0x69, 0x3e, -0x16, 0x21, 0xd3, 0x9d, 0x71, 0xc8, 0xb8, 0x9e, -0xa7, 0x07, 0xea, 0x51, 0x03, 0xa5, 0xe0, 0x87, -0x08, 0xba, 0x34, 0x7e, 0x54, 0x8e, 0xb8, 0x40, -0xa9, 0x05, 0xbc, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb5, 0x01, 0x22, 0x21, 0xe4, 0xfb, 0x13, -0x4e, 0xac, 0x7f, 0x86, 0x83, 0xd3, 0xe6, 0x40, -0x8f, 0x6a, 0x71, 0x5f, 0x98, 0x87, 0xc3, 0x15, -0x4b, 0xaa, 0xfd, 0xa8, 0x56, 0x14, 0xce, 0x3a, -0x12, 0x6f, 0x8e, 0x7d, 0x22, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0x67, -0x89, 0x9b, 0x44, 0xa8, 0xe5, 0xcc, 0x0b, 0x96, -0xb9, 0xae, 0x7e, 0x87, 0x6a, 0xc1, 0x3e, 0x2c, -0x9d, 0x0c, 0xa0, 0x75, 0xc4, 0x69, 0x7c, 0x3d, -0x3c, 0xb5, 0x00, 0xbf, 0x12, 0xdb, 0xed, 0x00, +0x21, 0x22, 0x44, 0x4b, 0x7b, 0xb6, 0xb5, 0x01, +0x34, 0x29, 0xf6, 0xc9, 0xb8, 0x24, 0xc0, 0x36, +0x02, 0xae, 0x1c, 0x5e, 0x8a, 0x1d, 0x49, 0x8a, +0xa1, 0x14, 0xd6, 0x83, 0x5a, 0x07, 0x53, 0xf3, +0x3b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, +0x01, 0x22, 0x21, 0xc4, 0x22, 0x4f, 0xc3, 0x19, +0xf3, 0xaf, 0xa7, 0xf8, 0xea, 0x46, 0x85, 0x80, +0xf7, 0xd1, 0x52, 0x38, 0x2c, 0xd8, 0xd0, 0x30, +0x69, 0xdd, 0xf6, 0xe7, 0x9a, 0x77, 0xff, 0x6e, +0x6c, 0x2a, 0xe2, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb5, 0x01, 0x22, 0x21, 0x46, 0x2e, 0x5f, +0x16, 0x47, 0x8d, 0xdf, 0x9a, 0xe8, 0xde, 0xa8, +0x79, 0x11, 0xaa, 0xdc, 0x72, 0xf6, 0x4d, 0x37, +0xa8, 0x16, 0x39, 0x03, 0xa6, 0x7d, 0x5a, 0xd8, +0xaa, 0x11, 0x32, 0xea, 0x87, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0x23, +0xa1, 0x8a, 0x94, 0x67, 0xeb, 0xc0, 0x30, 0x3f, +0x0e, 0x06, 0x4c, 0xd2, 0x9f, 0xb9, 0xe3, 0x2a, +0xaa, 0x36, 0x04, 0x0f, 0xb5, 0x01, 0x36, 0x20, +0x55, 0xdc, 0x07, 0x8d, 0x85, 0xe1, 0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb7, 0x01, 0x22, -0x21, 0x67, 0x81, 0xb5, 0x06, 0xfa, 0xd4, 0x57, -0xb1, 0x94, 0xf2, 0x60, 0x4a, 0xaa, 0x64, 0xc1, -0xbd, 0x3c, 0x86, 0xba, 0xea, 0x47, 0xc7, 0xd2, -0x96, 0x56, 0x7b, 0x8e, 0xd7, 0x1f, 0x0c, 0x06, -0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, -0x01, 0x22, 0x21, 0xf6, 0xa6, 0x4c, 0xc7, 0xed, -0x39, 0x6c, 0x38, 0xdb, 0x21, 0xb7, 0x77, 0x86, -0x8a, 0xda, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xa2, 0xe0, -0x5f, 0x87, 0xd7, 0x8b, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb9, 0x01, 0x22, 0x21, 0xf8, 0x2e, 0x0d, -0x03, 0xce, 0x09, 0xc6, 0x54, 0x85, 0x20, 0x7c, -0xcd, 0xe0, 0x51, 0xd8, 0x32, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xdb, -0x98, 0x8c, 0x9a, 0xdd, 0xd7, 0xb8, 0x03, 0x04, -0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0x65, -0xef, 0xa9, 0x39, 0xf5, 0x86, 0xeb, 0x6a, 0x55, -0xdb, 0x55, 0xdb, 0xa4, 0xc9, 0x66, 0x4e, 0x40, -0x5c, 0x96, 0xaf, 0x75, 0x73, 0x81, 0xd4, 0xbd, -0x76, 0xbc, 0x95, 0x85, 0x22, 0xa8, 0xd8, 0x00, +0x21, 0x09, 0xf5, 0xa8, 0xfb, 0x47, 0x6d, 0xf2, +0x9d, 0x04, 0x03, 0xb8, 0x6b, 0xc0, 0x2a, 0xf9, +0xf9, 0x23, 0xe3, 0xd2, 0xba, 0x1c, 0x2b, 0x08, +0x0d, 0xed, 0x3f, 0xfa, 0x89, 0x57, 0xc4, 0x3f, +0x3a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, +0x01, 0x22, 0x21, 0x67, 0xb8, 0x68, 0xe4, 0xea, +0x8f, 0xcf, 0xc1, 0x6e, 0xae, 0x0d, 0x54, 0x13, +0xf8, 0xc4, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xef, 0x3f, 0x94, 0x61, +0xc9, 0xf1, 0x79, 0x3f, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb9, 0x01, 0x22, 0x21, 0x6d, 0x66, 0x9b, +0xeb, 0x4a, 0x9b, 0x92, 0x37, 0x17, 0x74, 0x0d, +0x40, 0x1f, 0x15, 0xa7, 0xc5, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xd7, +0x11, 0xbc, 0x2c, 0xd2, 0x33, 0x55, 0x03, 0x04, +0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0xc3, +0x3e, 0x17, 0xca, 0x4e, 0xcf, 0x1f, 0xdf, 0xb8, +0x58, 0xae, 0xed, 0xd3, 0xc0, 0xbe, 0x20, 0x55, +0x4f, 0x63, 0xde, 0xe9, 0x2e, 0xe1, 0x2d, 0xd1, +0x74, 0xab, 0x90, 0x9d, 0x98, 0x9a, 0xc9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbb, 0x01, 0x22, -0x21, 0x88, 0x3d, 0xeb, 0x1a, 0x1b, 0xec, 0xad, -0xc7, 0x4b, 0x53, 0xb3, 0x04, 0xf4, 0xf4, 0xa4, -0x57, 0x77, 0xdd, 0x7a, 0xc9, 0xb1, 0x00, 0x63, -0xc9, 0xf7, 0xa6, 0x86, 0x48, 0x38, 0x20, 0x90, -0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, -0x01, 0x22, 0x21, 0x22, 0x0a, 0x33, 0x74, 0x3e, -0x40, 0x33, 0x43, 0x2c, 0x8d, 0xe8, 0x80, 0x69, -0xce, 0xe6, 0x1f, 0x72, 0x63, 0x99, 0x22, 0xdb, -0xc4, 0x3a, 0xb8, 0x21, 0x70, 0x63, 0x86, 0xf7, -0x22, 0x6d, 0x21, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xbd, 0x01, 0x22, 0x21, 0xc3, 0xa6, 0xf8, -0xbc, 0xa4, 0xc4, 0x3e, 0x74, 0xae, 0xd1, 0x4e, -0x9e, 0x1f, 0x26, 0x48, 0x1c, 0x90, 0x63, 0x65, -0x7f, 0xb1, 0xc4, 0x4d, 0x9b, 0xef, 0x12, 0x83, -0x1c, 0xb1, 0x72, 0x00, 0x64, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0x82, -0x15, 0x83, 0x2b, 0x0f, 0xce, 0x2e, 0x86, 0x9c, -0xf4, 0xdf, 0x49, 0x7e, 0x73, 0xfb, 0x9c, 0x01, -0x63, 0x46, 0xf5, 0x50, 0x6b, 0xaf, 0x46, 0x24, -0x45, 0xff, 0x24, 0x87, 0x91, 0x26, 0x00, 0x00, +0x21, 0xc6, 0xab, 0x7e, 0xe5, 0xdc, 0x65, 0x51, +0xa8, 0xda, 0x3f, 0xaf, 0x56, 0x92, 0x65, 0x07, +0xa7, 0xe5, 0xe6, 0x2b, 0xa2, 0x8d, 0x43, 0x66, +0xb7, 0x23, 0xda, 0x3c, 0x85, 0x93, 0x02, 0x20, +0xad, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, +0x01, 0x22, 0x21, 0x8a, 0x9c, 0xda, 0x04, 0x23, +0x74, 0x64, 0x4e, 0x7d, 0xae, 0x74, 0x8c, 0xe9, +0x32, 0x23, 0xc0, 0x62, 0x67, 0xb2, 0xf4, 0xe2, +0x6b, 0x82, 0x87, 0x34, 0xe2, 0x4d, 0xe3, 0x74, +0x30, 0x7a, 0x0d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xbd, 0x01, 0x22, 0x21, 0x86, 0x25, 0x0c, +0x06, 0x92, 0xd9, 0x34, 0xaf, 0x09, 0xc9, 0x56, +0xac, 0xd1, 0xdd, 0x06, 0x92, 0xd4, 0x6c, 0x7a, +0xa8, 0x30, 0x9f, 0xa3, 0x9a, 0x1d, 0x04, 0x80, +0xc7, 0x41, 0xb3, 0x77, 0x8c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0x8d, +0x30, 0x9a, 0x6f, 0x88, 0xaa, 0x6e, 0x61, 0xcc, +0xdc, 0xfa, 0x4c, 0x08, 0x5a, 0x01, 0x08, 0x74, +0x1f, 0x46, 0xd2, 0xc5, 0x12, 0xff, 0x8c, 0xde, +0x73, 0xe6, 0xd7, 0x7e, 0x0b, 0x56, 0x88, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbf, 0x01, 0x22, -0x21, 0x33, 0x59, 0x3c, 0x3c, 0x8b, 0x23, 0x18, -0x19, 0xd6, 0x56, 0xc2, 0xfa, 0xc3, 0x6a, 0xac, -0x08, 0x17, 0x7d, 0x22, 0x93, 0xea, 0xf3, 0x89, -0x0a, 0x12, 0x3e, 0xd4, 0x7a, 0x9e, 0x45, 0x12, -0xc1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, -0x01, 0x22, 0x21, 0xdb, 0xf2, 0xda, 0xbd, 0x91, -0x66, 0x45, 0xb2, 0xcf, 0x10, 0xfb, 0xcf, 0xd8, -0x98, 0x8e, 0xd1, 0x8a, 0x34, 0x9e, 0xc4, 0xf3, -0x8b, 0x84, 0xb2, 0x4e, 0x23, 0x24, 0x9e, 0xb4, -0x7f, 0x5a, 0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc1, 0x01, 0x22, 0x21, 0x41, 0xdc, 0x97, -0xd3, 0xf4, 0xd7, 0x50, 0xfc, 0xeb, 0x0b, 0x8b, -0x1c, 0x52, 0xa2, 0xe3, 0xb3, 0x0f, 0x33, 0xe3, -0x4a, 0xe3, 0x59, 0xb7, 0x89, 0x6c, 0xc6, 0xe0, -0x0b, 0xc2, 0x2a, 0x56, 0x76, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0x95, -0xa7, 0x04, 0x48, 0xab, 0x6a, 0x48, 0x55, 0xa5, -0xc0, 0x7b, 0x30, 0xd8, 0x66, 0x8d, 0x4b, 0x64, -0xdf, 0xa4, 0x5b, 0xb7, 0x6f, 0x3f, 0x03, 0xbc, -0xb1, 0x18, 0xb5, 0x3e, 0x38, 0xbd, 0x90, 0x00, +0x21, 0xb0, 0x6a, 0x85, 0x48, 0x04, 0xcf, 0xc5, +0xc5, 0xa2, 0x01, 0xfc, 0x65, 0x39, 0x75, 0xc8, +0xc4, 0xc0, 0xb1, 0xb5, 0x9b, 0x6e, 0x40, 0x90, +0x13, 0xe8, 0x7e, 0xd7, 0x06, 0xf2, 0xab, 0x5a, +0x62, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, +0x01, 0x22, 0x21, 0x4d, 0x0d, 0x06, 0x67, 0x8c, +0xc9, 0xd7, 0x74, 0xd9, 0x3c, 0xc3, 0x4f, 0x43, +0x4d, 0x97, 0x80, 0x2b, 0xf9, 0x84, 0x89, 0x8d, +0x42, 0x84, 0x9a, 0xf0, 0xd4, 0x08, 0x97, 0x37, +0xdc, 0x21, 0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc1, 0x01, 0x22, 0x21, 0x1f, 0xc1, 0xa2, +0x2a, 0xf2, 0xab, 0xa9, 0x5a, 0x43, 0x24, 0x91, +0x89, 0x3c, 0x21, 0xf2, 0x54, 0x8a, 0x5d, 0x66, +0xb4, 0xe7, 0xf4, 0x6c, 0x17, 0xb6, 0x54, 0x54, +0x08, 0xc2, 0x84, 0x3e, 0xc0, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0x3e, +0x71, 0xe4, 0x6b, 0x15, 0x61, 0x8b, 0x91, 0x29, +0x0c, 0xbf, 0x9e, 0xca, 0x9c, 0x7e, 0x90, 0x39, +0x07, 0xb7, 0xc6, 0x8a, 0xa7, 0xdf, 0x25, 0x72, +0x81, 0xa5, 0xac, 0x86, 0x28, 0x81, 0x1a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc3, 0x01, 0x22, -0x21, 0x4e, 0x1d, 0xec, 0xde, 0x1f, 0x17, 0x16, -0x37, 0x4f, 0x30, 0x61, 0xbb, 0xb3, 0x4c, 0x6c, -0xec, 0xe0, 0x1b, 0xfa, 0x32, 0x3e, 0x3a, 0xb9, -0x46, 0x71, 0x68, 0xd4, 0xab, 0x09, 0xd1, 0x10, -0x75, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, -0x01, 0x22, 0x21, 0xa7, 0x68, 0x4c, 0xbc, 0x87, -0x20, 0x90, 0x7f, 0xfc, 0xa4, 0x2a, 0x43, 0x01, -0x22, 0xf9, 0x49, 0x54, 0x5a, 0x00, 0x9c, 0x95, -0xbb, 0xa4, 0x98, 0x46, 0x7f, 0xbb, 0x5c, 0x34, -0xd1, 0x0c, 0x13, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc5, 0x01, 0x22, 0x21, 0x41, 0x52, 0xd3, -0xe6, 0x4e, 0x55, 0x02, 0x38, 0xc4, 0x4b, 0x8d, -0x92, 0xab, 0x4b, 0x80, 0x24, 0x5c, 0x7b, 0x56, -0xe5, 0xc0, 0xaa, 0x1c, 0xa9, 0xe3, 0xab, 0xba, -0x73, 0x00, 0xce, 0xcc, 0x04, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0xd4, -0x63, 0xdd, 0x41, 0xc7, 0x84, 0xe0, 0x31, 0x88, -0xdf, 0x70, 0x59, 0xa8, 0x2a, 0xbc, 0xd5, 0x3d, -0x1f, 0x47, 0x63, 0xe2, 0x5b, 0x56, 0xf9, 0xa6, -0x14, 0x37, 0xc7, 0x6c, 0xbd, 0x9a, 0x72, 0x00, +0x21, 0x13, 0x92, 0x9d, 0x9a, 0xf0, 0x92, 0x53, +0xab, 0x24, 0x9f, 0xef, 0x20, 0x9a, 0xb8, 0x22, +0xd8, 0xd5, 0xd1, 0x61, 0x68, 0xfd, 0x7b, 0x7c, +0xee, 0x7b, 0xdc, 0xfe, 0xb1, 0x2c, 0x1a, 0x49, +0x20, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, +0x01, 0x22, 0x21, 0x2f, 0xa9, 0xd6, 0xd0, 0xb3, +0xc2, 0xf9, 0xfd, 0x6c, 0xd4, 0x9a, 0xd1, 0xca, +0x26, 0x8c, 0x23, 0x43, 0x0e, 0xb4, 0xd5, 0xbd, +0x63, 0xa0, 0x0b, 0xc4, 0x19, 0x76, 0xd6, 0xfa, +0xa2, 0x09, 0x09, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc5, 0x01, 0x22, 0x21, 0x13, 0x11, 0xe7, +0xb7, 0xaf, 0xdc, 0xca, 0xcd, 0x57, 0x4d, 0x74, +0xc8, 0x91, 0xbb, 0x71, 0xa1, 0xe5, 0xa8, 0x57, +0x35, 0x73, 0x35, 0xea, 0xf9, 0x50, 0x1f, 0x5f, +0x74, 0x6f, 0xd7, 0x04, 0xb2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0xf8, +0x7c, 0x4a, 0x59, 0xb7, 0x9f, 0x8c, 0xff, 0x2e, +0x3d, 0x64, 0x5f, 0xdb, 0x8c, 0x8e, 0x74, 0x35, +0x2c, 0x69, 0x51, 0x66, 0xf7, 0x3e, 0xe5, 0x95, +0xf0, 0xb7, 0xc7, 0xa8, 0xdc, 0x89, 0xde, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc7, 0x01, 0x22, -0x21, 0x49, 0xca, 0xc5, 0x90, 0xe2, 0x41, 0x66, -0x06, 0xad, 0x52, 0x47, 0x8b, 0x4e, 0xca, 0xeb, -0x88, 0xb8, 0xff, 0xea, 0xa6, 0xa6, 0xcf, 0xf2, -0x34, 0x10, 0xbf, 0x4e, 0x29, 0x17, 0xba, 0x52, -0xe1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, -0x01, 0x22, 0x21, 0x7f, 0xd3, 0x8c, 0xf0, 0xb2, -0x4c, 0xe3, 0x97, 0x7e, 0xeb, 0x71, 0xb0, 0x24, -0x54, 0xcd, 0x51, 0x30, 0xdf, 0x1c, 0x4f, 0xb3, -0x2a, 0xbf, 0xbf, 0x22, 0x68, 0xea, 0x8d, 0x32, -0x77, 0xaf, 0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc9, 0x01, 0x22, 0x21, 0xc1, 0x85, 0xd2, -0x93, 0x41, 0x4c, 0x4f, 0xeb, 0xc4, 0x5b, 0xbb, -0x85, 0xfc, 0xb4, 0xe2, 0x4d, 0x1b, 0x0c, 0x83, -0x98, 0x22, 0xbe, 0x5a, 0xb4, 0xad, 0x16, 0x84, -0x18, 0x7b, 0xea, 0xbf, 0xf5, 0x00, 0x03, 0x04, +0x21, 0x1e, 0x46, 0x11, 0x7f, 0x01, 0x06, 0x7b, +0x3b, 0xc7, 0x44, 0x93, 0xf9, 0x49, 0x96, 0x1d, +0xc2, 0x65, 0x28, 0x43, 0x69, 0xa6, 0x2f, 0xc8, +0x88, 0xe4, 0xcc, 0xa9, 0x7d, 0x58, 0x67, 0xd3, +0xb6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, +0x01, 0x22, 0x21, 0x29, 0xfd, 0xf0, 0x6d, 0x7b, +0xa7, 0x7e, 0xc6, 0xd8, 0x54, 0xfc, 0x69, 0xe6, +0x94, 0x01, 0x0e, 0x1e, 0x91, 0x1d, 0x37, 0x83, +0x67, 0x3c, 0xfb, 0xe7, 0xdd, 0x15, 0x20, 0x65, +0x2f, 0x03, 0x5c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc9, 0x01, 0x22, 0x21, 0x4e, 0xa4, 0xb5, +0xc2, 0xd4, 0x70, 0xc0, 0xb6, 0x62, 0xfa, 0x21, +0x09, 0x27, 0xfc, 0x1a, 0xb4, 0x6c, 0x23, 0x1a, +0x2f, 0x7c, 0x09, 0x78, 0x57, 0x2a, 0xbd, 0x89, +0xda, 0x9a, 0xd7, 0x16, 0xe8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0xf5, -0xcd, 0x62, 0x29, 0x80, 0x6b, 0x5b, 0xb4, 0xf8, -0x8c, 0x93, 0xe9, 0xa3, 0x8e, 0x14, 0x64, 0x18, -0x1b, 0xe8, 0x5c, 0xb7, 0xaa, 0xa9, 0x0f, 0x17, -0xd7, 0xb2, 0x4d, 0x42, 0x9c, 0x99, 0x13, 0x00, +0x72, 0x36, 0x44, 0x46, 0xe9, 0xa3, 0x26, 0xb0, +0x78, 0x11, 0x35, 0x6d, 0x45, 0x6b, 0x1f, 0x76, +0xa6, 0xb6, 0x1d, 0x06, 0x9f, 0x7c, 0x80, 0x21, +0x2a, 0x01, 0xfe, 0x26, 0x0d, 0xea, 0x23, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcb, 0x01, 0x22, -0x21, 0x66, 0x8b, 0xb1, 0x6f, 0x57, 0xf1, 0x77, -0x9a, 0x75, 0x5f, 0x20, 0x65, 0x86, 0xbb, 0x42, -0xd9, 0xa1, 0xe7, 0x0f, 0xd5, 0xfb, 0xff, 0xba, -0x96, 0xd5, 0xe8, 0x55, 0x34, 0xd0, 0xae, 0x23, -0xfd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, -0x01, 0x22, 0x21, 0x5c, 0x23, 0x0f, 0x54, 0x62, -0x34, 0x67, 0x57, 0xa9, 0x9e, 0x00, 0xa6, 0xf4, -0x61, 0xcd, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xb4, 0xbb, 0x9c, 0x43, -0x1f, 0x3c, 0xd6, 0x9b, 0x03, 0x04, 0x51, 0x02, -0x00, 0xcd, 0x01, 0x22, 0x21, 0x53, 0xc5, 0xb4, -0x10, 0x0d, 0x75, 0xe1, 0x56, 0x24, 0xb3, 0x46, -0x45, 0xe9, 0x0d, 0xeb, 0xd7, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0xe3, -0x8b, 0x4a, 0xd1, 0x36, 0x8a, 0x6a, 0x03, 0x04, -0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0x0b, -0xc0, 0x8a, 0xc4, 0x32, 0xc3, 0x9a, 0x46, 0x31, -0xee, 0x19, 0x17, 0x98, 0x02, 0x4b, 0x3c, 0x42, -0x73, 0x28, 0x12, 0x3b, 0xcb, 0xef, 0x5d, 0x59, -0x8a, 0xbf, 0x9b, 0x50, 0x38, 0x56, 0xf8, 0x00, +0x21, 0x70, 0x5d, 0xca, 0x97, 0xa3, 0x40, 0xa5, +0x4e, 0x92, 0x76, 0xba, 0xba, 0xc7, 0x58, 0x74, +0x69, 0xc6, 0x27, 0x42, 0xde, 0x8f, 0x02, 0xd4, +0x7a, 0x7d, 0x4b, 0xd1, 0xa5, 0x13, 0x5f, 0x45, +0xea, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, +0x01, 0x22, 0x21, 0xf2, 0xdf, 0x4b, 0x17, 0x24, +0xc5, 0x92, 0x4a, 0xc4, 0x01, 0x35, 0x02, 0x8b, +0x4d, 0x79, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x0d, 0x78, 0x4c, 0x47, +0xe3, 0x26, 0xa7, 0x79, 0x03, 0x04, 0x51, 0x02, +0x00, 0xcd, 0x01, 0x22, 0x21, 0x70, 0xb9, 0x32, +0xdc, 0xa9, 0x95, 0xab, 0x62, 0xb1, 0x98, 0xa8, +0x04, 0x47, 0xcd, 0x6e, 0xe8, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x22, +0xea, 0x44, 0x3b, 0xd3, 0xce, 0xc4, 0x03, 0x04, +0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0xbe, +0x5d, 0x43, 0xda, 0x51, 0xb0, 0x04, 0x4e, 0xa6, +0x49, 0x2b, 0xf1, 0x25, 0xe2, 0xf2, 0xe4, 0x99, +0x31, 0x39, 0xcd, 0xf3, 0x5c, 0x7e, 0x61, 0xe9, +0x2f, 0xf6, 0x3c, 0xdf, 0x20, 0xe4, 0xf2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcf, 0x01, 0x22, -0x21, 0x13, 0xb8, 0x63, 0x97, 0x53, 0x43, 0xa2, -0xb5, 0x1f, 0x27, 0xb7, 0x64, 0xb8, 0xb6, 0x20, -0x5d, 0xb4, 0x50, 0x4e, 0x29, 0x04, 0xae, 0xd4, -0x41, 0x58, 0xff, 0xe8, 0x62, 0x59, 0xe3, 0x2c, -0x20, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, -0x01, 0x22, 0x21, 0xe2, 0x5f, 0x2d, 0x3f, 0x9e, -0x15, 0x04, 0xb3, 0xca, 0xb0, 0xe4, 0x7a, 0xc1, -0xc5, 0x1c, 0xf3, 0x43, 0x20, 0xca, 0xca, 0x90, -0x31, 0x3b, 0x2a, 0xda, 0x2d, 0x69, 0x48, 0x45, -0xc7, 0xeb, 0x85, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd1, 0x01, 0x22, 0x21, 0xb5, 0x10, 0x3b, -0x96, 0x3a, 0x05, 0x74, 0xbd, 0xbd, 0xea, 0x4f, -0xb5, 0x81, 0x99, 0x18, 0xf2, 0x3b, 0xd6, 0xc1, -0x42, 0xcf, 0xc4, 0xe5, 0x6a, 0x61, 0x86, 0x98, -0x0a, 0x4d, 0xf1, 0x5c, 0x43, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x6d, -0xd2, 0x8d, 0x9e, 0xcb, 0x7e, 0xb3, 0x29, 0x80, -0x3e, 0xcc, 0xce, 0x8a, 0xd1, 0x33, 0xd0, 0xc3, -0xa8, 0xcd, 0xcd, 0xcb, 0xfb, 0xec, 0xb1, 0x0c, -0x6f, 0x9a, 0x3b, 0x8b, 0x2b, 0x6b, 0x50, 0x00, +0x21, 0x1a, 0x39, 0xe4, 0xf3, 0xf2, 0x0a, 0x7e, +0x1f, 0x6c, 0xe2, 0xbf, 0x62, 0x4e, 0xf5, 0xe5, +0xb3, 0xa1, 0xb4, 0x2f, 0xa2, 0x97, 0x52, 0xb1, +0x61, 0xcc, 0x1c, 0xb2, 0x06, 0x97, 0xb4, 0x57, +0x2a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, +0x01, 0x22, 0x21, 0x25, 0x8d, 0x65, 0x50, 0x16, +0x86, 0x39, 0x36, 0xb3, 0x21, 0xc8, 0x64, 0xb3, +0x37, 0x4f, 0x09, 0xc4, 0x53, 0x6a, 0xaf, 0xb8, +0xd9, 0x05, 0xd6, 0xdc, 0x06, 0x30, 0x2f, 0x18, +0x93, 0xa1, 0x77, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd1, 0x01, 0x22, 0x21, 0xb5, 0xbb, 0xdb, +0xaa, 0x25, 0x97, 0x6e, 0x8c, 0xc9, 0x29, 0xba, +0x85, 0x7e, 0x0b, 0xb6, 0x2c, 0x74, 0x49, 0xb4, +0x1e, 0x82, 0x15, 0x7d, 0x79, 0xfc, 0x7a, 0x36, +0xaf, 0xa8, 0x61, 0x05, 0xae, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0xa0, +0x1a, 0x9a, 0xec, 0xb2, 0xec, 0xa0, 0x9e, 0x59, +0xcc, 0x9d, 0xce, 0x76, 0xad, 0xa2, 0xce, 0xf6, +0x68, 0x24, 0xf9, 0x8c, 0x1e, 0x56, 0x6d, 0x86, +0x94, 0xb0, 0x82, 0x88, 0x1e, 0x82, 0xfd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd3, 0x01, 0x22, -0x21, 0x4b, 0xca, 0x32, 0x46, 0x94, 0x72, 0x39, -0x72, 0x24, 0x94, 0x27, 0x6c, 0x3f, 0x44, 0xf4, -0x71, 0x60, 0x8a, 0x53, 0xe4, 0x10, 0x7d, 0x88, -0x85, 0x51, 0x2c, 0x23, 0xb6, 0x56, 0x5a, 0x72, -0x4a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, -0x01, 0x22, 0x21, 0xdf, 0x30, 0xc9, 0x23, 0x0d, -0x59, 0x00, 0x34, 0x59, 0xcf, 0xa0, 0x3c, 0x5a, -0xc7, 0x94, 0x42, 0xb6, 0x32, 0xe1, 0x41, 0x9b, -0x2b, 0x1d, 0x4d, 0xae, 0x24, 0x6f, 0xbb, 0xc6, -0x8e, 0xb6, 0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd5, 0x01, 0x22, 0x21, 0x04, 0xd7, 0xe5, -0xc3, 0x30, 0xa3, 0x54, 0xf5, 0x0b, 0x69, 0xb7, -0x75, 0x9d, 0x0a, 0xef, 0x9a, 0xa9, 0x87, 0x73, -0xbb, 0xc5, 0xa8, 0xb5, 0xa1, 0xa9, 0x6a, 0xd3, -0x55, 0xf0, 0xcb, 0xfa, 0x14, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0x22, -0x0b, 0x90, 0x23, 0xcd, 0x43, 0xe2, 0x88, 0x2e, -0xab, 0x06, 0x2b, 0x12, 0xed, 0x23, 0x0f, 0x4f, -0x44, 0x64, 0x64, 0x65, 0x00, 0x42, 0xeb, 0xf8, -0x89, 0xe4, 0xfe, 0x59, 0x44, 0x85, 0xbf, 0x00, +0x21, 0xfd, 0x6a, 0xeb, 0x71, 0x04, 0x50, 0x12, +0x99, 0x93, 0xc2, 0x1f, 0x2f, 0x1c, 0x56, 0x0e, +0xd1, 0xf9, 0x49, 0xc5, 0xbd, 0x8b, 0xab, 0x6f, +0xab, 0x5a, 0xb4, 0x6f, 0x67, 0xd3, 0x51, 0x9a, +0xc7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, +0x01, 0x22, 0x21, 0x0f, 0x29, 0x15, 0x9a, 0xa4, +0x1e, 0x8a, 0x63, 0x2b, 0xdb, 0x5a, 0x51, 0x3f, +0xd8, 0x0a, 0x55, 0x57, 0xeb, 0xd3, 0xbe, 0x2c, +0x70, 0x4c, 0x14, 0xe3, 0xcb, 0x8a, 0x0b, 0x4e, +0xc0, 0xeb, 0xfe, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd5, 0x01, 0x22, 0x21, 0x13, 0xab, 0x39, +0x24, 0x59, 0xbd, 0x27, 0x88, 0x0d, 0x46, 0x2b, +0x58, 0x46, 0xbb, 0x44, 0xcc, 0xc1, 0x3d, 0x21, +0x82, 0xe1, 0x5b, 0xad, 0x54, 0x5d, 0xaa, 0x17, +0xfb, 0x50, 0xda, 0x3a, 0x79, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0x82, +0x79, 0x03, 0xa9, 0x90, 0x97, 0x62, 0x28, 0x2e, +0x9c, 0x33, 0x48, 0x54, 0x83, 0x56, 0x70, 0x6a, +0xe1, 0x1b, 0x7b, 0xda, 0x23, 0x7a, 0xa9, 0x6b, +0xdc, 0x50, 0xb8, 0x35, 0x98, 0xdd, 0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd7, 0x01, 0x22, -0x21, 0x82, 0x9e, 0xf8, 0x13, 0x20, 0xd0, 0x31, -0xeb, 0xef, 0x96, 0x94, 0x85, 0x26, 0x9d, 0x18, -0x55, 0xf2, 0x76, 0x05, 0x33, 0xc7, 0xbe, 0xc4, -0xe6, 0x45, 0x2e, 0xe1, 0x63, 0x2f, 0xb4, 0xdb, -0x46, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, -0x01, 0x22, 0x21, 0x55, 0x72, 0xff, 0x71, 0x55, -0x60, 0x60, 0x3f, 0xe7, 0xea, 0x5e, 0x59, 0x5e, -0x73, 0xfd, 0x0a, 0x42, 0xc2, 0x7d, 0xc6, 0x48, -0xfb, 0x82, 0x2a, 0xa6, 0xd5, 0x88, 0x4c, 0x61, -0xca, 0x66, 0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd9, 0x01, 0x22, 0x21, 0x87, 0x0a, 0x55, -0x7a, 0x34, 0xd9, 0x57, 0xc1, 0x9d, 0xc8, 0xeb, -0xf6, 0x2c, 0x67, 0x4c, 0xfa, 0x34, 0xbe, 0xd4, -0x65, 0xb1, 0xa9, 0x35, 0xbb, 0xca, 0x29, 0x3e, -0xb7, 0x82, 0x97, 0xc7, 0xf7, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0xeb, -0x53, 0x7b, 0x9d, 0xcb, 0x9e, 0xb6, 0xbe, 0x15, -0xdc, 0x94, 0xb2, 0x6e, 0x6a, 0x07, 0x93, 0xc3, -0x8d, 0xc7, 0x5b, 0xee, 0x31, 0x2e, 0x46, 0xf7, -0xb1, 0x35, 0x1a, 0x9a, 0x2a, 0x7b, 0x0e, 0x00, +0x21, 0x58, 0x73, 0x79, 0xb0, 0x26, 0x97, 0xd9, +0xa3, 0x10, 0x84, 0xaf, 0x4c, 0x54, 0x38, 0xef, +0x53, 0xeb, 0xb9, 0x63, 0xef, 0x34, 0xdc, 0xfa, +0x6e, 0x92, 0x6d, 0xf5, 0xa0, 0x36, 0xab, 0xae, +0xac, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, +0x01, 0x22, 0x21, 0xab, 0xc6, 0x30, 0xf7, 0xd6, +0x9a, 0x0e, 0x48, 0x41, 0xd3, 0x65, 0xe4, 0x89, +0xe2, 0x76, 0xee, 0x13, 0x14, 0x06, 0x9a, 0x57, +0xca, 0x34, 0x94, 0xee, 0xd9, 0x44, 0x06, 0x4d, +0x99, 0xba, 0x78, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd9, 0x01, 0x22, 0x21, 0x0d, 0x88, 0x5a, +0x69, 0x07, 0x05, 0xce, 0xf4, 0x6e, 0xb6, 0x20, +0xd2, 0xda, 0x6b, 0xf7, 0x4f, 0x5b, 0xe4, 0x7f, +0xeb, 0xe5, 0xdc, 0x7c, 0x5a, 0x0c, 0x21, 0x46, +0xb2, 0x8d, 0x2b, 0x0d, 0xcb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0x3a, +0x8d, 0x23, 0x1a, 0xd5, 0xc7, 0xb4, 0x70, 0xe2, +0x7f, 0xd6, 0xf2, 0xa2, 0x56, 0x47, 0x45, 0xce, +0x6d, 0x7c, 0x61, 0xc7, 0x86, 0xf5, 0x52, 0xef, +0x43, 0x92, 0x92, 0x18, 0x7b, 0x68, 0xe8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdb, 0x01, 0x22, -0x21, 0x34, 0x5d, 0x84, 0x29, 0x24, 0xfc, 0xab, -0x0f, 0x76, 0x4c, 0xff, 0x2e, 0x4b, 0x33, 0x48, -0x4a, 0x17, 0x01, 0x0d, 0x20, 0xae, 0x3b, 0x3b, -0x94, 0x8d, 0xaf, 0x41, 0x51, 0xf6, 0xc6, 0x65, -0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, -0x01, 0x22, 0x21, 0xfd, 0xaa, 0xc3, 0x9c, 0x0e, -0x23, 0x57, 0x1e, 0xc5, 0xda, 0xe4, 0x0c, 0xea, -0x0d, 0x4b, 0x48, 0xbf, 0x29, 0xad, 0x03, 0xc5, -0x20, 0xc3, 0x81, 0x34, 0xec, 0x48, 0x61, 0x1b, -0x38, 0xef, 0xb8, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xdd, 0x01, 0x22, 0x21, 0xa1, 0xf3, 0xdb, -0x4f, 0xcb, 0xbe, 0xc2, 0xc9, 0x15, 0x31, 0x6c, -0x45, 0x61, 0x4a, 0x72, 0x27, 0x6b, 0x6b, 0xd4, -0x56, 0x18, 0x10, 0x6a, 0x03, 0x39, 0x5b, 0x57, -0x98, 0xab, 0x80, 0x7c, 0x4f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0xc1, -0xe2, 0x4b, 0xa1, 0xa1, 0x44, 0x23, 0xba, 0x78, -0xbc, 0xa8, 0xc9, 0x0f, 0x25, 0xfa, 0x27, 0x24, -0x5c, 0xff, 0x53, 0x36, 0x13, 0xb1, 0x2c, 0x93, -0xb3, 0xc0, 0x9b, 0x5c, 0x74, 0xb2, 0x91, 0x00, +0x21, 0x71, 0x41, 0x09, 0xd0, 0xf0, 0x7a, 0xac, +0x5b, 0xd8, 0x23, 0xc0, 0x4a, 0x55, 0x95, 0x60, +0x70, 0x51, 0x05, 0x09, 0xf0, 0xc6, 0xb2, 0x49, +0x97, 0x2b, 0xff, 0x8d, 0xf6, 0x3f, 0xfe, 0xa1, +0x9d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, +0x01, 0x22, 0x21, 0xfd, 0x3e, 0xcb, 0x5d, 0xcd, +0x6d, 0x5b, 0xa6, 0x31, 0x25, 0xbe, 0xc3, 0x0b, +0xfc, 0xa9, 0x8e, 0xe8, 0xe2, 0xb3, 0xdd, 0x9d, +0x8d, 0x13, 0xd7, 0xa9, 0x61, 0xec, 0xa8, 0x41, +0xfc, 0x29, 0x11, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xdd, 0x01, 0x22, 0x21, 0xd2, 0x7c, 0x8a, +0x19, 0x49, 0x52, 0x40, 0x82, 0x14, 0x31, 0xbe, +0x8d, 0xd8, 0x0a, 0x73, 0x03, 0xa8, 0x1b, 0x4d, +0x17, 0x9d, 0xb5, 0x4e, 0xb7, 0x8c, 0x54, 0x64, +0xb4, 0x34, 0x4c, 0xe5, 0x36, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0xc9, +0x1b, 0x73, 0x06, 0x8a, 0x80, 0x0d, 0x1e, 0x21, +0xe7, 0x4b, 0x20, 0x60, 0x22, 0x10, 0xe7, 0x9e, +0xd4, 0xaa, 0xcb, 0x04, 0x2c, 0x4a, 0xf5, 0x96, +0xcb, 0x7d, 0x34, 0xe2, 0x7e, 0xbf, 0x74, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdf, 0x01, 0x22, -0x21, 0x6b, 0x03, 0x15, 0x41, 0xf3, 0x90, 0x63, -0xf4, 0xff, 0xec, 0xb6, 0x42, 0x27, 0x8b, 0xcc, -0xd5, 0x71, 0x0e, 0x7d, 0x82, 0x98, 0x8e, 0x0f, -0x4e, 0x58, 0xef, 0x66, 0xa7, 0x26, 0x45, 0x89, -0x9a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, -0x01, 0x22, 0x21, 0x4b, 0x9f, 0xcf, 0x07, 0xc8, -0x61, 0xf9, 0xcb, 0x5c, 0x45, 0x8c, 0xb7, 0x62, -0xdd, 0xea, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xa0, 0xd7, 0x6f, 0xe5, -0x66, 0xd6, 0xd8, 0x02, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe1, 0x01, 0x22, 0x21, 0xae, 0x57, 0x06, -0xc2, 0xc0, 0x45, 0x3e, 0x6c, 0x1f, 0x40, 0x0c, -0x78, 0xbf, 0x35, 0x9f, 0x09, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x13, -0x48, 0xa1, 0x89, 0xbd, 0xdf, 0xb7, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0xa9, -0x2f, 0xd8, 0xb5, 0x6a, 0xa4, 0x4f, 0xab, 0xfb, -0xf7, 0xb1, 0xf4, 0x9c, 0xfe, 0x51, 0xf6, 0x10, -0xf9, 0x3d, 0x14, 0x2b, 0x36, 0x19, 0xca, 0x81, -0xff, 0x52, 0x0f, 0xb9, 0xda, 0x83, 0x48, 0x00, +0x21, 0x5c, 0xa4, 0xaa, 0x2c, 0x26, 0xdf, 0x9d, +0x8f, 0xab, 0xfb, 0x38, 0x64, 0x82, 0xfc, 0x16, +0x90, 0x68, 0xea, 0x3d, 0x84, 0x89, 0x49, 0xff, +0x57, 0x11, 0x63, 0x02, 0x22, 0x88, 0x91, 0xce, +0x0b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, +0x01, 0x22, 0x21, 0x5f, 0x89, 0x36, 0x71, 0xcb, +0xff, 0xa0, 0x9e, 0xf3, 0x37, 0x16, 0x4e, 0x3a, +0x62, 0x5f, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xa7, 0xa0, 0x82, 0xee, +0xf7, 0x99, 0xbd, 0x40, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe1, 0x01, 0x22, 0x21, 0xdb, 0xea, 0x01, +0x9a, 0xaf, 0xed, 0xc7, 0xd2, 0x8a, 0xe9, 0xbd, +0xdb, 0x94, 0x0b, 0x08, 0x18, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x4d, +0xd4, 0x49, 0x10, 0x98, 0x38, 0x7b, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0xfe, +0x30, 0xe7, 0x32, 0xc5, 0x3b, 0xaf, 0x8f, 0xe0, +0x91, 0xf5, 0xdb, 0xac, 0xcc, 0x9d, 0xc9, 0x72, +0x48, 0x2b, 0xf6, 0x30, 0x31, 0x79, 0x9a, 0x9f, +0xca, 0xd9, 0xde, 0x12, 0xb9, 0x98, 0xe4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe3, 0x01, 0x22, -0x21, 0x51, 0xc8, 0xc3, 0x62, 0x2e, 0x92, 0x10, -0xfc, 0xe2, 0xfa, 0xb9, 0xb7, 0xa4, 0x73, 0xd0, -0x4f, 0x9c, 0x5d, 0x54, 0x5d, 0x38, 0x84, 0x69, -0x29, 0xae, 0xcc, 0xcd, 0x80, 0x9f, 0x4f, 0x0a, -0xd1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, -0x01, 0x22, 0x21, 0x90, 0x53, 0x42, 0xf6, 0x6a, -0x18, 0x23, 0xbc, 0x0c, 0xc2, 0xee, 0x79, 0xc5, -0x6a, 0xa1, 0xe7, 0xa3, 0xbe, 0x75, 0x6e, 0x92, -0xc4, 0x8a, 0x93, 0x2e, 0x68, 0x13, 0x22, 0xc1, -0x21, 0xc9, 0xe6, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe5, 0x01, 0x22, 0x21, 0xc7, 0x74, 0x79, -0x73, 0x2a, 0x28, 0x59, 0x5c, 0x06, 0x0f, 0x99, -0x9d, 0x6e, 0x2c, 0x16, 0xc0, 0x8e, 0x2d, 0xc1, -0x12, 0x85, 0x83, 0x70, 0xc1, 0x25, 0xec, 0xe9, -0xee, 0xf3, 0xf0, 0xa7, 0xbf, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x9b, -0x37, 0xd9, 0xc8, 0x66, 0xf7, 0xdb, 0x90, 0x4c, -0xbd, 0x24, 0x8a, 0x52, 0xd2, 0xe0, 0x55, 0x33, -0x78, 0x93, 0x8d, 0x27, 0x25, 0xcb, 0xc3, 0x94, -0x67, 0x9b, 0x56, 0x35, 0x7e, 0x5b, 0x5e, 0x00, +0x21, 0x69, 0xa2, 0xd2, 0x44, 0x6a, 0x91, 0xd9, +0x2f, 0x15, 0x97, 0x97, 0xec, 0xda, 0x50, 0x1b, +0xb2, 0x9f, 0x2d, 0xf6, 0x72, 0xba, 0x68, 0xab, +0xa8, 0x7e, 0x7b, 0x7a, 0x36, 0xea, 0x79, 0xb7, +0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, +0x01, 0x22, 0x21, 0x7c, 0xd5, 0x2a, 0xb5, 0xf3, +0x23, 0x54, 0x78, 0x15, 0x8a, 0xd9, 0xe5, 0x25, +0xf0, 0x00, 0x0f, 0x37, 0x96, 0x17, 0x4d, 0x15, +0xcb, 0x55, 0xa3, 0xa1, 0x10, 0xc7, 0x36, 0x6e, +0x6e, 0x59, 0xee, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe5, 0x01, 0x22, 0x21, 0x15, 0xb9, 0x30, +0x62, 0xc3, 0x08, 0x30, 0x98, 0x15, 0x40, 0x4a, +0xc9, 0x4d, 0xaf, 0x7f, 0xc9, 0x62, 0xee, 0xb0, +0xa1, 0x29, 0xfc, 0x14, 0x58, 0x31, 0x83, 0x72, +0x3a, 0x51, 0x9f, 0x75, 0x9d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x8a, +0x63, 0xc8, 0x83, 0x37, 0xb4, 0x06, 0x55, 0x80, +0xe0, 0x80, 0x71, 0x69, 0x0f, 0x37, 0x66, 0xa3, +0x8d, 0x38, 0xba, 0x22, 0xab, 0x39, 0x78, 0x6d, +0x1b, 0x33, 0x01, 0x04, 0x4e, 0xbc, 0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe7, 0x01, 0x22, -0x21, 0x6d, 0xa6, 0xcb, 0xfe, 0xfd, 0x0e, 0xfb, -0x05, 0xe8, 0x59, 0x60, 0xbf, 0x70, 0xd4, 0x94, -0x85, 0x50, 0x3d, 0x72, 0xef, 0xd5, 0xaa, 0x91, -0xd9, 0x8f, 0xf3, 0x47, 0x2e, 0x5d, 0xd6, 0x01, -0xeb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, -0x01, 0x22, 0x21, 0x94, 0x6d, 0x3d, 0x46, 0xe6, -0xdd, 0x49, 0xed, 0x28, 0x63, 0x8d, 0xf8, 0xad, -0xe7, 0x9c, 0x37, 0x58, 0xae, 0xe4, 0xe4, 0x19, -0xfe, 0x6a, 0xa7, 0x6f, 0x7f, 0x05, 0xb0, 0x1c, -0xb0, 0xd3, 0xab, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe9, 0x01, 0x22, 0x21, 0x50, 0x59, 0xe3, -0x14, 0x9f, 0xb9, 0x3d, 0xda, 0x2a, 0xd1, 0xdc, -0x01, 0xc7, 0x7f, 0x63, 0x42, 0xde, 0x04, 0xbc, -0xfe, 0xcb, 0x62, 0xd4, 0x10, 0xfb, 0x6f, 0x10, -0xad, 0x9d, 0xc2, 0x02, 0x47, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0x1c, -0x4b, 0x85, 0xfc, 0x51, 0x82, 0x4f, 0x1d, 0x20, -0x1c, 0x12, 0xf8, 0xdb, 0xff, 0x25, 0x81, 0xae, -0x87, 0x76, 0x7f, 0x14, 0x88, 0xcf, 0xef, 0x28, -0xf8, 0xc3, 0xe0, 0xb8, 0x5d, 0x9e, 0x0e, 0x00, +0x21, 0x7c, 0x70, 0xeb, 0x7f, 0x69, 0x2a, 0xcc, +0x6b, 0x02, 0x1d, 0xce, 0x5e, 0x6f, 0x71, 0x85, +0xd2, 0xa1, 0xbd, 0x9c, 0x66, 0x8b, 0x02, 0x1d, +0x38, 0xe4, 0xbc, 0xf2, 0x9c, 0x48, 0x36, 0x69, +0x70, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, +0x01, 0x22, 0x21, 0xb2, 0xdd, 0x4f, 0xc6, 0xe2, +0x4d, 0x9b, 0x0b, 0x97, 0x93, 0xe6, 0x90, 0x76, +0x5f, 0xd6, 0x61, 0x3f, 0x7f, 0x17, 0xff, 0x5c, +0x86, 0x56, 0xd2, 0xf8, 0xbf, 0xe0, 0x96, 0x2c, +0x5c, 0x73, 0xf5, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe9, 0x01, 0x22, 0x21, 0x96, 0x76, 0x6a, +0x06, 0x8d, 0x49, 0xca, 0x7f, 0x57, 0x96, 0x2f, +0x26, 0xdb, 0xa5, 0xf8, 0x47, 0x52, 0xd8, 0x95, +0x8f, 0x8e, 0x9f, 0xcd, 0x6f, 0xb5, 0x53, 0x80, +0x93, 0xf6, 0x4e, 0x34, 0xd9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0xed, +0x09, 0xd2, 0xf9, 0xb9, 0x77, 0xcc, 0xb3, 0x0d, +0xb8, 0x7f, 0x7e, 0x4b, 0xd8, 0x96, 0xd7, 0xca, +0xbf, 0xaa, 0x15, 0xfb, 0xac, 0xb6, 0x02, 0xfe, +0x38, 0x67, 0x75, 0x2b, 0xbc, 0xe7, 0x14, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xeb, 0x01, 0x22, -0x21, 0x32, 0x80, 0xd9, 0x3c, 0x45, 0xf8, 0xa5, -0xa9, 0x12, 0x6b, 0x50, 0xc5, 0x94, 0x86, 0xdf, -0x6e, 0x41, 0xbb, 0x90, 0xca, 0x45, 0x43, 0xbd, -0x0f, 0x92, 0x8a, 0xcf, 0x85, 0xe0, 0x82, 0x65, -0x6d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, -0x01, 0x22, 0x21, 0xbc, 0x98, 0x03, 0x8f, 0x23, -0x95, 0x38, 0xd6, 0x4d, 0xff, 0xc8, 0x40, 0x89, -0x89, 0x1b, 0xca, 0xb4, 0xa4, 0xe6, 0xe0, 0xff, -0xf7, 0x2e, 0xe1, 0x37, 0x59, 0xd2, 0x52, 0x19, -0xc7, 0x30, 0xc5, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xed, 0x01, 0x22, 0x21, 0xcc, 0x9f, 0xf4, -0x69, 0x32, 0xef, 0xd2, 0xb7, 0x23, 0xde, 0xba, -0xaf, 0x84, 0x5c, 0x84, 0xe8, 0x66, 0x6a, 0x3f, -0x18, 0xe5, 0x4d, 0xe0, 0x24, 0x74, 0x15, 0x51, -0xe8, 0x93, 0xb2, 0x73, 0x0c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0x55, -0x40, 0x6f, 0x2b, 0xdc, 0x7f, 0x36, 0x3f, 0xad, -0x42, 0xe8, 0x1f, 0x27, 0x2a, 0x16, 0x13, 0x38, -0x34, 0x82, 0x23, 0x1c, 0xa7, 0x8f, 0x7d, 0xcb, -0x7e, 0xe2, 0x5c, 0x0b, 0x62, 0x02, 0xf4, 0x00, +0x21, 0x35, 0xf8, 0x7f, 0xc3, 0x36, 0x15, 0x20, +0xc9, 0xa7, 0x25, 0x9e, 0xe3, 0x4e, 0x86, 0x15, +0xf1, 0xbf, 0x82, 0xba, 0x5d, 0x80, 0x83, 0x70, +0x66, 0x6b, 0x6d, 0xfb, 0x77, 0xf1, 0x99, 0xfe, +0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, +0x01, 0x22, 0x21, 0x40, 0xf0, 0x07, 0xcf, 0x9c, +0x5e, 0x81, 0x7f, 0x09, 0x80, 0x84, 0x73, 0xc3, +0x88, 0x37, 0xf3, 0x06, 0x66, 0xdd, 0x9c, 0x02, +0x0d, 0xb5, 0x92, 0x66, 0x18, 0xda, 0xd5, 0x1b, +0x60, 0x7a, 0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xed, 0x01, 0x22, 0x21, 0x47, 0xce, 0x2d, +0x2a, 0xe2, 0x6c, 0x29, 0xe1, 0x19, 0x2e, 0x7b, +0x45, 0x45, 0x45, 0x35, 0xfa, 0x10, 0x68, 0x47, +0xd5, 0x2f, 0x95, 0xb4, 0x3a, 0x5e, 0x19, 0xb9, +0xb1, 0xe8, 0x77, 0x38, 0x81, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0xca, +0x6c, 0x50, 0x99, 0x7c, 0x2a, 0x89, 0xea, 0x8c, +0xab, 0x2f, 0xed, 0x46, 0x08, 0x10, 0xa8, 0xd5, +0x55, 0x6c, 0xce, 0xb9, 0xa4, 0x36, 0xcd, 0xf9, +0xe8, 0x94, 0x02, 0x6c, 0x5d, 0xcb, 0xc2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xef, 0x01, 0x22, -0x21, 0x85, 0x4f, 0xb1, 0x36, 0x43, 0x79, 0x5e, -0xf0, 0x49, 0x50, 0x55, 0x1a, 0x32, 0xd3, 0xc7, -0xf4, 0x67, 0x59, 0x05, 0xcd, 0x85, 0xf8, 0x9c, -0xc1, 0x17, 0x85, 0xd6, 0x8c, 0x89, 0xe6, 0x84, -0x55, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, -0x01, 0x22, 0x21, 0x32, 0xef, 0xfa, 0x53, 0xab, -0x47, 0x41, 0x6a, 0x8d, 0x44, 0x88, 0x10, 0x03, -0x76, 0x21, 0xac, 0x43, 0x50, 0xf8, 0x0b, 0xda, -0x4f, 0x61, 0x65, 0x4e, 0x5e, 0xfb, 0x02, 0x37, -0x51, 0x3a, 0xea, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf1, 0x01, 0x22, 0x21, 0x9d, 0x69, 0xca, -0xd1, 0xc9, 0x29, 0x82, 0xf7, 0xe6, 0xce, 0xf4, -0x73, 0x9c, 0x6a, 0x20, 0x58, 0x9f, 0xe7, 0xf2, -0x14, 0x17, 0x62, 0x19, 0xaf, 0xcd, 0x53, 0x2f, -0xcb, 0x65, 0xf2, 0xa1, 0x3d, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0xf1, -0xe2, 0x9a, 0x27, 0xf5, 0x34, 0xe7, 0xda, 0x03, -0x17, 0xf8, 0x61, 0xe5, 0x8e, 0x8f, 0x35, 0xc9, -0xf0, 0xfc, 0xc2, 0xc8, 0xb5, 0x00, 0x34, 0x1e, -0x45, 0x99, 0xe9, 0xeb, 0x69, 0x9e, 0x78, 0x00, +0x21, 0xad, 0x68, 0x11, 0x56, 0xbc, 0x31, 0xfc, +0x99, 0x19, 0x82, 0x38, 0xbb, 0xf2, 0xc3, 0xcb, +0x92, 0xc2, 0x7e, 0xfc, 0x86, 0x04, 0x10, 0x8a, +0xba, 0xde, 0x85, 0xcc, 0xf3, 0x34, 0xb9, 0xb5, +0x6a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, +0x01, 0x22, 0x21, 0x98, 0x52, 0x2a, 0x42, 0x28, +0x39, 0xbc, 0x68, 0xc4, 0xb0, 0x4a, 0x9c, 0x78, +0xc4, 0xd1, 0x31, 0x4f, 0x64, 0x52, 0x2d, 0x56, +0x3b, 0x25, 0x58, 0xce, 0xeb, 0x2d, 0x4e, 0x1a, +0x9c, 0xdf, 0x24, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf1, 0x01, 0x22, 0x21, 0x19, 0xe2, 0xf2, +0x6f, 0xa5, 0x6d, 0x63, 0xd3, 0xa2, 0x40, 0x1b, +0x90, 0x17, 0x5f, 0xd8, 0x62, 0x2c, 0xcd, 0x59, +0xac, 0xf1, 0x7a, 0x15, 0x3c, 0xf3, 0xad, 0x80, +0xcd, 0xf2, 0x5c, 0x76, 0x11, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0xdb, +0x49, 0x58, 0xc1, 0xaf, 0xec, 0x8f, 0x51, 0x23, +0xf1, 0x54, 0xa7, 0xbe, 0x63, 0xc4, 0x2b, 0xb1, +0x47, 0x47, 0x99, 0x5b, 0x8f, 0xe9, 0xe3, 0x3f, +0xc4, 0xa1, 0x70, 0xd2, 0xe2, 0x7e, 0xb7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf3, 0x01, 0x22, -0x21, 0x1a, 0x6c, 0x2e, 0x15, 0x9a, 0xa8, 0x34, -0xce, 0xde, 0x4d, 0x9d, 0x20, 0xfb, 0x7e, 0xf1, -0x1c, 0xcb, 0x75, 0x4a, 0x80, 0x87, 0xe1, 0xc5, -0xd2, 0x3d, 0x5e, 0x5c, 0x79, 0xf2, 0x09, 0x63, -0x76, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, -0x01, 0x22, 0x21, 0x17, 0x0a, 0x79, 0x66, 0x3e, -0xf8, 0x5b, 0x90, 0x8a, 0xa5, 0xd7, 0xdc, 0x64, -0x25, 0x9f, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xf7, 0xac, 0xa6, 0xe7, -0x36, 0xf3, 0x57, 0x6e, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf5, 0x01, 0x22, 0x21, 0x80, 0xfc, 0x05, -0xf0, 0x83, 0x79, 0x6d, 0x01, 0x0b, 0x00, 0xb0, -0x2b, 0x25, 0xcd, 0xa6, 0x11, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x22, -0x25, 0x85, 0xbc, 0x39, 0xd3, 0x1b, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0x94, -0x9b, 0x17, 0xa9, 0xbf, 0x5d, 0x72, 0x67, 0x2a, -0xcb, 0xaf, 0xc7, 0x57, 0xb4, 0xd0, 0xce, 0xc4, -0x4c, 0x69, 0xb8, 0x10, 0x09, 0x61, 0x70, 0x4e, -0x87, 0x0c, 0xf3, 0x26, 0x4a, 0x65, 0x43, 0x00, +0x21, 0x51, 0xe7, 0x71, 0x58, 0x48, 0xc2, 0x89, +0x69, 0xa2, 0x50, 0x97, 0xc9, 0xbe, 0x12, 0xcd, +0x79, 0x8d, 0x7a, 0xce, 0xbe, 0xa1, 0x76, 0xb1, +0xa7, 0x25, 0x5b, 0xb7, 0x8b, 0x14, 0xde, 0x7a, +0xf5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, +0x01, 0x22, 0x21, 0x07, 0xfe, 0x99, 0x7c, 0x02, +0xc3, 0x45, 0x27, 0x55, 0xa8, 0x7c, 0x46, 0x41, +0xa2, 0x49, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xf2, 0x61, 0x71, 0xda, +0x48, 0x32, 0xd2, 0x1c, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf5, 0x01, 0x22, 0x21, 0xa4, 0x8d, 0x9b, +0x61, 0xb2, 0x03, 0x1e, 0x1f, 0x34, 0xe0, 0x8f, +0x27, 0x78, 0xa7, 0x7c, 0xa6, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x72, +0xdd, 0x91, 0x1f, 0xf6, 0xbc, 0xab, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0x3e, +0xef, 0x94, 0x14, 0xff, 0x01, 0x1c, 0x15, 0x4b, +0x6b, 0x77, 0x8c, 0x78, 0xde, 0x62, 0x09, 0x28, +0x49, 0xd9, 0xac, 0xa6, 0xed, 0x96, 0xaf, 0xaf, +0x45, 0x2e, 0xf4, 0x30, 0x65, 0xd3, 0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf7, 0x01, 0x22, -0x21, 0x2e, 0x6c, 0x40, 0xed, 0xff, 0xb5, 0xda, -0x0e, 0x2e, 0xea, 0x62, 0xba, 0xc6, 0xca, 0xd9, -0x58, 0xeb, 0x08, 0x79, 0x55, 0xd5, 0x02, 0xb3, -0x0a, 0x4e, 0xe1, 0x69, 0x2b, 0x4e, 0x79, 0x98, -0xf5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, -0x01, 0x22, 0x21, 0xe8, 0x91, 0xcd, 0x47, 0x32, -0x6c, 0x34, 0x4c, 0x9b, 0x64, 0x67, 0x0b, 0x77, -0xa9, 0xdd, 0xf7, 0xab, 0xc7, 0x0b, 0x46, 0xcf, -0x87, 0x9e, 0xd0, 0xb2, 0x22, 0xc0, 0xb9, 0xcb, -0x36, 0x77, 0xcf, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf9, 0x01, 0x22, 0x21, 0x67, 0x79, 0x27, -0xaf, 0x5b, 0x41, 0x32, 0xf4, 0x31, 0x44, 0x7a, -0x8a, 0xef, 0x67, 0x16, 0x39, 0xde, 0xb0, 0x15, -0x6e, 0xd0, 0xeb, 0xbd, 0x1e, 0xc9, 0x63, 0x8e, -0xd3, 0x82, 0xb6, 0xb3, 0x59, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0x45, -0x6f, 0x2c, 0xe0, 0xeb, 0x55, 0xda, 0x0c, 0xe8, -0xf7, 0x10, 0xa1, 0xf8, 0x78, 0xd0, 0x64, 0x25, -0x95, 0x6e, 0x25, 0x1c, 0x93, 0xf6, 0x58, 0x4f, -0x77, 0xa2, 0x1f, 0x96, 0x1d, 0xe8, 0xd1, 0x00, +0x21, 0x29, 0xea, 0x92, 0x31, 0x67, 0xd3, 0x77, +0xa2, 0x88, 0x67, 0x93, 0xca, 0x89, 0x1e, 0x14, +0xd8, 0x29, 0x39, 0xf9, 0x9d, 0x5c, 0x15, 0x2f, +0x92, 0x8c, 0x09, 0xa6, 0xd3, 0x0f, 0x5b, 0x12, +0x77, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, +0x01, 0x22, 0x21, 0xe4, 0x91, 0xbb, 0xa7, 0x27, +0x1e, 0x6a, 0x64, 0xe4, 0xae, 0x3c, 0x8a, 0x72, +0x89, 0x36, 0x3e, 0xaa, 0x93, 0xbd, 0x2b, 0x1a, +0xe5, 0x1a, 0xca, 0xd0, 0x28, 0x46, 0xbf, 0x04, +0x9d, 0x9c, 0x42, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf9, 0x01, 0x22, 0x21, 0x7e, 0xc8, 0x7c, +0xbd, 0x99, 0x7c, 0x1c, 0x9d, 0x16, 0xba, 0xf7, +0xb2, 0x01, 0xff, 0x10, 0xb6, 0xc2, 0xef, 0x9d, +0x9d, 0x0b, 0xb8, 0xea, 0x9d, 0x9e, 0x9d, 0x6c, +0x4c, 0x91, 0xe0, 0x56, 0x03, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0xd8, +0x58, 0x31, 0x33, 0x23, 0xe3, 0x71, 0xca, 0x0a, +0x79, 0xd5, 0x78, 0x93, 0x38, 0x70, 0x79, 0x2e, +0x26, 0x91, 0x5d, 0x69, 0x53, 0xd3, 0x81, 0xde, +0xff, 0x79, 0x74, 0x54, 0x19, 0xe3, 0x9c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfb, 0x01, 0x22, -0x21, 0x24, 0x8a, 0x62, 0xf6, 0x4f, 0x17, 0x89, -0x54, 0xdb, 0xcc, 0x2a, 0x53, 0x0f, 0x58, 0x2a, -0xd5, 0x95, 0xaf, 0xfe, 0x2f, 0xcc, 0x6b, 0xb9, -0x85, 0xc4, 0xe1, 0x76, 0xe6, 0x6e, 0xeb, 0x2d, -0x66, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, -0x01, 0x22, 0x21, 0x78, 0x0c, 0x48, 0x11, 0x3d, -0xd8, 0xcc, 0xe3, 0x40, 0x79, 0xcf, 0x07, 0x61, -0xb2, 0x80, 0xb9, 0x30, 0xc6, 0x30, 0x7b, 0x75, -0x53, 0x59, 0x8d, 0x9f, 0xfb, 0xaf, 0x3f, 0x5e, -0xdc, 0xa1, 0xe4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xfd, 0x01, 0x22, 0x21, 0xb2, 0xc8, 0xcf, -0x5a, 0x31, 0x0d, 0x93, 0xc1, 0x70, 0x0f, 0xfe, -0x63, 0x02, 0x51, 0xfb, 0x77, 0xbb, 0x83, 0x8d, -0x76, 0xd2, 0x4f, 0x10, 0xd8, 0xb5, 0x4d, 0x53, -0x74, 0xdb, 0x6e, 0xf3, 0xc2, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0xc4, -0x00, 0xa2, 0x44, 0x99, 0x7a, 0x8f, 0xfb, 0x04, -0xf8, 0xad, 0x9b, 0x58, 0xcd, 0xac, 0x1f, 0x8c, -0xa6, 0xa9, 0xad, 0x1a, 0xaa, 0x84, 0xb6, 0x5c, -0x9a, 0x68, 0xc1, 0xf0, 0x5c, 0x56, 0x1c, 0x00, +0x21, 0x26, 0x2e, 0x61, 0x36, 0xc1, 0x11, 0xfe, +0x49, 0x9f, 0x86, 0x4b, 0xb7, 0xf5, 0xf7, 0x4c, +0xa8, 0x67, 0xb4, 0x8c, 0xbc, 0x53, 0x63, 0xcb, +0x01, 0xe6, 0x48, 0x1d, 0x2b, 0x23, 0xd9, 0x68, +0x6d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, +0x01, 0x22, 0x21, 0xef, 0x0f, 0x8d, 0x1e, 0x9c, +0x69, 0x21, 0xd8, 0x88, 0x55, 0xe1, 0x38, 0x5b, +0x60, 0x52, 0xc7, 0xb0, 0xcb, 0xd2, 0x97, 0x7b, +0xc0, 0xde, 0x79, 0xe7, 0x7a, 0xea, 0x52, 0x22, +0xf8, 0x1d, 0xb7, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xfd, 0x01, 0x22, 0x21, 0xe4, 0x9e, 0xac, +0xdf, 0xd7, 0x98, 0x4c, 0xfe, 0x9b, 0x63, 0x08, +0x89, 0x96, 0x29, 0xa2, 0x4f, 0x30, 0xbc, 0xc5, +0xfe, 0x68, 0x82, 0x80, 0xf7, 0x78, 0xca, 0x4e, +0x50, 0x3a, 0xe3, 0x82, 0x3f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0x11, +0x95, 0x9d, 0xaa, 0xd2, 0x53, 0x18, 0x44, 0xde, +0x77, 0x15, 0xb4, 0xf2, 0x09, 0x0e, 0x78, 0x87, +0xc5, 0xd9, 0x4c, 0xfe, 0xd1, 0xd0, 0x22, 0x22, +0x6f, 0xf4, 0xa0, 0x85, 0xe9, 0x11, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xff, 0x01, 0x22, -0x21, 0xeb, 0xe5, 0x5c, 0x16, 0xfd, 0x1e, 0xbb, -0x7e, 0x8b, 0x24, 0x47, 0x6e, 0x96, 0xd7, 0xc7, -0xef, 0xd5, 0x36, 0x8d, 0x2a, 0xff, 0xd5, 0x26, -0x43, 0xf9, 0xd0, 0x31, 0xd1, 0xb4, 0xb3, 0xf0, -0xbf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, -0x01, 0x22, 0x21, 0x8a, 0xfc, 0x37, 0x2e, 0xa2, -0xf7, 0x7d, 0x87, 0x44, 0xa9, 0xe2, 0xb8, 0xfe, -0xf1, 0x31, 0x44, 0xda, 0x27, 0x6a, 0x49, 0xe9, -0x7f, 0xd7, 0xe3, 0xc5, 0xf6, 0x78, 0xd7, 0x82, -0x44, 0x70, 0x90, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x01, 0x01, 0x22, 0x21, 0x7d, 0x66, 0x36, -0xc0, 0x47, 0x3a, 0xea, 0x75, 0x16, 0xa3, 0xdd, -0xf2, 0x56, 0xc3, 0x18, 0xa6, 0x96, 0x60, 0xc8, -0x17, 0x95, 0x5b, 0x89, 0x08, 0x6d, 0xb4, 0xb5, -0x7e, 0x3f, 0x44, 0x53, 0x31, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0xc4, -0xe4, 0x5c, 0x0c, 0xe8, 0xef, 0x8e, 0xc3, 0x40, -0x1c, 0x4e, 0xcc, 0x72, 0xdf, 0xa1, 0x62, 0x7a, -0x0a, 0x37, 0xac, 0x60, 0xae, 0x12, 0x06, 0xe5, -0x25, 0x2d, 0xea, 0xc6, 0xc7, 0x66, 0xd3, 0x00, +0x21, 0xee, 0x6e, 0x9e, 0x5f, 0xf2, 0x79, 0xee, +0x4e, 0x35, 0x24, 0xfe, 0xe8, 0x66, 0xbe, 0xfc, +0xe9, 0x4c, 0x6a, 0xab, 0x4b, 0x54, 0x43, 0x26, +0xeb, 0x95, 0x24, 0xb5, 0x70, 0xd8, 0x2e, 0xef, +0xb7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, +0x01, 0x22, 0x21, 0x64, 0x9d, 0xc9, 0xb5, 0x8f, +0xb3, 0x73, 0x62, 0x0a, 0x64, 0x43, 0x05, 0x84, +0xf6, 0x82, 0x27, 0xb4, 0x66, 0xca, 0xc0, 0xd7, +0x34, 0x9f, 0xc9, 0x5d, 0xd5, 0xc7, 0x3a, 0xd6, +0xd5, 0xba, 0x1e, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x01, 0x01, 0x22, 0x21, 0xc4, 0x90, 0xe9, +0x09, 0x02, 0xf2, 0x64, 0x09, 0x14, 0x2f, 0xbd, +0xcf, 0xea, 0x31, 0xe2, 0x71, 0x80, 0xd8, 0x79, +0x3d, 0xef, 0x91, 0x80, 0xf1, 0xa5, 0xd2, 0xbc, +0x30, 0x31, 0xf8, 0xb0, 0xf8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0x79, +0x49, 0x6c, 0x09, 0x08, 0x22, 0xf6, 0x41, 0x7e, +0x8c, 0xfc, 0x94, 0xf6, 0x6b, 0xfc, 0x2a, 0x51, +0x0a, 0x46, 0xa5, 0xa6, 0xa2, 0xdb, 0x64, 0xba, +0xd7, 0x54, 0x95, 0xaa, 0x55, 0x45, 0x46, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x03, 0x01, 0x22, -0x21, 0xd0, 0x84, 0x71, 0x49, 0xa2, 0x7b, 0x53, -0x0e, 0x22, 0x37, 0xb9, 0x8a, 0x0b, 0xea, 0xf4, -0x15, 0xa1, 0x81, 0xc9, 0xd2, 0x7e, 0x4e, 0xc4, -0xab, 0x54, 0xad, 0x1b, 0xfd, 0xce, 0x52, 0x5f, -0x9f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, -0x01, 0x22, 0x21, 0x14, 0xf8, 0x70, 0x86, 0x81, -0x48, 0x78, 0x31, 0x88, 0xf6, 0xbe, 0x1b, 0xf1, -0xda, 0x2f, 0x41, 0x82, 0x1a, 0x44, 0x4a, 0x3c, -0xf6, 0x33, 0xd0, 0x18, 0xe1, 0x00, 0x94, 0xa1, -0x9e, 0x13, 0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x05, 0x01, 0x22, 0x21, 0xda, 0x64, 0x14, -0x8e, 0x96, 0x5c, 0xcd, 0x49, 0x8d, 0x02, 0xd8, -0xa0, 0x1f, 0x56, 0x78, 0xb9, 0x02, 0x36, 0x55, -0x8c, 0xf5, 0xcc, 0xe8, 0x41, 0xcb, 0xa5, 0x1f, -0x7d, 0xd3, 0xa0, 0xb7, 0x53, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0xb5, -0xe8, 0x68, 0xc7, 0x02, 0x3c, 0x2f, 0x57, 0xc5, -0xcd, 0xf0, 0x68, 0x1d, 0xf3, 0xb3, 0x63, 0xaf, -0xdb, 0xba, 0xd8, 0x6e, 0x0a, 0xbb, 0xf1, 0x84, -0x6a, 0x2f, 0xfd, 0x45, 0x89, 0xa6, 0x48, 0x00, +0x21, 0x39, 0xc4, 0x4b, 0x5a, 0x82, 0x1d, 0xfb, +0xa7, 0x5d, 0x54, 0xb9, 0x2c, 0xd9, 0xdc, 0x59, +0x09, 0x81, 0x53, 0xe6, 0xf1, 0xf5, 0x9b, 0xfb, +0x94, 0x74, 0xec, 0xda, 0xe7, 0xa5, 0xeb, 0xbe, +0xc3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, +0x01, 0x22, 0x21, 0xd3, 0x16, 0x37, 0x28, 0x5b, +0x98, 0x0e, 0x55, 0xb0, 0x2e, 0x99, 0x9f, 0xa7, +0x35, 0x68, 0x68, 0xa8, 0x69, 0x92, 0x92, 0xf5, +0x3d, 0xec, 0x9a, 0x3c, 0x15, 0xb5, 0x9b, 0xdb, +0xdf, 0xfa, 0xd0, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x05, 0x01, 0x22, 0x21, 0x72, 0x2f, 0xc3, +0xc4, 0x20, 0x52, 0x80, 0x41, 0x8e, 0x99, 0xb6, +0x77, 0x56, 0xa0, 0x69, 0x7a, 0xda, 0xff, 0x47, +0xd3, 0x50, 0x8e, 0xa5, 0xbf, 0xd6, 0x91, 0xb1, +0x56, 0xbf, 0x21, 0xd9, 0x0f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0x74, +0x1c, 0x51, 0x97, 0xdd, 0x06, 0xad, 0xbe, 0x88, +0x34, 0x68, 0xb6, 0xe8, 0xe0, 0xe5, 0xdc, 0x64, +0x99, 0x86, 0x93, 0xb2, 0xe7, 0x89, 0xbe, 0x9e, +0xd9, 0x0d, 0x4f, 0x61, 0x28, 0x10, 0x72, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x07, 0x01, 0x22, -0x21, 0x22, 0xa5, 0x9e, 0x88, 0xb5, 0x5d, 0x86, -0x9a, 0x6e, 0xc6, 0x99, 0xec, 0x6e, 0x4d, 0xff, -0xc8, 0x6e, 0xdf, 0x90, 0x6e, 0x26, 0x75, 0x43, -0x67, 0x37, 0xa6, 0xab, 0x97, 0xc2, 0x46, 0x47, -0x2a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, -0x01, 0x22, 0x21, 0x82, 0x01, 0xcf, 0x50, 0x0e, -0x10, 0x48, 0x84, 0x0d, 0xdf, 0x88, 0xc0, 0xe2, -0x18, 0x7a, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x29, 0x2e, 0xb3, 0x5d, -0x7b, 0x60, 0x97, 0xee, 0x03, 0x04, 0x51, 0x02, -0x00, 0x09, 0x01, 0x22, 0x21, 0x70, 0x24, 0xf3, -0x41, 0x69, 0xd0, 0xf7, 0xad, 0x3c, 0x44, 0xd0, -0xd4, 0x9e, 0x9c, 0x89, 0x28, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x32, -0xed, 0x45, 0x15, 0x10, 0xe3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0x9b, -0x3f, 0x51, 0xd3, 0x5d, 0xab, 0x55, 0x25, 0xe9, -0xc8, 0xe7, 0xb5, 0xaa, 0x01, 0xc9, 0xc6, 0xca, -0x73, 0x65, 0x30, 0xdb, 0xa0, 0x51, 0xcf, 0xab, -0xfb, 0xf2, 0xe7, 0xdd, 0x4a, 0xaf, 0xfe, 0x00, +0x21, 0xe2, 0xa4, 0xc3, 0xeb, 0x2c, 0x82, 0xd6, +0xd3, 0x72, 0x85, 0x81, 0x18, 0xc3, 0xd5, 0x41, +0x79, 0x32, 0x82, 0xd6, 0x55, 0x4f, 0x9f, 0x63, +0x1b, 0xf8, 0x87, 0xe0, 0x0e, 0xf9, 0xe4, 0xf0, +0x15, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, +0x01, 0x22, 0x21, 0x71, 0x46, 0xac, 0x6a, 0x02, +0xd2, 0x63, 0x61, 0xe4, 0x1e, 0xb4, 0x82, 0x76, +0x77, 0x69, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1f, 0x1e, 0x2b, 0xff, +0xa9, 0x29, 0xf8, 0xaf, 0x03, 0x04, 0x51, 0x02, +0x00, 0x09, 0x01, 0x22, 0x21, 0xf3, 0xcf, 0x65, +0xe3, 0xc1, 0x87, 0x19, 0x5f, 0x0c, 0xca, 0x51, +0xef, 0xe8, 0xeb, 0xe4, 0xa8, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x52, +0xaa, 0xd6, 0xc9, 0x3f, 0x76, 0xf2, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0xf8, +0xe5, 0x54, 0x43, 0xd7, 0x64, 0x7c, 0x87, 0x8f, +0xc3, 0xe5, 0xb5, 0xc5, 0x75, 0xf9, 0xb6, 0xfb, +0x29, 0xdd, 0x4c, 0x0c, 0x4e, 0x27, 0x75, 0x5c, +0x16, 0x1c, 0x86, 0x82, 0x7e, 0xd5, 0x5b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0b, 0x01, 0x22, -0x21, 0x5d, 0x32, 0x0e, 0x01, 0x49, 0xf1, 0x99, -0x76, 0x59, 0x85, 0xf5, 0xe2, 0xbe, 0x67, 0x40, -0x16, 0x71, 0xbe, 0x0e, 0x8e, 0xad, 0xd8, 0xfb, -0x7b, 0x63, 0xb1, 0xe2, 0x7b, 0xb2, 0x65, 0xe1, -0x91, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, -0x01, 0x22, 0x21, 0x40, 0xc2, 0x7c, 0xc0, 0xaf, -0x0e, 0x4b, 0x0d, 0x3c, 0x9d, 0x36, 0xa9, 0x06, -0x29, 0xe3, 0xa5, 0x4b, 0x67, 0x20, 0x52, 0x1d, -0x6c, 0x39, 0x58, 0x0a, 0xdf, 0xe6, 0x77, 0x59, -0x23, 0x9b, 0x49, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x0d, 0x01, 0x22, 0x21, 0xca, 0x38, 0x2c, -0x7d, 0xd5, 0x10, 0xe4, 0x64, 0x5b, 0x9f, 0x72, -0xd8, 0xcb, 0x76, 0x73, 0xb7, 0x7f, 0x00, 0x1c, -0x5e, 0x25, 0x35, 0xa9, 0x92, 0x4d, 0xfa, 0x22, -0x88, 0xc2, 0xb4, 0x5a, 0xa7, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0xb8, -0xc3, 0xe9, 0xa9, 0xf3, 0x8e, 0x90, 0x6d, 0xa2, -0xc9, 0x8e, 0x6a, 0x61, 0xc6, 0xd6, 0x98, 0x3b, -0x57, 0xa3, 0x1e, 0xe7, 0x80, 0xdc, 0x2a, 0xfe, -0x6e, 0xc2, 0x5b, 0xd7, 0x55, 0x9c, 0xaf, 0x00, +0x21, 0xee, 0x1e, 0x8d, 0x37, 0x88, 0x46, 0xf1, +0x74, 0x6b, 0x7d, 0xaf, 0xe1, 0x1b, 0x59, 0x0f, +0x43, 0xe8, 0xa5, 0xb7, 0xb0, 0x97, 0x51, 0x27, +0xf0, 0x0b, 0x90, 0x02, 0x0f, 0xa3, 0xa4, 0x14, +0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, +0x01, 0x22, 0x21, 0x84, 0x96, 0x87, 0x00, 0x09, +0x39, 0x8c, 0x82, 0x65, 0xda, 0xc4, 0x51, 0xa9, +0x60, 0x2a, 0x53, 0xf3, 0xe4, 0xf2, 0x0c, 0x21, +0x21, 0xce, 0xfa, 0x27, 0x1f, 0x6f, 0x5e, 0xa8, +0x76, 0x5b, 0x66, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x0d, 0x01, 0x22, 0x21, 0x92, 0x84, 0xa6, +0x15, 0x03, 0x2b, 0x7d, 0xca, 0x09, 0x87, 0x87, +0x7a, 0x36, 0x03, 0xd6, 0xec, 0x30, 0x06, 0x07, +0x37, 0x10, 0x97, 0x76, 0x85, 0x2f, 0xab, 0x8b, +0x35, 0x83, 0x37, 0x79, 0x60, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0x19, +0x84, 0x2c, 0xe1, 0xf3, 0x29, 0x6f, 0xfe, 0x32, +0x7c, 0x28, 0x9c, 0x01, 0x92, 0xb1, 0x3c, 0x76, +0xbe, 0xfe, 0x2b, 0x75, 0xe2, 0x7b, 0x99, 0x15, +0x3d, 0x85, 0xe3, 0x5f, 0xda, 0xc9, 0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0f, 0x01, 0x22, -0x21, 0xdb, 0x4b, 0x59, 0x8b, 0x65, 0xff, 0x40, -0xab, 0x8a, 0xa9, 0x88, 0x48, 0x1c, 0x19, 0x76, -0x67, 0x67, 0xb5, 0x13, 0xa0, 0x86, 0xe2, 0xb4, -0x36, 0xca, 0xcb, 0xde, 0xbb, 0x2b, 0xe3, 0x7e, -0x07, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, -0x01, 0x22, 0x21, 0x0c, 0x96, 0x81, 0xe7, 0x9c, -0x70, 0xca, 0x5a, 0x0a, 0xfe, 0x2c, 0x60, 0xa0, -0xc1, 0x48, 0xf9, 0x15, 0xcf, 0xd8, 0xd7, 0xa6, -0xec, 0x62, 0x16, 0xe5, 0x0a, 0x2c, 0xdd, 0x87, -0x27, 0x29, 0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x11, 0x01, 0x22, 0x21, 0xa2, 0x56, 0x67, -0x60, 0xac, 0x35, 0xbd, 0xc9, 0xdd, 0x8c, 0xa8, -0x29, 0xc6, 0xf8, 0x8f, 0x7e, 0x57, 0x39, 0x60, -0xb7, 0x44, 0xc1, 0x64, 0x47, 0x78, 0xb8, 0x68, -0xce, 0x91, 0xfd, 0x9f, 0x1c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0x73, -0x69, 0xe2, 0x20, 0x02, 0x84, 0xc1, 0x9d, 0x83, -0x98, 0x5f, 0xc4, 0xc2, 0xab, 0x7c, 0xda, 0xa5, -0xd7, 0xa5, 0xad, 0x49, 0xdf, 0x14, 0xbc, 0x17, -0x7a, 0x84, 0xac, 0x85, 0x2c, 0xb6, 0xc3, 0x00, +0x21, 0x23, 0x69, 0x2d, 0xbe, 0x13, 0xc0, 0x43, +0x6a, 0x0b, 0x3d, 0xcc, 0x77, 0x52, 0x6a, 0xad, +0xd9, 0x9a, 0x53, 0x21, 0xb7, 0x06, 0x5c, 0x9d, +0xcf, 0x4b, 0x05, 0x47, 0x84, 0x7c, 0xd2, 0xa7, +0xf2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, +0x01, 0x22, 0x21, 0xe8, 0xb9, 0x53, 0x42, 0xc8, +0xb3, 0xb6, 0x90, 0xdb, 0xde, 0xe9, 0x84, 0x6b, +0x1c, 0xdc, 0x23, 0xa1, 0xde, 0xcb, 0x08, 0xd3, +0xc5, 0x00, 0xbe, 0x42, 0x6f, 0xa7, 0x8a, 0xc7, +0x67, 0x9f, 0x93, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x11, 0x01, 0x22, 0x21, 0x5b, 0xfd, 0xb1, +0x65, 0xb9, 0xaf, 0xe0, 0x01, 0x7f, 0xc8, 0x76, +0x09, 0x9e, 0x2b, 0x31, 0x14, 0x30, 0x45, 0xb2, +0x45, 0x50, 0x0a, 0xb6, 0x5b, 0x46, 0xbc, 0x19, +0x18, 0x9a, 0x67, 0xc1, 0x94, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0x90, +0xac, 0xf8, 0xc7, 0xc7, 0xcd, 0x8a, 0x7a, 0x85, +0x00, 0x65, 0xc2, 0x4a, 0xd8, 0xe8, 0xea, 0x1a, +0xd6, 0xa7, 0x03, 0x3b, 0xf2, 0x29, 0x7f, 0x86, +0x77, 0xf5, 0x13, 0xca, 0xad, 0x2d, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x13, 0x01, 0x22, -0x21, 0x88, 0x71, 0xc9, 0x17, 0xe7, 0x99, 0x4c, -0x68, 0x14, 0x06, 0x86, 0x21, 0x38, 0x9b, 0xff, -0xf9, 0xcb, 0x04, 0x63, 0xba, 0x78, 0xcc, 0x9f, -0x7c, 0xfb, 0x22, 0xb1, 0xbb, 0x2b, 0xe0, 0x8a, -0xb9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, -0x01, 0x22, 0x21, 0x05, 0xaa, 0xb2, 0xac, 0x40, -0xb2, 0xfc, 0x8e, 0x06, 0x55, 0xd4, 0x22, 0x6f, -0xf3, 0x0a, 0x31, 0x58, 0xb7, 0x54, 0x65, 0xcb, -0x49, 0x2a, 0x55, 0x81, 0x63, 0x27, 0xaa, 0x86, -0x8d, 0x7d, 0x74, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x15, 0x01, 0x22, 0x21, 0x25, 0x8d, 0x3f, -0x40, 0x7a, 0x61, 0x6d, 0x5c, 0x87, 0x4f, 0xcd, -0x29, 0x09, 0x80, 0xf1, 0x99, 0xdb, 0xe3, 0x18, -0x08, 0xcb, 0xa3, 0xe2, 0x06, 0x93, 0xb2, 0x11, -0x33, 0x4b, 0xa6, 0x5f, 0xb0, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x45, -0x2f, 0x90, 0xe2, 0x83, 0xbe, 0xcb, 0x19, 0x38, -0x83, 0x14, 0x28, 0x2f, 0xfd, 0xfb, 0x11, 0x2b, -0xd0, 0xb8, 0xe0, 0x44, 0xaa, 0xfc, 0x5f, 0x3b, -0x08, 0x7b, 0x9e, 0x78, 0x93, 0x1f, 0xf8, 0x00, +0x21, 0xd0, 0x03, 0xe0, 0x69, 0x96, 0x17, 0xe0, +0x07, 0x58, 0x16, 0xb1, 0x60, 0xd3, 0xbc, 0x08, +0x22, 0x08, 0x48, 0x03, 0x71, 0x8f, 0xce, 0xc7, +0x84, 0x12, 0xb1, 0x33, 0xca, 0xb9, 0x86, 0xd9, +0xae, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, +0x01, 0x22, 0x21, 0x25, 0x37, 0xc4, 0x00, 0xd5, +0xda, 0x60, 0xe8, 0x03, 0xe7, 0x07, 0x33, 0x53, +0x4d, 0xc4, 0x97, 0xd4, 0xd6, 0x37, 0x36, 0x15, +0x95, 0xda, 0xc5, 0x8a, 0x7c, 0x40, 0x8b, 0x47, +0x73, 0x1b, 0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x15, 0x01, 0x22, 0x21, 0xac, 0x0f, 0xee, +0x12, 0x5a, 0xc1, 0x9e, 0x04, 0x72, 0x01, 0x32, +0x2c, 0xae, 0x7e, 0x5f, 0xe5, 0x18, 0x32, 0x33, +0x72, 0x1b, 0x9a, 0x1e, 0x0e, 0x29, 0x11, 0xd4, +0x92, 0x6d, 0x6b, 0x68, 0x4c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x88, +0xf1, 0x7e, 0x3d, 0xf0, 0x6c, 0xfa, 0xe5, 0xe5, +0x85, 0xbd, 0xb4, 0x0f, 0xa6, 0xea, 0x63, 0x20, +0x7c, 0x95, 0xb2, 0xa3, 0xae, 0x0b, 0x52, 0x61, +0x5d, 0x24, 0x51, 0x1c, 0xcf, 0x87, 0xf4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x17, 0x01, 0x22, -0x21, 0x65, 0x07, 0x95, 0x65, 0xcb, 0xcd, 0x98, -0xbe, 0x61, 0x9c, 0x1f, 0x83, 0x35, 0x0a, 0xa0, -0xc6, 0x87, 0xdf, 0x0a, 0xce, 0x58, 0xb4, 0xce, -0x9c, 0x82, 0x1c, 0x05, 0xaa, 0x5a, 0xcc, 0x06, -0xc7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, -0x01, 0x22, 0x21, 0xb6, 0x55, 0x41, 0x15, 0x98, -0xef, 0x78, 0x98, 0x7e, 0xd7, 0xa0, 0xfc, 0xf2, -0x5c, 0x95, 0xb8, 0x3a, 0xf7, 0x69, 0x48, 0xdf, -0xa7, 0x42, 0xf5, 0x11, 0x52, 0xaa, 0x04, 0x3a, -0xc4, 0xce, 0x98, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x19, 0x01, 0x22, 0x21, 0xf8, 0xc3, 0xb4, -0x7c, 0xfa, 0xa3, 0xf6, 0x4e, 0x13, 0x21, 0x60, -0x80, 0xae, 0xb3, 0xca, 0x16, 0x1d, 0x19, 0xcd, -0x70, 0xbf, 0xa4, 0xdf, 0xa9, 0xff, 0x3d, 0xd5, -0xef, 0xca, 0x47, 0x9a, 0x60, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0x5d, -0x18, 0x23, 0x09, 0x02, 0x21, 0x4b, 0x32, 0xbc, -0x42, 0xf2, 0xb7, 0xdb, 0xdc, 0x83, 0xf4, 0x62, -0xc7, 0x89, 0x02, 0xc3, 0xc9, 0xf3, 0x48, 0xc6, -0x77, 0xd2, 0xc4, 0x9b, 0xdb, 0x5f, 0x53, 0x00, +0x21, 0xec, 0x8e, 0x39, 0xc0, 0xc6, 0x7e, 0x42, +0x59, 0x81, 0xdb, 0x05, 0x09, 0xf2, 0xa0, 0x18, +0x52, 0xf3, 0xb9, 0xe5, 0xae, 0xf8, 0x1b, 0x34, +0x3a, 0x69, 0xed, 0xfe, 0x58, 0x6b, 0x26, 0x86, +0xed, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, +0x01, 0x22, 0x21, 0x0e, 0xfb, 0xea, 0xa1, 0x0f, +0xb6, 0x07, 0x88, 0x33, 0x1c, 0xf2, 0x3a, 0x14, +0x45, 0xd8, 0x29, 0x32, 0x5a, 0x2b, 0x27, 0x31, +0x3a, 0x57, 0x4f, 0xa4, 0xf3, 0x53, 0x29, 0x5f, +0x10, 0xa3, 0xd2, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x19, 0x01, 0x22, 0x21, 0x57, 0x56, 0x7c, +0xd7, 0xa2, 0x6d, 0xc3, 0xd4, 0xc8, 0xea, 0x68, +0x5c, 0xef, 0xd3, 0x6a, 0x8c, 0x86, 0xc8, 0x4d, +0xcf, 0x4b, 0xed, 0x3b, 0x04, 0x19, 0x4f, 0x79, +0x83, 0xe6, 0x89, 0x04, 0xa6, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0x9f, +0x8f, 0x0b, 0x72, 0xf3, 0x58, 0xf3, 0xe4, 0xcc, +0x42, 0x5a, 0xd6, 0x01, 0xa4, 0xc0, 0x23, 0x8b, +0x3a, 0x69, 0x72, 0xc2, 0x0f, 0x41, 0x08, 0x44, +0x44, 0x8d, 0x94, 0x2b, 0x59, 0x5c, 0x66, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1b, 0x01, 0x22, -0x21, 0xd0, 0xc7, 0xb0, 0xfb, 0xf1, 0xc9, 0x66, -0x0a, 0x98, 0x61, 0xcd, 0xc6, 0x3b, 0x0a, 0xc2, -0xa5, 0xcf, 0x35, 0xfb, 0xb0, 0xe6, 0xbc, 0x1f, -0x38, 0x9f, 0x35, 0x5d, 0x1d, 0x0b, 0x60, 0xe2, -0x3e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, -0x01, 0x22, 0x21, 0xc4, 0xc8, 0x8c, 0x43, 0xfb, -0x11, 0x6d, 0xd9, 0x08, 0x7e, 0xbc, 0x39, 0x87, -0xd1, 0x98, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd8, 0xef, 0xc2, 0x54, -0x90, 0x07, 0x4f, 0xb0, 0x03, 0x04, 0x51, 0x02, -0x00, 0x1d, 0x01, 0x22, 0x21, 0x42, 0x58, 0x19, -0x89, 0x2e, 0x7e, 0xf6, 0xa2, 0x90, 0xb8, 0x0a, -0x3c, 0x2c, 0x67, 0xf7, 0xf3, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x70, -0xc2, 0xb9, 0xa6, 0x14, 0x5f, 0x4b, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0xe0, -0xf7, 0x30, 0x73, 0xb5, 0xf5, 0x7f, 0x7d, 0xdb, -0x98, 0xe9, 0xba, 0xea, 0xee, 0x4b, 0xeb, 0x45, -0x9a, 0x10, 0x1b, 0xea, 0xbd, 0x77, 0x1b, 0x53, -0x50, 0xef, 0xb0, 0x41, 0x57, 0xa2, 0x68, 0x00, +0x21, 0x9b, 0x4f, 0xfa, 0xed, 0x4c, 0x4a, 0x18, +0xd1, 0xa2, 0x83, 0x1d, 0x7d, 0x47, 0xdb, 0x1b, +0x20, 0xbc, 0x9c, 0xd7, 0xf6, 0x01, 0x09, 0xa5, +0x84, 0xde, 0x8e, 0x35, 0x1c, 0x49, 0x7e, 0xd5, +0x55, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, +0x01, 0x22, 0x21, 0x67, 0x70, 0x0a, 0x29, 0x5f, +0x56, 0x23, 0x16, 0xda, 0x31, 0xaa, 0x36, 0x91, +0xd9, 0x4d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x8d, 0x46, 0xc7, 0xaf, +0xa0, 0x8a, 0x5a, 0x9e, 0x03, 0x04, 0x51, 0x02, +0x00, 0x1d, 0x01, 0x22, 0x21, 0xfb, 0x3f, 0x9d, +0x1a, 0xf1, 0x2b, 0x18, 0x2d, 0xc3, 0xd9, 0x4e, +0xc7, 0xa1, 0x05, 0x86, 0xc1, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x7e, +0x6f, 0x5b, 0x17, 0x24, 0x99, 0xac, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0xf4, +0x39, 0x4e, 0xdd, 0xda, 0xbe, 0xa1, 0xb0, 0x1a, +0x91, 0xba, 0xff, 0xfe, 0xf5, 0x9c, 0xf6, 0x4d, +0x0d, 0x9b, 0xff, 0x0e, 0x04, 0x53, 0x03, 0x88, +0xf0, 0xc8, 0x75, 0x44, 0x06, 0xd3, 0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1f, 0x01, 0x22, -0x21, 0x9f, 0x0f, 0xda, 0x3f, 0x24, 0x42, 0x20, -0xa1, 0x4e, 0xd9, 0x80, 0x32, 0x0f, 0xe7, 0x8d, -0x0a, 0x17, 0xe6, 0x8e, 0x9c, 0xaa, 0x34, 0x90, -0xe1, 0xe2, 0x67, 0xd5, 0xba, 0x2c, 0x79, 0x40, -0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, -0x01, 0x22, 0x21, 0x67, 0xb9, 0xa0, 0x0d, 0x81, -0xa3, 0xa5, 0xab, 0x76, 0x07, 0x6b, 0x86, 0xe5, -0x57, 0xcc, 0x7b, 0xf7, 0x12, 0xa2, 0xde, 0xff, -0x41, 0x85, 0x94, 0xc7, 0x64, 0x88, 0xfe, 0x62, -0x66, 0xee, 0xa6, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x21, 0x01, 0x22, 0x21, 0x5e, 0x5b, 0xc4, -0xcd, 0x29, 0x24, 0xb9, 0x7c, 0x2d, 0xd6, 0xf2, -0xa8, 0x15, 0x1d, 0x18, 0x46, 0xa4, 0x94, 0x90, -0x39, 0xc5, 0x69, 0x40, 0xef, 0x07, 0x41, 0xe0, -0xb9, 0x74, 0x3f, 0x34, 0x1b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0x2f, -0xfb, 0xd6, 0x35, 0x8c, 0xd5, 0xe1, 0xde, 0xe3, -0xef, 0xba, 0xf5, 0x7d, 0xfa, 0xe4, 0xf7, 0x45, -0x53, 0xdf, 0xfd, 0x73, 0xa0, 0xeb, 0xe3, 0xfc, -0xb6, 0x93, 0x87, 0x7d, 0x01, 0x2c, 0x0c, 0x00, +0x21, 0x06, 0xc2, 0x9a, 0x7c, 0xd5, 0x03, 0xd0, +0x88, 0x15, 0xff, 0x97, 0x7c, 0x5c, 0x42, 0x7c, +0xac, 0xe0, 0xeb, 0x5b, 0xab, 0x59, 0x1f, 0xa2, +0x3e, 0x8c, 0xba, 0xc1, 0xca, 0xf1, 0x83, 0x05, +0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, +0x01, 0x22, 0x21, 0x46, 0xaf, 0x3a, 0x45, 0x47, +0x75, 0x58, 0x3e, 0x04, 0xe8, 0x0a, 0x52, 0x70, +0xbd, 0x28, 0x7a, 0x59, 0x0c, 0x36, 0xec, 0xac, +0x42, 0xc6, 0x7a, 0x42, 0x6a, 0x8a, 0xc5, 0x09, +0xe1, 0x0b, 0xf3, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x21, 0x01, 0x22, 0x21, 0xa7, 0x9d, 0xd6, +0xe8, 0x22, 0xc9, 0xbc, 0x40, 0xd2, 0xe2, 0x0d, +0x93, 0x08, 0x92, 0x69, 0xdc, 0xdb, 0x7e, 0xf3, +0x7d, 0xd3, 0xf3, 0x44, 0x4f, 0x28, 0x39, 0x38, +0x16, 0x55, 0xec, 0xc3, 0x03, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0xa4, +0x03, 0x01, 0x46, 0x5c, 0x70, 0x68, 0xa7, 0x34, +0xaf, 0xfc, 0x24, 0x5a, 0xa5, 0x0f, 0x62, 0xbf, +0xe6, 0x10, 0x47, 0x83, 0x48, 0x03, 0x06, 0x35, +0xb0, 0x84, 0xad, 0x83, 0x34, 0xf7, 0xe9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x23, 0x01, 0x22, -0x21, 0x10, 0xb3, 0x0e, 0x48, 0x79, 0xec, 0xde, -0xc1, 0xa6, 0x9a, 0x82, 0xd0, 0xb6, 0xe8, 0xed, -0x5e, 0x97, 0x06, 0x9f, 0x7f, 0x5e, 0x54, 0xc0, -0x6a, 0xee, 0x88, 0x2a, 0x11, 0xc4, 0x22, 0x38, -0x41, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, -0x01, 0x22, 0x21, 0x39, 0xc9, 0xe4, 0xda, 0xdb, -0xf1, 0x27, 0x48, 0x69, 0x9c, 0xdc, 0xf9, 0x61, -0x5f, 0x49, 0xcc, 0x2d, 0xad, 0x2c, 0x33, 0xd7, -0x4d, 0xde, 0x19, 0xe9, 0xc9, 0xd2, 0xdb, 0x7b, -0x82, 0x99, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x25, 0x01, 0x22, 0x21, 0x8d, 0x76, 0x50, -0x54, 0x21, 0xc0, 0x77, 0x64, 0xb1, 0x79, 0x1f, -0x41, 0xdd, 0xf8, 0x2a, 0x6b, 0xbb, 0xac, 0x6b, -0x44, 0x2c, 0x3c, 0x0e, 0x6b, 0x5c, 0xe3, 0x8c, -0xae, 0x7d, 0x1c, 0x59, 0x4e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0x4b, -0x98, 0xff, 0x41, 0x44, 0x14, 0x98, 0x49, 0x2c, -0x3f, 0xc7, 0xb5, 0xac, 0x36, 0xab, 0x8e, 0x52, -0x97, 0xf9, 0xd4, 0xfd, 0x53, 0x31, 0x40, 0xe1, -0x04, 0x66, 0xfc, 0xec, 0x2e, 0x15, 0x79, 0x00, +0x21, 0xdd, 0x8c, 0x18, 0x7d, 0xc1, 0xc0, 0xff, +0xed, 0x63, 0x63, 0x17, 0xe4, 0xf9, 0x42, 0x1b, +0xf9, 0x20, 0xce, 0x39, 0xc3, 0x9b, 0x41, 0x83, +0x2f, 0xc1, 0x57, 0x49, 0x2e, 0x90, 0x81, 0xb4, +0x1a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, +0x01, 0x22, 0x21, 0xf7, 0xb7, 0xe4, 0xc5, 0x99, +0xe9, 0x3b, 0x9d, 0x82, 0xcf, 0x45, 0xc8, 0x38, +0x38, 0x4c, 0xbf, 0xe9, 0xcc, 0x7e, 0x24, 0x6d, +0x75, 0xde, 0xfb, 0x17, 0xce, 0xd3, 0x81, 0x50, +0x80, 0xaa, 0x19, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x25, 0x01, 0x22, 0x21, 0x2f, 0x00, 0x9c, +0x6a, 0xb2, 0xd7, 0x78, 0x2f, 0x2c, 0x30, 0x7b, +0xce, 0x76, 0x86, 0xc9, 0x37, 0xe0, 0xdd, 0x52, +0x84, 0xa3, 0x54, 0xf9, 0x34, 0xde, 0xb6, 0xe2, +0x7c, 0xff, 0xd4, 0xa8, 0xce, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0xc3, +0x88, 0xa8, 0x85, 0x02, 0x4e, 0x28, 0x7c, 0x15, +0xaa, 0xfe, 0x48, 0xde, 0xf3, 0x9c, 0xfe, 0x35, +0xdc, 0x56, 0x9f, 0x6f, 0xd3, 0xed, 0xc6, 0x82, +0x2e, 0x8f, 0xad, 0x68, 0x0b, 0xe1, 0xf5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x27, 0x01, 0x22, -0x21, 0x70, 0x0d, 0xbb, 0x04, 0x92, 0x7c, 0x6f, -0x7b, 0x85, 0xc0, 0xf4, 0x46, 0xc4, 0xd3, 0xab, -0x33, 0x9c, 0x2b, 0x5b, 0x75, 0xff, 0x30, 0x9b, -0xa8, 0x1e, 0x75, 0x03, 0x8d, 0x62, 0xb6, 0x9b, -0x1e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, -0x01, 0x22, 0x21, 0xf7, 0x09, 0xef, 0x25, 0xf2, -0x39, 0xcc, 0xf9, 0xa1, 0x70, 0x38, 0x70, 0x82, -0x1c, 0x8c, 0x6b, 0xef, 0xd1, 0x88, 0x08, 0x91, -0xc5, 0x67, 0x13, 0x09, 0xfb, 0x8e, 0xf0, 0x28, -0x6e, 0x0d, 0x5c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x29, 0x01, 0x22, 0x21, 0x9d, 0x50, 0x8a, -0xe1, 0x88, 0xff, 0xc0, 0x39, 0x81, 0xb3, 0x1c, -0x7a, 0x5e, 0x1f, 0xac, 0xa4, 0xf8, 0x05, 0x19, -0xf6, 0x08, 0xd9, 0xf9, 0x84, 0x18, 0x61, 0x92, -0xdd, 0x46, 0xee, 0x7a, 0x31, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x0f, -0x31, 0x06, 0x78, 0x72, 0xb6, 0x4e, 0xc2, 0x87, -0xe8, 0xcb, 0xbf, 0xc9, 0xbf, 0xa7, 0x32, 0xba, -0x25, 0x48, 0x78, 0xe9, 0x90, 0xe4, 0x05, 0x3f, -0xf0, 0xab, 0xab, 0xba, 0x15, 0xcf, 0xec, 0x00, +0x21, 0x24, 0x00, 0x38, 0xd0, 0xac, 0x35, 0x3b, +0xc0, 0xcc, 0xb3, 0x69, 0x79, 0xc4, 0x98, 0xc8, +0x21, 0xbc, 0x8b, 0x4f, 0x13, 0x91, 0xc6, 0x40, +0x96, 0xb4, 0x29, 0xb5, 0x10, 0x43, 0x95, 0x65, +0xcd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, +0x01, 0x22, 0x21, 0x29, 0xfa, 0x38, 0x75, 0x8d, +0x6f, 0x0d, 0xda, 0xeb, 0xbb, 0x9c, 0xe3, 0x4d, +0x5c, 0x58, 0xbc, 0x90, 0x26, 0x4b, 0x53, 0xae, +0xc8, 0xaa, 0x09, 0x8e, 0xd2, 0xb6, 0x63, 0x98, +0xde, 0xf2, 0x62, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x29, 0x01, 0x22, 0x21, 0x87, 0x19, 0xc5, +0x5e, 0x9f, 0x76, 0xba, 0x41, 0x7d, 0xd1, 0x7b, +0xd6, 0xc0, 0x16, 0x08, 0x5d, 0x2d, 0x23, 0xa4, +0xf6, 0x84, 0xea, 0x9b, 0x6d, 0x09, 0x8a, 0x60, +0x73, 0x14, 0x0c, 0x6c, 0x4c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x1b, +0x2f, 0x5c, 0x58, 0xc0, 0x41, 0x63, 0x4e, 0x96, +0x0b, 0x10, 0xc1, 0xb1, 0x6e, 0x36, 0xb6, 0x2e, +0x2b, 0x70, 0x6e, 0x13, 0xd6, 0x79, 0x70, 0x11, +0x45, 0x33, 0xcc, 0x35, 0xe2, 0x4c, 0x25, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2b, 0x01, 0x22, -0x21, 0x59, 0x1e, 0xcd, 0x10, 0x1b, 0x42, 0xda, -0x03, 0x1c, 0xe0, 0x7d, 0x8f, 0x07, 0xd1, 0x20, -0x9f, 0x93, 0xb3, 0x1e, 0xfd, 0x6c, 0xf8, 0x24, -0x54, 0x40, 0x67, 0x1a, 0xa5, 0x7b, 0x57, 0xbd, -0x33, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, -0x01, 0x22, 0x21, 0xd4, 0x35, 0x90, 0xc4, 0x8a, -0x23, 0x51, 0xd8, 0xd4, 0xd4, 0x03, 0xa3, 0xc9, -0x3e, 0x82, 0x9c, 0x76, 0x77, 0xd9, 0x75, 0x59, -0x5e, 0x78, 0xc0, 0xd7, 0x5e, 0xfc, 0x1f, 0x3a, -0x00, 0x74, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x2d, 0x01, 0x22, 0x21, 0x65, 0x12, 0xca, -0x9d, 0xef, 0xc2, 0xe4, 0xa5, 0xff, 0x83, 0x9a, -0xdb, 0x1c, 0x09, 0xf8, 0xea, 0x76, 0x5e, 0x41, -0xdd, 0x2b, 0xfd, 0x84, 0x54, 0xf3, 0x69, 0x29, -0x35, 0x5b, 0x8f, 0x1d, 0xa1, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0x1f, -0x4c, 0xb6, 0x64, 0x7b, 0x6b, 0x4f, 0x23, 0x5e, -0x26, 0xfe, 0x18, 0x07, 0x5f, 0x74, 0x72, 0x9c, -0x5d, 0x07, 0xe8, 0xe4, 0xc8, 0x33, 0x3b, 0x20, -0x92, 0xd4, 0x65, 0x9a, 0x05, 0x90, 0xe2, 0x00, +0x21, 0x8d, 0xad, 0x1a, 0xc5, 0x0f, 0x0e, 0x3d, +0xf7, 0x29, 0xaa, 0x99, 0x65, 0x54, 0xa7, 0xb4, +0x2a, 0x20, 0xbb, 0xb8, 0xb4, 0x52, 0x87, 0xc7, +0xfe, 0xec, 0x92, 0xf7, 0xec, 0x22, 0x6c, 0x43, +0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, +0x01, 0x22, 0x21, 0x6f, 0xa5, 0xc6, 0xb6, 0x36, +0x69, 0x6a, 0x85, 0x70, 0x95, 0x32, 0xdd, 0x3f, +0x2c, 0xa5, 0x3f, 0xdc, 0xbc, 0x34, 0x20, 0xd8, +0x67, 0xe1, 0xa5, 0x53, 0xc8, 0x10, 0x2f, 0xd2, +0x8b, 0xa4, 0x4d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x2d, 0x01, 0x22, 0x21, 0xf9, 0xef, 0x56, +0x4c, 0x8e, 0x4f, 0x70, 0xe2, 0xe0, 0xc8, 0x87, +0x94, 0x83, 0x13, 0x54, 0x44, 0x6d, 0x2e, 0x9b, +0x7f, 0xcc, 0x84, 0x97, 0x90, 0xab, 0x77, 0x19, +0x83, 0x5d, 0x78, 0x61, 0xd5, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0x0a, +0xf3, 0xef, 0xb4, 0xc5, 0x71, 0xc6, 0x39, 0xd7, +0x36, 0xab, 0x9a, 0x38, 0x89, 0x8d, 0x64, 0xf3, +0xe7, 0x99, 0x7d, 0xf1, 0xed, 0x1e, 0x85, 0x9f, +0xcd, 0x69, 0xc7, 0x0c, 0x37, 0x2d, 0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2f, 0x01, 0x22, -0x21, 0x0e, 0x8a, 0x2b, 0xa7, 0xb9, 0x0a, 0x96, -0x41, 0xde, 0xd0, 0x1d, 0xc6, 0x9f, 0xbe, 0x4b, -0x84, 0xe1, 0x65, 0x74, 0xa4, 0x9a, 0x8f, 0x79, -0xb6, 0xda, 0x95, 0xfa, 0xc2, 0x58, 0xee, 0x46, -0x2a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, -0x01, 0x22, 0x21, 0xeb, 0xab, 0xd1, 0xe0, 0xc9, -0x58, 0x5a, 0x7c, 0xef, 0xcb, 0xde, 0xa6, 0x35, -0xae, 0xe3, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x8c, 0x9b, -0x6d, 0xc5, 0x20, 0x3e, 0x03, 0x04, 0x51, 0x02, -0x00, 0x31, 0x01, 0x22, 0x21, 0x18, 0xe4, 0x2b, -0x4f, 0xed, 0xa6, 0xe0, 0xb6, 0x05, 0x49, 0x91, -0x36, 0x0e, 0xb6, 0xa1, 0x66, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x41, -0xfd, 0x86, 0xab, 0xdd, 0xe6, 0x4d, 0x03, 0x04, -0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0x1e, -0x02, 0x00, 0x41, 0xf3, 0xbd, 0xad, 0x98, 0x4d, -0x01, 0xc8, 0xe3, 0xbe, 0xd0, 0x4a, 0x51, 0x06, -0x5c, 0x67, 0x8b, 0xd3, 0x70, 0x58, 0x38, 0x36, -0x61, 0x43, 0x52, 0x7b, 0x12, 0xf8, 0xd1, 0x00, +0x21, 0xd5, 0x9c, 0x10, 0xd8, 0x04, 0x5d, 0xe2, +0xd0, 0xdb, 0x06, 0x05, 0xec, 0xdb, 0x1c, 0xf0, +0x10, 0x1a, 0x66, 0x00, 0x65, 0x17, 0x95, 0x7b, +0x38, 0x45, 0xe5, 0x0b, 0xb8, 0xd5, 0x02, 0x71, +0xf8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, +0x01, 0x22, 0x21, 0x6d, 0xf1, 0x2a, 0x38, 0xa0, +0xc4, 0xce, 0x72, 0x14, 0x5c, 0x6c, 0xe0, 0x0f, +0xad, 0x8a, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x6c, 0x24, 0x31, 0x94, +0xa1, 0x1a, 0x4d, 0xde, 0x03, 0x04, 0x51, 0x02, +0x00, 0x31, 0x01, 0x22, 0x21, 0xe9, 0x06, 0x46, +0x99, 0x17, 0xf5, 0x0d, 0x05, 0xa2, 0xba, 0x30, +0x30, 0x14, 0x04, 0x2e, 0x40, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xdd, +0x41, 0x64, 0x07, 0xd8, 0x0d, 0xc0, 0x03, 0x04, +0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0xf2, +0x1f, 0x28, 0x05, 0x13, 0xaf, 0x5b, 0x87, 0x7d, +0xfb, 0x72, 0x27, 0x5d, 0xca, 0x51, 0xee, 0x33, +0x28, 0x57, 0x6b, 0xb4, 0x4d, 0x3d, 0x55, 0x18, +0x31, 0x96, 0xe2, 0x21, 0x18, 0x7e, 0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x33, 0x01, 0x22, -0x21, 0x33, 0x19, 0xb8, 0xad, 0xaf, 0x67, 0x86, -0xb3, 0xdd, 0xfc, 0x71, 0xe8, 0xe0, 0x9d, 0xc1, -0xb6, 0x4a, 0x40, 0x48, 0xfc, 0x56, 0xd6, 0x54, -0xb6, 0xc7, 0xf5, 0x0c, 0xff, 0x4c, 0xca, 0x45, -0x47, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, -0x01, 0x22, 0x21, 0xe9, 0xb4, 0xfe, 0x00, 0xb1, -0x19, 0xfa, 0xcb, 0x36, 0x1a, 0x40, 0x8e, 0xfd, -0x6b, 0xfd, 0x50, 0xbb, 0x9b, 0xb9, 0x5f, 0x6c, -0xf5, 0x0e, 0xde, 0xe4, 0xce, 0x31, 0x60, 0xfc, -0xdf, 0x97, 0x54, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x35, 0x01, 0x22, 0x21, 0xed, 0x76, 0xf3, -0xba, 0xf2, 0x82, 0xd1, 0x65, 0x11, 0x12, 0xb9, -0x7e, 0xe9, 0x36, 0x34, 0x55, 0x2e, 0xdf, 0x0d, -0xd1, 0xfa, 0x3f, 0x3d, 0xb9, 0x87, 0x5a, 0x58, -0x0c, 0x61, 0xde, 0xcb, 0x38, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0x70, -0xcc, 0x4d, 0xe3, 0xc2, 0x86, 0xf4, 0x4f, 0x02, -0x09, 0x1a, 0xf3, 0x50, 0x28, 0xfb, 0x86, 0xcb, -0xb5, 0x19, 0x44, 0xda, 0xd3, 0xba, 0x43, 0x6c, -0x9f, 0xe8, 0x51, 0x50, 0x47, 0xa9, 0xe9, 0x00, +0x21, 0x4b, 0x1e, 0xc3, 0xff, 0x01, 0x2c, 0x94, +0xbd, 0x99, 0xb7, 0x86, 0x9c, 0x02, 0x24, 0x02, +0x41, 0x37, 0x48, 0xab, 0xe6, 0x87, 0x57, 0x7d, +0x75, 0x17, 0xfd, 0x53, 0x67, 0x40, 0xc5, 0x73, +0x31, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, +0x01, 0x22, 0x21, 0x2a, 0xdd, 0xe0, 0xcb, 0x70, +0xf9, 0x89, 0x8d, 0x94, 0x63, 0x10, 0x3c, 0xee, +0x33, 0x0d, 0xd3, 0x60, 0x60, 0x04, 0xb1, 0x58, +0x4b, 0xce, 0x3e, 0x70, 0xa8, 0xc8, 0x55, 0xed, +0x99, 0x1e, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x35, 0x01, 0x22, 0x21, 0x37, 0xdf, 0xf3, +0xcb, 0x1e, 0xaf, 0x45, 0xb9, 0xad, 0x9b, 0xed, +0xf4, 0x69, 0x6c, 0xfb, 0x28, 0xe5, 0x8a, 0xbd, +0xef, 0x19, 0x22, 0xf3, 0x38, 0x2a, 0xb7, 0x07, +0xe0, 0x0a, 0xb2, 0x73, 0x73, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0xc3, +0x11, 0x8b, 0x13, 0xa0, 0xb7, 0xe3, 0x3d, 0x4f, +0x79, 0x05, 0x6a, 0xf3, 0xd6, 0x59, 0x77, 0x02, +0x0d, 0x69, 0x0d, 0x97, 0x19, 0x97, 0x1b, 0x58, +0x0c, 0x54, 0x2f, 0x41, 0xaf, 0x0b, 0x51, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x37, 0x01, 0x22, -0x21, 0x57, 0xfe, 0x43, 0x00, 0x8b, 0x6a, 0x3f, -0xe3, 0x38, 0x92, 0xd0, 0xcb, 0x38, 0x9e, 0x6e, -0xd5, 0x3d, 0xf4, 0x87, 0x1c, 0x6d, 0xa2, 0x93, -0x32, 0x99, 0x80, 0x54, 0xa2, 0x31, 0x3d, 0x5b, -0x50, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, -0x01, 0x22, 0x21, 0x9f, 0x17, 0x27, 0xef, 0xba, -0x2b, 0x40, 0xd6, 0xb2, 0x2f, 0xea, 0xb0, 0x2e, -0x4a, 0xfc, 0x90, 0x15, 0xd2, 0x3c, 0x0c, 0xcf, -0xc6, 0xe2, 0x36, 0x9e, 0x97, 0x10, 0x39, 0x81, -0x68, 0xbb, 0x04, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x39, 0x01, 0x22, 0x21, 0xd4, 0x10, 0xed, -0x97, 0xb4, 0x6e, 0xac, 0x75, 0xb9, 0x7f, 0x8d, -0xf8, 0x36, 0x52, 0x69, 0x63, 0x5e, 0x5b, 0x70, -0xfe, 0xb1, 0xac, 0xda, 0x22, 0x95, 0x55, 0xb9, -0x63, 0x73, 0x3c, 0x7e, 0xd9, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0x91, -0x48, 0x0c, 0x98, 0xa5, 0xa6, 0x6f, 0xdf, 0xd7, -0x18, 0x1c, 0x9f, 0xa0, 0xc0, 0xb1, 0x8f, 0x87, -0x60, 0xd9, 0x19, 0x3d, 0x97, 0xc9, 0x04, 0xa7, -0x14, 0xf5, 0x86, 0x75, 0x37, 0x95, 0x5e, 0x00, +0x21, 0x5c, 0xc8, 0x3a, 0x82, 0x82, 0x80, 0x03, +0x56, 0x36, 0x5f, 0xcd, 0x71, 0x0b, 0x6a, 0x6f, +0x0a, 0x41, 0x3d, 0x71, 0xce, 0xd7, 0x00, 0xee, +0x6c, 0x73, 0x9c, 0x98, 0xdf, 0x57, 0x8e, 0x94, +0xd4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, +0x01, 0x22, 0x21, 0xf3, 0x21, 0xbd, 0xf8, 0x63, +0xe9, 0x61, 0x91, 0x03, 0x4a, 0xb4, 0xe5, 0x84, +0x81, 0xbf, 0xdb, 0x8e, 0x8c, 0x21, 0x1b, 0xb3, +0x70, 0xc2, 0x53, 0x29, 0xc2, 0xfe, 0xd0, 0x9f, +0xd9, 0x89, 0x4a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x39, 0x01, 0x22, 0x21, 0x53, 0xab, 0x26, +0xc1, 0xce, 0x17, 0x8b, 0xca, 0x65, 0x56, 0xb0, +0x07, 0xf6, 0xf0, 0xfb, 0x5c, 0x19, 0xec, 0x76, +0xf9, 0x42, 0x93, 0xb2, 0xad, 0x63, 0xc7, 0xb3, +0x28, 0x84, 0xec, 0x77, 0xc7, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0x61, +0x5a, 0x77, 0xb4, 0xef, 0x4b, 0x47, 0xf5, 0x3a, +0x83, 0x2e, 0x38, 0x2f, 0x6f, 0x7b, 0x63, 0x04, +0xf4, 0x29, 0x16, 0xb4, 0x95, 0xbe, 0xff, 0x79, +0x41, 0xfa, 0x3f, 0x1d, 0x19, 0x60, 0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3b, 0x01, 0x22, -0x21, 0x66, 0xad, 0xb7, 0xe4, 0xcc, 0x2b, 0x62, -0xb8, 0x13, 0xf0, 0x94, 0x78, 0x50, 0xde, 0x69, -0x5e, 0x43, 0x0b, 0x38, 0x0d, 0xbf, 0x11, 0xc9, -0x47, 0x90, 0x96, 0xe4, 0xcf, 0x2f, 0x3a, 0xac, -0x1f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, -0x01, 0x22, 0x21, 0x9d, 0x65, 0xa4, 0xf1, 0x8f, -0x04, 0xba, 0x3f, 0xc9, 0x50, 0x0f, 0x8f, 0x37, -0x6a, 0xc7, 0xfc, 0xae, 0x69, 0x14, 0xee, 0x3b, -0x18, 0xd1, 0xb5, 0xc4, 0x82, 0x0e, 0xc6, 0xda, -0x3f, 0xa6, 0x02, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x3d, 0x01, 0x22, 0x21, 0x06, 0x8b, 0xbe, -0x24, 0xbb, 0x5c, 0x82, 0xc1, 0xcd, 0xb8, 0x47, -0xdd, 0xd7, 0xe7, 0xc8, 0x13, 0x0a, 0x1f, 0x71, -0xd5, 0x22, 0xf7, 0xd4, 0x40, 0x62, 0x53, 0x26, -0x6f, 0x49, 0x46, 0x73, 0x9d, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0x82, -0xdd, 0x44, 0xe3, 0x2a, 0x0a, 0x1e, 0x01, 0xc4, -0xb8, 0xec, 0x4c, 0x6d, 0x82, 0xb4, 0xfb, 0x3e, -0xea, 0x52, 0x45, 0x07, 0xb9, 0x1f, 0x63, 0xae, -0x14, 0x13, 0x4c, 0x5d, 0xff, 0xff, 0x6d, 0x00, +0x21, 0x39, 0x3f, 0x3c, 0x4f, 0xec, 0x5c, 0x96, +0xca, 0x5e, 0x65, 0x36, 0x2b, 0xfa, 0x4f, 0x73, +0x39, 0x29, 0x68, 0xc9, 0x4b, 0x61, 0xeb, 0x45, +0xeb, 0xcf, 0xb8, 0x8a, 0x43, 0x7e, 0x04, 0x12, +0x4d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, +0x01, 0x22, 0x21, 0x71, 0xaa, 0x80, 0x8c, 0xba, +0xf0, 0x20, 0x2f, 0x23, 0xd3, 0x5f, 0x0a, 0x39, +0xed, 0x1c, 0x97, 0x02, 0x04, 0x68, 0x0e, 0xd0, +0x13, 0xb2, 0xf9, 0xa3, 0x77, 0x65, 0xc1, 0x42, +0x83, 0x44, 0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x3d, 0x01, 0x22, 0x21, 0xd3, 0xcf, 0xd7, +0x5f, 0x85, 0xeb, 0xc9, 0x1f, 0x71, 0x0b, 0x0d, +0x1e, 0xb2, 0x59, 0x42, 0xa1, 0xf3, 0x17, 0x98, +0xda, 0x1b, 0x57, 0x02, 0x1b, 0xbb, 0x0b, 0x87, +0xcf, 0x99, 0x6b, 0x05, 0xc2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0x28, +0xdc, 0x14, 0xcd, 0xad, 0x8d, 0x15, 0x1f, 0x79, +0xb7, 0x4d, 0xb2, 0xa3, 0x9a, 0x9e, 0x8f, 0x3a, +0x9e, 0x68, 0x84, 0xb3, 0x3d, 0x07, 0xcf, 0x03, +0xec, 0xeb, 0x30, 0x2f, 0xc3, 0x8d, 0xf2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3f, 0x01, 0x22, -0x21, 0xdb, 0x0d, 0xff, 0x7a, 0xaa, 0x5c, 0xde, -0x57, 0x05, 0x33, 0xde, 0x89, 0x32, 0x1e, 0xea, -0xde, 0x70, 0x28, 0x15, 0x28, 0x34, 0x61, 0x5c, -0x07, 0xf4, 0xa7, 0xa3, 0x0c, 0x05, 0x5e, 0xca, -0xa2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, -0x01, 0x22, 0x21, 0x3a, 0x2c, 0x4a, 0x97, 0x29, -0xd5, 0x30, 0x0f, 0xd5, 0xb1, 0x97, 0x07, 0x7b, -0x53, 0x20, 0xa5, 0x7f, 0xdd, 0xa9, 0x14, 0x8a, -0xe2, 0xe9, 0x62, 0x2f, 0x45, 0x7b, 0x2c, 0x43, -0x11, 0x00, 0xe1, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x41, 0x01, 0x22, 0x21, 0x80, 0x46, 0x50, -0xe5, 0xb9, 0x28, 0xef, 0xc2, 0x34, 0x58, 0x9b, -0xbd, 0x74, 0x91, 0xba, 0x3b, 0x63, 0x1e, 0x56, -0x26, 0x9c, 0xc8, 0x84, 0x80, 0xc2, 0x3f, 0xa2, -0xb7, 0x2e, 0x7f, 0xaf, 0x90, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0xb0, -0x37, 0x80, 0x7b, 0x8f, 0x8b, 0xf3, 0xf9, 0xfc, -0x09, 0x11, 0xdc, 0x56, 0x1b, 0x7b, 0xf4, 0x0b, -0xd8, 0x59, 0x22, 0xf8, 0x46, 0xa9, 0xf8, 0x5f, -0x75, 0x3f, 0x19, 0x3a, 0x8c, 0xa9, 0xd1, 0x00, +0x21, 0x1a, 0x3e, 0x0d, 0xad, 0xcc, 0xed, 0x28, +0x78, 0x6a, 0x50, 0x07, 0x61, 0x8e, 0x8d, 0xd8, +0xfd, 0xaa, 0x2f, 0x1c, 0x20, 0x16, 0xdc, 0x9d, +0x30, 0x71, 0x27, 0x29, 0xf6, 0x6e, 0xcc, 0xd0, +0xd1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, +0x01, 0x22, 0x21, 0x9d, 0xa3, 0xb5, 0xce, 0x24, +0x64, 0x92, 0x29, 0x45, 0x3e, 0xcc, 0x6a, 0x4d, +0x88, 0xf8, 0x22, 0x13, 0x38, 0x7a, 0xf2, 0x4f, +0x3c, 0x29, 0x46, 0x85, 0x8b, 0x60, 0x3c, 0xb2, +0x08, 0x31, 0xfc, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x41, 0x01, 0x22, 0x21, 0x37, 0x5d, 0xcf, +0x4a, 0xe4, 0xa7, 0x61, 0xc6, 0x1f, 0x94, 0xd8, +0x4b, 0xf6, 0x96, 0x04, 0x92, 0xc1, 0x3e, 0x15, +0x7d, 0x0a, 0xd7, 0xb4, 0xa7, 0x6b, 0x3e, 0xcd, +0x85, 0xb6, 0x46, 0x9e, 0xa7, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0x48, +0x31, 0xfc, 0xcc, 0xd1, 0x50, 0x4e, 0x43, 0xbb, +0x42, 0xba, 0xe3, 0x82, 0xec, 0x89, 0x0d, 0x7d, +0xda, 0x70, 0xe4, 0x73, 0xeb, 0x9f, 0x54, 0xba, +0x3f, 0xda, 0x22, 0xcd, 0x43, 0x4e, 0xff, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x43, 0x01, 0x22, -0x21, 0x9c, 0x8d, 0x7c, 0xe5, 0xc8, 0x1f, 0x80, -0xbe, 0x20, 0x86, 0xe1, 0x1e, 0xdf, 0x64, 0x9b, -0x4b, 0xf7, 0xaf, 0xde, 0xb2, 0x1c, 0xbb, 0x40, -0xc5, 0x74, 0x22, 0x01, 0x02, 0x64, 0x1b, 0xcc, -0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, -0x01, 0x22, 0x21, 0x65, 0x4c, 0xe5, 0x76, 0x86, -0x4e, 0x01, 0xd9, 0xf6, 0x7f, 0x0e, 0x9a, 0xd0, -0x82, 0xf6, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xf8, 0x5d, 0x82, 0x32, -0x13, 0xd1, 0xd2, 0x95, 0x03, 0x04, 0x51, 0x02, -0x00, 0x45, 0x01, 0x22, 0x21, 0xf1, 0xb8, 0xaf, -0xb5, 0xd4, 0xba, 0xb7, 0x1f, 0x37, 0xcb, 0x56, -0x65, 0xe7, 0xff, 0x14, 0xb3, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xd5, -0x27, 0xa6, 0x33, 0x1b, 0x7b, 0xfe, 0x03, 0x04, -0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0x52, -0x31, 0x50, 0xcd, 0xe1, 0xac, 0xc3, 0x62, 0x59, -0xae, 0x31, 0xf3, 0x1b, 0x79, 0xd8, 0xd7, 0x40, -0xa9, 0xc8, 0x80, 0x35, 0x64, 0xe5, 0xdf, 0x03, -0x19, 0x79, 0xdc, 0x50, 0xa2, 0x60, 0x30, 0x00, +0x21, 0x35, 0xca, 0x2c, 0x0c, 0x4c, 0xf9, 0xae, +0x09, 0x00, 0xae, 0x65, 0x25, 0x9d, 0xd2, 0x27, +0x14, 0x88, 0xa2, 0x7c, 0x45, 0x23, 0x48, 0x97, +0x7c, 0x01, 0x2b, 0xb6, 0x96, 0x46, 0xf9, 0x6a, +0xc5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, +0x01, 0x22, 0x21, 0x8a, 0xaf, 0x9d, 0x25, 0x8b, +0xf4, 0xaf, 0xa4, 0x3e, 0xe5, 0xfc, 0x6c, 0x41, +0xa9, 0xdc, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xa4, 0x27, 0x7b, 0x01, +0xa0, 0x57, 0x99, 0x66, 0x03, 0x04, 0x51, 0x02, +0x00, 0x45, 0x01, 0x22, 0x21, 0x51, 0xc4, 0xd8, +0x32, 0x99, 0x3a, 0x45, 0x28, 0x75, 0x9f, 0xe0, +0x87, 0x1c, 0xf7, 0xdb, 0x7f, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xd1, +0x1e, 0xc5, 0x54, 0x4e, 0x61, 0x94, 0x03, 0x04, +0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0xb7, +0xaa, 0xdc, 0xde, 0xba, 0x1c, 0xac, 0x38, 0x7e, +0xe3, 0xbf, 0x91, 0x87, 0xd5, 0x0f, 0x6b, 0xe0, +0x67, 0xa5, 0x54, 0x5e, 0x6a, 0x3e, 0xc9, 0x87, +0xd1, 0xd5, 0xf4, 0xd8, 0x61, 0x48, 0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x47, 0x01, 0x22, -0x21, 0xc3, 0x59, 0xf2, 0xef, 0x32, 0xdf, 0x61, -0xf8, 0x20, 0x3f, 0x72, 0xde, 0x0f, 0xdc, 0x3d, -0xfb, 0x29, 0xe3, 0x5f, 0x50, 0xa1, 0x90, 0x19, -0x16, 0xea, 0x3f, 0xa1, 0xe5, 0x9d, 0x5a, 0x5c, -0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, -0x01, 0x22, 0x21, 0x20, 0xef, 0x46, 0x52, 0xb1, -0x91, 0x64, 0x6c, 0xe9, 0x23, 0xdb, 0xa6, 0xbd, -0x57, 0x0c, 0x7d, 0x90, 0xd3, 0x19, 0x22, 0x3f, -0x88, 0xd3, 0x9e, 0x9a, 0xbb, 0xb4, 0x7a, 0x63, -0x7d, 0xed, 0x97, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x49, 0x01, 0x22, 0x21, 0x96, 0xe0, 0xb1, -0xf9, 0x36, 0x89, 0x7b, 0x1d, 0x1c, 0x2a, 0x01, -0xea, 0x4b, 0x70, 0xf9, 0xd2, 0xb5, 0xb8, 0xda, -0x68, 0x6b, 0xc4, 0xc2, 0xd0, 0xdb, 0x5a, 0xd4, -0xcb, 0xd8, 0xb2, 0xba, 0xf4, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0xd6, -0x7d, 0x71, 0x22, 0x84, 0xe5, 0x0c, 0xcc, 0x9f, -0xed, 0xf7, 0xd7, 0x3b, 0x24, 0xc9, 0x28, 0xb7, -0x54, 0x56, 0xc4, 0xa9, 0xbb, 0xfb, 0x4c, 0x0d, -0xfb, 0xc7, 0xa7, 0xf2, 0x70, 0x3b, 0x05, 0x00, +0x21, 0xeb, 0xbe, 0x0d, 0x3d, 0x1c, 0xf3, 0x9c, +0xbd, 0x92, 0x9f, 0xc2, 0xbb, 0x9f, 0xda, 0xed, +0x70, 0xcf, 0x39, 0x11, 0x21, 0xd0, 0x29, 0xa2, +0xd4, 0xd0, 0x72, 0x6c, 0x3c, 0x18, 0x19, 0xe7, +0x32, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, +0x01, 0x22, 0x21, 0xfe, 0x3c, 0x8b, 0x0f, 0x08, +0x2f, 0xea, 0xa7, 0x1d, 0xa3, 0xea, 0x40, 0x5d, +0xe5, 0xa1, 0x42, 0xad, 0x2b, 0x0e, 0x21, 0x10, +0x9b, 0x42, 0x69, 0x36, 0x2a, 0x47, 0xf3, 0xfb, +0xba, 0x24, 0x42, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x49, 0x01, 0x22, 0x21, 0x3f, 0xca, 0xcb, +0x1a, 0x56, 0x60, 0xd0, 0x29, 0xa7, 0xb5, 0x14, +0xea, 0xce, 0x79, 0x63, 0x40, 0x0e, 0x8a, 0xf3, +0x7f, 0x7d, 0x44, 0x64, 0x15, 0xfd, 0xc5, 0x2d, +0xa4, 0xb6, 0xc9, 0xa1, 0xf1, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0x96, +0x08, 0xcd, 0x58, 0xc5, 0x3b, 0x08, 0x36, 0xf8, +0xf4, 0x6b, 0xd8, 0x32, 0x18, 0x28, 0x6a, 0x50, +0x4f, 0x49, 0x0b, 0xf1, 0xa6, 0x86, 0xfb, 0x30, +0x64, 0x53, 0xb9, 0x81, 0xb3, 0x29, 0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4b, 0x01, 0x22, -0x21, 0x33, 0x19, 0x54, 0x94, 0x9d, 0x08, 0xd5, -0x81, 0xe8, 0x88, 0xf1, 0xf3, 0xb5, 0x34, 0xb5, -0x63, 0xdf, 0xfb, 0xa2, 0x67, 0x31, 0xba, 0x00, -0x20, 0xbe, 0xfd, 0xa2, 0x90, 0x46, 0x49, 0xe2, -0x0e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, -0x01, 0x22, 0x21, 0xf1, 0xb0, 0xd9, 0x88, 0xaf, -0x50, 0x2a, 0x03, 0x1c, 0x71, 0xb7, 0x29, 0xda, -0x2d, 0x59, 0xf3, 0x46, 0xd2, 0x42, 0x08, 0xad, -0x91, 0x1c, 0xcb, 0x11, 0xb7, 0x17, 0x10, 0x8c, -0x8b, 0xba, 0xf0, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x4d, 0x01, 0x22, 0x21, 0x42, 0xbd, 0x03, -0xbd, 0xda, 0x8f, 0xf1, 0xb4, 0x33, 0x75, 0xae, -0x3f, 0xc6, 0xfb, 0xad, 0xc1, 0x88, 0xf7, 0x68, -0x72, 0xe2, 0x6c, 0xf7, 0x0f, 0x50, 0x34, 0x4f, -0x24, 0xe9, 0x04, 0x0c, 0xd3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x8c, -0xd8, 0x2f, 0x49, 0xbf, 0x92, 0x42, 0xa0, 0xe7, -0x7b, 0x66, 0x34, 0x54, 0x4b, 0x5b, 0x97, 0x1d, -0xd7, 0x63, 0x1b, 0xb4, 0xa5, 0x9a, 0x2b, 0x1f, -0x95, 0x8f, 0xe9, 0x4a, 0xb1, 0x82, 0x14, 0x00, +0x21, 0xe4, 0xd4, 0x78, 0x59, 0x2c, 0xdb, 0x8b, +0xb1, 0xc6, 0xd4, 0xa6, 0x87, 0xb6, 0xbd, 0x20, +0x62, 0xcb, 0x72, 0x48, 0x33, 0x80, 0x40, 0x60, +0x24, 0x64, 0x57, 0xc5, 0x19, 0xd2, 0x3d, 0x53, +0x55, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, +0x01, 0x22, 0x21, 0xeb, 0x1a, 0xe7, 0x1b, 0xaf, +0x33, 0xf4, 0x1e, 0x69, 0xc2, 0x7b, 0x1c, 0xa3, +0x6d, 0x0f, 0x6c, 0xbf, 0x80, 0xf6, 0xc4, 0x09, +0x55, 0xb0, 0xcb, 0x1d, 0xa1, 0xf0, 0x53, 0xbd, +0x4c, 0x3b, 0x04, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x4d, 0x01, 0x22, 0x21, 0x41, 0x36, 0x6e, +0x21, 0xbe, 0x03, 0x7e, 0xe5, 0x85, 0xf4, 0xa9, +0xf5, 0xb4, 0x21, 0xa2, 0xc3, 0x6c, 0x8d, 0xcd, +0x1a, 0x99, 0x36, 0x94, 0x42, 0xbd, 0xe4, 0xb3, +0xc7, 0x90, 0x60, 0x94, 0x07, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x51, +0x9e, 0x2d, 0x0d, 0x8b, 0xe4, 0x61, 0xb7, 0xe4, +0xda, 0x27, 0x9c, 0xef, 0x55, 0x50, 0xfc, 0x49, +0xad, 0xc7, 0x5b, 0x42, 0x02, 0x74, 0x17, 0x6f, +0xfe, 0xf3, 0xce, 0x50, 0x11, 0x50, 0xec, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4f, 0x01, 0x22, -0x21, 0xb2, 0x8a, 0x05, 0xe7, 0x34, 0x7a, 0x9b, -0x65, 0x16, 0x0b, 0x21, 0x52, 0x0a, 0xbb, 0x19, -0x7e, 0xf1, 0x9b, 0x35, 0xcf, 0xfc, 0x65, 0x11, -0xeb, 0x29, 0xf3, 0xfb, 0xdb, 0x57, 0x82, 0xec, -0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, -0x01, 0x22, 0x21, 0xd6, 0xcb, 0x85, 0xc7, 0x35, -0x75, 0x51, 0xf4, 0x60, 0xa4, 0x1d, 0x78, 0xad, -0xc6, 0x73, 0x53, 0xf9, 0x8f, 0xe9, 0xe5, 0x8d, -0x06, 0x9a, 0x61, 0x58, 0x6c, 0x5b, 0x28, 0x98, -0xac, 0xd1, 0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x51, 0x01, 0x22, 0x21, 0xa4, 0x03, 0x4f, -0xfe, 0x2e, 0x4a, 0xc3, 0xfa, 0x1f, 0x38, 0x85, -0x1b, 0x98, 0x65, 0x61, 0xc4, 0x6f, 0xcb, 0x30, -0xc3, 0xac, 0xcc, 0x29, 0x32, 0x96, 0x0c, 0x59, -0x12, 0x20, 0x8a, 0xcf, 0x7a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0x4e, -0x24, 0xb5, 0x7d, 0xdd, 0x8e, 0xf7, 0x25, 0x46, -0x99, 0xac, 0x49, 0xab, 0x81, 0x32, 0xce, 0x77, -0xbe, 0x81, 0xb3, 0x1b, 0x21, 0x0d, 0x85, 0xfe, -0xa8, 0x5a, 0x0a, 0xa7, 0xd6, 0xe3, 0xdc, 0x00, +0x21, 0x9c, 0x34, 0x71, 0xd8, 0x65, 0x40, 0xf8, +0x6c, 0xbd, 0xc9, 0x3f, 0x26, 0x7a, 0x24, 0x8a, +0x2a, 0x96, 0xb4, 0x9e, 0x52, 0x6b, 0x54, 0xea, +0x65, 0x80, 0xe8, 0xcc, 0x86, 0xdb, 0x0b, 0xe8, +0x89, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, +0x01, 0x22, 0x21, 0xc5, 0xc1, 0x64, 0xe5, 0x94, +0xd1, 0x29, 0xfe, 0xc6, 0xe6, 0xa0, 0x26, 0x59, +0x08, 0xa4, 0x77, 0xd1, 0x4a, 0x46, 0x88, 0x69, +0xad, 0x51, 0xa3, 0xa9, 0x7b, 0x2c, 0x8a, 0x0f, +0xb6, 0x5c, 0xb0, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x51, 0x01, 0x22, 0x21, 0x15, 0x9d, 0xa1, +0x99, 0xf0, 0x92, 0x79, 0xd1, 0x12, 0x3d, 0x3f, +0xb0, 0x5e, 0x02, 0x50, 0x90, 0xaf, 0x46, 0xfe, +0x4b, 0x1a, 0x3c, 0xd6, 0x78, 0x4d, 0x6f, 0x8d, +0x25, 0x08, 0x76, 0x1a, 0x2b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0xca, +0xbe, 0x98, 0x2c, 0x83, 0x3c, 0x06, 0xb5, 0x22, +0x18, 0xae, 0x27, 0xc0, 0x38, 0xa5, 0x4c, 0xf8, +0x2d, 0x85, 0x5b, 0x08, 0xda, 0x7b, 0x85, 0xf4, +0x69, 0xac, 0x29, 0xc3, 0x3f, 0xf4, 0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x53, 0x01, 0x22, -0x21, 0x71, 0xc3, 0x3e, 0x28, 0xf7, 0xc3, 0xfd, -0xd2, 0xa9, 0xd3, 0x39, 0xfc, 0xf0, 0x6e, 0xcb, -0x61, 0x21, 0x6a, 0xb9, 0xe4, 0x55, 0xa9, 0xbc, -0x81, 0x95, 0xa0, 0x4e, 0x57, 0x7e, 0x44, 0x57, -0x02, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, -0x01, 0x22, 0x21, 0x0c, 0xe2, 0x82, 0x58, 0xdf, -0x99, 0x4e, 0x23, 0xfc, 0x2f, 0xa2, 0x0e, 0x95, -0x98, 0x41, 0x48, 0x6a, 0x0e, 0x0c, 0xdd, 0xde, -0x84, 0xdd, 0x69, 0x31, 0xb9, 0x9a, 0x87, 0x70, -0x21, 0x80, 0x42, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x55, 0x01, 0x22, 0x21, 0xd6, 0x07, 0x34, -0x66, 0x8d, 0xf1, 0x29, 0x34, 0x7c, 0xf2, 0xf5, -0x1d, 0x34, 0xfe, 0x8e, 0x9e, 0x65, 0xc9, 0x87, -0x13, 0x1a, 0xb1, 0x80, 0x4c, 0x3b, 0xd5, 0x4b, -0x89, 0xc3, 0x76, 0xb1, 0xc1, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0xda, -0x10, 0x5e, 0xae, 0x8a, 0xc4, 0xf6, 0x03, 0xb6, -0xee, 0xdf, 0x1b, 0xdf, 0xfa, 0xc8, 0x24, 0x0b, -0xdd, 0xbd, 0xeb, 0xeb, 0x58, 0x46, 0xef, 0x4f, -0x7d, 0xa1, 0xcf, 0xb0, 0x02, 0x60, 0x48, 0x00, +0x21, 0xc2, 0x6c, 0x6f, 0x79, 0x3a, 0x26, 0xff, +0x3b, 0xa1, 0xde, 0xf2, 0x86, 0x35, 0x34, 0x38, +0x55, 0x20, 0xfb, 0x3e, 0x06, 0xe4, 0x11, 0x74, +0xb8, 0xab, 0xc2, 0xd7, 0x0a, 0x09, 0xd3, 0x38, +0x33, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, +0x01, 0x22, 0x21, 0x87, 0xce, 0x6a, 0xa1, 0x3c, +0x06, 0xdf, 0xa6, 0xeb, 0x99, 0xea, 0x06, 0x54, +0x6f, 0x7f, 0x30, 0x76, 0xaa, 0xac, 0xa3, 0xd7, +0x24, 0x11, 0x83, 0xb3, 0x2c, 0xb9, 0x6a, 0x77, +0x37, 0x29, 0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x55, 0x01, 0x22, 0x21, 0x10, 0x08, 0x9b, +0x62, 0xf8, 0x65, 0x9c, 0x98, 0x72, 0xc7, 0xc9, +0x4d, 0x26, 0x98, 0xb3, 0x31, 0x8a, 0x3c, 0x03, +0x99, 0x5c, 0xf1, 0x38, 0xc3, 0x22, 0x11, 0x18, +0x6e, 0x13, 0x8b, 0x85, 0x06, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x87, +0x9c, 0x0f, 0x02, 0x39, 0x6d, 0x57, 0x42, 0xe9, +0x74, 0xfa, 0x79, 0x19, 0x1f, 0xe1, 0x55, 0x84, +0x31, 0x75, 0x27, 0x21, 0xb3, 0x72, 0x2d, 0x4f, +0xd8, 0xa0, 0x17, 0xf1, 0x8b, 0x84, 0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x57, 0x01, 0x22, -0x21, 0x88, 0x46, 0x6b, 0x45, 0xa1, 0x06, 0x4d, -0xc4, 0xba, 0xf8, 0xb2, 0x9a, 0x5d, 0x17, 0xd1, -0x81, 0x48, 0x47, 0x8a, 0x6b, 0xb2, 0x14, 0x59, -0xe2, 0x0e, 0x5b, 0x87, 0x59, 0x30, 0xe6, 0xb8, -0xee, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, -0x01, 0x22, 0x21, 0xd1, 0xc9, 0x7e, 0xc9, 0xcd, -0x28, 0x6b, 0x9a, 0x9e, 0x42, 0xe6, 0x1b, 0x04, -0xa6, 0xd8, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x38, 0x69, 0x17, 0x7e, -0xba, 0x51, 0x22, 0x88, 0x03, 0x04, 0x51, 0x02, -0x00, 0x59, 0x01, 0x22, 0x21, 0x46, 0xac, 0x35, -0xf0, 0x12, 0xd9, 0xde, 0xe7, 0x61, 0x9b, 0x70, -0xc6, 0x9a, 0xa0, 0x91, 0x84, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x2b, -0xbb, 0x49, 0x7d, 0xfa, 0x94, 0x4b, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0x4c, -0xe6, 0x95, 0x14, 0x8e, 0x36, 0x30, 0x5e, 0x4b, -0x3b, 0xf1, 0x3b, 0xc2, 0x8f, 0x72, 0x05, 0x68, -0x03, 0xc7, 0xf6, 0x26, 0xbb, 0x16, 0x0c, 0xf5, -0x5a, 0x30, 0x66, 0x5a, 0xd3, 0xde, 0xeb, 0x00, +0x21, 0xbf, 0xa5, 0x3a, 0x92, 0xee, 0x51, 0x0f, +0xf4, 0x08, 0xd3, 0xe4, 0xd4, 0x6e, 0x62, 0x69, +0x76, 0x73, 0x2e, 0x4f, 0x03, 0xa5, 0x87, 0x0c, +0xbc, 0xc0, 0x3a, 0x7e, 0x71, 0x4e, 0xd8, 0x03, +0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, +0x01, 0x22, 0x21, 0xf3, 0xa5, 0xd0, 0x6d, 0xd4, +0xc3, 0x93, 0x0c, 0xeb, 0xbc, 0xb3, 0x3a, 0xc6, +0x6a, 0x01, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7e, 0x7d, 0x58, 0x08, +0xda, 0xb0, 0x6f, 0x51, 0x03, 0x04, 0x51, 0x02, +0x00, 0x59, 0x01, 0x22, 0x21, 0x6c, 0x99, 0x54, +0x1a, 0x60, 0xa0, 0x85, 0x46, 0xbd, 0xd2, 0xd3, +0x44, 0x31, 0x28, 0x5c, 0x66, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xb5, +0xda, 0x7c, 0x0e, 0x21, 0x47, 0x20, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0x6e, +0xec, 0x0b, 0x26, 0xbf, 0x77, 0xbe, 0x46, 0xcd, +0x81, 0x29, 0x82, 0x65, 0xf1, 0x0e, 0x1d, 0xc5, +0x75, 0xd6, 0xaa, 0xfc, 0xc7, 0x0f, 0x7a, 0xce, +0xe3, 0xc0, 0xf6, 0x35, 0xbc, 0xd9, 0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5b, 0x01, 0x22, -0x21, 0x1c, 0x4f, 0x1a, 0xad, 0x3f, 0x31, 0xbe, -0x0f, 0xc9, 0x3d, 0x07, 0xda, 0x9b, 0xfe, 0x27, -0x19, 0x52, 0xc5, 0x57, 0x11, 0xa5, 0x8f, 0xc0, -0xc8, 0x3d, 0xe8, 0x5b, 0x7b, 0x90, 0xe9, 0x3e, -0x7a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, -0x01, 0x22, 0x21, 0x4f, 0xa4, 0x04, 0x87, 0x72, -0x27, 0x84, 0xf4, 0xa0, 0x1c, 0xf6, 0x69, 0xcb, -0x40, 0x5b, 0x1e, 0xed, 0xa8, 0x49, 0xfe, 0xb9, -0xbe, 0xa4, 0x4d, 0x76, 0x8c, 0x64, 0xe3, 0x76, -0xbf, 0x56, 0x84, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x5d, 0x01, 0x22, 0x21, 0xb8, 0x7f, 0x8b, -0xd5, 0xcb, 0xc0, 0x0a, 0x66, 0x5e, 0xd4, 0xb7, -0x15, 0x15, 0x4c, 0xf3, 0xec, 0x7d, 0xe1, 0xee, -0xf0, 0xdb, 0x30, 0xad, 0x29, 0x68, 0x7b, 0xc6, -0x7c, 0x6d, 0x2a, 0x11, 0x9b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0xde, -0xbb, 0x22, 0x9b, 0xac, 0x08, 0xfd, 0xef, 0x0a, -0x42, 0x79, 0xd9, 0xd0, 0x94, 0xe6, 0xc6, 0x4a, -0xfe, 0x05, 0xe5, 0xe7, 0x56, 0x6b, 0x01, 0xf6, -0x70, 0x96, 0x66, 0xbb, 0xa7, 0xd3, 0xdd, 0x00, +0x21, 0x4f, 0xbd, 0x9a, 0x8a, 0x4f, 0x3d, 0x8b, +0x5b, 0x45, 0xb0, 0x38, 0x85, 0x67, 0x83, 0x63, +0x7a, 0x37, 0xbd, 0x49, 0x8c, 0xb1, 0xeb, 0x32, +0xb9, 0x1a, 0x78, 0x73, 0x7f, 0xbe, 0xdf, 0x55, +0x86, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, +0x01, 0x22, 0x21, 0x52, 0x64, 0x8e, 0xf3, 0x72, +0x08, 0xa2, 0x0a, 0xce, 0xb2, 0x3b, 0xd6, 0x07, +0xab, 0xa9, 0xa1, 0x42, 0x3e, 0x83, 0x6f, 0x63, +0xc4, 0xcb, 0x6e, 0x71, 0x65, 0xad, 0x60, 0x3c, +0x8c, 0xbe, 0x48, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x5d, 0x01, 0x22, 0x21, 0x00, 0xb3, 0x0e, +0x67, 0x8f, 0xc5, 0x00, 0x16, 0xa0, 0xe9, 0xbf, +0x5b, 0x0f, 0x44, 0x7f, 0x95, 0xb0, 0x30, 0x11, +0xc5, 0x43, 0x5d, 0xd9, 0xc2, 0x15, 0x15, 0xfa, +0xee, 0x1c, 0x4c, 0xc6, 0x90, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0xa2, +0x13, 0x10, 0x59, 0x5a, 0xaa, 0x3f, 0x85, 0x63, +0xbc, 0x73, 0xbe, 0xe2, 0x0d, 0xb8, 0x19, 0x20, +0xa1, 0xf5, 0x07, 0x71, 0x71, 0x99, 0x44, 0xb2, +0xe5, 0xf9, 0xb6, 0x8c, 0xcc, 0x08, 0x81, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5f, 0x01, 0x22, -0x21, 0x4f, 0xb0, 0x75, 0x7e, 0xaf, 0x21, 0xc3, -0xd2, 0x4b, 0x62, 0xb0, 0x0e, 0x2e, 0xcb, 0x9e, -0x36, 0x7f, 0x06, 0x64, 0xf8, 0xb1, 0x09, 0xb2, -0xc7, 0x4b, 0x6e, 0xff, 0xf7, 0x98, 0xb3, 0x11, -0xab, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, -0x01, 0x22, 0x21, 0xba, 0xaa, 0xf3, 0xde, 0x64, -0xd2, 0x8d, 0x6c, 0x19, 0xc4, 0x04, 0x47, 0x8f, -0xd1, 0x5b, 0x2b, 0x14, 0xd2, 0x92, 0x3f, 0xd8, -0xc7, 0x3b, 0x67, 0xbc, 0x33, 0xb2, 0x47, 0x83, -0x6c, 0x46, 0x6d, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x61, 0x01, 0x22, 0x21, 0xb8, 0x40, 0xc1, -0x0a, 0x83, 0xd8, 0x2b, 0x54, 0xee, 0xec, 0x7b, -0x77, 0xc4, 0x11, 0x6b, 0x38, 0x91, 0x96, 0xea, -0x3c, 0x9d, 0x6c, 0xd6, 0xe3, 0xa3, 0x07, 0x2a, -0x15, 0x12, 0x16, 0xca, 0x69, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0x0e, -0x6c, 0xbe, 0x26, 0x3d, 0x14, 0x0e, 0x83, 0xa1, -0xc3, 0x74, 0xd7, 0x4f, 0xfa, 0xc8, 0x92, 0x70, -0x52, 0x47, 0x27, 0xe1, 0x7a, 0x9a, 0xe4, 0x1a, -0xf0, 0x9d, 0x82, 0x30, 0xc9, 0xeb, 0xe6, 0x00, +0x21, 0x08, 0x01, 0x1c, 0xf1, 0xcc, 0x69, 0x39, +0x9b, 0x3d, 0xbd, 0xee, 0x85, 0xbe, 0x27, 0x25, +0xd3, 0xcb, 0x71, 0xce, 0x33, 0x90, 0x0a, 0xf4, +0xf1, 0x7b, 0x0e, 0x7e, 0xec, 0xa5, 0xd0, 0x48, +0x7d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, +0x01, 0x22, 0x21, 0xae, 0xf3, 0x49, 0x16, 0xb4, +0xca, 0xc6, 0xe9, 0xaf, 0x47, 0xad, 0x75, 0xef, +0x23, 0xc7, 0x3d, 0xab, 0x2f, 0x2a, 0x95, 0xe7, +0xf8, 0x71, 0x05, 0x0e, 0x1d, 0x78, 0x28, 0x3e, +0xc2, 0xf9, 0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x61, 0x01, 0x22, 0x21, 0xdf, 0x9a, 0x62, +0x51, 0xc9, 0xad, 0xe8, 0x53, 0x3f, 0x0e, 0xa4, +0x9e, 0xfa, 0x6c, 0x02, 0xdb, 0x5b, 0x95, 0x4c, +0xc8, 0x2c, 0xe8, 0x92, 0xfe, 0x89, 0x95, 0xb0, +0xbe, 0x6b, 0x45, 0x5e, 0xe9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0x32, +0xaa, 0x77, 0x75, 0xba, 0xa0, 0x6c, 0x2b, 0xdb, +0xbc, 0x78, 0x0a, 0x78, 0x2a, 0x30, 0x9c, 0x54, +0xe1, 0xf3, 0x6c, 0x68, 0x48, 0x10, 0xdb, 0x76, +0x08, 0xdd, 0x02, 0x32, 0x02, 0x01, 0x9d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x63, 0x01, 0x22, -0x21, 0x5c, 0x14, 0x1b, 0x3f, 0x7e, 0x64, 0x9c, -0x02, 0x14, 0xd2, 0x08, 0x99, 0x1a, 0x24, 0xde, -0xb5, 0x64, 0x01, 0x4f, 0xbf, 0x22, 0x82, 0x9e, -0xe0, 0x6b, 0x19, 0x4f, 0x4f, 0x25, 0xaa, 0xab, -0x45, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, -0x01, 0x22, 0x21, 0xb2, 0x98, 0xb2, 0xc1, 0xfa, -0x0a, 0x66, 0x10, 0xc2, 0xd3, 0x54, 0xd5, 0x05, -0x44, 0xa6, 0x6b, 0x4b, 0x9a, 0xda, 0x48, 0xf1, -0x05, 0x8a, 0x5d, 0x4f, 0xe1, 0xb0, 0xcf, 0xd3, -0x11, 0xbe, 0x51, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x65, 0x01, 0x22, 0x21, 0x3e, 0xc0, 0x71, -0x30, 0x5b, 0x96, 0xe3, 0xc0, 0x92, 0x80, 0x88, -0xdc, 0x41, 0xcc, 0xf6, 0x47, 0xc9, 0xdd, 0x5f, -0xeb, 0x32, 0x24, 0xac, 0x64, 0x01, 0x78, 0xc4, -0x98, 0x9b, 0x25, 0xde, 0x87, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0x7b, -0xf4, 0x99, 0x70, 0x0b, 0x38, 0x37, 0xaa, 0x23, -0x1d, 0x1b, 0xc5, 0xcd, 0x77, 0xe8, 0x60, 0x28, -0xc3, 0x21, 0x21, 0x2d, 0x74, 0x98, 0x5c, 0xe3, -0x8d, 0x56, 0x80, 0x28, 0xd0, 0x0a, 0xac, 0x00, +0x21, 0x4e, 0x66, 0x88, 0x8c, 0x4d, 0xd7, 0x15, +0x5e, 0xf7, 0xeb, 0x50, 0xb4, 0x8f, 0xec, 0xfa, +0x0a, 0x48, 0x0e, 0x24, 0x77, 0x11, 0xb6, 0x31, +0xcf, 0xa8, 0x3c, 0x8b, 0x72, 0x9c, 0x5c, 0xfa, +0x29, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, +0x01, 0x22, 0x21, 0xf0, 0x79, 0xd8, 0xd3, 0x63, +0xa7, 0x7f, 0x72, 0x7c, 0x9c, 0xee, 0xda, 0x0e, +0x1d, 0xfd, 0x6a, 0xc4, 0x87, 0x3f, 0x85, 0xa5, +0xa8, 0xd1, 0x33, 0x10, 0xd4, 0x1f, 0xc4, 0x05, +0x85, 0x6a, 0x61, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x65, 0x01, 0x22, 0x21, 0xd8, 0x7f, 0x4a, +0xeb, 0xf0, 0x86, 0xd0, 0x87, 0xe8, 0xc4, 0x02, +0x18, 0xbd, 0x8d, 0x0e, 0xff, 0xc2, 0xbe, 0x12, +0x38, 0x6d, 0xea, 0x07, 0xfa, 0x36, 0xc3, 0x66, +0xfb, 0x11, 0x9c, 0x26, 0xe6, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0x3d, +0x65, 0xd9, 0xcf, 0x6b, 0xd9, 0x0d, 0x4f, 0x1e, +0x0d, 0x60, 0x86, 0x15, 0xa8, 0x0a, 0x57, 0x8d, +0xf3, 0x2d, 0x10, 0xdf, 0xf4, 0xac, 0xa6, 0x48, +0x10, 0x56, 0x51, 0xbb, 0x7e, 0xdf, 0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x67, 0x01, 0x22, -0x21, 0xa9, 0xed, 0x88, 0xf0, 0xe5, 0xd2, 0xce, -0xfd, 0x72, 0x13, 0x9c, 0x6c, 0x75, 0xe5, 0x38, -0x10, 0x31, 0x6f, 0xd7, 0xe3, 0xbb, 0x3c, 0x0c, -0x88, 0xa3, 0x7b, 0x13, 0xab, 0x1f, 0x16, 0xf0, -0xc6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, -0x01, 0x22, 0x21, 0xb5, 0xd8, 0x28, 0xc3, 0x40, -0xe1, 0xb9, 0x9b, 0xef, 0x15, 0xc3, 0x43, 0xe8, -0xf3, 0x6c, 0x6a, 0x4c, 0x29, 0x08, 0xcc, 0xd8, -0x48, 0x9f, 0x87, 0x59, 0x67, 0x78, 0x79, 0x96, -0x1f, 0xa9, 0x50, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x69, 0x01, 0x22, 0x21, 0x82, 0x7b, 0x67, -0x5e, 0xd1, 0x43, 0x21, 0x03, 0x0c, 0x5e, 0x52, -0x43, 0x16, 0x72, 0xf7, 0xac, 0xc2, 0x93, 0x5c, -0xe3, 0xb4, 0x08, 0xa5, 0xd9, 0xfc, 0x57, 0x6f, -0x92, 0x68, 0x1c, 0x0a, 0x5d, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0xed, -0x7b, 0x98, 0x75, 0x05, 0xc2, 0x2b, 0xc2, 0xf3, -0xe6, 0x7e, 0x7d, 0x20, 0x0e, 0xe0, 0x47, 0x75, -0x91, 0x6a, 0x47, 0xb3, 0x88, 0x99, 0x00, 0xd9, -0x3c, 0xd7, 0xd3, 0x35, 0x91, 0x06, 0x5b, 0x00, +0x21, 0x1b, 0x65, 0x47, 0x7e, 0x3e, 0x12, 0x2a, +0x99, 0x40, 0xd1, 0xac, 0x45, 0x93, 0x33, 0x1d, +0x6e, 0x09, 0xab, 0x1c, 0x5a, 0xba, 0x3c, 0x40, +0xa7, 0x1d, 0x2c, 0x6b, 0xb2, 0xd4, 0x87, 0xfc, +0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, +0x01, 0x22, 0x21, 0xd0, 0xf1, 0x72, 0xbf, 0x75, +0x5a, 0xcf, 0xb4, 0x62, 0x56, 0x00, 0xdc, 0x66, +0x9b, 0x72, 0x39, 0x8d, 0x92, 0x67, 0xd5, 0x6d, +0x90, 0xe4, 0x0c, 0x46, 0x32, 0x1f, 0xe9, 0x68, +0x68, 0xe7, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x69, 0x01, 0x22, 0x21, 0x01, 0x17, 0xf3, +0x0d, 0xfb, 0xdf, 0x0c, 0xdc, 0x74, 0x15, 0xd4, +0xe6, 0xf2, 0x78, 0x27, 0xce, 0x75, 0x6a, 0x5a, +0x31, 0x90, 0xb2, 0xc4, 0x14, 0xee, 0xa0, 0x02, +0xed, 0xf3, 0x24, 0xb4, 0x2f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0xbe, +0x8b, 0x5d, 0xfe, 0x91, 0x2c, 0x11, 0xd5, 0x65, +0xc9, 0x45, 0x21, 0xc7, 0xe0, 0x96, 0x45, 0xab, +0xac, 0x0c, 0xf8, 0xfb, 0x0f, 0x0b, 0x85, 0x9d, +0x8e, 0x93, 0xbf, 0xbc, 0xe2, 0xb0, 0x4d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6b, 0x01, 0x22, -0x21, 0x05, 0x9a, 0xd8, 0x93, 0xf8, 0x40, 0x42, -0x2b, 0xdb, 0x6e, 0xde, 0x37, 0x87, 0xea, 0xef, -0x54, 0x1c, 0x9a, 0xe3, 0x31, 0x6c, 0x43, 0x03, -0x5a, 0x7b, 0x2a, 0x51, 0x57, 0x01, 0x00, 0x4f, -0x7a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, -0x01, 0x22, 0x21, 0x62, 0x72, 0x89, 0x54, 0x9f, -0x86, 0x70, 0x1e, 0xd5, 0xc0, 0xc2, 0x53, 0x32, -0xb0, 0x06, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd3, 0x66, 0xa7, 0xfe, -0xa8, 0xef, 0xf6, 0xba, 0x03, 0x04, 0x51, 0x02, -0x00, 0x6d, 0x01, 0x22, 0x21, 0x0f, 0x18, 0x93, -0x19, 0xd7, 0xcc, 0x49, 0x74, 0x71, 0xe4, 0x10, -0x71, 0xec, 0x29, 0xa8, 0x38, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0xa4, -0xec, 0xd2, 0xec, 0x5a, 0xbc, 0x69, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0xd2, -0x1a, 0xe1, 0xc6, 0xd1, 0x03, 0x8a, 0x89, 0xff, -0x41, 0xbc, 0x4e, 0x37, 0x96, 0xca, 0x78, 0x2c, -0xa7, 0x1b, 0x20, 0x5a, 0x4f, 0x17, 0x0b, 0x1d, -0x47, 0x8e, 0x56, 0x73, 0x91, 0x4e, 0xb8, 0x00, +0x21, 0x56, 0xf1, 0x72, 0xd3, 0x4b, 0xf2, 0x4e, +0x99, 0xb4, 0xe5, 0x78, 0xca, 0xf2, 0x77, 0xe3, +0xf7, 0xa1, 0x47, 0xfc, 0xbb, 0x91, 0x81, 0xfe, +0xfa, 0xd0, 0x31, 0x32, 0x44, 0x62, 0xa4, 0x90, +0xe3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, +0x01, 0x22, 0x21, 0x8b, 0x7e, 0x35, 0x92, 0x54, +0xd8, 0xed, 0x1b, 0xa1, 0x32, 0x04, 0x80, 0x8f, +0x9a, 0x8a, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xb2, 0xfc, 0xb8, 0x1a, +0x5c, 0x71, 0xa0, 0x5f, 0x03, 0x04, 0x51, 0x02, +0x00, 0x6d, 0x01, 0x22, 0x21, 0xf1, 0x98, 0xc8, +0xf8, 0x6f, 0xcf, 0xe4, 0xd3, 0x66, 0x9c, 0x44, +0xda, 0xad, 0x31, 0x65, 0x40, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x6a, +0x6e, 0xdb, 0x2b, 0xba, 0x96, 0xa0, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0x5a, +0x51, 0x38, 0xbf, 0xf6, 0x01, 0xab, 0x29, 0x83, +0x93, 0xf3, 0xe1, 0xf4, 0x03, 0xb6, 0x4e, 0x3e, +0xf5, 0x53, 0xac, 0x17, 0x72, 0x17, 0xbc, 0x39, +0x7f, 0x70, 0x6a, 0x02, 0xc2, 0x7b, 0x56, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6f, 0x01, 0x22, -0x21, 0x29, 0x99, 0x7b, 0x51, 0xdb, 0xcc, 0xc6, -0xbb, 0x5e, 0x8c, 0x21, 0x50, 0xdc, 0xfd, 0xfd, -0x55, 0xf2, 0x64, 0x92, 0x61, 0x7c, 0x7e, 0x4d, -0x8f, 0x04, 0x8f, 0xc8, 0x79, 0x7c, 0x8f, 0xc4, -0x43, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, -0x01, 0x22, 0x21, 0x65, 0x6d, 0xa0, 0xd0, 0x01, -0xe0, 0x8f, 0xb2, 0x0c, 0x9d, 0xc1, 0xcd, 0x53, -0xc3, 0xce, 0x9e, 0x9b, 0xe2, 0x9d, 0x58, 0x33, -0x75, 0xbf, 0x88, 0x14, 0x81, 0x35, 0xf2, 0xc2, -0x68, 0xe4, 0x86, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x71, 0x01, 0x22, 0x21, 0x4d, 0x5f, 0x65, -0x61, 0xfc, 0xfb, 0x65, 0x5c, 0x6f, 0xc6, 0x16, -0x50, 0x08, 0x04, 0xd6, 0x79, 0x39, 0x46, 0xc8, -0xd5, 0xdc, 0x00, 0x5d, 0x2b, 0x31, 0x1b, 0x94, -0xe3, 0xc5, 0x0a, 0x16, 0xbd, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0x84, -0xe9, 0xc5, 0x08, 0x79, 0xcd, 0xbb, 0xf8, 0x19, -0x2a, 0x43, 0x1d, 0xde, 0x36, 0x45, 0x3b, 0xfd, -0xf0, 0xa4, 0x1b, 0x35, 0x55, 0xde, 0x69, 0xab, -0xb3, 0x3b, 0x0e, 0x2f, 0x7a, 0x82, 0xee, 0x00, +0x21, 0x37, 0xe9, 0xbe, 0x4f, 0x63, 0x8f, 0x73, +0x66, 0x61, 0x24, 0x37, 0xfc, 0x51, 0x3d, 0x84, +0xb1, 0x6d, 0x21, 0xd8, 0x39, 0x77, 0xfc, 0xdd, +0x26, 0x0f, 0xde, 0x58, 0xe3, 0x38, 0x16, 0x01, +0xa0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, +0x01, 0x22, 0x21, 0xbd, 0xe5, 0xad, 0x0d, 0xad, +0xad, 0xbf, 0x7a, 0x01, 0x30, 0x3b, 0x46, 0x1b, +0xc7, 0x28, 0xbb, 0x2c, 0x79, 0xa6, 0xd6, 0x0c, +0x7b, 0x10, 0x81, 0x6e, 0x70, 0xa6, 0xfb, 0xee, +0xea, 0x7b, 0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x71, 0x01, 0x22, 0x21, 0xa8, 0x9c, 0x88, +0xaf, 0x98, 0x60, 0xe7, 0x2e, 0x7f, 0x1d, 0xbe, +0x56, 0xdb, 0xce, 0x21, 0x93, 0x25, 0x93, 0x51, +0x0d, 0xef, 0x88, 0x18, 0x81, 0x5f, 0xf5, 0x9b, +0xf1, 0x86, 0x15, 0x96, 0x9f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0x86, +0xe0, 0x61, 0xc6, 0x28, 0x48, 0x34, 0x69, 0xab, +0x25, 0x4f, 0xc0, 0xbe, 0x32, 0x69, 0x57, 0xdf, +0xf2, 0xc4, 0xbe, 0x40, 0x6a, 0x09, 0x57, 0x45, +0xc6, 0xd4, 0xdb, 0x88, 0x3e, 0xb4, 0xb4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x73, 0x01, 0x22, -0x21, 0xae, 0x1d, 0x05, 0x16, 0x36, 0x7d, 0x83, -0x64, 0xf3, 0x41, 0xb5, 0x3e, 0x5f, 0x09, 0xd2, -0x66, 0xf8, 0xb0, 0xb3, 0x52, 0x8e, 0x17, 0x55, -0xf7, 0x69, 0x4d, 0xa7, 0x66, 0xa9, 0xfd, 0x39, -0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, -0x01, 0x22, 0x21, 0x8e, 0x30, 0xc3, 0xe8, 0x4d, -0x8c, 0x07, 0xba, 0xae, 0x4a, 0x71, 0xf9, 0xe8, -0xed, 0x00, 0xca, 0x03, 0xe1, 0x77, 0x35, 0x3d, -0x46, 0x18, 0xec, 0x61, 0xb4, 0xaa, 0xd4, 0xef, -0x44, 0x46, 0x87, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x75, 0x01, 0x22, 0x21, 0x37, 0x00, 0xa9, -0x31, 0xcb, 0x33, 0xd4, 0x40, 0xa2, 0x24, 0x7a, -0xd7, 0x93, 0x65, 0xfb, 0x04, 0x96, 0x8b, 0xc0, -0x77, 0xd5, 0x84, 0x9d, 0x55, 0x85, 0xe2, 0x4e, -0x2f, 0x68, 0xcd, 0xf1, 0x49, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0x42, -0x46, 0x51, 0x02, 0x43, 0x90, 0xc6, 0x76, 0x88, -0xac, 0xad, 0x48, 0xa9, 0x0c, 0x61, 0x68, 0xbc, -0x12, 0x88, 0x41, 0xf4, 0x17, 0x14, 0x0f, 0x9d, -0x73, 0x26, 0xab, 0x94, 0x55, 0x2f, 0x1c, 0x00, +0x21, 0x6e, 0xa1, 0xaf, 0xf2, 0xe7, 0x22, 0x06, +0x60, 0x1b, 0x73, 0x43, 0x31, 0x18, 0x46, 0xd0, +0xf2, 0xcf, 0x72, 0x09, 0x37, 0x5f, 0x02, 0x68, +0xed, 0x0a, 0x8f, 0x8a, 0x59, 0x28, 0x1e, 0x65, +0x4b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, +0x01, 0x22, 0x21, 0xa4, 0x5d, 0x71, 0xb8, 0x13, +0xaf, 0xb7, 0x38, 0xeb, 0x17, 0xdb, 0xd3, 0x5e, +0x9b, 0xd5, 0xca, 0xe9, 0x9d, 0x6f, 0x35, 0x2e, +0x61, 0xd0, 0xc3, 0x52, 0x00, 0xfd, 0x1a, 0xd7, +0xf0, 0x35, 0x18, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x75, 0x01, 0x22, 0x21, 0xf1, 0xb9, 0x39, +0x7c, 0x90, 0x99, 0xcf, 0xed, 0xd7, 0xc1, 0xc1, +0xd0, 0x58, 0x5b, 0x7f, 0x44, 0xde, 0x0f, 0x7d, +0x4e, 0x3f, 0xcd, 0x0c, 0xa7, 0x56, 0xd6, 0xd1, +0xda, 0xbb, 0xa2, 0xd5, 0x6c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0xde, +0x40, 0x1a, 0x61, 0x4b, 0xa4, 0x2c, 0xa3, 0xc5, +0x86, 0xd5, 0x76, 0x9d, 0x1d, 0x38, 0xd4, 0x1d, +0xf2, 0xf8, 0xc6, 0x5a, 0xc1, 0x11, 0x45, 0x53, +0xf1, 0xe6, 0x9f, 0x64, 0xbb, 0x19, 0x72, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x77, 0x01, 0x22, -0x21, 0xad, 0x3e, 0xfa, 0x76, 0x58, 0x21, 0x50, -0x21, 0xaa, 0x7a, 0x14, 0x9a, 0xdf, 0x68, 0xe2, -0x09, 0x21, 0x97, 0xaf, 0xf6, 0xdb, 0x33, 0xc3, -0xc8, 0x7b, 0xd9, 0x8c, 0x23, 0xc1, 0xc5, 0x1f, -0x6c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, -0x01, 0x22, 0x21, 0x08, 0xa6, 0x66, 0x6b, 0x5d, -0xc0, 0x92, 0x28, 0xe4, 0x8d, 0xf8, 0x81, 0x45, -0xe1, 0xf5, 0x59, 0x8e, 0x55, 0xc7, 0x65, 0x79, -0x68, 0x8e, 0xfc, 0xad, 0x00, 0xad, 0x3b, 0xa9, -0xe6, 0xfd, 0x4b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x79, 0x01, 0x22, 0x21, 0x61, 0x48, 0x7e, -0x8b, 0x97, 0x6e, 0x9d, 0x79, 0x7d, 0x6f, 0xbb, -0xf1, 0x34, 0x1d, 0x3f, 0x18, 0xbb, 0xa3, 0x46, -0x20, 0x48, 0xf9, 0x07, 0xe6, 0x83, 0xd2, 0xde, -0x83, 0x85, 0x0e, 0x48, 0x68, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0x22, -0xc4, 0x50, 0x4e, 0x34, 0xd2, 0x70, 0x76, 0xd4, -0xe7, 0xef, 0xfe, 0xf1, 0x21, 0x41, 0x53, 0x7e, -0x50, 0xb5, 0x75, 0x53, 0x1e, 0x36, 0x3d, 0xcd, -0xe3, 0x8c, 0xd4, 0x11, 0xb9, 0xf0, 0x3a, 0x00, +0x21, 0x7f, 0x81, 0x4a, 0x37, 0x9d, 0xa6, 0x7a, +0xfe, 0x72, 0xad, 0xd0, 0x31, 0xda, 0x77, 0xac, +0x9d, 0xb4, 0x5d, 0x72, 0x2e, 0xd2, 0x40, 0xc6, +0xce, 0xc0, 0x42, 0x58, 0xfc, 0x9b, 0x5d, 0x23, +0xe3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, +0x01, 0x22, 0x21, 0x50, 0x24, 0x5e, 0xce, 0xef, +0xdf, 0x2b, 0x40, 0x24, 0xf6, 0xb5, 0x09, 0x7e, +0x78, 0x6a, 0x2b, 0x52, 0x9d, 0xc8, 0x97, 0xed, +0x31, 0x26, 0x22, 0x47, 0x54, 0x59, 0xba, 0x9b, +0x5f, 0xff, 0xaf, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x79, 0x01, 0x22, 0x21, 0x2d, 0x83, 0x3f, +0x9c, 0x79, 0x67, 0x3f, 0xc2, 0x30, 0x2d, 0xac, +0x2e, 0x72, 0x5b, 0x74, 0x3b, 0x1a, 0xa5, 0xf3, +0xe5, 0x16, 0x39, 0x4d, 0x07, 0x7f, 0xcc, 0xc3, +0x0d, 0x89, 0xc7, 0x71, 0xc6, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0xf6, +0x38, 0x35, 0x01, 0xc1, 0xf5, 0x38, 0xc3, 0x0f, +0xa9, 0x99, 0x9d, 0xbd, 0x22, 0xe9, 0x5f, 0xeb, +0xcf, 0x6b, 0x2e, 0x80, 0x0c, 0x55, 0xbc, 0x62, +0xdc, 0x6e, 0x9a, 0x56, 0xce, 0xf2, 0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7b, 0x01, 0x22, -0x21, 0x8a, 0xd9, 0x9a, 0x9a, 0xfe, 0xb2, 0xd0, -0x03, 0x84, 0xce, 0x0f, 0x9f, 0x05, 0x35, 0xed, -0xb9, 0x17, 0x05, 0x99, 0x98, 0x4a, 0x03, 0x7c, -0x5c, 0x44, 0x1c, 0xb4, 0x09, 0x1e, 0x20, 0x69, -0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, -0x01, 0x22, 0x21, 0xa5, 0xd8, 0xf2, 0x25, 0x3b, -0xa5, 0x8a, 0x4a, 0xfb, 0xb8, 0xab, 0xfa, 0x5d, -0x03, 0xb4, 0x32, 0x8b, 0xbd, 0x06, 0x35, 0xdb, -0x8c, 0x78, 0x03, 0x56, 0x45, 0xbc, 0x4c, 0xa0, -0x90, 0x22, 0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x7d, 0x01, 0x22, 0x21, 0xa4, 0xb5, 0x62, -0x4b, 0xae, 0x1d, 0xe5, 0x61, 0x6b, 0xf1, 0xf3, -0xcb, 0x6d, 0x58, 0x76, 0x4a, 0x02, 0xc8, 0xf4, -0x16, 0x81, 0xdd, 0x00, 0x6d, 0x96, 0x83, 0x86, -0xdb, 0x64, 0x4e, 0x1e, 0x57, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0x40, -0x88, 0x7b, 0xf2, 0xb6, 0xce, 0x20, 0xd5, 0xa6, -0x25, 0xca, 0x03, 0xd1, 0x80, 0xfb, 0x4c, 0x16, -0xb2, 0x74, 0x3e, 0xe9, 0x90, 0x32, 0xeb, 0xec, -0x18, 0xa5, 0xba, 0xc2, 0xc1, 0xa2, 0xbb, 0x00, +0x21, 0xf0, 0xf2, 0xc4, 0x88, 0xee, 0x79, 0x24, +0xd9, 0x6a, 0x55, 0xc4, 0x59, 0xf6, 0x4a, 0xfa, +0xa4, 0x00, 0xf3, 0x32, 0xc4, 0xf1, 0x7a, 0x79, +0x93, 0x15, 0xa1, 0x1e, 0x55, 0x95, 0xc8, 0x34, +0x31, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, +0x01, 0x22, 0x21, 0x39, 0xca, 0xe9, 0x4c, 0xf5, +0x48, 0x12, 0xac, 0xb5, 0x53, 0x4f, 0xe5, 0x62, +0xbb, 0x40, 0xe7, 0xa9, 0xe7, 0x0f, 0x74, 0x80, +0x32, 0x5c, 0x51, 0x24, 0x56, 0x7e, 0x41, 0x86, +0x3f, 0xb8, 0x18, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x7d, 0x01, 0x22, 0x21, 0xdf, 0x7d, 0xf8, +0x1d, 0xad, 0xdd, 0x1a, 0x73, 0xb0, 0xe5, 0xfb, +0xe9, 0x34, 0x35, 0x14, 0xb2, 0x6b, 0xb8, 0x14, +0xe8, 0x53, 0xbf, 0x8f, 0x36, 0x17, 0x9a, 0x78, +0x0a, 0x6b, 0xed, 0x4e, 0xd4, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0xc4, +0xb9, 0x58, 0x85, 0xb7, 0x9a, 0x17, 0x59, 0x56, +0x6b, 0x80, 0x2f, 0xb5, 0xaa, 0x40, 0x91, 0xb2, +0x42, 0x29, 0x4b, 0xf3, 0x9c, 0x98, 0xb7, 0x4f, +0x1a, 0xdd, 0x6a, 0x75, 0xf5, 0xbc, 0x16, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7f, 0x01, 0x22, -0x21, 0xbc, 0x92, 0xb9, 0xff, 0x20, 0x4b, 0x53, -0x49, 0xe7, 0x7d, 0xb8, 0x12, 0x16, 0x2a, 0xa9, -0x2a, 0x38, 0x20, 0x00, 0xe2, 0x5d, 0xfc, 0xd4, -0xf9, 0x8d, 0x4a, 0x7b, 0xc2, 0xaf, 0xdf, 0xa1, -0x0d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, -0x01, 0x22, 0x21, 0xba, 0x21, 0xdf, 0x31, 0x2f, -0x84, 0x1f, 0x51, 0x91, 0x1d, 0xd7, 0x6b, 0x38, -0xc8, 0x65, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x8c, 0x72, 0x9e, 0xf3, -0x69, 0x25, 0x27, 0x08, 0x03, 0x04, 0x51, 0x02, -0x00, 0x81, 0x01, 0x22, 0x21, 0x3c, 0x80, 0x2b, -0xb1, 0x06, 0xc7, 0x85, 0x14, 0x4d, 0xf2, 0x81, -0x9c, 0x62, 0xad, 0x7e, 0x50, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xa9, -0x36, 0x8f, 0xc3, 0xc8, 0x0c, 0xa0, 0x03, 0x04, -0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0x2a, -0xc0, 0xcc, 0x82, 0x70, 0x17, 0xf5, 0xe6, 0xb4, -0xdb, 0x2d, 0x75, 0x46, 0x27, 0x19, 0x34, 0x7f, -0x83, 0xb5, 0x34, 0x7d, 0xd4, 0x88, 0xad, 0x07, -0x55, 0xc4, 0xee, 0xbf, 0x6e, 0x0f, 0x2c, 0x00, +0x21, 0xac, 0x2e, 0xb2, 0xd6, 0x11, 0x31, 0x1a, +0xb8, 0x9e, 0x46, 0x79, 0x2f, 0x66, 0x76, 0x92, +0x01, 0xcd, 0x99, 0xe1, 0xbb, 0x02, 0x52, 0x46, +0x60, 0xd1, 0xc8, 0x60, 0xaa, 0xf7, 0x33, 0xaf, +0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, +0x01, 0x22, 0x21, 0x73, 0xed, 0x8b, 0xe8, 0x33, +0x86, 0x67, 0x8c, 0xa3, 0x69, 0x16, 0xcf, 0x0d, +0x5f, 0x79, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x2b, 0x48, 0xad, 0xb4, +0xac, 0x58, 0xf9, 0x3a, 0x03, 0x04, 0x51, 0x02, +0x00, 0x81, 0x01, 0x22, 0x21, 0xaa, 0x10, 0x71, +0x21, 0x23, 0xee, 0xe3, 0x37, 0xfd, 0x15, 0xfa, +0x2f, 0x07, 0x2d, 0x4c, 0xc3, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x21, +0x1c, 0xe7, 0xac, 0x83, 0x5b, 0x09, 0x03, 0x04, +0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0xe5, +0xfc, 0x73, 0x48, 0x60, 0x0d, 0x04, 0xaa, 0x13, +0x19, 0x04, 0x54, 0x9c, 0xc1, 0x5d, 0x41, 0x02, +0x69, 0xb6, 0xdd, 0x53, 0x10, 0xc8, 0x91, 0xed, +0x6c, 0x92, 0x8b, 0xec, 0x28, 0xfc, 0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x83, 0x01, 0x22, -0x21, 0xc1, 0x87, 0x72, 0xac, 0xa3, 0x2d, 0x5f, -0x16, 0x7f, 0xb5, 0x62, 0xc0, 0xba, 0x2e, 0x4b, -0xb2, 0x62, 0x68, 0x43, 0xab, 0x1c, 0x22, 0x90, -0x13, 0x4f, 0xfd, 0x09, 0xcf, 0x6d, 0x40, 0x24, -0x02, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, -0x01, 0x22, 0x21, 0xef, 0xfa, 0x85, 0x76, 0x95, -0x6c, 0x58, 0x58, 0xb4, 0x7b, 0xc1, 0x81, 0x7a, -0x73, 0x1a, 0x04, 0x08, 0x04, 0x01, 0x2c, 0x90, -0x2f, 0xc8, 0xd9, 0x8a, 0x60, 0x62, 0xd4, 0x30, -0x1e, 0x68, 0x20, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x85, 0x01, 0x22, 0x21, 0x72, 0x45, 0xb5, -0xc6, 0xfe, 0x51, 0x61, 0x8f, 0xa4, 0x0f, 0xb7, -0xf9, 0x72, 0xff, 0xfc, 0xa7, 0x4f, 0x8a, 0xb8, -0x23, 0x8f, 0x44, 0x46, 0x4a, 0x65, 0x82, 0x3d, -0x67, 0x83, 0xdc, 0x71, 0x2f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0x8a, -0x39, 0x4a, 0xa5, 0xa0, 0xac, 0x78, 0x77, 0x4e, -0x99, 0x12, 0xb0, 0x79, 0xc1, 0x63, 0xaf, 0xe2, -0xdd, 0xb5, 0x7e, 0x24, 0xcb, 0xa7, 0xf8, 0xc9, -0xf3, 0xf3, 0x52, 0x6d, 0x1f, 0x34, 0xa6, 0x00, +0x21, 0xb5, 0x1c, 0xd2, 0x42, 0x44, 0x92, 0x7f, +0x96, 0xa0, 0x39, 0x8d, 0x63, 0x2b, 0x8a, 0xf8, +0x33, 0x89, 0xf5, 0xda, 0xea, 0xdd, 0x6e, 0xda, +0xee, 0xf8, 0xb9, 0xb6, 0x6d, 0x71, 0xd5, 0xcf, +0x45, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, +0x01, 0x22, 0x21, 0x57, 0xc1, 0x7c, 0xeb, 0x02, +0xcb, 0x15, 0x54, 0x9b, 0x5e, 0x3b, 0x54, 0x6e, +0x0d, 0x19, 0x29, 0xd0, 0x62, 0xee, 0xc8, 0x28, +0x23, 0xcf, 0x4e, 0x6f, 0xb0, 0xb0, 0xd9, 0x5f, +0xc8, 0x5b, 0xc1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x85, 0x01, 0x22, 0x21, 0xdf, 0x9c, 0xe3, +0x37, 0x5a, 0xea, 0xaa, 0x46, 0x94, 0x81, 0xa7, +0x4a, 0xf0, 0x0e, 0xea, 0xd4, 0xda, 0x56, 0x03, +0x95, 0x57, 0xb3, 0xa8, 0x52, 0xc5, 0x64, 0x92, +0x73, 0xd0, 0x69, 0xbb, 0x61, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0x86, +0x90, 0xe5, 0x07, 0x16, 0xeb, 0xe5, 0x74, 0xa0, +0x1e, 0x5b, 0x72, 0xf0, 0x25, 0x38, 0xa8, 0x4c, +0x3d, 0xb8, 0xc2, 0x3a, 0x4f, 0x2b, 0xfe, 0x1f, +0x83, 0x8c, 0xfd, 0x8e, 0x94, 0x24, 0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x87, 0x01, 0x22, -0x21, 0x0b, 0x86, 0x25, 0xba, 0xc6, 0xb3, 0x41, -0x53, 0xdf, 0xa2, 0x4b, 0xde, 0xaf, 0x56, 0xb4, -0x30, 0x08, 0x8f, 0x08, 0x4c, 0x6b, 0xe0, 0x63, -0xb1, 0xe6, 0x0c, 0x64, 0x83, 0x07, 0x21, 0x0a, -0x5f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, -0x01, 0x22, 0x21, 0xf5, 0xbf, 0xd2, 0xab, 0xc3, -0x4e, 0x47, 0x0b, 0x04, 0x00, 0x14, 0x9f, 0x09, -0x4b, 0xd5, 0xc2, 0x7e, 0xd7, 0x0b, 0xfb, 0x05, -0xa8, 0xb6, 0x0c, 0xdf, 0x2d, 0x49, 0x8b, 0xa2, -0xf9, 0xd1, 0xe8, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x89, 0x01, 0x22, 0x21, 0x0e, 0xbe, 0x8e, -0xde, 0x1a, 0x5f, 0x8b, 0xc6, 0x56, 0x46, 0x95, -0x05, 0x07, 0xfd, 0x71, 0x75, 0xe1, 0x9c, 0xdf, -0xe0, 0x48, 0xcd, 0x0c, 0x67, 0xdf, 0x59, 0x74, -0x55, 0xe5, 0x66, 0x48, 0x6e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0x8b, -0x97, 0x3f, 0x99, 0x17, 0x28, 0xfc, 0xde, 0x56, -0x9b, 0xc3, 0x49, 0x72, 0xbf, 0xef, 0x0e, 0x7b, -0x28, 0xb0, 0x20, 0xab, 0x0e, 0x6f, 0x98, 0x91, -0x1a, 0xf3, 0x8c, 0x8e, 0x64, 0xa5, 0x0a, 0x00, +0x21, 0x58, 0xe4, 0xb4, 0x20, 0x28, 0xa5, 0x55, +0x32, 0x09, 0xbd, 0xeb, 0x9b, 0x90, 0x5d, 0xb3, +0x64, 0xa1, 0xd7, 0x16, 0xbb, 0x12, 0xf4, 0xe7, +0xe8, 0xc0, 0x43, 0xd0, 0x22, 0xfa, 0x45, 0x40, +0x6c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, +0x01, 0x22, 0x21, 0x89, 0x7e, 0xda, 0xb7, 0xbe, +0xd1, 0xb8, 0xf4, 0x36, 0xcc, 0x1b, 0x11, 0x3b, +0x04, 0x6c, 0x06, 0x70, 0xe3, 0x90, 0xdb, 0x46, +0x56, 0xae, 0xfd, 0x3b, 0xce, 0xb5, 0xe3, 0x4e, +0xb4, 0x61, 0xc1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x89, 0x01, 0x22, 0x21, 0x27, 0xa0, 0xff, +0x29, 0x4e, 0xeb, 0x16, 0x3a, 0xf7, 0xed, 0xe4, +0xa5, 0x14, 0x7b, 0x2b, 0x68, 0x2a, 0xce, 0xc4, +0x1d, 0x00, 0x14, 0x6c, 0xa6, 0xb7, 0x89, 0xad, +0xfe, 0x10, 0xce, 0x21, 0x7a, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0x84, +0x8b, 0x10, 0xa5, 0x01, 0x4d, 0xa5, 0xb6, 0xa3, +0x8d, 0x43, 0x06, 0x22, 0xee, 0x4b, 0x37, 0x5c, +0x44, 0xa3, 0x4e, 0x24, 0xdb, 0x85, 0xb3, 0x37, +0x13, 0x8d, 0xcc, 0x58, 0xaf, 0xa2, 0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8b, 0x01, 0x22, -0x21, 0xf5, 0x78, 0x6d, 0x2f, 0x0f, 0xed, 0x9c, -0x5b, 0xc7, 0xe6, 0xfa, 0xf0, 0xcd, 0xe3, 0x61, -0xd0, 0x95, 0x49, 0x03, 0x0b, 0x2d, 0x23, 0x6c, -0x83, 0x7d, 0x5a, 0xa8, 0x9c, 0xe2, 0x5c, 0x76, -0x23, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, -0x01, 0x22, 0x21, 0xed, 0x6f, 0x5d, 0x66, 0x61, -0x05, 0x01, 0xe3, 0xdb, 0xad, 0xab, 0xe1, 0x29, -0x6a, 0x49, 0x98, 0xef, 0xb5, 0x75, 0xf2, 0x0b, -0x74, 0x93, 0xb3, 0x8e, 0xcd, 0x64, 0xe6, 0x05, -0x4d, 0xf4, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x8d, 0x01, 0x22, 0x21, 0x31, 0xcb, 0xb7, -0x03, 0x29, 0x46, 0x75, 0x0a, 0x1b, 0xe2, 0xa0, -0xb5, 0x66, 0x21, 0x4f, 0xc6, 0x6e, 0x2a, 0xb1, -0xad, 0x30, 0xc5, 0xd5, 0xb1, 0x57, 0x89, 0x4e, -0x8a, 0xd7, 0x44, 0xf5, 0x42, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x3e, -0xe0, 0x7b, 0x40, 0x6f, 0x2f, 0xaf, 0x28, 0x9a, -0x75, 0xe1, 0xfb, 0xb9, 0x45, 0xf4, 0x60, 0x82, -0x36, 0x3d, 0x9a, 0xff, 0x8e, 0xf7, 0x6d, 0x06, -0xf2, 0x17, 0x0b, 0xfc, 0x01, 0x8f, 0xb7, 0x00, +0x21, 0xb9, 0xc7, 0xb3, 0xad, 0xc2, 0xa6, 0xbf, +0xe0, 0xda, 0xd8, 0x68, 0x21, 0xac, 0x73, 0xe0, +0x3d, 0x5c, 0x66, 0x23, 0x84, 0x2c, 0x26, 0x19, +0x09, 0x3c, 0x19, 0x4e, 0xe0, 0x26, 0x4b, 0xc1, +0x5e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, +0x01, 0x22, 0x21, 0x90, 0xe4, 0x85, 0x07, 0x68, +0x99, 0x71, 0xe1, 0x95, 0xe7, 0x1b, 0xac, 0x8b, +0x65, 0x5e, 0x0e, 0xc0, 0x28, 0x8e, 0xd7, 0x9f, +0x25, 0x27, 0xd2, 0x1a, 0x3b, 0x2d, 0xed, 0xcb, +0x62, 0x7d, 0x11, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x8d, 0x01, 0x22, 0x21, 0x41, 0xcd, 0xf3, +0xa0, 0x8c, 0x84, 0x67, 0xc9, 0xc8, 0x34, 0x27, +0x3e, 0xc8, 0x4b, 0xf1, 0xed, 0x00, 0x61, 0x63, +0xb2, 0x7c, 0xb5, 0xbb, 0x7c, 0xdd, 0xda, 0x73, +0x53, 0x7c, 0x52, 0x88, 0x6d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0xcf, +0xb3, 0x96, 0x78, 0xf8, 0x3b, 0x17, 0x58, 0x8b, +0x4d, 0x87, 0xf5, 0xb1, 0xe4, 0x04, 0xbc, 0x20, +0x41, 0x20, 0xe8, 0xd4, 0x44, 0xde, 0x6c, 0xd5, +0x30, 0x6c, 0x55, 0x23, 0x74, 0x51, 0xe1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8f, 0x01, 0x22, -0x21, 0xd4, 0x95, 0x25, 0xa9, 0x98, 0xec, 0xec, -0xea, 0x4b, 0x5f, 0xa5, 0x42, 0x92, 0x01, 0xc7, -0xb4, 0x7c, 0x5f, 0x50, 0xe3, 0xf4, 0x49, 0x56, -0xa7, 0x31, 0xd7, 0x73, 0xbd, 0xa4, 0xeb, 0x70, -0x54, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, -0x01, 0x22, 0x21, 0xde, 0x58, 0xa5, 0x97, 0x9b, -0x73, 0x3a, 0xb3, 0x43, 0x47, 0x3a, 0x6a, 0x70, -0x2c, 0x67, 0xa4, 0x2a, 0x5c, 0x53, 0x74, 0x14, -0x80, 0xb3, 0x45, 0xe3, 0xa3, 0xa2, 0x50, 0xc3, -0xae, 0xad, 0x86, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x91, 0x01, 0x22, 0x21, 0x41, 0x6f, 0x29, -0x14, 0xd1, 0x1c, 0x3a, 0xaf, 0x30, 0x03, 0xf9, -0x90, 0x46, 0x63, 0x4b, 0x25, 0xeb, 0xa0, 0x86, -0xf7, 0x00, 0x17, 0x27, 0xb2, 0x33, 0x40, 0x0e, -0xa2, 0x7e, 0x0f, 0xc5, 0xbf, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0xcd, -0x58, 0x54, 0xb8, 0x21, 0x33, 0x34, 0xb6, 0x89, -0xfe, 0x8d, 0xf6, 0x28, 0x84, 0xa4, 0xb8, 0x81, -0x9d, 0x12, 0xf7, 0x99, 0x6d, 0x9b, 0x79, 0x8e, -0x8e, 0xcd, 0xa4, 0xd3, 0x5c, 0x5e, 0x73, 0x00, +0x21, 0xc8, 0xdb, 0xdf, 0x1f, 0x03, 0xae, 0x69, +0xb2, 0x2b, 0xc2, 0x5b, 0xf7, 0xac, 0xc3, 0x68, +0xeb, 0xa0, 0xa7, 0x0d, 0x32, 0x7e, 0xf4, 0x4f, +0x17, 0xa0, 0x9f, 0x52, 0x8b, 0xd2, 0x89, 0x10, +0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, +0x01, 0x22, 0x21, 0x53, 0xdf, 0x1c, 0x33, 0xa9, +0xac, 0xd6, 0xd7, 0xf4, 0xae, 0xf0, 0x10, 0x7a, +0x0f, 0xf2, 0x53, 0xba, 0x77, 0x9d, 0x8f, 0xea, +0xb6, 0x75, 0xa3, 0x90, 0xac, 0x73, 0xfe, 0xee, +0xfc, 0xe1, 0x15, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x91, 0x01, 0x22, 0x21, 0xf8, 0xac, 0xee, +0x0b, 0x1e, 0x5d, 0x83, 0x0a, 0xf3, 0xe5, 0xe5, +0x3f, 0xa7, 0xc9, 0x4c, 0x7b, 0xc9, 0x45, 0x3f, +0x9b, 0xb3, 0x8e, 0xf3, 0x2c, 0xae, 0xfa, 0xdd, +0xc7, 0xbe, 0x27, 0x94, 0xb0, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0x31, +0xb4, 0x5c, 0x6f, 0x74, 0x25, 0x90, 0xe4, 0x9b, +0xac, 0x94, 0x9a, 0x10, 0xee, 0xdb, 0xf2, 0xd8, +0xbc, 0x1a, 0xf6, 0x04, 0x5f, 0xb3, 0xb3, 0xf9, +0x78, 0xc0, 0x56, 0x48, 0x9c, 0x6e, 0x7d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x93, 0x01, 0x22, -0x21, 0x72, 0x2c, 0xa0, 0xc1, 0xcd, 0xf6, 0x37, -0x73, 0xe4, 0xa2, 0x02, 0x92, 0xd8, 0x9c, 0x7f, -0x1e, 0x4f, 0xcc, 0xa4, 0xb8, 0x90, 0x41, 0x29, -0x84, 0x07, 0x35, 0x75, 0xce, 0x8f, 0x84, 0xf1, -0x00, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, -0x01, 0x22, 0x21, 0x6a, 0x56, 0xcc, 0xfe, 0x00, -0x2c, 0x98, 0x19, 0xe3, 0x05, 0x9e, 0x47, 0x07, -0x42, 0x19, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xea, 0x6c, 0xc2, 0x86, -0xa5, 0xe9, 0x96, 0x43, 0x03, 0x04, 0x51, 0x02, -0x00, 0x95, 0x01, 0x22, 0x21, 0x72, 0x4a, 0x29, -0x25, 0x5b, 0x02, 0x62, 0x08, 0xd0, 0x60, 0x44, -0xc2, 0x3b, 0x67, 0x79, 0xa6, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x09, -0x2b, 0xf2, 0x44, 0x9c, 0xb6, 0x69, 0x03, 0x04, -0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0x09, -0xf1, 0x92, 0x8f, 0x96, 0xa3, 0x67, 0xf6, 0x5d, -0xa4, 0x4f, 0x78, 0x98, 0x9c, 0xc8, 0x46, 0xeb, -0x63, 0x11, 0xa1, 0xb6, 0x16, 0xe9, 0xf6, 0x0c, -0xa0, 0x48, 0xa2, 0x0e, 0xe9, 0x94, 0x82, 0x00, +0x21, 0xef, 0x06, 0x3d, 0xe9, 0x88, 0x3a, 0x46, +0x3f, 0x42, 0xee, 0x54, 0xb9, 0xf1, 0xca, 0xbe, +0x46, 0x59, 0x05, 0x3d, 0x83, 0xb7, 0x09, 0x49, +0x4a, 0x10, 0x78, 0xd7, 0xb9, 0xf4, 0xe4, 0x69, +0xd2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, +0x01, 0x22, 0x21, 0x20, 0xb4, 0x7f, 0x7e, 0xd5, +0x75, 0x51, 0xf6, 0x78, 0x79, 0xa1, 0xa2, 0x9d, +0x08, 0x42, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xe4, 0xa1, 0xcd, 0x9d, +0x60, 0xc1, 0x81, 0x59, 0x03, 0x04, 0x51, 0x02, +0x00, 0x95, 0x01, 0x22, 0x21, 0x1c, 0x2f, 0xe5, +0xf2, 0xaa, 0x21, 0xff, 0xe4, 0x81, 0x97, 0x48, +0x87, 0xd1, 0x94, 0x5a, 0x93, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xe2, +0x8e, 0xc9, 0x00, 0xcc, 0xe6, 0x07, 0x03, 0x04, +0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0x25, +0xd0, 0x09, 0x31, 0x37, 0xed, 0x5b, 0x16, 0x3a, +0x62, 0xf2, 0xa0, 0xe7, 0x9e, 0xdb, 0x09, 0xdd, +0x00, 0x68, 0xa2, 0x05, 0x0f, 0x1c, 0x37, 0x31, +0x43, 0xfc, 0x3b, 0x88, 0xf2, 0xb1, 0xb0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x97, 0x01, 0x22, -0x21, 0x47, 0x7a, 0x31, 0xb6, 0x18, 0x2a, 0xd1, -0x7a, 0x2d, 0x34, 0xe2, 0x1e, 0x12, 0xbb, 0x65, -0x3b, 0x82, 0xc8, 0xb9, 0x0a, 0x7c, 0xda, 0x40, -0xdf, 0xa0, 0xcb, 0xd4, 0x3d, 0x9d, 0xfe, 0x35, -0x11, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, -0x01, 0x22, 0x21, 0x24, 0x17, 0x8b, 0x02, 0x98, -0x26, 0x9e, 0x7d, 0x66, 0xc4, 0xb1, 0x88, 0x24, -0xeb, 0x87, 0xf4, 0x66, 0x04, 0x50, 0xc3, 0x1b, -0x0c, 0x14, 0x76, 0xcd, 0x81, 0x82, 0x03, 0xa3, -0x32, 0x75, 0x7c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x99, 0x01, 0x22, 0x21, 0xc0, 0x96, 0x32, -0x52, 0xcc, 0x4a, 0x68, 0x18, 0xb2, 0xc6, 0x36, -0x48, 0xf8, 0x82, 0xac, 0x0a, 0xe6, 0xb5, 0xc0, -0x45, 0x27, 0xde, 0x88, 0xb4, 0x82, 0x63, 0x09, -0x8c, 0xf1, 0x2a, 0x97, 0x83, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0x17, -0x1a, 0xa7, 0x87, 0x62, 0x53, 0x0d, 0x5c, 0x20, -0xca, 0x9e, 0xbc, 0x50, 0x3f, 0xf6, 0x23, 0xf1, -0x0d, 0xb1, 0x35, 0xaf, 0x3a, 0x1b, 0xf4, 0x9d, -0x93, 0x44, 0x63, 0x75, 0x8b, 0x5a, 0x15, 0x00, +0x21, 0x76, 0x8a, 0x4d, 0x0d, 0x3d, 0x11, 0x59, +0x3d, 0x9c, 0x7b, 0xe3, 0xce, 0xff, 0x86, 0x0b, +0xc7, 0x20, 0x58, 0xc3, 0x22, 0x38, 0x1c, 0x76, +0xd0, 0xc9, 0xb8, 0x3e, 0xcd, 0x63, 0x28, 0x80, +0x27, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, +0x01, 0x22, 0x21, 0x4f, 0xb9, 0x38, 0x6e, 0xdf, +0x14, 0xa0, 0xf1, 0xa5, 0x5f, 0x33, 0x69, 0x28, +0x9d, 0xfb, 0x56, 0xf3, 0xd9, 0x47, 0xe5, 0x24, +0x72, 0xab, 0x1c, 0x61, 0x34, 0xa6, 0x5d, 0x5d, +0x0e, 0xd9, 0xce, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x99, 0x01, 0x22, 0x21, 0x22, 0xcd, 0x3c, +0x0a, 0x8b, 0x75, 0x80, 0x5d, 0xfe, 0xb3, 0x12, +0x1a, 0x48, 0x71, 0xf1, 0x9f, 0x20, 0xe3, 0xb8, +0xe8, 0xda, 0x9d, 0x99, 0xb0, 0xca, 0x2a, 0xf9, +0x2c, 0x20, 0x0b, 0x94, 0xeb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0x06, +0x20, 0x55, 0xa3, 0x9e, 0x7d, 0x44, 0x26, 0xd0, +0x7b, 0x0d, 0x91, 0x9d, 0x8c, 0xe2, 0x92, 0xd3, +0x4d, 0x0d, 0x2c, 0xe5, 0x86, 0x70, 0xb2, 0x7d, +0x7e, 0x6c, 0x96, 0xe0, 0x6e, 0x53, 0xe6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9b, 0x01, 0x22, -0x21, 0x3e, 0x6f, 0x79, 0x7c, 0x90, 0x04, 0x24, -0xb2, 0x8f, 0x79, 0x4d, 0xe3, 0x91, 0x61, 0xde, -0x0c, 0xe6, 0x60, 0xee, 0x1a, 0x7a, 0x0f, 0x2f, -0x1e, 0xe1, 0x29, 0x30, 0x16, 0x06, 0x4a, 0xec, -0x31, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, -0x01, 0x22, 0x21, 0x6a, 0x88, 0x9a, 0x52, 0x75, -0x5a, 0x50, 0x90, 0x29, 0x17, 0xd4, 0xc8, 0x29, -0xb8, 0x0e, 0x21, 0x82, 0x37, 0xdd, 0xe6, 0x21, -0xbf, 0xf2, 0x3e, 0x26, 0xce, 0x6e, 0x0e, 0x1a, -0x88, 0x92, 0x44, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x9d, 0x01, 0x22, 0x21, 0x4b, 0x53, 0x5d, -0x06, 0xc0, 0xd2, 0x00, 0x75, 0x37, 0xd4, 0xe5, -0xaa, 0x81, 0x26, 0x37, 0xf1, 0x0e, 0xf9, 0x92, -0xab, 0xe1, 0x56, 0xdb, 0x2c, 0x3b, 0x63, 0x92, -0x4f, 0xb1, 0x20, 0xe8, 0x07, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0xd9, -0x73, 0x34, 0xf7, 0x5a, 0xad, 0x14, 0x97, 0x0f, -0xe3, 0x81, 0x9e, 0x29, 0x98, 0x0d, 0x4c, 0xdf, -0x8d, 0x97, 0xad, 0x7a, 0x46, 0x25, 0x2f, 0x6f, -0xf2, 0xcf, 0xc8, 0xbd, 0x91, 0x4b, 0x57, 0x00, +0x21, 0xfb, 0x82, 0xe6, 0x1f, 0xe6, 0x26, 0xd4, +0xe8, 0xf9, 0x68, 0x6c, 0xba, 0xd0, 0x4a, 0xb7, +0xfd, 0xb8, 0x54, 0xe1, 0xb2, 0x82, 0x79, 0x9e, +0x82, 0x56, 0x5f, 0x0f, 0x19, 0x8b, 0xe0, 0x55, +0x23, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, +0x01, 0x22, 0x21, 0x02, 0x8c, 0x5b, 0x8c, 0x88, +0x22, 0xf1, 0xc1, 0x0e, 0x38, 0x29, 0x77, 0x0c, +0x46, 0x0f, 0xe9, 0x64, 0x06, 0x06, 0xcc, 0x74, +0x10, 0xb0, 0x74, 0x73, 0xff, 0x38, 0x33, 0x2f, +0x31, 0xe0, 0x65, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x9d, 0x01, 0x22, 0x21, 0x68, 0xeb, 0xc7, +0x1a, 0x7f, 0x5a, 0x4d, 0x40, 0x47, 0xf0, 0xb2, +0xcb, 0x8d, 0xe3, 0x05, 0xe3, 0xb2, 0x7f, 0xed, +0x61, 0x67, 0xbe, 0xd9, 0x45, 0xef, 0xe0, 0x04, +0x40, 0x8c, 0xdb, 0xd1, 0x3e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0xc7, +0x66, 0x32, 0x87, 0x26, 0xe4, 0x79, 0x39, 0xd8, +0x87, 0xb4, 0x42, 0x7a, 0xce, 0x3b, 0x10, 0xb0, +0xd3, 0xa6, 0x6b, 0x26, 0xc6, 0x11, 0xb7, 0x28, +0x5b, 0x37, 0xbf, 0x98, 0x56, 0x9c, 0x47, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9f, 0x01, 0x22, -0x21, 0xdd, 0xf5, 0x22, 0x57, 0x62, 0xf6, 0x69, -0x9c, 0xe8, 0x53, 0xff, 0xb3, 0x54, 0xb4, 0x72, -0xca, 0xcd, 0x03, 0xe5, 0xfa, 0x5e, 0x8a, 0xad, -0x5e, 0xe6, 0x74, 0x66, 0x4c, 0xce, 0xc8, 0x3b, -0xe7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, -0x01, 0x22, 0x21, 0xa6, 0xfc, 0xdd, 0x91, 0x77, -0x24, 0x34, 0x3d, 0x7b, 0x32, 0x8e, 0xbd, 0x97, -0x29, 0x6b, 0x3f, 0x49, 0xb6, 0xa2, 0xf0, 0xea, -0xdc, 0xdd, 0x94, 0x43, 0xf0, 0x91, 0xe3, 0x9d, -0x57, 0xa4, 0xad, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa1, 0x01, 0x22, 0x21, 0xaf, 0xe7, 0xaf, -0x65, 0x4f, 0x4a, 0x85, 0x5c, 0xc6, 0x90, 0x9f, -0x4b, 0xf1, 0x56, 0x50, 0x0c, 0xf6, 0xda, 0xc5, -0x3c, 0x42, 0x5a, 0x78, 0xbb, 0xb7, 0x81, 0x28, -0xf4, 0xda, 0xe3, 0xd4, 0xcb, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xec, -0x84, 0x01, 0xda, 0x81, 0x24, 0x12, 0x14, 0xf8, -0x8a, 0xe0, 0xfb, 0x3b, 0x62, 0xfb, 0x44, 0x39, -0xcf, 0xd9, 0xe2, 0x9b, 0x48, 0xf9, 0xe8, 0x35, -0x03, 0xfe, 0xae, 0x65, 0xe4, 0xc4, 0x1b, 0x00, +0x21, 0x0b, 0xd7, 0x1a, 0xcd, 0xd6, 0x37, 0x0b, +0xc1, 0x46, 0x11, 0x08, 0x03, 0x2e, 0xda, 0xce, +0x41, 0x22, 0xe9, 0xca, 0x71, 0xb4, 0x1d, 0xd5, +0xcb, 0xd8, 0x19, 0xfd, 0x48, 0x84, 0x72, 0x65, +0x4f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, +0x01, 0x22, 0x21, 0x44, 0xab, 0x01, 0x6c, 0xa1, +0x63, 0xb9, 0x15, 0x44, 0xd0, 0x7d, 0xa8, 0x63, +0xb8, 0xd8, 0x20, 0x76, 0xb6, 0x97, 0xe2, 0x37, +0xfd, 0x4a, 0x5f, 0x6d, 0x90, 0xf6, 0x67, 0xc1, +0x6b, 0x4d, 0xaf, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa1, 0x01, 0x22, 0x21, 0xa6, 0x10, 0xd5, +0x0c, 0x72, 0x26, 0x7a, 0x79, 0x41, 0x33, 0xe4, +0x5a, 0xed, 0xc0, 0x0a, 0x94, 0x88, 0x6b, 0xba, +0x36, 0x1d, 0x23, 0xa0, 0x96, 0xd2, 0x9c, 0x92, +0xb2, 0xc7, 0x01, 0xdb, 0xa2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0x85, +0xbe, 0x6d, 0x7d, 0xd9, 0xd4, 0x87, 0xb2, 0x0c, +0xae, 0x6e, 0x34, 0xb0, 0x00, 0xc5, 0xc5, 0x59, +0x7d, 0xb5, 0xd7, 0xd0, 0xe7, 0xc4, 0x63, 0xe6, +0x3f, 0x22, 0xb5, 0x32, 0xd5, 0x34, 0x9a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa3, 0x01, 0x22, -0x21, 0x2a, 0x7f, 0xa9, 0x4c, 0xa1, 0xfd, 0xe9, -0x00, 0xc9, 0x55, 0x54, 0xd1, 0xf0, 0x02, 0x00, -0x53, 0x17, 0xee, 0x3b, 0x6b, 0xfd, 0xd4, 0x1f, -0x33, 0x73, 0xb9, 0x4f, 0x91, 0x35, 0x78, 0x22, -0xc6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, -0x01, 0x22, 0x21, 0xb8, 0xa1, 0xa6, 0x5d, 0x91, -0xf0, 0xeb, 0x98, 0xb7, 0xe1, 0xd0, 0xff, 0x13, -0xf1, 0x89, 0x93, 0xba, 0x77, 0x9e, 0x22, 0xf1, -0x3d, 0xb9, 0xff, 0x57, 0xca, 0x31, 0x4d, 0x30, -0xb1, 0x67, 0x9a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa5, 0x01, 0x22, 0x21, 0x88, 0xe0, 0xe0, -0x86, 0xd9, 0x9f, 0x46, 0xfc, 0xe5, 0x49, 0x6d, -0xb4, 0x4c, 0xd5, 0x7e, 0x19, 0x37, 0x8f, 0x4a, -0xc0, 0xa2, 0xd1, 0x81, 0x57, 0xf1, 0x6c, 0xf7, -0x8c, 0x7a, 0x4b, 0x0f, 0x5d, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0xf9, -0xc2, 0xe3, 0xd5, 0x09, 0x2f, 0x9e, 0x69, 0x2b, -0x96, 0xba, 0x94, 0xbf, 0x16, 0x25, 0x02, 0x48, -0x00, 0x1f, 0x30, 0x5a, 0x9b, 0xab, 0x3f, 0x29, -0xe2, 0x02, 0xf0, 0x98, 0xde, 0xa7, 0x95, 0x00, +0x21, 0xa9, 0x0e, 0xfd, 0x00, 0x9d, 0xd2, 0xd1, +0x6e, 0xb2, 0xec, 0x0d, 0xc4, 0xfc, 0xc0, 0x29, +0xc9, 0xaa, 0x21, 0xee, 0xb3, 0xef, 0x9d, 0xd1, +0x49, 0xa0, 0xb2, 0x8b, 0x03, 0x7a, 0x68, 0x98, +0x71, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, +0x01, 0x22, 0x21, 0x84, 0xf4, 0xba, 0x08, 0x0a, +0xd3, 0xc9, 0x6a, 0xd5, 0xa5, 0x00, 0x17, 0x96, +0x2d, 0xbb, 0x9c, 0x3d, 0x63, 0xa3, 0x76, 0x22, +0x34, 0xe1, 0x22, 0x08, 0x79, 0x6d, 0xdf, 0x4c, +0xcd, 0xd7, 0x58, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa5, 0x01, 0x22, 0x21, 0x4b, 0x2e, 0xab, +0xa5, 0xbe, 0x91, 0x9f, 0xeb, 0x9b, 0x7b, 0x52, +0xc5, 0xdf, 0x15, 0xe7, 0x86, 0xbe, 0xaa, 0x96, +0xa2, 0x76, 0x92, 0x58, 0x76, 0xc2, 0x33, 0x4f, +0xa9, 0x3c, 0xa0, 0xf3, 0x3a, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0xd3, +0x8b, 0x46, 0xb4, 0xb9, 0x06, 0x72, 0x71, 0xe3, +0xe7, 0x4d, 0xeb, 0xef, 0xf3, 0x2c, 0x0e, 0xd5, +0x01, 0x76, 0x43, 0xec, 0xc6, 0x2d, 0xb4, 0x29, +0x89, 0xbe, 0xf2, 0xaa, 0x85, 0x72, 0x63, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa7, 0x01, 0x22, -0x21, 0x95, 0xdb, 0x8a, 0xc0, 0x66, 0x2f, 0x33, -0x44, 0x4f, 0x68, 0x8d, 0x2a, 0x02, 0x53, 0xc3, -0x7e, 0xff, 0x9d, 0xb2, 0xbc, 0x2e, 0xb4, 0x4b, -0x63, 0x17, 0xd3, 0x11, 0xc1, 0x5d, 0x7d, 0x2d, -0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, -0x01, 0x22, 0x21, 0x84, 0xc3, 0x59, 0xcd, 0x10, -0x21, 0x7a, 0x5c, 0x79, 0xe3, 0xdb, 0x5a, 0xf9, -0x79, 0xb2, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x54, 0xa4, -0xfd, 0x25, 0x90, 0x79, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa9, 0x01, 0x22, 0x21, 0xc7, 0x31, 0xfb, -0x7c, 0x22, 0xb1, 0x47, 0xe7, 0x08, 0x06, 0x25, -0x9f, 0x7a, 0x89, 0x5b, 0xee, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe5, -0x45, 0xf1, 0xce, 0xe0, 0x04, 0xdb, 0x03, 0x04, -0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x81, -0xc3, 0x2e, 0x9b, 0xc8, 0xeb, 0xa8, 0xfe, 0xa5, -0x6e, 0xf8, 0xbc, 0x09, 0xd1, 0xd9, 0x8e, 0xbc, -0x29, 0x8c, 0xbc, 0x23, 0x3d, 0x66, 0xe5, 0xea, -0x13, 0x66, 0x29, 0x4b, 0xd2, 0x81, 0x86, 0x00, +0x21, 0xdb, 0x7e, 0x95, 0x21, 0xa0, 0x01, 0x21, +0xad, 0xaa, 0x09, 0x47, 0xc8, 0xe6, 0xf9, 0xec, +0x3c, 0x21, 0xaa, 0xe1, 0x07, 0x0c, 0x0b, 0x8d, +0x58, 0x46, 0xc2, 0x6a, 0x4e, 0x8a, 0xa5, 0xcf, +0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, +0x01, 0x22, 0x21, 0x57, 0x00, 0x47, 0xa1, 0x8b, +0x1d, 0x6a, 0xc4, 0xbb, 0x15, 0x54, 0x20, 0xac, +0x9c, 0x46, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0xec, 0x8b, 0x53, +0x27, 0xf1, 0x93, 0xaa, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa9, 0x01, 0x22, 0x21, 0x70, 0x2a, 0x2e, +0x07, 0x74, 0xc9, 0xc6, 0xa5, 0x5b, 0x49, 0x5a, +0x6d, 0x27, 0x24, 0x11, 0xb1, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x40, +0xdf, 0xd8, 0xee, 0x26, 0x59, 0x0d, 0x03, 0x04, +0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x62, +0x92, 0xff, 0x7f, 0xb1, 0x2f, 0x62, 0xfe, 0x80, +0x76, 0x17, 0x10, 0x8b, 0x1f, 0xbc, 0x95, 0x4c, +0x82, 0x2a, 0x78, 0x4c, 0x9f, 0x3f, 0x77, 0xbd, +0x6f, 0x78, 0x45, 0x11, 0xb3, 0x07, 0x67, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xab, 0x01, 0x22, -0x21, 0xaf, 0xb0, 0xae, 0x6f, 0x1f, 0x49, 0xec, -0xb5, 0x34, 0x38, 0x91, 0x86, 0x5f, 0x3d, 0xac, -0xc8, 0x02, 0xfe, 0xbf, 0xe8, 0x63, 0x17, 0x60, -0x04, 0x64, 0x5e, 0x67, 0x0a, 0xcb, 0x19, 0x4b, -0x34, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, -0x01, 0x22, 0x21, 0x9a, 0x9b, 0x8d, 0xc4, 0x36, -0x44, 0x75, 0xd7, 0x38, 0xb6, 0x00, 0xd4, 0xc2, -0x48, 0xc0, 0x4d, 0xb6, 0x1c, 0x02, 0xf3, 0xf8, -0xdd, 0x6e, 0x34, 0x30, 0x55, 0x2b, 0xb8, 0x8a, -0x53, 0x49, 0x26, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xad, 0x01, 0x22, 0x21, 0x3d, 0xa4, 0x27, -0x0d, 0x2f, 0x77, 0x37, 0x5d, 0x67, 0x6a, 0x59, -0x1b, 0xbd, 0xe0, 0xae, 0x18, 0x8f, 0x48, 0xb5, -0x10, 0xeb, 0x1c, 0x4e, 0xe8, 0x72, 0x29, 0x44, -0xce, 0x7a, 0x80, 0x96, 0xdc, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0xa3, -0x56, 0xc2, 0x9a, 0x76, 0x47, 0xc1, 0xff, 0x31, -0x92, 0x54, 0x7a, 0xe2, 0x15, 0xc9, 0x45, 0xa3, -0x69, 0x79, 0xa8, 0x04, 0x4c, 0x5d, 0x75, 0x88, -0x32, 0x8e, 0x02, 0xa9, 0xc3, 0xb5, 0x56, 0x00, +0x21, 0x1f, 0x00, 0x9a, 0xaa, 0x65, 0x34, 0x81, +0xaf, 0x19, 0x14, 0xd3, 0xb9, 0x32, 0x91, 0xa3, +0xef, 0xdc, 0xff, 0xd5, 0xb5, 0x54, 0x97, 0xef, +0xb6, 0x15, 0x17, 0x63, 0xfd, 0x46, 0xaa, 0xe6, +0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, +0x01, 0x22, 0x21, 0x49, 0xc8, 0x62, 0xe4, 0xb7, +0x26, 0xe1, 0x0c, 0xd1, 0x92, 0x18, 0x83, 0x1c, +0x48, 0xa2, 0x36, 0xc1, 0xc1, 0xb4, 0x96, 0x5c, +0xe5, 0x2a, 0xf2, 0xaf, 0xb9, 0x9f, 0x31, 0x04, +0x43, 0xba, 0xab, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xad, 0x01, 0x22, 0x21, 0xf0, 0x38, 0xbd, +0x0f, 0x69, 0xff, 0x77, 0x3c, 0x2e, 0xd0, 0x85, +0xd7, 0x32, 0x84, 0x65, 0xb0, 0x80, 0x0a, 0xee, +0x76, 0xcc, 0x4e, 0xd7, 0x4e, 0x7b, 0x75, 0x0d, +0xac, 0x17, 0x3b, 0xe9, 0xa7, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0x97, +0xe2, 0xfa, 0x78, 0xab, 0x17, 0xfb, 0xa5, 0x17, +0x89, 0xb2, 0x6d, 0xd0, 0xec, 0x39, 0x29, 0xdb, +0xda, 0xf1, 0x60, 0xe8, 0x2f, 0x73, 0x52, 0x26, +0x90, 0xed, 0x69, 0xb3, 0x78, 0x91, 0xc7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xaf, 0x01, 0x22, -0x21, 0xbd, 0x34, 0x83, 0x5f, 0xa5, 0xf0, 0x83, -0x0c, 0x21, 0x54, 0x30, 0x02, 0xd8, 0x67, 0x04, -0x8a, 0xc8, 0x59, 0x73, 0x25, 0x50, 0xb5, 0x45, -0x2a, 0x6e, 0x07, 0x5b, 0x57, 0x7b, 0xbe, 0x64, -0x5b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, -0x01, 0x22, 0x21, 0x62, 0xa5, 0x66, 0x45, 0xb3, -0xd1, 0xd1, 0xa9, 0x60, 0x04, 0xa1, 0xbe, 0x62, -0x59, 0x28, 0x9b, 0xcb, 0x10, 0x24, 0x61, 0x92, -0x01, 0xbe, 0x3b, 0x99, 0x72, 0x04, 0x13, 0xf5, -0x62, 0x19, 0x96, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb1, 0x01, 0x22, 0x21, 0xf9, 0x62, 0xcf, -0xb5, 0x41, 0x41, 0x9e, 0x28, 0x60, 0x6b, 0xd4, -0x5a, 0x92, 0xa5, 0xb6, 0x73, 0x76, 0x5a, 0x0c, -0xe4, 0x04, 0xb5, 0x0b, 0xd1, 0xa2, 0xd1, 0xa8, -0x12, 0xb6, 0x91, 0x4b, 0x56, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0xae, -0x00, 0x02, 0x42, 0xbb, 0xda, 0xd7, 0xf4, 0xd7, -0x18, 0xf9, 0x85, 0x14, 0xd0, 0xf6, 0x80, 0xc2, -0x92, 0xca, 0xfb, 0xe5, 0x91, 0x20, 0x66, 0x21, -0x4b, 0xe5, 0x8f, 0x81, 0x38, 0xb6, 0x39, 0x00, +0x21, 0xa7, 0x66, 0x78, 0x0c, 0x23, 0xaf, 0x1a, +0x0b, 0xc6, 0x6e, 0xa9, 0xfc, 0xe9, 0x1f, 0x9a, +0x2a, 0x0c, 0xde, 0xeb, 0x9e, 0x74, 0xc3, 0xd1, +0x98, 0x67, 0xaa, 0xb0, 0x94, 0x72, 0x85, 0xd5, +0x31, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, +0x01, 0x22, 0x21, 0x42, 0x97, 0xd9, 0x78, 0xbf, +0x38, 0xaa, 0x17, 0xd2, 0xef, 0x62, 0x74, 0x1c, +0x70, 0xe9, 0xfa, 0x1a, 0x8a, 0x0d, 0xf7, 0x5d, +0x18, 0xf8, 0x5e, 0x6c, 0x80, 0xf0, 0x37, 0x3f, +0x01, 0xff, 0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb1, 0x01, 0x22, 0x21, 0x07, 0xe1, 0xfe, +0xa1, 0x9f, 0xa0, 0xcd, 0xfd, 0x28, 0xdf, 0x83, +0x8c, 0xf7, 0xdf, 0xb8, 0xd3, 0xad, 0x09, 0x57, +0x90, 0x80, 0x60, 0xbf, 0xc3, 0x4d, 0xee, 0x63, +0x4a, 0x5a, 0x20, 0x42, 0x39, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0xc8, +0xda, 0x48, 0x9e, 0x0c, 0xab, 0x6e, 0x33, 0x45, +0x30, 0x62, 0xec, 0xd2, 0x9b, 0x99, 0xf2, 0xc9, +0x44, 0x81, 0x30, 0x8c, 0x77, 0x6f, 0x1e, 0x74, +0xf3, 0x36, 0xe4, 0xfe, 0x8e, 0x8f, 0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb3, 0x01, 0x22, -0x21, 0xb0, 0x3b, 0x02, 0x49, 0x3f, 0x56, 0x4a, -0xa2, 0xe4, 0x4a, 0x89, 0x53, 0x77, 0x8b, 0x9a, -0x80, 0xbb, 0xb7, 0xbe, 0x3d, 0x50, 0x9b, 0x6f, -0x39, 0xb1, 0x2c, 0xe0, 0x91, 0xd6, 0xc9, 0xa8, -0x10, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, -0x01, 0x22, 0x21, 0xca, 0xa4, 0xe1, 0xf5, 0x55, -0x94, 0x33, 0x89, 0x46, 0x5e, 0xcb, 0x4d, 0x8e, -0xcb, 0xfc, 0xa4, 0x69, 0x7d, 0xc2, 0x42, 0x82, -0xc7, 0x1d, 0xe1, 0x57, 0xf2, 0x73, 0x37, 0xa4, -0x4b, 0xdc, 0xc2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb5, 0x01, 0x22, 0x21, 0xd3, 0xf8, 0xfd, -0xec, 0x16, 0xa6, 0x7d, 0x2c, 0xa8, 0x52, 0x2a, -0xbd, 0xb3, 0xc8, 0xb4, 0xee, 0x63, 0x56, 0x52, -0x8e, 0x04, 0xfb, 0xba, 0x59, 0x3b, 0xf9, 0xe4, -0x4c, 0x2c, 0x3a, 0x4d, 0x8a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0x94, -0x21, 0x12, 0x1a, 0x2a, 0xac, 0xad, 0x99, 0x2d, -0x81, 0x0d, 0xa9, 0x18, 0x06, 0xde, 0x13, 0x1b, -0xb7, 0x99, 0x11, 0xb3, 0x7b, 0xba, 0x9e, 0xd3, -0x14, 0x91, 0xd5, 0x88, 0xcc, 0x06, 0x60, 0x00, +0x21, 0xab, 0x65, 0x22, 0x9b, 0x7a, 0x58, 0xe0, +0x0e, 0x79, 0xc9, 0xda, 0x52, 0x88, 0xe7, 0x77, +0xfa, 0x4c, 0x2d, 0x2f, 0xbc, 0xc2, 0x27, 0x72, +0x47, 0x68, 0x1e, 0x0f, 0x13, 0x39, 0x07, 0x91, +0x84, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, +0x01, 0x22, 0x21, 0xad, 0xa1, 0xb9, 0xd0, 0xff, +0x02, 0x43, 0xaa, 0x3c, 0xdb, 0x8a, 0xfc, 0xf7, +0x79, 0x0a, 0xf3, 0x50, 0xdf, 0xe8, 0x10, 0x19, +0xac, 0x8d, 0xe6, 0x31, 0x46, 0xc8, 0x1b, 0x59, +0xaf, 0xb3, 0x68, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb5, 0x01, 0x22, 0x21, 0x2d, 0x5d, 0x9d, +0x15, 0x2a, 0xaf, 0x11, 0xbd, 0x11, 0x6e, 0x19, +0x54, 0x5a, 0x39, 0xb8, 0x64, 0xd7, 0xbb, 0x98, +0xb3, 0x32, 0x7c, 0x94, 0xe9, 0x54, 0xee, 0xca, +0x4b, 0xfa, 0xf4, 0x6f, 0xb4, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0xc0, +0xd6, 0xf1, 0xe3, 0xc3, 0x30, 0x9f, 0x16, 0x2f, +0x3d, 0x84, 0x24, 0xd3, 0x9b, 0x3d, 0xcd, 0x5d, +0xc4, 0xe8, 0xaa, 0x12, 0x33, 0x37, 0x69, 0xc3, +0xe4, 0x3a, 0xab, 0x7c, 0x9f, 0xb6, 0xaa, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb7, 0x01, 0x22, -0x21, 0x5a, 0x48, 0xcc, 0x9a, 0xc8, 0xad, 0x60, -0xf6, 0x04, 0x58, 0xf4, 0xa7, 0x7b, 0x32, 0xa6, -0x4d, 0x61, 0xfa, 0xd6, 0xf8, 0x6a, 0x17, 0x75, -0x4e, 0x45, 0x28, 0x8b, 0xcb, 0xa3, 0x9b, 0x8a, -0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, -0x01, 0x22, 0x21, 0x51, 0x03, 0xcd, 0x48, 0x3f, -0xb7, 0x2c, 0xde, 0x4c, 0xff, 0x23, 0x51, 0x14, -0x90, 0xb6, 0x68, 0x44, 0x42, 0xdc, 0x08, 0xb8, -0xb5, 0xf5, 0x76, 0xf3, 0xaa, 0x99, 0x33, 0xae, -0x19, 0x36, 0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb9, 0x01, 0x22, 0x21, 0x2b, 0xb3, 0x72, -0x67, 0x05, 0xae, 0xbb, 0xb1, 0x46, 0x0a, 0xe4, -0xd2, 0x43, 0xd0, 0x19, 0x88, 0x26, 0x37, 0x30, -0x7e, 0x00, 0xb8, 0x5a, 0x0d, 0xb0, 0x0a, 0xe3, -0x5f, 0x65, 0xa5, 0xc4, 0x8c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0xc0, -0xa8, 0xc5, 0xd8, 0x5b, 0x4d, 0xbb, 0x48, 0xc3, -0x05, 0x83, 0xe9, 0x16, 0xf8, 0x2a, 0xcf, 0x21, -0x47, 0xde, 0x07, 0x13, 0x79, 0xa7, 0x60, 0xf3, -0x65, 0x30, 0x05, 0x3e, 0x9c, 0x8c, 0x87, 0x00, +0x21, 0x1a, 0x48, 0xb1, 0xe4, 0x9a, 0xdc, 0x61, +0x47, 0xbd, 0x4b, 0x8e, 0x20, 0x8d, 0xbf, 0x29, +0xb8, 0x7a, 0x17, 0xef, 0xc4, 0xbd, 0xa4, 0x9b, +0x3f, 0x03, 0x18, 0xd5, 0xf5, 0x6f, 0xd9, 0x5e, +0xea, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, +0x01, 0x22, 0x21, 0x78, 0xab, 0xf1, 0x0d, 0x58, +0xd8, 0x54, 0xc4, 0xcd, 0x94, 0x91, 0x9b, 0x99, +0x90, 0x3e, 0xe0, 0xd3, 0xef, 0x0a, 0x2d, 0x4c, +0x0d, 0xd3, 0x29, 0xde, 0xb8, 0x3e, 0x37, 0x54, +0xa2, 0xa4, 0x5e, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb9, 0x01, 0x22, 0x21, 0xfb, 0x60, 0xec, +0xed, 0xe6, 0xe4, 0x33, 0xf0, 0x09, 0x12, 0x8c, +0x0f, 0x89, 0xf9, 0xac, 0x84, 0xbb, 0x04, 0x5d, +0xcb, 0x8b, 0x63, 0x56, 0xb2, 0x3b, 0x73, 0x6f, +0xc3, 0xfb, 0x02, 0x1d, 0xd9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0xd2, +0x65, 0xcf, 0x2a, 0x6b, 0x8d, 0xd6, 0x5f, 0x56, +0x94, 0x0d, 0x37, 0x4f, 0xe6, 0x2d, 0x5d, 0x3c, +0x52, 0x5e, 0xe6, 0xe3, 0x61, 0x04, 0x11, 0x59, +0x9f, 0xfa, 0xfd, 0x2b, 0x33, 0xce, 0x7c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbb, 0x01, 0x22, -0x21, 0x01, 0x13, 0x1f, 0xb7, 0xce, 0xb6, 0x06, -0xe2, 0x10, 0x5b, 0x6f, 0x6a, 0x75, 0x67, 0x4c, -0x07, 0x21, 0x30, 0xc8, 0x87, 0x13, 0xd7, 0x99, -0x8a, 0x91, 0xa6, 0xa9, 0x34, 0xf1, 0xeb, 0x8d, -0xd4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, -0x01, 0x22, 0x21, 0x3c, 0xd3, 0xbd, 0x29, 0xcb, -0xda, 0xa3, 0x70, 0x22, 0x07, 0xdf, 0x8f, 0x5c, -0xb2, 0x1c, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x70, 0x1d, 0x0e, 0x9a, -0xe0, 0x5f, 0x3c, 0xb0, 0x03, 0x04, 0x51, 0x02, -0x00, 0xbd, 0x01, 0x22, 0x21, 0xe4, 0x8d, 0xc6, -0x12, 0x79, 0x64, 0xd4, 0xcb, 0xc2, 0xd7, 0x96, -0x32, 0x5e, 0x9e, 0x0e, 0x7d, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xda, -0x7e, 0x17, 0x15, 0xbf, 0x54, 0xbd, 0x03, 0x04, -0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0x27, -0x89, 0xaa, 0xb7, 0x22, 0x19, 0xeb, 0x60, 0xa6, -0x05, 0x27, 0x89, 0xa0, 0xf4, 0x33, 0xcf, 0xf2, -0xbb, 0xc2, 0x5b, 0xea, 0x34, 0xf7, 0xc0, 0x7e, -0x6c, 0x3e, 0x3a, 0xa8, 0x6b, 0xea, 0x45, 0x00, +0x21, 0x7a, 0xab, 0xf9, 0x2c, 0x94, 0x1a, 0xc3, +0x45, 0x04, 0x89, 0x08, 0xc8, 0x04, 0x3d, 0x64, +0x80, 0xf0, 0x74, 0x3b, 0xa7, 0x65, 0xe6, 0xb1, +0xed, 0x5a, 0xbc, 0xb9, 0x94, 0x2f, 0xbf, 0x96, +0xf7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, +0x01, 0x22, 0x21, 0xa5, 0xf4, 0xbd, 0xbc, 0x94, +0x4e, 0x4f, 0x9b, 0x8d, 0x07, 0x14, 0xe5, 0x4e, +0x37, 0xe2, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x5e, 0x0c, 0xbc, 0x4a, +0x1f, 0x6e, 0xbb, 0xd2, 0x03, 0x04, 0x51, 0x02, +0x00, 0xbd, 0x01, 0x22, 0x21, 0x14, 0xed, 0x26, +0x72, 0x32, 0x2a, 0x62, 0x74, 0xad, 0xee, 0x7e, +0x7f, 0xa1, 0xe9, 0x2a, 0x38, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x46, +0x05, 0xc4, 0x09, 0x78, 0x11, 0xb3, 0x03, 0x04, +0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0xc1, +0x3c, 0x3d, 0xf6, 0x67, 0x56, 0x2d, 0x19, 0x72, +0x00, 0x03, 0xed, 0xcf, 0x2f, 0x5a, 0x36, 0xa8, +0x5f, 0x2d, 0xca, 0x2c, 0x2e, 0xb5, 0xa5, 0x6b, +0x85, 0x2f, 0xbd, 0xb3, 0x2a, 0x1e, 0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbf, 0x01, 0x22, -0x21, 0x87, 0xa7, 0xcd, 0x5b, 0x10, 0x86, 0x28, -0x3d, 0x4e, 0xe4, 0xd8, 0x29, 0x85, 0x94, 0x38, -0x0a, 0x1e, 0x9e, 0xb7, 0x83, 0x07, 0xca, 0x74, -0xd4, 0x30, 0xe8, 0x1a, 0xc5, 0xef, 0x0a, 0x1c, -0x63, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, -0x01, 0x22, 0x21, 0x8b, 0x43, 0xc7, 0x08, 0x51, -0xe0, 0x53, 0xf2, 0x93, 0xa1, 0x0d, 0x51, 0x39, -0x06, 0x04, 0xe7, 0x49, 0x3a, 0xb9, 0xd1, 0x64, -0xe9, 0xad, 0x52, 0xf6, 0xc9, 0xea, 0xe6, 0x85, -0xd0, 0x1a, 0x19, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc1, 0x01, 0x22, 0x21, 0xf3, 0x4a, 0xb3, -0xce, 0xe2, 0xee, 0x13, 0xc9, 0x4d, 0xfe, 0x47, -0x09, 0x89, 0x80, 0xc0, 0xbe, 0x2f, 0x0b, 0xb3, -0x5c, 0x06, 0x51, 0x05, 0xc0, 0xd4, 0x7f, 0xd6, -0x6a, 0x72, 0xcd, 0xa4, 0x2b, 0x00, 0x03, 0x04, +0x21, 0x96, 0xf7, 0x2f, 0xe9, 0x33, 0xae, 0x86, +0xee, 0x0e, 0xb9, 0x90, 0xc6, 0xcf, 0xd6, 0x73, +0x71, 0x41, 0xd1, 0x99, 0xe3, 0x3c, 0xd7, 0xd7, +0xaf, 0x5a, 0xb2, 0x3c, 0x70, 0x7e, 0xea, 0xf8, +0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, +0x01, 0x22, 0x21, 0x39, 0x2c, 0x59, 0xfa, 0xf9, +0xd5, 0xc7, 0x39, 0xf4, 0x3b, 0x30, 0x39, 0x3c, +0xcb, 0x61, 0x30, 0xb4, 0x3e, 0x43, 0xb0, 0x5f, +0x0c, 0x34, 0xb6, 0x7e, 0xe9, 0x51, 0x1a, 0xb2, +0xcc, 0x97, 0xfc, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc1, 0x01, 0x22, 0x21, 0xfa, 0xd8, 0x72, +0x3f, 0x5f, 0x12, 0xd2, 0x13, 0x75, 0xb9, 0x0d, +0x3c, 0xc6, 0xd9, 0xaa, 0x5b, 0x0a, 0xe0, 0x21, +0xfb, 0x5f, 0x0b, 0x07, 0x7f, 0x51, 0xce, 0x28, +0x75, 0x20, 0xa3, 0xb9, 0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0xce, -0xa9, 0x02, 0xd8, 0xaa, 0x7b, 0xe1, 0x3a, 0xa4, -0xef, 0x8d, 0xd8, 0x82, 0x72, 0xfd, 0x53, 0xcd, -0xa5, 0x41, 0x82, 0x08, 0x99, 0x2c, 0x1d, 0xca, -0x7b, 0x73, 0x77, 0x65, 0x0f, 0xeb, 0xd7, 0x00, +0x43, 0x48, 0x7f, 0x9a, 0x59, 0x65, 0xfa, 0x35, +0x09, 0xb4, 0xb5, 0xb8, 0xa7, 0x3f, 0xf8, 0xb4, +0xda, 0x34, 0x41, 0x90, 0x70, 0xde, 0xdf, 0x31, +0xe4, 0xa9, 0xf6, 0x33, 0xbc, 0xec, 0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc3, 0x01, 0x22, -0x21, 0x4e, 0x71, 0x38, 0x2f, 0x66, 0x88, 0x93, -0xf4, 0x72, 0x5f, 0x8c, 0x69, 0x64, 0x2b, 0x17, -0x54, 0x6b, 0xdd, 0x4d, 0xef, 0x3a, 0x8d, 0x49, -0x1c, 0x8a, 0x50, 0x29, 0x7b, 0x1f, 0xc8, 0x83, -0x9f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, -0x01, 0x22, 0x21, 0x9e, 0x5f, 0x30, 0xcf, 0x4c, -0xf2, 0x4a, 0x4b, 0xb1, 0xe9, 0x4d, 0x46, 0x34, -0x3e, 0x3b, 0xce, 0x0f, 0x71, 0x55, 0x1b, 0x13, -0x8f, 0xd4, 0x76, 0xa3, 0x67, 0xaf, 0xf7, 0xfa, -0xe1, 0x9a, 0x94, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc5, 0x01, 0x22, 0x21, 0x30, 0x4f, 0x4a, -0xd1, 0x25, 0x0e, 0xaa, 0xe0, 0x13, 0xdc, 0x49, -0x17, 0xaf, 0x0d, 0xae, 0xeb, 0x7c, 0xcf, 0x97, -0xfa, 0x62, 0xa1, 0x6f, 0x5b, 0xd7, 0x78, 0xea, -0x59, 0x21, 0x0a, 0x26, 0x43, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0x88, -0x1b, 0xad, 0x16, 0x2e, 0x25, 0xa2, 0xcc, 0x0e, -0x61, 0x93, 0xec, 0x20, 0xe7, 0xc9, 0x02, 0x17, -0x68, 0x49, 0x85, 0x9d, 0xd8, 0x06, 0x52, 0xc9, -0xf3, 0x43, 0xbc, 0xfb, 0xa3, 0xbe, 0x9f, 0x00, +0x21, 0x63, 0xae, 0x0c, 0xfa, 0x69, 0x5d, 0x86, +0x2c, 0x0e, 0x22, 0x63, 0xd1, 0xb3, 0xe9, 0x74, +0x70, 0x29, 0x6d, 0xe0, 0x77, 0x72, 0x04, 0xff, +0xd3, 0x6b, 0x00, 0x06, 0x44, 0xac, 0x81, 0xad, +0xca, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, +0x01, 0x22, 0x21, 0xff, 0x16, 0x53, 0xd5, 0xed, +0xa1, 0x07, 0x8f, 0x90, 0x9f, 0x3e, 0xc6, 0x41, +0x1a, 0x5d, 0xdc, 0xbe, 0xb6, 0xbe, 0xef, 0x6e, +0xbf, 0xcc, 0xf9, 0x43, 0x37, 0x9e, 0xdb, 0x45, +0x6f, 0x95, 0x83, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc5, 0x01, 0x22, 0x21, 0x5c, 0xca, 0xdd, +0xc9, 0xb9, 0xf6, 0xb0, 0x1a, 0x76, 0x35, 0x07, +0x91, 0x32, 0x02, 0x54, 0xa7, 0xbb, 0xd4, 0xdc, +0x61, 0xc4, 0x65, 0x67, 0x33, 0xa1, 0x02, 0xed, +0xa1, 0x62, 0xf5, 0x72, 0x3b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0x78, +0x00, 0x76, 0x87, 0x1b, 0x8d, 0xe4, 0xd8, 0x22, +0x4a, 0xc2, 0xc4, 0x22, 0xda, 0x00, 0x13, 0x05, +0x09, 0xb3, 0x8f, 0x59, 0xed, 0x67, 0x31, 0x7b, +0xcb, 0xbd, 0xdb, 0x3d, 0x82, 0x50, 0xb0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc7, 0x01, 0x22, -0x21, 0x8f, 0xa6, 0xba, 0xe9, 0xce, 0xd0, 0x6a, -0xe0, 0x87, 0x8d, 0x05, 0xea, 0xa5, 0x1a, 0x67, -0x49, 0x5a, 0x6f, 0xf5, 0xae, 0x3c, 0x51, 0x28, -0xfc, 0x9d, 0x9b, 0x2a, 0x6d, 0xfd, 0x86, 0x21, -0xa2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, -0x01, 0x22, 0x21, 0x7e, 0x71, 0x05, 0xc1, 0x03, -0x10, 0x45, 0x3d, 0x1e, 0xbf, 0x1e, 0x47, 0x66, -0xda, 0x19, 0x14, 0x22, 0x62, 0x43, 0xd5, 0x68, -0x8e, 0xe4, 0x9d, 0x3e, 0xe3, 0xe8, 0xd3, 0x3c, -0xd9, 0x0e, 0x81, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc9, 0x01, 0x22, 0x21, 0xe2, 0xe6, 0x06, -0xb1, 0x12, 0x13, 0x21, 0xf9, 0xfb, 0x0a, 0x19, -0x1f, 0x63, 0x7a, 0x82, 0x94, 0xb6, 0xe8, 0x64, -0xa9, 0x23, 0xe8, 0x8f, 0x41, 0x12, 0x69, 0x3c, -0xd8, 0xcc, 0x42, 0xe4, 0x27, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0xad, -0xde, 0x5d, 0x5c, 0x3b, 0x17, 0x09, 0x9c, 0xe6, -0xbc, 0x10, 0x53, 0x93, 0xb1, 0x54, 0x62, 0x84, -0xdb, 0x58, 0xe6, 0x6e, 0xbc, 0xcb, 0x33, 0x52, -0xbe, 0xeb, 0x59, 0xa6, 0x97, 0x7e, 0x4d, 0x00, +0x21, 0x23, 0xea, 0x2f, 0xd1, 0x67, 0x45, 0xc3, +0x43, 0xc0, 0x78, 0xe0, 0x9f, 0x49, 0xff, 0xda, +0x3d, 0x02, 0x56, 0x79, 0x86, 0x0a, 0xd3, 0xdb, +0xb9, 0x2a, 0x95, 0x71, 0x2b, 0x60, 0xcf, 0x6a, +0x7b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, +0x01, 0x22, 0x21, 0x1c, 0x98, 0x85, 0xaf, 0xa5, +0x1c, 0x00, 0x55, 0x37, 0x52, 0x18, 0xf0, 0x46, +0x1a, 0x32, 0xc2, 0x4f, 0x00, 0x58, 0xd1, 0x07, +0xde, 0x80, 0x5a, 0xec, 0x30, 0xc4, 0x8c, 0x44, +0xf8, 0xdb, 0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc9, 0x01, 0x22, 0x21, 0xcb, 0x2f, 0xa3, +0x50, 0x6e, 0xef, 0x7b, 0xf6, 0x05, 0x5a, 0x0f, +0x09, 0x76, 0x29, 0x2c, 0x33, 0xbb, 0x85, 0xf0, +0x24, 0xf0, 0xd8, 0x90, 0x89, 0x3a, 0x59, 0x1e, +0xac, 0x2d, 0xac, 0xec, 0x74, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0xaf, +0x43, 0x52, 0x0e, 0x0a, 0x8d, 0x7d, 0x71, 0xb2, +0x6a, 0xd2, 0xe9, 0xcf, 0x36, 0xc1, 0x3c, 0x2f, +0xb7, 0x1f, 0x51, 0xef, 0xec, 0xf3, 0x32, 0xf0, +0x6b, 0xc3, 0x2c, 0x27, 0x55, 0xfc, 0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcb, 0x01, 0x22, -0x21, 0x9a, 0x21, 0xb8, 0x5b, 0x59, 0xdd, 0x62, -0xa6, 0x61, 0xb1, 0x9e, 0xa5, 0xc2, 0x48, 0x3d, -0x41, 0xfc, 0x46, 0x65, 0x22, 0x2e, 0xe8, 0x47, -0x62, 0xa7, 0xaa, 0x14, 0x35, 0x18, 0x23, 0xa4, -0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, -0x01, 0x22, 0x21, 0xa0, 0x1e, 0xf9, 0xd4, 0x47, -0xa5, 0x06, 0xbf, 0xbb, 0x4d, 0x24, 0xd0, 0xad, -0x2d, 0x3a, 0x77, 0x2a, 0xb5, 0x34, 0x6a, 0xec, -0x70, 0x8e, 0x64, 0x7e, 0x8d, 0x0e, 0x99, 0xeb, -0xd2, 0xe1, 0xe2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xcd, 0x01, 0x22, 0x21, 0x5e, 0xad, 0xaa, -0xb3, 0x19, 0xd2, 0xc2, 0x67, 0xd5, 0xd2, 0x8f, -0xbd, 0xbb, 0x28, 0xea, 0xf1, 0xb5, 0xeb, 0x83, -0x30, 0xbc, 0x54, 0xde, 0x36, 0x74, 0x6f, 0xd1, -0x42, 0x73, 0x10, 0x67, 0xd6, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0x69, -0x23, 0x67, 0x9d, 0x08, 0xd7, 0x1d, 0x49, 0x2d, -0x53, 0xeb, 0x53, 0xed, 0x38, 0xc1, 0xdd, 0xf3, -0xc1, 0x5f, 0x0a, 0x4d, 0x58, 0x45, 0x56, 0xd7, -0xaa, 0x4e, 0x84, 0xa3, 0x12, 0x4f, 0x71, 0x00, +0x21, 0xb9, 0x5d, 0xb5, 0xb9, 0xae, 0xb3, 0x52, +0x5e, 0xcd, 0x9d, 0x6b, 0xf1, 0x30, 0xfe, 0x1a, +0x9e, 0x62, 0x21, 0x58, 0xc9, 0x20, 0x3c, 0x51, +0x82, 0x5d, 0x10, 0x3e, 0x8c, 0x95, 0x5e, 0x52, +0x86, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, +0x01, 0x22, 0x21, 0x20, 0x40, 0x8e, 0xee, 0xb5, +0x69, 0xda, 0xd7, 0xab, 0x11, 0x97, 0x58, 0x5f, +0xe6, 0x50, 0x38, 0xa2, 0x10, 0x4e, 0xa2, 0xae, +0xac, 0x5b, 0xbd, 0x84, 0x1e, 0x49, 0xa7, 0xd0, +0x72, 0x17, 0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xcd, 0x01, 0x22, 0x21, 0x58, 0x35, 0xb2, +0xa4, 0xa9, 0xd1, 0x84, 0x1a, 0xe2, 0xcf, 0x12, +0xfa, 0xc9, 0xb2, 0xc3, 0xa0, 0x31, 0x55, 0x4b, +0xbd, 0x01, 0x5f, 0x69, 0x28, 0x0e, 0x92, 0xca, +0x9e, 0x86, 0x98, 0xcf, 0xfa, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0x42, +0x1b, 0x7c, 0xe7, 0x6b, 0x7b, 0x53, 0xea, 0x36, +0x9b, 0xe7, 0x7e, 0x90, 0x54, 0x23, 0xe9, 0xff, +0x6c, 0xe0, 0x66, 0x66, 0xde, 0xf7, 0x83, 0x64, +0xeb, 0x84, 0xb7, 0x6b, 0x0e, 0xb4, 0x62, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcf, 0x01, 0x22, -0x21, 0x2b, 0xc8, 0xae, 0x57, 0xae, 0x72, 0x06, -0xb0, 0x33, 0xcf, 0xcd, 0x23, 0xfb, 0x8f, 0x6f, -0x89, 0xf2, 0x71, 0x6f, 0xb3, 0xc6, 0xa4, 0x3d, -0x27, 0x56, 0x22, 0xb4, 0x21, 0x0e, 0x87, 0xe7, -0xcd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, -0x01, 0x22, 0x21, 0x64, 0x6e, 0xf8, 0x17, 0x64, -0x2c, 0xe8, 0x35, 0x7e, 0xf5, 0x32, 0x22, 0xf1, -0x93, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x3f, 0xef, 0x7b, 0xe4, -0x11, 0x15, 0xed, 0x84, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd1, 0x01, 0x22, 0x21, 0xc2, 0xe8, 0x37, -0xcd, 0xb3, 0xa3, 0x40, 0xae, 0x01, 0xbc, 0x53, -0x97, 0x03, 0x8d, 0xea, 0x47, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x4d, -0x58, 0x60, 0xe6, 0x7b, 0x5b, 0xba, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x7b, -0x53, 0x71, 0xed, 0xcb, 0xd9, 0x32, 0x7b, 0x0e, -0xc0, 0xa3, 0x10, 0x91, 0x1f, 0x06, 0xb2, 0x42, -0xe6, 0x19, 0x82, 0x08, 0xc5, 0x95, 0xbe, 0x6c, -0x1d, 0xe1, 0x13, 0x58, 0x55, 0xb6, 0xc2, 0x00, +0x21, 0x1f, 0x5f, 0xd7, 0xcd, 0xc9, 0x8b, 0x6d, +0x71, 0xe3, 0x60, 0xbc, 0xb8, 0xd1, 0xba, 0xa9, +0x87, 0x1f, 0xa9, 0x54, 0x48, 0x1d, 0x94, 0x61, +0x49, 0xda, 0x93, 0x3e, 0xa0, 0xa7, 0x11, 0x3d, +0x5d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, +0x01, 0x22, 0x21, 0xd3, 0x52, 0x4f, 0xc9, 0x2a, +0xc2, 0x03, 0x9d, 0x6e, 0x63, 0xb9, 0x8b, 0x74, +0x9d, 0x9a, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xdb, 0xb6, 0x2c, 0x96, +0x65, 0x58, 0x93, 0xbc, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd1, 0x01, 0x22, 0x21, 0x90, 0x5e, 0x9f, +0x43, 0x32, 0x6a, 0x40, 0xbe, 0x73, 0x3d, 0x86, +0xf4, 0xee, 0x82, 0x42, 0xf6, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xb8, +0xc4, 0x7d, 0x91, 0xe8, 0x1c, 0xc1, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x82, +0xc1, 0x15, 0x68, 0x0d, 0xad, 0xdf, 0x73, 0xca, +0x76, 0xc7, 0xab, 0xf8, 0xd3, 0xc6, 0xd9, 0xbb, +0x4c, 0xa2, 0xfb, 0xbc, 0x7d, 0x81, 0x01, 0xf4, +0x77, 0xab, 0xd3, 0x9b, 0x5b, 0xf9, 0x1d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd3, 0x01, 0x22, -0x21, 0x33, 0xda, 0x0c, 0x75, 0xba, 0x00, 0xe3, -0xf2, 0x79, 0x4c, 0xd2, 0x4e, 0xed, 0x2a, 0x5d, -0x72, 0x09, 0xed, 0x72, 0x78, 0x37, 0xc9, 0x1d, -0xbb, 0xe4, 0x71, 0xb1, 0x12, 0x5e, 0xa6, 0x2e, -0x0a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, -0x01, 0x22, 0x21, 0x5b, 0x14, 0x7e, 0xfb, 0x95, -0xb1, 0xf5, 0x6c, 0x65, 0x41, 0x34, 0x26, 0x94, -0x5e, 0xb5, 0xc8, 0x75, 0xe4, 0x79, 0x3e, 0x55, -0x12, 0xba, 0x97, 0x5e, 0xa5, 0x3f, 0x2b, 0xc0, -0xf3, 0x7a, 0x0a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd5, 0x01, 0x22, 0x21, 0x90, 0x40, 0x0f, -0xf5, 0x19, 0xb0, 0xe6, 0x0d, 0xbf, 0x30, 0x57, -0xd4, 0xde, 0x0a, 0xa1, 0x1a, 0x3a, 0xf7, 0x20, -0x68, 0x24, 0x94, 0x83, 0xbe, 0x3d, 0x01, 0xdf, -0x9d, 0xff, 0xac, 0xa7, 0x67, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0x7f, -0x1b, 0x21, 0x9e, 0x8b, 0x46, 0x22, 0x66, 0x06, -0x20, 0xbb, 0x71, 0xb4, 0xed, 0xa3, 0x16, 0x96, -0xda, 0xfa, 0xa5, 0xee, 0x17, 0x44, 0xf2, 0x72, -0xf6, 0xee, 0x9c, 0xf6, 0xb0, 0xd1, 0x9d, 0x00, +0x21, 0x8e, 0x14, 0x2d, 0x1a, 0xd4, 0xe4, 0xfd, +0x8d, 0xf1, 0x29, 0x5d, 0x05, 0x2a, 0x2f, 0x04, +0x2a, 0xc8, 0x3c, 0x19, 0x5d, 0xf1, 0x54, 0x64, +0x51, 0xfb, 0xbe, 0x83, 0x5e, 0xd4, 0xd9, 0x16, +0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, +0x01, 0x22, 0x21, 0x08, 0xd1, 0xf1, 0xe0, 0xcf, +0x7d, 0xd7, 0x57, 0x3b, 0x87, 0x13, 0x1b, 0xce, +0xd4, 0x17, 0x6b, 0x9f, 0x4a, 0x6d, 0x75, 0x37, +0xef, 0xc8, 0xf4, 0xab, 0xe7, 0xb1, 0xd3, 0x21, +0x8e, 0x06, 0x96, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd5, 0x01, 0x22, 0x21, 0x7b, 0xea, 0xd1, +0xd8, 0xb7, 0x84, 0xe9, 0x63, 0x4b, 0xee, 0x6f, +0x2c, 0xeb, 0x59, 0xb5, 0xa2, 0xd3, 0xbd, 0xff, +0x3f, 0xbe, 0xa9, 0x96, 0x33, 0xbe, 0xd3, 0x86, +0x41, 0xf0, 0x9f, 0x61, 0xe0, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0x0f, +0x58, 0xc8, 0x03, 0x41, 0xd8, 0x3a, 0xe5, 0x46, +0x16, 0x0a, 0xd6, 0x54, 0x56, 0x3f, 0xcb, 0x85, +0xff, 0x24, 0x07, 0x88, 0xe0, 0x72, 0xf4, 0x37, +0x69, 0x56, 0x44, 0x09, 0xb1, 0xcc, 0xe4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd7, 0x01, 0x22, -0x21, 0x3e, 0xda, 0x14, 0x58, 0xce, 0x9a, 0x5e, -0x2b, 0xbb, 0x67, 0x54, 0x99, 0xcb, 0x71, 0x10, -0xc2, 0x39, 0x1f, 0xb7, 0xea, 0xf2, 0xea, 0x29, -0xcc, 0x6e, 0xe2, 0x2b, 0x63, 0x66, 0x61, 0x04, -0x77, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, -0x01, 0x22, 0x21, 0xd1, 0x27, 0x3e, 0x55, 0x3c, -0x22, 0x02, 0x11, 0xd2, 0xaf, 0x8f, 0xfe, 0xcc, -0xa7, 0x6c, 0x07, 0x55, 0x8d, 0xfe, 0x6b, 0xd5, -0x5e, 0x0c, 0xc9, 0x54, 0xb8, 0x76, 0xd2, 0xee, -0x24, 0xbe, 0xd4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd9, 0x01, 0x22, 0x21, 0x0d, 0x48, 0x7d, -0xae, 0x2f, 0x1d, 0x62, 0x0d, 0x60, 0x68, 0x24, -0xea, 0xb6, 0xf3, 0x5b, 0xb5, 0x68, 0x60, 0xc1, -0x38, 0xac, 0x98, 0x10, 0x15, 0xa6, 0xaa, 0x1a, -0xb5, 0xbf, 0x73, 0x6b, 0xa1, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0xfa, -0x70, 0x41, 0x8a, 0x0d, 0x7d, 0x8c, 0xe8, 0x97, -0xe9, 0x24, 0xbc, 0x10, 0xe3, 0x64, 0x44, 0xd0, -0x6c, 0x0a, 0x1c, 0xcb, 0xed, 0x2e, 0xb3, 0x90, -0xee, 0xae, 0x29, 0x11, 0xc6, 0x82, 0xc7, 0x00, +0x21, 0x39, 0x3c, 0x05, 0xb9, 0x2d, 0x75, 0x60, +0x62, 0xfd, 0x17, 0x8d, 0xc0, 0x77, 0x8d, 0x7a, +0xe4, 0x28, 0xa4, 0x42, 0x7c, 0x57, 0xe1, 0xb5, +0xc3, 0x3e, 0xe6, 0xf5, 0xcf, 0xa8, 0xe5, 0xb5, +0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, +0x01, 0x22, 0x21, 0xc6, 0x27, 0x6c, 0xd3, 0xd4, +0x05, 0xe6, 0x75, 0x01, 0xc7, 0x3d, 0xaa, 0xd4, +0x06, 0x5a, 0xcd, 0x69, 0x9a, 0x6e, 0x84, 0xb1, +0x2e, 0x85, 0x9c, 0xf4, 0x60, 0x81, 0xee, 0x43, +0xe5, 0xad, 0x0d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd9, 0x01, 0x22, 0x21, 0x20, 0x32, 0x0a, +0x84, 0xf6, 0x84, 0xda, 0x33, 0xef, 0x8b, 0x3e, +0x4e, 0x8e, 0xbb, 0xeb, 0x97, 0xac, 0x80, 0x6e, +0x15, 0xff, 0x2c, 0xb4, 0xe6, 0xf5, 0x9c, 0x9d, +0x7b, 0x39, 0x68, 0xfa, 0x16, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0xe0, +0x43, 0xb1, 0x5f, 0x4d, 0xf6, 0x3c, 0x6e, 0x53, +0xd4, 0x03, 0x19, 0x89, 0xf1, 0x2a, 0xd8, 0x56, +0x6f, 0xed, 0x45, 0xca, 0x41, 0xdb, 0x35, 0xc5, +0xe4, 0xd6, 0x1f, 0xe0, 0xa6, 0x21, 0x40, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdb, 0x01, 0x22, -0x21, 0x39, 0x4f, 0x54, 0x37, 0xb2, 0x97, 0xf4, -0xaa, 0xea, 0x73, 0xe2, 0xdc, 0xaf, 0x46, 0x0b, -0xf7, 0x68, 0x0e, 0x97, 0xbd, 0x5b, 0xe0, 0x7b, -0x89, 0xf2, 0xdd, 0x5b, 0x53, 0xdb, 0x40, 0x87, -0x66, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, -0x01, 0x22, 0x21, 0x55, 0x8a, 0x0d, 0xf9, 0xc2, -0x6b, 0xba, 0xfd, 0x08, 0xc4, 0x37, 0x82, 0x8a, -0xef, 0x81, 0x28, 0x69, 0xb9, 0x1b, 0x22, 0x2b, -0x00, 0xd6, 0xc4, 0xd6, 0xcb, 0x68, 0x4b, 0x59, -0x86, 0x4d, 0xff, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xdd, 0x01, 0x22, 0x21, 0x06, 0x52, 0xee, -0x40, 0x9b, 0xec, 0x93, 0xa3, 0x7b, 0x4a, 0xbb, -0x94, 0x42, 0x93, 0x9a, 0xe5, 0xa7, 0xed, 0x51, -0xda, 0x83, 0x97, 0x0d, 0xbe, 0xc9, 0xc9, 0xc9, -0x77, 0x75, 0xb7, 0x73, 0x20, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0xeb, -0x3c, 0x24, 0xac, 0x0d, 0x54, 0x85, 0x70, 0xf8, -0x83, 0x44, 0xf9, 0x67, 0x00, 0x16, 0xe7, 0xf3, -0xf5, 0x86, 0x4a, 0x01, 0x00, 0x6c, 0xc5, 0x54, -0x7a, 0x6c, 0x6b, 0x4d, 0xfb, 0x42, 0xc0, 0x00, +0x21, 0xd2, 0x2d, 0xf2, 0x87, 0xb3, 0x45, 0xbe, +0x3e, 0x8f, 0xa8, 0xf3, 0x2b, 0x6b, 0x17, 0x8b, +0x00, 0x80, 0x8f, 0xda, 0x06, 0xcf, 0x18, 0x8a, +0x3d, 0xf3, 0x39, 0x66, 0xa0, 0xe6, 0xf9, 0xb3, +0x17, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, +0x01, 0x22, 0x21, 0xd5, 0x7d, 0x1f, 0xba, 0xda, +0x2a, 0xbf, 0x83, 0xf6, 0x34, 0xc4, 0x1f, 0xb6, +0xc9, 0x52, 0x21, 0x22, 0xdf, 0xe0, 0xe9, 0xac, +0x61, 0xea, 0xca, 0x86, 0x26, 0x34, 0x62, 0xf7, +0xc7, 0x28, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xdd, 0x01, 0x22, 0x21, 0xde, 0x76, 0xbc, +0xb8, 0x04, 0xf1, 0xf0, 0x68, 0x1c, 0xf9, 0xd0, +0x1e, 0x5b, 0x6e, 0xcf, 0x59, 0xff, 0xdc, 0x14, +0x91, 0x93, 0x12, 0xe8, 0x42, 0x5f, 0x3e, 0x40, +0x71, 0xe1, 0x9a, 0x53, 0xe5, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0x31, +0xe7, 0xa5, 0x3a, 0x80, 0x9b, 0x93, 0x63, 0xbd, +0x6e, 0x25, 0x7f, 0xb3, 0x2f, 0x9d, 0x69, 0x09, +0xc7, 0x03, 0x65, 0x6b, 0x4c, 0x7e, 0x73, 0xc4, +0x10, 0x15, 0x58, 0x08, 0x1c, 0xd3, 0xba, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdf, 0x01, 0x22, -0x21, 0xd6, 0x69, 0xea, 0x87, 0x15, 0x30, 0x62, -0x7e, 0xc5, 0x78, 0x39, 0x66, 0xc9, 0x16, 0x03, -0x2c, 0x60, 0x8d, 0xf6, 0x3b, 0xf2, 0xbd, 0x6a, -0x5a, 0x1b, 0x26, 0x3b, 0x29, 0x54, 0x8b, 0x95, -0x90, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, -0x01, 0x22, 0x21, 0x7f, 0xb7, 0x97, 0xae, 0x82, -0x9c, 0xe9, 0x8f, 0x79, 0x63, 0x67, 0xfa, 0x16, -0xe2, 0x92, 0x85, 0x00, 0x41, 0xf5, 0xc6, 0x4a, -0xb5, 0x9d, 0x93, 0xb2, 0xbe, 0xfb, 0x87, 0x0c, -0xe1, 0x00, 0xcc, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe1, 0x01, 0x22, 0x21, 0x33, 0x64, 0xf6, -0x9e, 0x64, 0x43, 0x1a, 0xb5, 0x87, 0x8f, 0xb7, -0x4c, 0x1c, 0xfa, 0x6d, 0x66, 0xf7, 0x6b, 0x62, -0x91, 0x11, 0x82, 0x66, 0xe2, 0x5b, 0x87, 0x86, -0x85, 0xc4, 0x71, 0xdb, 0x61, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0xba, -0xd4, 0xeb, 0x5f, 0x61, 0x5a, 0xe0, 0x17, 0x5d, -0xa6, 0x6e, 0xb4, 0x6f, 0x35, 0x41, 0x59, 0x2d, -0x62, 0xf3, 0x15, 0x88, 0xb3, 0x24, 0x35, 0xb1, -0x08, 0x87, 0x35, 0xc4, 0xf0, 0x0b, 0x2b, 0x00, +0x21, 0x23, 0xf4, 0xf0, 0x8c, 0x12, 0xe1, 0x60, +0x16, 0x65, 0x28, 0xc2, 0x5d, 0x9a, 0x0f, 0xf8, +0x88, 0x19, 0xf3, 0x96, 0xa9, 0xea, 0x5e, 0x6f, +0x84, 0xf7, 0x16, 0x24, 0xa2, 0xe4, 0xc6, 0xb0, +0xdb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, +0x01, 0x22, 0x21, 0xef, 0x3e, 0xdf, 0x73, 0xed, +0xe4, 0x13, 0x11, 0xad, 0x07, 0x76, 0xbe, 0xcb, +0xdd, 0xca, 0x81, 0x0b, 0x58, 0x16, 0x9c, 0x63, +0x7b, 0x83, 0x19, 0xce, 0xd2, 0x81, 0x70, 0xd2, +0x42, 0x0c, 0xe9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe1, 0x01, 0x22, 0x21, 0x96, 0x9f, 0xab, +0x6d, 0xf6, 0x35, 0xce, 0xe9, 0xa6, 0x14, 0xa3, +0x02, 0xd2, 0x23, 0xd1, 0x81, 0x30, 0xf6, 0x6e, +0x6a, 0x4d, 0x47, 0x8b, 0xd4, 0x00, 0x68, 0x4d, +0x98, 0xd7, 0xa3, 0xaf, 0xf4, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0xdb, +0xc6, 0x6d, 0x2d, 0xda, 0xea, 0x3a, 0xc5, 0x0f, +0xe0, 0xf4, 0x9f, 0x6c, 0xaf, 0x1a, 0x08, 0x88, +0x91, 0xa7, 0xd0, 0x3d, 0x53, 0x0a, 0x05, 0xbb, +0x97, 0x29, 0xfb, 0x35, 0xb4, 0x06, 0x2c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe3, 0x01, 0x22, -0x21, 0xbc, 0x5e, 0x98, 0x7d, 0x75, 0xda, 0x7f, -0xe7, 0x83, 0x81, 0xf8, 0x5c, 0x01, 0x5a, 0x4e, -0xa3, 0x55, 0xf7, 0x31, 0x63, 0x45, 0xae, 0x72, -0x93, 0xdb, 0xad, 0x25, 0xdc, 0x5d, 0xf5, 0x37, -0xb8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, -0x01, 0x22, 0x21, 0x79, 0xe3, 0xd1, 0x2e, 0xba, -0xb4, 0x72, 0xb2, 0xe1, 0xa1, 0x86, 0xc0, 0xdd, -0xd1, 0x59, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x90, 0xb0, -0xb7, 0xa9, 0xdd, 0x23, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe5, 0x01, 0x22, 0x21, 0x15, 0x58, 0x33, -0x49, 0xcd, 0xdb, 0xfe, 0x96, 0xd8, 0x7c, 0x4e, -0x65, 0x3a, 0xe8, 0x16, 0xde, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x63, -0x11, 0xf0, 0x8b, 0xb1, 0xdc, 0xfe, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x1a, -0xac, 0x8a, 0xf3, 0xcd, 0x59, 0x16, 0x00, 0x15, -0x15, 0xb5, 0xb5, 0x5d, 0xa8, 0x6a, 0xf8, 0x33, -0x41, 0xf9, 0x16, 0xc8, 0xc2, 0x9d, 0x46, 0xe4, -0x15, 0x39, 0x06, 0x22, 0xe9, 0x5a, 0x55, 0x00, +0x21, 0x25, 0xe7, 0x56, 0x44, 0xea, 0xb5, 0xa1, +0xa6, 0x9a, 0xb7, 0xf5, 0xc9, 0x4e, 0xb1, 0xb2, +0x1a, 0x60, 0x68, 0x35, 0xa7, 0x34, 0xb1, 0x50, +0x2b, 0x29, 0x99, 0x0a, 0x66, 0x2a, 0xa9, 0x9d, +0x45, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, +0x01, 0x22, 0x21, 0x65, 0x8f, 0x17, 0x44, 0xe1, +0x1d, 0xe6, 0xed, 0xe7, 0x2b, 0x1c, 0x2d, 0x26, +0x46, 0x31, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xaf, 0x2e, 0xc0, 0x81, +0x37, 0xbe, 0xc6, 0xb1, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe5, 0x01, 0x22, 0x21, 0x7a, 0x61, 0xf3, +0x5c, 0x60, 0x28, 0x02, 0x65, 0x2c, 0xff, 0x1e, +0x9f, 0x31, 0x1d, 0x63, 0xb2, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xb6, +0xc8, 0x1b, 0x16, 0x21, 0x26, 0x77, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x8a, +0x0f, 0x33, 0xe2, 0x0f, 0x35, 0xe6, 0x98, 0x3e, +0x60, 0x56, 0xe4, 0x5a, 0x5d, 0xa6, 0xa2, 0x8f, +0x44, 0x24, 0x55, 0x96, 0xec, 0x48, 0x4e, 0xe0, +0xdd, 0xc3, 0x64, 0xde, 0xb2, 0x77, 0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe7, 0x01, 0x22, -0x21, 0x3f, 0x57, 0x09, 0x49, 0xad, 0x05, 0x9e, -0xf0, 0xc6, 0x4a, 0x7e, 0xdb, 0xee, 0x47, 0x30, -0xa2, 0x46, 0x88, 0xdc, 0xdc, 0x71, 0xf3, 0x62, -0xbd, 0xf7, 0x49, 0xdb, 0x49, 0xc7, 0x0f, 0x10, -0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, -0x01, 0x22, 0x21, 0x58, 0xd3, 0x55, 0x45, 0xc1, -0x6e, 0xdb, 0x94, 0x75, 0xf2, 0x10, 0xdc, 0x00, -0x52, 0x55, 0x41, 0xf6, 0x57, 0xdb, 0xe9, 0x92, -0x08, 0x83, 0x9e, 0x3e, 0xdb, 0x22, 0x61, 0x5e, -0x9c, 0xb3, 0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe9, 0x01, 0x22, 0x21, 0xe5, 0xc3, 0xb5, -0x27, 0xaa, 0x0c, 0xf0, 0x23, 0x08, 0xac, 0x3e, -0xd9, 0x42, 0x9f, 0x1f, 0x09, 0x1b, 0x92, 0x51, -0x69, 0x32, 0xb6, 0x51, 0x4c, 0x82, 0xa6, 0x21, -0x88, 0x7d, 0xa9, 0x1c, 0x79, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0x74, -0xfa, 0xa8, 0x41, 0x73, 0xae, 0xea, 0x11, 0x50, -0x22, 0xde, 0x51, 0x7a, 0xf7, 0xa4, 0x07, 0x68, -0xf0, 0x36, 0xe8, 0x23, 0xe5, 0xd2, 0x4a, 0xac, -0x5c, 0x01, 0x28, 0xb5, 0x97, 0xec, 0x09, 0x00, +0x21, 0x0d, 0x00, 0x6d, 0xb7, 0xdf, 0x80, 0x35, +0x28, 0x26, 0x13, 0x7b, 0x70, 0x5e, 0xc7, 0xe4, +0xdf, 0x28, 0xd1, 0xc9, 0xf6, 0x13, 0xbc, 0x43, +0xee, 0x50, 0x9b, 0xbe, 0x49, 0x56, 0x90, 0x5c, +0xef, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, +0x01, 0x22, 0x21, 0x37, 0x7c, 0xc4, 0xfa, 0x70, +0x3f, 0xa4, 0x39, 0x54, 0x4b, 0xc9, 0x3e, 0xe3, +0x8b, 0x20, 0xe8, 0xdb, 0x18, 0xc3, 0x33, 0xb2, +0xd3, 0x67, 0x6d, 0xdd, 0x03, 0x7b, 0x93, 0x22, +0x7b, 0x8c, 0x31, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe9, 0x01, 0x22, 0x21, 0x24, 0x31, 0x67, +0xbe, 0xcb, 0x39, 0xe1, 0x2d, 0x3d, 0x7c, 0x8b, +0x65, 0x35, 0x98, 0x7a, 0xc5, 0x8e, 0x8b, 0x7b, +0x1a, 0xe8, 0xd8, 0x2e, 0x2f, 0x6b, 0xb3, 0x7d, +0x6d, 0xc9, 0x37, 0x38, 0x2b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0x52, +0xb0, 0x65, 0x6b, 0xd3, 0xf8, 0xc7, 0x18, 0x67, +0x59, 0xdf, 0x15, 0xba, 0x19, 0xc1, 0xa8, 0x21, +0x30, 0x67, 0x82, 0xa9, 0x1f, 0x22, 0x82, 0x10, +0x6f, 0x11, 0xf0, 0xc8, 0x43, 0x1b, 0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xeb, 0x01, 0x22, -0x21, 0x3e, 0x5c, 0xcb, 0x5e, 0xad, 0x67, 0xbc, -0x23, 0x88, 0x48, 0x4f, 0xd5, 0x51, 0x58, 0xbf, -0xfd, 0x59, 0x5b, 0x33, 0xc4, 0x28, 0x51, 0x4b, -0x1f, 0x6d, 0x36, 0x97, 0xf4, 0x65, 0x80, 0xc4, -0x00, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, -0x01, 0x22, 0x21, 0x44, 0xb1, 0xb6, 0xd1, 0x78, -0x94, 0x65, 0xf4, 0x0f, 0xaf, 0x5a, 0xe2, 0xb1, -0x6d, 0x0b, 0x6c, 0xb9, 0x2c, 0x25, 0x26, 0xf2, -0xa3, 0xb2, 0x6a, 0x60, 0x9f, 0x10, 0x17, 0x31, -0x35, 0xaa, 0x40, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xed, 0x01, 0x22, 0x21, 0xda, 0xca, 0x74, -0xf8, 0x45, 0xec, 0xa8, 0xf2, 0x8c, 0xd1, 0x71, -0xcc, 0xb5, 0x7b, 0xdc, 0xdc, 0x72, 0x7d, 0x4e, -0xb5, 0x8e, 0x8e, 0x65, 0xea, 0x3c, 0x25, 0xe1, -0x0e, 0x48, 0x66, 0x8e, 0xaf, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0x2f, -0x51, 0x4c, 0x4c, 0xf3, 0xd8, 0x3f, 0x32, 0x75, -0x81, 0x6d, 0xa2, 0x84, 0x09, 0x5d, 0xd4, 0x92, -0x27, 0x9a, 0x15, 0x96, 0xbd, 0xbd, 0x9c, 0xc5, -0x74, 0x2e, 0x7f, 0xed, 0x6a, 0xe8, 0xbf, 0x00, +0x21, 0x76, 0x68, 0xf8, 0x07, 0xb3, 0x10, 0x1f, +0xb6, 0xb2, 0x1d, 0x59, 0xc1, 0x02, 0x15, 0xe5, +0x86, 0xec, 0x95, 0xb9, 0x4e, 0x99, 0xef, 0x19, +0x1f, 0xa2, 0x62, 0x49, 0x56, 0xf5, 0x57, 0x75, +0xcf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, +0x01, 0x22, 0x21, 0x07, 0xb0, 0x0c, 0x9a, 0xa5, +0xc7, 0x2c, 0x32, 0x3e, 0xdc, 0x2f, 0x89, 0xdb, +0xe8, 0xf0, 0x8d, 0xf7, 0x92, 0x4b, 0x2b, 0x17, +0xb4, 0x07, 0xd0, 0x60, 0x6d, 0xf1, 0xf1, 0x43, +0x94, 0xb4, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xed, 0x01, 0x22, 0x21, 0xc0, 0xea, 0x70, +0x7f, 0x0d, 0x99, 0xfd, 0x94, 0x98, 0xa3, 0xaf, +0xce, 0x90, 0x3d, 0xa2, 0x7a, 0x18, 0x81, 0xb3, +0x3a, 0x87, 0x62, 0x38, 0xf5, 0x0a, 0xec, 0x47, +0x10, 0xc7, 0xc2, 0x1d, 0xf3, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0x7f, +0x1f, 0x94, 0x05, 0x80, 0xeb, 0x18, 0x35, 0xc1, +0x15, 0x04, 0x49, 0xa2, 0x1a, 0xa5, 0xb9, 0x4f, +0x0a, 0x17, 0xb8, 0x8b, 0x0c, 0xbc, 0x8e, 0x2d, +0xdb, 0x0a, 0x93, 0x53, 0x43, 0xc0, 0xfe, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xef, 0x01, 0x22, -0x21, 0xc2, 0xba, 0x1d, 0xed, 0x45, 0x20, 0x69, -0x90, 0x39, 0x08, 0xee, 0xb4, 0x48, 0x81, 0x84, -0xd4, 0x07, 0x3a, 0xb3, 0x65, 0xa8, 0xc5, 0x7e, -0x55, 0xe1, 0x9a, 0x4d, 0xbe, 0xf8, 0x8e, 0xc5, -0xc7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, -0x01, 0x22, 0x21, 0xbd, 0x88, 0x79, 0x0a, 0xe4, -0x46, 0x8e, 0x45, 0xb1, 0x10, 0xf0, 0x71, 0x68, -0xe9, 0xb9, 0x8f, 0x08, 0xd5, 0xcd, 0xd1, 0x68, -0xf7, 0xd8, 0xba, 0xa4, 0xb2, 0x61, 0x3b, 0x8e, -0x10, 0xea, 0xda, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf1, 0x01, 0x22, 0x21, 0x4c, 0xc4, 0x9e, -0x91, 0xb2, 0x1c, 0xde, 0xcf, 0xdd, 0xe6, 0x67, -0xeb, 0xd0, 0xfc, 0xb3, 0x99, 0x99, 0x7e, 0xbf, -0x8e, 0x85, 0x3c, 0x51, 0x49, 0xbf, 0x96, 0xc3, -0x4a, 0x14, 0x2c, 0x45, 0x29, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0x47, -0x7b, 0xf5, 0x12, 0x83, 0x1c, 0xfb, 0x74, 0x3c, -0xb1, 0xaf, 0x93, 0xd9, 0x70, 0x1b, 0xb7, 0xb3, -0x13, 0x0a, 0xd6, 0xad, 0xf5, 0x95, 0x33, 0x06, -0xae, 0xae, 0xcf, 0x32, 0x7e, 0x3e, 0xb2, 0x00, +0x21, 0x0a, 0x3e, 0xbc, 0xe0, 0xbd, 0xef, 0xbb, +0x23, 0x54, 0x84, 0xd8, 0xdc, 0xaf, 0x9e, 0x95, +0x1f, 0x17, 0xaa, 0x7d, 0x88, 0xc9, 0x43, 0x17, +0x7a, 0xd7, 0x31, 0x95, 0x7f, 0x56, 0x75, 0xf9, +0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, +0x01, 0x22, 0x21, 0x2e, 0x5d, 0x5a, 0x34, 0x2f, +0x5d, 0x22, 0x9f, 0x57, 0x70, 0x31, 0x8e, 0xf8, +0xa2, 0xf7, 0x3a, 0x8c, 0x9e, 0x0d, 0x8a, 0xb8, +0x37, 0xa0, 0xbb, 0xd1, 0x03, 0x7e, 0x4b, 0x43, +0x0c, 0xb3, 0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf1, 0x01, 0x22, 0x21, 0x7b, 0x28, 0xbf, +0xb5, 0x38, 0x38, 0xa3, 0xeb, 0xcf, 0x46, 0xb6, +0x1b, 0xb8, 0x76, 0x92, 0x5a, 0x85, 0xe2, 0xcf, +0x79, 0xb6, 0x9a, 0xa2, 0xd9, 0x43, 0x24, 0x0c, +0xe2, 0xcc, 0x5c, 0xec, 0x18, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0x36, +0x54, 0x85, 0x65, 0xdd, 0xb6, 0x44, 0xd4, 0x00, +0xc3, 0x77, 0x62, 0xf5, 0x36, 0x9b, 0xd0, 0x36, +0x8d, 0x3c, 0x38, 0xc6, 0x75, 0x4c, 0x8e, 0x28, +0x82, 0x3d, 0xa8, 0x6e, 0x0e, 0x60, 0xef, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf3, 0x01, 0x22, -0x21, 0xfc, 0xec, 0xae, 0x39, 0x94, 0x66, 0xf0, -0x45, 0x95, 0xf3, 0xd1, 0xa8, 0x55, 0x09, 0x6b, -0xc3, 0xef, 0x91, 0xb7, 0x2c, 0x20, 0x65, 0x3e, -0x1a, 0x88, 0x69, 0x36, 0xa7, 0xa1, 0xf6, 0x32, -0x32, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, -0x01, 0x22, 0x21, 0xe4, 0x43, 0x34, 0x48, 0xd1, -0x8a, 0x45, 0xf2, 0xa3, 0x9e, 0xf3, 0x8f, 0x97, -0xc9, 0x2d, 0x3e, 0x26, 0xd5, 0x2e, 0xfe, 0x1f, -0xff, 0xc0, 0x7f, 0x5e, 0xab, 0x52, 0xf5, 0x71, -0xb5, 0xb6, 0x7b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf5, 0x01, 0x22, 0x21, 0xd7, 0x9a, 0xcb, -0xd9, 0xbf, 0x4a, 0xc7, 0xc9, 0xdf, 0xb7, 0x8a, -0xac, 0x80, 0x24, 0x07, 0xac, 0x63, 0x17, 0x2d, -0x4a, 0x84, 0x1f, 0x92, 0x99, 0xb4, 0xb2, 0x7b, -0xd7, 0xb2, 0x5a, 0xa5, 0x17, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0x8d, -0x81, 0x49, 0x88, 0xb6, 0xd7, 0xc5, 0xd0, 0x0f, -0x53, 0xc8, 0xa7, 0xf1, 0xd1, 0xfe, 0x13, 0x93, -0x0b, 0xc1, 0xc3, 0x04, 0x05, 0x10, 0x08, 0xfe, -0xf8, 0xe7, 0xd1, 0x01, 0x5a, 0xb3, 0xfb, 0x00, +0x21, 0x59, 0x9e, 0xbf, 0x09, 0xe9, 0x1a, 0x4d, +0x01, 0x38, 0x32, 0xb0, 0x55, 0x2f, 0xe3, 0xec, +0x8c, 0x67, 0xa5, 0xbd, 0xb0, 0xf5, 0x62, 0x38, +0x89, 0x27, 0xff, 0x07, 0xd4, 0xc7, 0x6e, 0x23, +0xfd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, +0x01, 0x22, 0x21, 0x61, 0x17, 0x0f, 0xb1, 0x38, +0xec, 0x74, 0xe6, 0x54, 0xba, 0xdd, 0x0b, 0x35, +0xe1, 0xf7, 0xbc, 0x24, 0xfa, 0x2d, 0x59, 0x1a, +0x0a, 0x66, 0xb6, 0x5a, 0xbf, 0x9a, 0x42, 0x10, +0x56, 0x8d, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf5, 0x01, 0x22, 0x21, 0xf2, 0x52, 0xa3, +0x74, 0xbc, 0xd7, 0x59, 0x01, 0x00, 0x56, 0x6f, +0x37, 0x5d, 0xc4, 0x13, 0xa5, 0xaa, 0x74, 0xb2, +0xae, 0x2b, 0xa4, 0x19, 0x2a, 0x7a, 0xe6, 0x3b, +0xcb, 0x41, 0x63, 0x97, 0xdd, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0x9a, +0x09, 0xdc, 0xf2, 0x92, 0x0c, 0xa8, 0xd8, 0x0b, +0x96, 0x93, 0x2d, 0xc3, 0x18, 0x77, 0x7c, 0x91, +0xa5, 0xa0, 0x20, 0x77, 0x46, 0x1f, 0x8a, 0x8d, +0x86, 0x40, 0x45, 0x86, 0x88, 0x49, 0x73, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf7, 0x01, 0x22, -0x21, 0x3d, 0x10, 0x05, 0x93, 0xba, 0x3f, 0xb6, -0x38, 0xae, 0xf2, 0x3d, 0xed, 0x36, 0x9b, 0x21, -0x3b, 0x8a, 0x25, 0x8b, 0x15, 0x96, 0x05, 0xbe, -0xcc, 0x53, 0xaf, 0x84, 0x8a, 0x46, 0xf5, 0x7a, -0x49, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, -0x01, 0x22, 0x21, 0x8a, 0xd0, 0xdc, 0x3c, 0x10, -0xa0, 0x4c, 0xf0, 0xb6, 0xd4, 0x11, 0x14, 0xff, -0x64, 0xf3, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x48, 0x15, 0xeb, 0x68, -0x59, 0xf8, 0x45, 0x38, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf9, 0x01, 0x22, 0x21, 0x2b, 0xcf, 0x7c, -0xaa, 0x60, 0xad, 0x0e, 0x0a, 0x35, 0x87, 0x96, -0x35, 0x7b, 0x55, 0xfe, 0xeb, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0c, -0x98, 0x5d, 0xc4, 0xe8, 0xf4, 0xc7, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0x35, -0x9f, 0x18, 0xa6, 0x89, 0x06, 0xd5, 0xb0, 0xbc, -0x6d, 0x31, 0x22, 0x9f, 0x61, 0x03, 0x76, 0xb9, -0x4a, 0x72, 0x85, 0xff, 0x90, 0x8b, 0x56, 0x97, -0x2e, 0xca, 0x1d, 0x6e, 0x0b, 0x9b, 0x5f, 0x00, +0x21, 0x9e, 0x72, 0x7b, 0xd0, 0x49, 0x86, 0x9e, +0x2f, 0x28, 0x30, 0x55, 0xeb, 0xe4, 0x3d, 0x79, +0x97, 0x02, 0x3c, 0xc9, 0x68, 0xeb, 0xb4, 0x52, +0x1b, 0x5b, 0x00, 0x5c, 0xf2, 0xd2, 0x0d, 0xdf, +0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, +0x01, 0x22, 0x21, 0x9b, 0x8b, 0xef, 0x3e, 0x10, +0x8b, 0x8b, 0xbd, 0xbf, 0x3f, 0x0b, 0x42, 0xb5, +0xd2, 0xf7, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xa2, 0x7f, 0xed, 0x1c, +0x50, 0x52, 0xab, 0x9a, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf9, 0x01, 0x22, 0x21, 0x08, 0xcf, 0xfa, +0xb6, 0xe1, 0x53, 0x2c, 0x33, 0x7b, 0xd4, 0xf4, +0x90, 0x87, 0xa5, 0x01, 0xe3, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xd3, +0xef, 0x7a, 0x39, 0x28, 0xcb, 0xe1, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0xc4, +0x56, 0x5f, 0xd5, 0x17, 0xa6, 0xfc, 0xb3, 0x84, +0xa6, 0x14, 0x9b, 0x03, 0x99, 0x6a, 0x3d, 0x0a, +0x2a, 0x27, 0x67, 0x09, 0xcd, 0xe5, 0x89, 0x6f, +0x21, 0x67, 0x59, 0x56, 0x7c, 0x9d, 0x15, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfb, 0x01, 0x22, -0x21, 0x9b, 0xde, 0xed, 0xa8, 0x4d, 0xe5, 0xab, -0xb6, 0x44, 0xcf, 0xc2, 0xef, 0x6b, 0x60, 0xa0, -0x76, 0x89, 0xfd, 0x3d, 0x46, 0x39, 0x0b, 0x75, -0x6c, 0xa7, 0xb0, 0xcd, 0xe1, 0x4c, 0xf8, 0xb3, -0x50, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, -0x01, 0x22, 0x21, 0xa2, 0xa4, 0xb5, 0x25, 0x92, -0x82, 0x5a, 0x3b, 0x0e, 0x56, 0xfe, 0xe9, 0x9f, -0xaa, 0x94, 0xca, 0xda, 0x77, 0x7b, 0xc6, 0xdd, -0x21, 0x58, 0x5a, 0xfb, 0xce, 0x1e, 0x3c, 0x5b, -0x2d, 0xa0, 0x22, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xfd, 0x01, 0x22, 0x21, 0x6c, 0xae, 0xeb, -0x1e, 0x97, 0xe8, 0xcb, 0x07, 0x53, 0x4d, 0x3a, -0xef, 0xdb, 0xfd, 0x69, 0x90, 0x65, 0x08, 0xea, -0x5e, 0x5e, 0xef, 0x54, 0xf7, 0xd7, 0x17, 0x53, -0x1f, 0x48, 0x64, 0x7f, 0x08, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0xa5, -0x02, 0xca, 0x28, 0x8e, 0x47, 0x73, 0x6e, 0xe8, -0x80, 0x48, 0x38, 0x88, 0xa7, 0x4c, 0x37, 0x18, -0xf9, 0xa3, 0xf0, 0x28, 0x46, 0x39, 0x53, 0xa7, -0x69, 0x74, 0x17, 0x0f, 0x96, 0xc6, 0x45, 0x00, +0x21, 0x49, 0x32, 0x75, 0xa3, 0x74, 0xa6, 0x4b, +0x28, 0x34, 0x28, 0x26, 0xac, 0xf4, 0x0c, 0x21, +0xc2, 0xb6, 0x7d, 0x72, 0xcd, 0x9f, 0x3c, 0x1c, +0xca, 0xf9, 0x62, 0x04, 0xfe, 0x6f, 0xbf, 0x33, +0x41, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, +0x01, 0x22, 0x21, 0x99, 0x6d, 0x95, 0x8b, 0xa4, +0xba, 0x27, 0xa6, 0x00, 0xa8, 0xcc, 0x4f, 0x31, +0xcd, 0x72, 0xa3, 0xe0, 0xe0, 0xae, 0xf4, 0xf2, +0x08, 0xa9, 0x22, 0x92, 0x07, 0x4b, 0x29, 0x26, +0x1a, 0x96, 0x33, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xfd, 0x01, 0x22, 0x21, 0x07, 0xce, 0x2a, +0x10, 0xd9, 0x47, 0x5a, 0xa1, 0x6d, 0x19, 0x0d, +0xa7, 0x50, 0xd2, 0xe8, 0x4a, 0x99, 0x4a, 0xa2, +0xc7, 0xcb, 0x3f, 0xdd, 0x32, 0x5c, 0xe5, 0xee, +0xb9, 0xd9, 0x68, 0xeb, 0xbf, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0x1f, +0x82, 0x0e, 0xdd, 0x87, 0x22, 0xd2, 0xa6, 0x44, +0x67, 0x85, 0x55, 0xc3, 0x89, 0x48, 0x3b, 0x93, +0x71, 0xd4, 0x79, 0xaa, 0x0c, 0x82, 0x34, 0xee, +0x81, 0x1e, 0x1a, 0xb6, 0x42, 0xe0, 0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xff, 0x01, 0x22, -0x21, 0x15, 0x36, 0x94, 0x8a, 0x80, 0x30, 0xd4, -0x37, 0xdd, 0x53, 0x66, 0x5d, 0x51, 0x86, 0xad, -0x80, 0x42, 0x48, 0xe7, 0x82, 0x93, 0x6b, 0xdc, -0x60, 0xd0, 0x58, 0x05, 0x56, 0x83, 0x7a, 0xcf, -0xee, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, -0x01, 0x22, 0x21, 0xda, 0x2d, 0xac, 0x27, 0x14, -0x61, 0xe4, 0x55, 0x06, 0xef, 0x54, 0x5b, 0x05, -0x68, 0x9d, 0xec, 0x52, 0x3e, 0x97, 0xd1, 0x8c, -0x49, 0x8a, 0x6d, 0x9c, 0x42, 0x82, 0x25, 0x90, -0x29, 0xf8, 0x45, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x01, 0x01, 0x22, 0x21, 0x45, 0x1f, 0x54, -0xc7, 0x86, 0x59, 0xe5, 0xde, 0x2f, 0x9b, 0x2f, -0x38, 0x5b, 0xe3, 0xd8, 0xdb, 0xd5, 0x46, 0x8e, -0xc5, 0x3a, 0xf0, 0x1e, 0xcb, 0x8a, 0x37, 0x59, -0xc0, 0x6f, 0x1d, 0x92, 0xc8, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0xcf, -0x4f, 0xda, 0xa3, 0x02, 0xb2, 0xde, 0x8b, 0x53, -0x48, 0xa4, 0xe6, 0x70, 0x58, 0x04, 0x62, 0x45, -0x76, 0x4f, 0x59, 0x87, 0x74, 0x69, 0xf2, 0x3c, -0x12, 0xcf, 0x7d, 0x79, 0x5a, 0xf4, 0x0b, 0x00, +0x21, 0x65, 0x39, 0xba, 0x95, 0xec, 0xb6, 0x2b, +0x1d, 0xb9, 0xd0, 0x13, 0x83, 0xaa, 0x20, 0x02, +0xbf, 0xa1, 0x3c, 0x98, 0x9e, 0xf7, 0xc9, 0xa3, +0x05, 0x26, 0x18, 0x87, 0x72, 0xa9, 0x52, 0xa8, +0xfb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, +0x01, 0x22, 0x21, 0xb6, 0x73, 0xa2, 0xb6, 0x6a, +0x30, 0x39, 0x20, 0x7e, 0x7f, 0x21, 0x86, 0x54, +0xc6, 0xbe, 0x5a, 0xa6, 0x6a, 0x58, 0xc4, 0xbd, +0xbd, 0x36, 0xff, 0x69, 0x0d, 0x82, 0x03, 0x7f, +0x19, 0x51, 0x16, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x01, 0x01, 0x22, 0x21, 0xd6, 0xc4, 0xf4, +0x4e, 0xe9, 0x0f, 0x96, 0x1c, 0xe0, 0x08, 0x0f, +0x54, 0x12, 0xdc, 0x98, 0x4a, 0x5b, 0xb0, 0x13, +0xea, 0xa0, 0x96, 0x75, 0x8b, 0x44, 0xf5, 0x18, +0x17, 0xe1, 0xb1, 0x58, 0x38, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0x3a, +0x1f, 0xb4, 0x82, 0x56, 0x51, 0x37, 0x2c, 0x80, +0xcf, 0x4c, 0x7d, 0x95, 0xe6, 0x6a, 0xfb, 0xea, +0x9f, 0x13, 0x97, 0x65, 0xab, 0x77, 0x6e, 0xf5, +0x87, 0x01, 0x4d, 0x53, 0x74, 0xba, 0x58, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x03, 0x01, 0x22, -0x21, 0x31, 0x76, 0x54, 0x61, 0xed, 0xdd, 0xb5, -0xaf, 0x25, 0xeb, 0x90, 0x4c, 0x56, 0x95, 0x37, -0xe4, 0x6f, 0x01, 0x9b, 0x1f, 0xf4, 0x8e, 0x76, -0xa3, 0x01, 0x00, 0xfc, 0x8c, 0xc8, 0xde, 0x9b, -0x41, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, -0x01, 0x22, 0x21, 0x2b, 0x2d, 0x85, 0xc0, 0x84, -0xbd, 0x56, 0x2e, 0xb8, 0xd9, 0xb9, 0x18, 0xbb, -0x42, 0xf7, 0x50, 0x95, 0xab, 0xdf, 0x09, 0x89, -0xcf, 0xf2, 0x16, 0xcb, 0x13, 0xad, 0x5c, 0x98, -0x9e, 0xb4, 0xf8, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x05, 0x01, 0x22, 0x21, 0xd6, 0xa9, 0xc4, -0x5d, 0xf3, 0xcc, 0x9f, 0x08, 0x8e, 0x58, 0x9d, -0x61, 0xf5, 0xea, 0xc4, 0x04, 0xf1, 0x8c, 0xda, -0xc2, 0xe0, 0xed, 0xa8, 0x8d, 0xd4, 0x94, 0x5f, -0xb4, 0x19, 0x20, 0x54, 0xfc, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0xb7, -0x26, 0xa1, 0x25, 0xd7, 0x48, 0xdd, 0x0f, 0xf0, -0x68, 0xa6, 0x86, 0x54, 0xb0, 0x86, 0xa3, 0xab, -0xfc, 0xf0, 0x9b, 0x3e, 0xc0, 0x96, 0x87, 0x39, -0x9e, 0x74, 0x93, 0x93, 0xaf, 0x0f, 0x60, 0x00, +0x21, 0xbf, 0xdb, 0x4d, 0x92, 0xca, 0x38, 0x54, +0xb9, 0xa5, 0x97, 0x04, 0xb5, 0x64, 0xb2, 0xc0, +0xc4, 0x01, 0x8e, 0x86, 0x38, 0x7d, 0xe5, 0x5f, +0x23, 0x07, 0xf6, 0x0e, 0xfd, 0xd5, 0xfa, 0xad, +0x26, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, +0x01, 0x22, 0x21, 0xd7, 0x80, 0xed, 0x05, 0xea, +0x84, 0xd7, 0x1b, 0x65, 0x96, 0xe4, 0x7d, 0x67, +0x6b, 0xe6, 0xea, 0xab, 0xcf, 0xbd, 0xdf, 0x0b, +0x01, 0x9b, 0x7a, 0x6c, 0xd5, 0xdd, 0x0a, 0x5d, +0x9f, 0xbd, 0x94, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x05, 0x01, 0x22, 0x21, 0x22, 0x0d, 0x1d, +0xfe, 0x4b, 0x89, 0xdc, 0xb2, 0x7e, 0xb1, 0x5c, +0x27, 0x06, 0x74, 0x92, 0x3b, 0x61, 0x51, 0x26, +0x1a, 0xc5, 0x95, 0xbf, 0xc4, 0xba, 0x6e, 0xcc, +0xcf, 0x97, 0x31, 0x75, 0xb2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0xf9, +0x55, 0xeb, 0x9d, 0xe9, 0x78, 0xd7, 0x28, 0xb2, +0xc7, 0xcc, 0x5a, 0x26, 0xdd, 0x88, 0x6c, 0xd3, +0x3e, 0xac, 0x8a, 0x00, 0x92, 0x35, 0xda, 0x77, +0xf2, 0x60, 0x91, 0x13, 0x1f, 0x3e, 0xb6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x07, 0x01, 0x22, -0x21, 0x71, 0x97, 0x0e, 0x81, 0x01, 0x25, 0x70, -0x7b, 0x9d, 0xc7, 0x3a, 0x24, 0xa7, 0xd1, 0xf6, -0x9b, 0x9e, 0x33, 0xc3, 0x60, 0x20, 0x5d, 0x52, -0xe3, 0x83, 0x9a, 0xe2, 0x22, 0x7c, 0x45, 0x4f, -0xde, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, -0x01, 0x22, 0x21, 0x7e, 0x6e, 0x03, 0xda, 0x5e, -0xcd, 0xe0, 0x86, 0x62, 0xca, 0xc1, 0x1f, 0x1e, -0x91, 0xe0, 0xfb, 0x26, 0x6b, 0x93, 0xe4, 0xe8, -0x2e, 0xcc, 0x0f, 0x66, 0x1d, 0x86, 0xd9, 0xdc, -0xea, 0xd2, 0x06, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x09, 0x01, 0x22, 0x21, 0x6c, 0xfc, 0x21, -0xca, 0xa4, 0xe7, 0xc8, 0xb9, 0x56, 0x16, 0x72, -0x6b, 0x3f, 0x06, 0xaf, 0x23, 0x72, 0xec, 0xd2, -0x04, 0x00, 0x82, 0x5e, 0x4b, 0xa9, 0x75, 0x81, -0x93, 0xb8, 0x37, 0xd6, 0x7c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0x36, -0x03, 0xde, 0xca, 0x1d, 0xd7, 0x42, 0x7c, 0xc9, -0xe5, 0x14, 0x33, 0x40, 0x84, 0x06, 0xd4, 0xc7, -0x25, 0xcb, 0x54, 0x65, 0x5c, 0x3d, 0x2d, 0x54, -0x92, 0xd5, 0xa7, 0x5a, 0xff, 0x04, 0x6f, 0x00, +0x21, 0x3b, 0x2e, 0xdf, 0xfa, 0x0d, 0x5b, 0x59, +0x95, 0x43, 0x6f, 0x39, 0xc7, 0xb2, 0x9c, 0x48, +0xfc, 0xb6, 0xac, 0xa8, 0x8a, 0xab, 0xd4, 0x87, +0xe5, 0x79, 0x32, 0x96, 0xc1, 0x40, 0x39, 0xc0, +0xbf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, +0x01, 0x22, 0x21, 0x4d, 0x3f, 0x9c, 0xfc, 0x52, +0x1b, 0x22, 0xce, 0x7e, 0x8c, 0xba, 0x78, 0x2d, +0xbf, 0x56, 0x2a, 0xd7, 0xd4, 0xaa, 0x65, 0x69, +0xef, 0x2e, 0xdc, 0x09, 0x88, 0x99, 0x86, 0xf9, +0xba, 0xb0, 0xbe, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x09, 0x01, 0x22, 0x21, 0xe6, 0xf1, 0x93, +0x8c, 0x9c, 0xf1, 0xc0, 0x54, 0x9d, 0xb6, 0x1c, +0x7a, 0xcf, 0xc0, 0x5b, 0xa7, 0x47, 0x3f, 0xdf, +0xbe, 0xa6, 0xb7, 0x3a, 0xed, 0xe8, 0xd5, 0xee, +0x0a, 0x9c, 0x02, 0x0d, 0x4e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0xce, +0x63, 0x08, 0xc6, 0xb3, 0x09, 0xbd, 0x27, 0xeb, +0x24, 0xcd, 0xcc, 0xb4, 0x88, 0xba, 0x4e, 0x4b, +0x36, 0xb4, 0x55, 0xa8, 0xd2, 0x7c, 0xd0, 0x65, +0xbe, 0xd4, 0xbc, 0x1e, 0x12, 0xd2, 0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0b, 0x01, 0x22, -0x21, 0x97, 0x59, 0x6c, 0xa8, 0xe6, 0x1b, 0x6f, -0x8e, 0xa4, 0xe3, 0xa4, 0x8c, 0x51, 0xf0, 0x9f, -0xc0, 0x06, 0x0c, 0x04, 0xdd, 0x94, 0x3c, 0x3e, -0xd5, 0x0d, 0xee, 0x73, 0x6f, 0xa3, 0xcc, 0x99, -0x5b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, -0x01, 0x22, 0x21, 0xdf, 0x04, 0x76, 0xf0, 0xd3, -0x6a, 0x61, 0xb5, 0x0b, 0xff, 0x47, 0xc5, 0x7c, -0xe3, 0xe6, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x74, 0x43, -0xc6, 0xa0, 0xf6, 0x84, 0x03, 0x04, 0x51, 0x02, -0x00, 0x0d, 0x01, 0x22, 0x21, 0x7c, 0x40, 0xbd, -0x6e, 0x9d, 0x99, 0xef, 0xbd, 0xfc, 0xa0, 0xfb, -0xc1, 0xb9, 0x40, 0x97, 0xd9, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xd0, -0x89, 0x5e, 0x68, 0x10, 0xc6, 0x1a, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0x38, -0x85, 0x9e, 0x8c, 0x74, 0xf5, 0x17, 0xb2, 0x07, -0x49, 0x75, 0x7a, 0x8c, 0xa1, 0x6f, 0x67, 0xbb, -0x43, 0x11, 0x8a, 0x7b, 0x4a, 0x1d, 0xe7, 0xb4, -0xe2, 0xa0, 0x6c, 0xf6, 0xec, 0x9a, 0x06, 0x00, +0x21, 0xf5, 0x0c, 0x2a, 0x31, 0x5b, 0x23, 0xea, +0x67, 0x82, 0x56, 0x47, 0x9f, 0x3f, 0x5e, 0xf9, +0xe3, 0x7e, 0x42, 0x90, 0x65, 0x20, 0x6f, 0x67, +0xbe, 0xcc, 0x2c, 0xcc, 0x6a, 0xdd, 0x52, 0xcb, +0xe6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, +0x01, 0x22, 0x21, 0x08, 0x92, 0x6a, 0x7e, 0x71, +0x21, 0x99, 0x5e, 0xb6, 0x9d, 0x6a, 0x7f, 0xf0, +0x38, 0xd6, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xc1, 0x25, 0x39, 0x05, +0xe2, 0x5e, 0xbc, 0x40, 0x03, 0x04, 0x51, 0x02, +0x00, 0x0d, 0x01, 0x22, 0x21, 0x37, 0x6d, 0xbf, +0x55, 0x9a, 0x7d, 0x0f, 0x67, 0xd5, 0x1a, 0x0a, +0x57, 0x10, 0x17, 0xa9, 0x52, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x2e, +0xf2, 0x7b, 0xc1, 0x44, 0x32, 0x7f, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0xc4, +0x11, 0x81, 0x77, 0xbd, 0x0d, 0xef, 0x5b, 0x32, +0x06, 0x06, 0x65, 0x77, 0xdd, 0x6c, 0xfa, 0x39, +0xae, 0x9e, 0xab, 0xd1, 0xc3, 0x42, 0x19, 0x06, +0x71, 0xa6, 0x1b, 0xc5, 0x18, 0xad, 0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0f, 0x01, 0x22, -0x21, 0xf0, 0x34, 0x03, 0xe5, 0xaa, 0x4f, 0x84, -0xd0, 0xc4, 0xb1, 0x26, 0xeb, 0xf0, 0x25, 0x19, -0x8f, 0x79, 0xb3, 0xcb, 0x43, 0xd9, 0x7e, 0x46, -0x3e, 0x3f, 0x20, 0x3c, 0xe8, 0x72, 0xa2, 0xce, -0x8e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, -0x01, 0x22, 0x21, 0x61, 0xda, 0x19, 0x8a, 0x64, -0x9e, 0xc2, 0x63, 0x7d, 0x20, 0xff, 0xc2, 0xbf, -0xf8, 0xaf, 0xe2, 0x49, 0x44, 0x41, 0x09, 0x87, -0xce, 0xc1, 0x87, 0xe9, 0xf7, 0xbf, 0xc8, 0x89, -0x89, 0xc8, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x11, 0x01, 0x22, 0x21, 0x2f, 0xc3, 0xed, -0xd5, 0x62, 0x83, 0x34, 0x80, 0x51, 0x8f, 0x40, -0x1a, 0x6e, 0x47, 0x97, 0xd3, 0x12, 0x2d, 0xba, -0x85, 0x8d, 0xf1, 0x0d, 0xad, 0x4c, 0x06, 0xab, -0x9d, 0xab, 0x6d, 0x09, 0xc5, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0x17, -0x9c, 0x6c, 0x36, 0x11, 0x31, 0xe4, 0xc5, 0x0e, -0x9d, 0xdb, 0xc0, 0x8d, 0xca, 0x69, 0x4c, 0xab, -0xf9, 0xb3, 0x33, 0x92, 0x9d, 0x90, 0xb9, 0xf4, -0x9f, 0xc9, 0xfa, 0x92, 0x40, 0x34, 0xcb, 0x00, +0x21, 0x91, 0x34, 0x96, 0x14, 0x86, 0x9a, 0x7b, +0x77, 0x35, 0xbf, 0x4c, 0x6e, 0x4c, 0xd1, 0x58, +0xf2, 0xe3, 0xd3, 0xb8, 0x77, 0x16, 0xeb, 0x10, +0x30, 0xba, 0x90, 0xb2, 0x2c, 0xc7, 0x52, 0xfb, +0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, +0x01, 0x22, 0x21, 0x3b, 0x8f, 0x6b, 0x5c, 0xc0, +0x1f, 0x50, 0x03, 0xfb, 0x75, 0xe5, 0xd1, 0x18, +0xfc, 0x74, 0xc1, 0xec, 0x38, 0xb1, 0x5a, 0x43, +0x15, 0x51, 0x25, 0x81, 0x98, 0x5f, 0x7c, 0x79, +0xcf, 0x2d, 0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x11, 0x01, 0x22, 0x21, 0xd1, 0x82, 0xeb, +0x14, 0x49, 0x10, 0x84, 0x94, 0x97, 0x09, 0x1b, +0x2e, 0xcf, 0x8d, 0x4b, 0x75, 0x44, 0x41, 0xe6, +0xd6, 0x5a, 0x1b, 0x30, 0x2e, 0x14, 0x76, 0x7c, +0x6b, 0x37, 0x28, 0xad, 0x4b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0x24, +0xb9, 0x81, 0x8e, 0xdf, 0x23, 0xf2, 0xf8, 0x2c, +0x7c, 0x87, 0x97, 0xdc, 0x3a, 0x96, 0xde, 0xd4, +0x3b, 0x52, 0x7d, 0x4d, 0x98, 0x1f, 0x26, 0x1f, +0x03, 0xf0, 0xaa, 0x26, 0x03, 0x1a, 0x9d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x13, 0x01, 0x22, -0x21, 0x3a, 0x2b, 0xb5, 0x58, 0x86, 0xd3, 0xd7, -0x21, 0x2f, 0x87, 0x2f, 0x69, 0x16, 0xfa, 0x52, -0x20, 0x54, 0xe3, 0x69, 0x3e, 0x3b, 0x4a, 0x0b, -0xed, 0x0f, 0x9c, 0x61, 0xab, 0x48, 0x93, 0x45, -0x3f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, -0x01, 0x22, 0x21, 0x55, 0x76, 0xfa, 0x7f, 0x3b, -0x7d, 0x46, 0x1f, 0xb5, 0xa0, 0xf8, 0x9c, 0x94, -0x1e, 0x22, 0x29, 0x61, 0x78, 0x7c, 0x39, 0xd1, -0x43, 0x86, 0x56, 0x02, 0x05, 0x3e, 0x3c, 0x39, -0x5a, 0x66, 0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x15, 0x01, 0x22, 0x21, 0x73, 0xb3, 0x06, -0x88, 0x8c, 0x85, 0x2e, 0xf1, 0x3c, 0x56, 0x68, -0xaf, 0x5b, 0x4f, 0x57, 0xc0, 0x32, 0x9d, 0xcb, -0x5f, 0xe2, 0x5e, 0xb9, 0x71, 0xb2, 0x29, 0x84, -0x82, 0x09, 0x26, 0x3f, 0x8b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0xe9, -0xf7, 0x3b, 0x7d, 0xc7, 0x11, 0x7e, 0x00, 0x43, -0x79, 0xce, 0xd1, 0xad, 0x79, 0xce, 0x73, 0x8a, -0xb7, 0x2b, 0xee, 0x35, 0xd9, 0x12, 0x10, 0xa9, -0x37, 0x90, 0x73, 0xae, 0xdf, 0xa5, 0x7e, 0x00, +0x21, 0x77, 0x81, 0xdb, 0x00, 0xf3, 0x04, 0xbe, +0xb5, 0xf2, 0x4e, 0xcd, 0x31, 0xb7, 0x03, 0xad, +0xba, 0x70, 0x21, 0xdb, 0xd8, 0x3b, 0xc3, 0x75, +0xc7, 0x16, 0xf4, 0x7b, 0x4f, 0x38, 0xbe, 0x46, +0x73, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, +0x01, 0x22, 0x21, 0x63, 0x9d, 0xf4, 0x65, 0x8b, +0xa3, 0xd9, 0xf9, 0x04, 0xb5, 0x6d, 0xe1, 0x32, +0xc0, 0xc4, 0xf7, 0x90, 0xe3, 0xbf, 0xa9, 0x5f, +0xdc, 0x5b, 0x45, 0xab, 0x06, 0xc9, 0x0e, 0x56, +0x38, 0xbc, 0x07, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x15, 0x01, 0x22, 0x21, 0x45, 0x60, 0x90, +0x3b, 0x16, 0xc9, 0xa0, 0x5a, 0x85, 0x06, 0xab, +0x9d, 0x01, 0x58, 0xa0, 0xf1, 0x0b, 0x30, 0xff, +0x63, 0x8f, 0x97, 0x22, 0x5e, 0xb9, 0x1b, 0xbf, +0xac, 0x36, 0xf2, 0x67, 0x04, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x69, +0xcb, 0xf3, 0x1f, 0x27, 0xfb, 0x92, 0xab, 0x40, +0x4a, 0x3d, 0xe6, 0x37, 0x21, 0x6e, 0xed, 0xd9, +0x3e, 0x4b, 0xae, 0xab, 0x0e, 0x15, 0x45, 0xe6, +0xbb, 0x67, 0xb4, 0xb5, 0xb0, 0xf5, 0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x17, 0x01, 0x22, -0x21, 0xf0, 0x47, 0x3e, 0xbf, 0xfc, 0xea, 0x73, -0x41, 0x33, 0x1c, 0xcb, 0xb6, 0xab, 0x9a, 0x08, -0x96, 0xd9, 0x85, 0xc0, 0x5d, 0x3c, 0x3a, 0xee, -0x5d, 0xeb, 0xa6, 0x32, 0x62, 0x01, 0x2f, 0xf8, -0x55, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, -0x01, 0x22, 0x21, 0x17, 0xd0, 0x61, 0x72, 0xf1, -0x10, 0xb5, 0x7c, 0xf8, 0x62, 0x60, 0xc6, 0x7c, -0x37, 0x5e, 0xfe, 0xb7, 0x7d, 0xb2, 0x10, 0xcd, -0xa8, 0xfe, 0x3c, 0x8f, 0x74, 0xec, 0xf3, 0xa5, -0xd5, 0x2f, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x19, 0x01, 0x22, 0x21, 0x8e, 0xbf, 0x3c, -0xf2, 0xa4, 0x5d, 0xb9, 0x26, 0xfa, 0x60, 0x18, -0x70, 0xe4, 0xee, 0x40, 0x40, 0x9a, 0xd4, 0x5d, -0x04, 0x39, 0x6e, 0x9e, 0x8c, 0x4b, 0x8a, 0x86, -0x27, 0xf3, 0x3f, 0x8e, 0x60, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0xa8, -0x71, 0x72, 0x8d, 0x8c, 0x2b, 0x27, 0x1f, 0x69, -0x2b, 0xb6, 0x14, 0xd1, 0xc4, 0x71, 0xbe, 0xb8, -0xdd, 0x5f, 0xba, 0x6a, 0x98, 0x1f, 0xf0, 0x30, -0x93, 0xda, 0x8d, 0x85, 0x66, 0x52, 0x9d, 0x00, +0x21, 0x51, 0x75, 0x4d, 0xe9, 0xa8, 0x91, 0x0a, +0x9b, 0xa4, 0xf0, 0xeb, 0xf5, 0x45, 0xa4, 0xdc, +0xa6, 0x08, 0xbb, 0x37, 0x7d, 0x18, 0xf3, 0x46, +0xa4, 0x03, 0xca, 0xab, 0x23, 0xb4, 0xf2, 0xf2, +0xd9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, +0x01, 0x22, 0x21, 0x0f, 0x38, 0xc2, 0xe9, 0x77, +0x01, 0x94, 0x0d, 0x8f, 0x3c, 0x34, 0x3c, 0x99, +0x8d, 0x1c, 0x4f, 0x69, 0x21, 0xde, 0x8f, 0x0c, +0x34, 0x8f, 0x1f, 0xb0, 0x75, 0x42, 0xee, 0x99, +0x16, 0x90, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x19, 0x01, 0x22, 0x21, 0xc2, 0xf9, 0x88, +0x25, 0x7d, 0x59, 0x45, 0x21, 0xf0, 0xd4, 0x96, +0x66, 0xc5, 0x50, 0xae, 0x9d, 0x40, 0xf6, 0x02, +0x2e, 0x6b, 0x93, 0x42, 0x24, 0x1a, 0x24, 0xe6, +0xdc, 0x0a, 0x1c, 0x47, 0x27, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0x14, +0xff, 0xe1, 0xf7, 0x80, 0x4b, 0xd2, 0xa5, 0xfd, +0x7b, 0xae, 0x5b, 0x8c, 0xd0, 0xef, 0xfb, 0xb1, +0x17, 0x61, 0x84, 0xee, 0xa0, 0x85, 0x30, 0x93, +0xd6, 0xa4, 0xf3, 0xb2, 0xc0, 0xa8, 0x25, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1b, 0x01, 0x22, -0x21, 0x9e, 0x20, 0xa8, 0x3a, 0x84, 0x0d, 0x03, -0x91, 0xad, 0x07, 0x53, 0x6f, 0x1b, 0x16, 0x2c, -0xca, 0xe8, 0x3e, 0x1c, 0x92, 0x16, 0x67, 0xaf, -0x94, 0x7e, 0xf7, 0x02, 0xa1, 0xf9, 0x31, 0x7b, -0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, -0x01, 0x22, 0x21, 0x91, 0xa7, 0x84, 0x19, 0xf3, -0x0d, 0xc6, 0x76, 0x49, 0x8f, 0xc9, 0xf6, 0x02, -0x67, 0x5c, 0xb1, 0xd5, 0xd6, 0x21, 0xab, 0x6c, -0x23, 0x7c, 0x36, 0xb2, 0xbb, 0xd2, 0x24, 0x27, -0x2e, 0x3d, 0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x1d, 0x01, 0x22, 0x21, 0x50, 0x40, 0x9f, -0x9e, 0x3d, 0xa9, 0x3e, 0x2e, 0x24, 0x59, 0x24, -0xd0, 0x93, 0x45, 0x43, 0x50, 0x9a, 0x3b, 0x14, -0x20, 0x52, 0x49, 0x14, 0x3e, 0xcf, 0xf2, 0x4f, -0xb6, 0xce, 0x32, 0x40, 0x90, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0xe8, -0x12, 0x6d, 0x17, 0x73, 0x21, 0x09, 0x5f, 0xa9, -0x9a, 0xb7, 0x66, 0x5b, 0x23, 0x5f, 0x0b, 0xd1, -0xb5, 0x7a, 0xc6, 0x11, 0xa3, 0x37, 0xd9, 0xcb, -0xcd, 0xc1, 0xe7, 0xd0, 0xe8, 0x9b, 0xd6, 0x00, +0x21, 0xd7, 0xe3, 0xce, 0xd8, 0x68, 0x42, 0x31, +0x42, 0x20, 0xe8, 0xdb, 0x70, 0xf1, 0xe1, 0x65, +0xb4, 0x13, 0x0b, 0xd8, 0x49, 0xd8, 0xd4, 0x3b, +0xdf, 0x2e, 0x58, 0x3d, 0x4d, 0x43, 0x9f, 0xeb, +0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, +0x01, 0x22, 0x21, 0xf1, 0xbb, 0x21, 0xde, 0x06, +0xc5, 0xd8, 0x62, 0x92, 0x5a, 0x2e, 0xbd, 0xb5, +0xc0, 0x71, 0x22, 0x4d, 0x39, 0x01, 0xe8, 0x2e, +0xe2, 0x2b, 0xf2, 0x83, 0x9a, 0x77, 0x6b, 0xcb, +0xbf, 0x63, 0xd9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x1d, 0x01, 0x22, 0x21, 0x27, 0x54, 0xc5, +0xcc, 0xbd, 0x0b, 0xd0, 0xc5, 0xd1, 0x4c, 0xd2, +0x80, 0x51, 0xb0, 0xe9, 0x66, 0x3e, 0xf1, 0xa0, +0xcc, 0xf6, 0x2d, 0x29, 0x05, 0x51, 0x20, 0x5b, +0x41, 0xe0, 0xc0, 0x94, 0x8b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0x96, +0xb2, 0x23, 0x1c, 0xe8, 0x74, 0x5a, 0x32, 0x0d, +0x70, 0x46, 0x1e, 0xa4, 0x28, 0x11, 0xfd, 0xda, +0x18, 0xc8, 0xbe, 0xa1, 0x2a, 0x11, 0xf8, 0x3e, +0xdf, 0x7f, 0x0a, 0x08, 0xd4, 0x12, 0x80, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1f, 0x01, 0x22, -0x21, 0x21, 0x61, 0x7d, 0x6f, 0x2a, 0x33, 0x8f, -0x5d, 0xfc, 0xd2, 0xfa, 0x3b, 0x3f, 0x38, 0x7f, -0x52, 0x25, 0x7d, 0x17, 0x28, 0xea, 0xa0, 0xf9, -0xe8, 0x4d, 0xd3, 0x2d, 0xdc, 0xcf, 0x31, 0x13, -0xa8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, -0x01, 0x22, 0x21, 0xb7, 0xf8, 0xa2, 0xb6, 0x97, -0x55, 0x56, 0xac, 0x7b, 0x17, 0x49, 0xa2, 0xd8, -0x9a, 0xb8, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x50, 0x10, 0xd6, 0x52, -0x9b, 0xdb, 0xe8, 0x1c, 0x03, 0x04, 0x51, 0x02, -0x00, 0x21, 0x01, 0x22, 0x21, 0x16, 0x4b, 0xd7, -0x9e, 0x9a, 0x91, 0x6b, 0xc5, 0xb9, 0x0c, 0x91, -0xfe, 0x6d, 0xe0, 0xc3, 0xb4, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x7b, -0x7a, 0x6a, 0x10, 0x1f, 0x42, 0xa7, 0x03, 0x04, -0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0x5b, -0xc3, 0xe5, 0xd6, 0xa6, 0x55, 0xca, 0xe6, 0xe2, -0x13, 0xf7, 0x97, 0x2f, 0x22, 0x04, 0x12, 0x02, -0xb7, 0xfd, 0xc9, 0x7f, 0x77, 0xf5, 0x53, 0x3d, -0x3e, 0x57, 0x42, 0x04, 0x33, 0xa4, 0xf8, 0x00, +0x21, 0xec, 0x15, 0x5e, 0x59, 0x45, 0xb6, 0x95, +0x6b, 0xdc, 0x2c, 0x26, 0xe6, 0x4e, 0x80, 0x2d, +0x31, 0x7b, 0xee, 0xe8, 0x68, 0x9f, 0x9d, 0x68, +0x27, 0x08, 0x21, 0xfe, 0x36, 0x08, 0x47, 0x3f, +0xf7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, +0x01, 0x22, 0x21, 0x6e, 0x02, 0x91, 0x4b, 0xf5, +0x4b, 0x75, 0x12, 0xb3, 0x15, 0xb2, 0x63, 0x15, +0x54, 0xa6, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3c, 0xe8, 0x2b, 0xac, +0x55, 0xda, 0x19, 0xc9, 0x03, 0x04, 0x51, 0x02, +0x00, 0x21, 0x01, 0x22, 0x21, 0x17, 0x62, 0x1e, +0x80, 0x2f, 0x97, 0xc6, 0x14, 0x0b, 0xef, 0x96, +0x1e, 0xb5, 0xbb, 0xa1, 0x14, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x06, +0xd2, 0x42, 0xc1, 0xbe, 0x94, 0x41, 0x03, 0x04, +0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0x80, +0x16, 0xde, 0x3a, 0x9a, 0x24, 0xd5, 0xf7, 0x21, +0x5d, 0x73, 0x99, 0x7f, 0x92, 0x9c, 0xae, 0x7c, +0x31, 0x3a, 0x90, 0x4a, 0xe4, 0xa7, 0x5c, 0xca, +0xc4, 0x83, 0xee, 0xa0, 0x86, 0xc2, 0x82, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x23, 0x01, 0x22, -0x21, 0x78, 0x97, 0x27, 0xd8, 0xb8, 0x1d, 0xd7, -0x5b, 0xe1, 0xed, 0xec, 0x28, 0x8b, 0x64, 0xef, -0x47, 0x91, 0x55, 0xab, 0xbe, 0x04, 0xd9, 0x97, -0x54, 0xa5, 0xb3, 0x9f, 0xbe, 0x25, 0xa8, 0xb8, -0xc5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, -0x01, 0x22, 0x21, 0x17, 0x27, 0x11, 0xbb, 0x2e, -0xe6, 0x49, 0xc9, 0xa1, 0x94, 0x0d, 0x81, 0x90, -0xb1, 0xfa, 0xa8, 0x91, 0x44, 0x79, 0x59, 0xa3, -0x43, 0x70, 0xb2, 0x66, 0xb1, 0xd6, 0x7a, 0x50, -0xaf, 0x47, 0xfe, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x25, 0x01, 0x22, 0x21, 0x35, 0x20, 0x26, -0x09, 0x88, 0x9f, 0x67, 0x6b, 0x82, 0x95, 0x59, -0xd6, 0xc2, 0x8a, 0x13, 0x25, 0x92, 0xc4, 0x52, -0x4a, 0x09, 0x58, 0x5d, 0x4f, 0x3f, 0x59, 0x43, -0x0d, 0x18, 0x09, 0xb2, 0x71, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0x6e, -0xac, 0x12, 0x47, 0xb4, 0xc1, 0xaa, 0x38, 0x5f, -0x52, 0xfd, 0xa1, 0xcb, 0x59, 0xb2, 0xca, 0x63, -0x6f, 0x0c, 0xe6, 0x79, 0x3e, 0xe2, 0x4b, 0x57, -0xc0, 0x40, 0xd2, 0x5f, 0x10, 0xc7, 0x1f, 0x00, +0x21, 0x91, 0x34, 0x07, 0xa5, 0x85, 0x64, 0x1c, +0xd3, 0x37, 0xca, 0x4b, 0xe1, 0x9d, 0x0a, 0xa5, +0xd0, 0x61, 0xb4, 0xc1, 0x6d, 0x5d, 0xdc, 0xe9, +0x7f, 0x6a, 0x03, 0xb8, 0x1d, 0x65, 0x18, 0xda, +0x88, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, +0x01, 0x22, 0x21, 0x5c, 0x92, 0x4c, 0x5a, 0xaa, +0xe1, 0x18, 0xe9, 0x76, 0x4c, 0x5a, 0xe6, 0xe5, +0xc6, 0x0c, 0x70, 0xdd, 0xd6, 0xd7, 0x1b, 0xad, +0xe1, 0xf1, 0xaa, 0x22, 0x2d, 0xff, 0x31, 0xb8, +0x38, 0xaa, 0x61, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x25, 0x01, 0x22, 0x21, 0x99, 0x7e, 0xda, +0x57, 0xa9, 0x1c, 0x21, 0x07, 0x82, 0xeb, 0xcb, +0x67, 0x5b, 0x4b, 0xbb, 0xd0, 0x63, 0xb3, 0xf2, +0x18, 0xca, 0x15, 0x49, 0x6a, 0xce, 0x19, 0xd7, +0x03, 0xce, 0x51, 0xd2, 0x7d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0xd7, +0x0f, 0xc8, 0x81, 0x9a, 0xc3, 0x1b, 0x98, 0xad, +0xb5, 0xec, 0xd2, 0xe5, 0xe1, 0xc6, 0xb3, 0xa1, +0x8e, 0x10, 0xa2, 0x9a, 0x5c, 0x2f, 0xbc, 0x16, +0x8f, 0xf0, 0xcd, 0xc1, 0xa1, 0x8b, 0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x27, 0x01, 0x22, -0x21, 0x0c, 0x79, 0x10, 0x4a, 0xe4, 0x96, 0x15, -0x70, 0xbe, 0x0b, 0x80, 0xa2, 0x2d, 0xa2, 0x66, -0xcb, 0xf9, 0xfe, 0xa2, 0xad, 0xf1, 0x39, 0x1c, -0xd2, 0xa1, 0x6a, 0xb6, 0x43, 0x5b, 0xa2, 0x95, -0x23, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, -0x01, 0x22, 0x21, 0xd4, 0xce, 0xad, 0xf9, 0xcf, -0xea, 0xcd, 0xda, 0x97, 0x45, 0xc8, 0x1c, 0x15, -0xce, 0x7a, 0x71, 0xf5, 0x68, 0x3c, 0xbb, 0x83, -0x40, 0x91, 0xb5, 0x47, 0xa2, 0x12, 0xdb, 0x36, -0x1a, 0xbe, 0xb0, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x29, 0x01, 0x22, 0x21, 0xad, 0xfe, 0x19, -0x00, 0x5f, 0xe3, 0xa6, 0xf9, 0xcc, 0x39, 0x1d, -0x93, 0x11, 0x86, 0x11, 0x0e, 0x8e, 0x72, 0xcc, -0x42, 0xc8, 0xaa, 0x91, 0xc5, 0xce, 0xc0, 0xaa, -0xae, 0xdb, 0x23, 0x8d, 0x2b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x7e, -0xc1, 0x9d, 0x98, 0x36, 0xc2, 0x1b, 0x15, 0xe9, -0x44, 0x2c, 0x0d, 0x85, 0x18, 0x2c, 0xd2, 0x8a, -0x47, 0xbb, 0x14, 0x1e, 0x3f, 0xaa, 0xb4, 0x67, -0x4b, 0x6a, 0xb7, 0x2c, 0x1d, 0xa5, 0x40, 0x00, +0x21, 0xd8, 0xb7, 0xa7, 0xf8, 0x09, 0xae, 0x2f, +0xf6, 0xbe, 0x2d, 0xe9, 0x81, 0xf2, 0x9d, 0x0b, +0xe6, 0x1c, 0xda, 0x68, 0x0b, 0xd4, 0xf2, 0xe7, +0x2a, 0x15, 0xf6, 0x05, 0xf6, 0x11, 0x97, 0x57, +0x03, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, +0x01, 0x22, 0x21, 0x4d, 0x5c, 0x55, 0x5e, 0x52, +0x96, 0x96, 0x18, 0x74, 0x6b, 0xf6, 0x57, 0xb1, +0x1a, 0x59, 0x13, 0xee, 0x6d, 0x3c, 0x4b, 0xc2, +0x99, 0x31, 0x60, 0xa4, 0x3e, 0x07, 0x04, 0x88, +0xf5, 0xde, 0x9d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x29, 0x01, 0x22, 0x21, 0xe7, 0x7a, 0xac, +0x55, 0xd2, 0x3a, 0xc6, 0xc5, 0xbb, 0xf7, 0x0e, +0x7c, 0x79, 0x76, 0x03, 0xac, 0x23, 0xf0, 0x72, +0x8b, 0xe7, 0x31, 0x08, 0x94, 0x01, 0x07, 0xae, +0x3e, 0x74, 0xda, 0x1f, 0x9b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x48, +0x0a, 0xa5, 0x83, 0x06, 0xb3, 0x45, 0x27, 0xbd, +0x6b, 0x21, 0x75, 0x0d, 0xc7, 0x62, 0x39, 0x34, +0x6e, 0x59, 0xf4, 0x68, 0xda, 0x0c, 0xb3, 0x44, +0xd6, 0x50, 0xe2, 0x18, 0xd6, 0x23, 0xce, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2b, 0x01, 0x22, -0x21, 0x94, 0x47, 0x21, 0x65, 0xbc, 0xd1, 0x95, -0x4d, 0x11, 0x33, 0x60, 0xcb, 0xc5, 0xaf, 0x38, -0x10, 0x61, 0x0a, 0xaa, 0x14, 0x30, 0x13, 0xbc, -0x3b, 0x49, 0x17, 0xcd, 0xdd, 0x9c, 0xf1, 0x7e, -0x5d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, -0x01, 0x22, 0x21, 0x6b, 0x23, 0xbd, 0x71, 0x72, -0x05, 0xe7, 0x62, 0xf3, 0x9e, 0xc6, 0x68, 0xd3, -0x9b, 0x1f, 0xda, 0x9f, 0x1f, 0x46, 0xc9, 0xe4, -0xc0, 0x65, 0xf0, 0x05, 0x50, 0xb8, 0x64, 0x6c, -0x37, 0xfa, 0xaa, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x2d, 0x01, 0x22, 0x21, 0x6b, 0xda, 0xa0, -0xf9, 0xe5, 0x7d, 0x61, 0x18, 0xe2, 0x24, 0x6d, -0x63, 0x73, 0x5f, 0xa5, 0x42, 0x47, 0x63, 0x78, -0xd7, 0x22, 0x59, 0xe7, 0xa5, 0x10, 0x99, 0x1a, -0x8f, 0x68, 0xdf, 0xf8, 0x6b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0x87, -0x22, 0x98, 0x4c, 0x16, 0x18, 0x96, 0x86, 0x77, -0xd9, 0xdf, 0x0b, 0x5e, 0xc4, 0xd7, 0xb0, 0x49, -0x51, 0x8f, 0x81, 0xfa, 0xcf, 0x53, 0x73, 0x3f, -0x28, 0x85, 0x59, 0xde, 0xb3, 0x9e, 0xa7, 0x00, +0x21, 0x59, 0xb1, 0x8f, 0x04, 0xf1, 0x97, 0xe8, +0x88, 0x63, 0x29, 0xe1, 0x1c, 0xcf, 0xa7, 0x6b, +0xc5, 0x4e, 0x92, 0x14, 0x0d, 0x33, 0x4e, 0x40, +0xf9, 0x38, 0x9e, 0xee, 0xd5, 0x24, 0xdd, 0x27, +0x70, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, +0x01, 0x22, 0x21, 0xb4, 0x9b, 0x5a, 0xa3, 0x50, +0x26, 0xb3, 0x04, 0xdc, 0x99, 0xd2, 0x21, 0xfe, +0xd0, 0xeb, 0xfa, 0xcd, 0x09, 0x93, 0xeb, 0xa1, +0x96, 0xd2, 0xe0, 0xfa, 0x75, 0xaf, 0x8f, 0x74, +0x3b, 0xc5, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x2d, 0x01, 0x22, 0x21, 0xe6, 0xed, 0x60, +0xf6, 0xf5, 0x34, 0xaa, 0x76, 0x31, 0x21, 0x1a, +0xf1, 0xa5, 0x3c, 0x73, 0xc2, 0xa1, 0x69, 0xa3, +0x2b, 0x39, 0x6d, 0x60, 0xa1, 0xb5, 0x71, 0x93, +0x14, 0x2b, 0xde, 0x2e, 0xa5, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0x07, +0xe1, 0xfc, 0x5c, 0x8e, 0x9f, 0xac, 0x82, 0x23, +0xb7, 0x8e, 0x20, 0xc8, 0x9f, 0xc6, 0xec, 0xf4, +0x18, 0xae, 0x84, 0xa3, 0x98, 0xa9, 0x69, 0xaa, +0xea, 0xb3, 0x7e, 0x6a, 0x3e, 0xb0, 0xe7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2f, 0x01, 0x22, -0x21, 0xde, 0x66, 0x7a, 0x68, 0xa5, 0xe6, 0x1a, -0x91, 0x74, 0x7a, 0x24, 0x2e, 0xa0, 0x46, 0xdd, -0xb6, 0xab, 0x65, 0x63, 0x1b, 0xf4, 0x0e, 0x3b, -0xb9, 0xb9, 0x65, 0x07, 0xfb, 0x5d, 0x99, 0x52, -0xc1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, -0x01, 0x22, 0x21, 0x86, 0x8b, 0x57, 0xbc, 0x0a, -0xc3, 0xca, 0x17, 0x7c, 0x41, 0xb0, 0xb1, 0x1d, -0x89, 0x81, 0xaa, 0x07, 0x42, 0xe2, 0x28, 0x9c, -0x3e, 0x58, 0x61, 0x27, 0xe7, 0xc1, 0xe5, 0x48, -0x64, 0x2d, 0x34, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x31, 0x01, 0x22, 0x21, 0x89, 0x69, 0xd4, -0x9b, 0x9e, 0xa4, 0x8e, 0x9e, 0x51, 0x22, 0x8c, -0x57, 0x16, 0x2c, 0xd6, 0x0c, 0xdf, 0x18, 0xe8, -0x47, 0xd4, 0x1e, 0xa5, 0x72, 0xbb, 0xd9, 0x29, -0x18, 0x2d, 0xe9, 0xd3, 0xb3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0x85, -0xe6, 0x8d, 0x6c, 0xac, 0x09, 0xc5, 0x8b, 0x69, -0x25, 0x3a, 0xcb, 0x5b, 0x07, 0x38, 0x78, 0x44, -0x0b, 0x1d, 0x1f, 0xfe, 0x33, 0xd3, 0x92, 0x4f, -0x6b, 0x49, 0x1f, 0xc7, 0xf2, 0xe5, 0xa7, 0x00, +0x21, 0x0c, 0xfe, 0x01, 0x41, 0xc7, 0xbe, 0x9c, +0x61, 0x14, 0x26, 0x76, 0xfe, 0x7d, 0x7d, 0x0d, +0x35, 0x37, 0x14, 0x83, 0x12, 0xe6, 0xdc, 0x35, +0xbc, 0x01, 0xea, 0x93, 0x24, 0x4d, 0x29, 0x09, +0xbe, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, +0x01, 0x22, 0x21, 0x76, 0x78, 0xf5, 0xfd, 0xce, +0xa6, 0x79, 0x98, 0x1f, 0x5d, 0xbb, 0x46, 0x76, +0x79, 0x3d, 0xcf, 0x02, 0x6c, 0x70, 0x84, 0xc9, +0xee, 0x58, 0xfb, 0x14, 0x89, 0x37, 0x65, 0xed, +0xf7, 0xde, 0xea, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x31, 0x01, 0x22, 0x21, 0xc5, 0x16, 0xc6, +0x59, 0xea, 0x9e, 0xb9, 0x43, 0x99, 0xb2, 0xc6, +0x6c, 0x53, 0x96, 0x09, 0xdd, 0x60, 0x36, 0x05, +0x3f, 0xe5, 0x6d, 0xb5, 0x70, 0x9c, 0xbd, 0xb6, +0x5c, 0x7c, 0xcf, 0xdf, 0x8a, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0x82, +0x17, 0x92, 0xe0, 0x1b, 0x9c, 0x61, 0x49, 0xa8, +0xa4, 0x71, 0xf4, 0x01, 0x6c, 0xbf, 0x5b, 0x7b, +0x17, 0x26, 0x5c, 0x2d, 0x3c, 0x25, 0xd7, 0xd6, +0xea, 0x4c, 0x14, 0x35, 0x15, 0x6e, 0x5e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x33, 0x01, 0x22, -0x21, 0x25, 0x9c, 0x4a, 0xb4, 0xb2, 0x24, 0x85, -0xe9, 0xe4, 0x3d, 0x17, 0x03, 0x47, 0x3d, 0x3b, -0x2e, 0x33, 0xd9, 0x75, 0x88, 0x03, 0xe5, 0x8a, -0x3d, 0x5a, 0xda, 0x70, 0x4a, 0x45, 0xab, 0xa0, -0x7c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, -0x01, 0x22, 0x21, 0xd6, 0x26, 0xa0, 0x8b, 0x05, -0xb1, 0xf1, 0x0e, 0xfa, 0xde, 0x5b, 0x67, 0x8b, -0x08, 0x3b, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x66, 0xc2, 0xf8, 0xf5, -0x9f, 0xa7, 0xc4, 0x77, 0x03, 0x04, 0x51, 0x02, -0x00, 0x35, 0x01, 0x22, 0x21, 0xef, 0x98, 0xd6, -0x5a, 0x48, 0x19, 0x5c, 0xdf, 0x15, 0x81, 0x74, -0x4a, 0x01, 0x33, 0xad, 0x60, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x62, -0x3f, 0x33, 0xc1, 0x77, 0x41, 0xc3, 0x03, 0x04, -0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0x09, -0x53, 0x54, 0x7d, 0x07, 0xd2, 0xed, 0xe1, 0xc7, -0x99, 0xfe, 0x85, 0x96, 0xa3, 0x0f, 0xd4, 0x0b, -0x17, 0x4f, 0x6b, 0x2c, 0x53, 0x1a, 0x2f, 0x39, -0x9e, 0x5b, 0xdd, 0xd8, 0x1b, 0x1f, 0xfe, 0x00, +0x21, 0x83, 0x7f, 0x55, 0xdb, 0xc4, 0xe0, 0x81, +0xb3, 0x98, 0xf9, 0x1a, 0xfd, 0x95, 0xc5, 0x37, +0xe7, 0xfe, 0x07, 0x1e, 0xd0, 0x6d, 0xc4, 0x85, +0xb3, 0xdf, 0x8a, 0xaa, 0xe6, 0x18, 0xc8, 0xfa, +0xf4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, +0x01, 0x22, 0x21, 0x3f, 0xb0, 0x0e, 0xa1, 0x75, +0x7c, 0x72, 0xcd, 0x8a, 0x1d, 0xcf, 0xae, 0x31, +0x9f, 0xd2, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x12, 0x22, 0x9e, 0x37, +0xfd, 0x4b, 0x78, 0xc2, 0x03, 0x04, 0x51, 0x02, +0x00, 0x35, 0x01, 0x22, 0x21, 0x72, 0x97, 0x35, +0x01, 0xc7, 0xac, 0x55, 0x93, 0x2b, 0xc0, 0x61, +0xa4, 0xe8, 0xa5, 0x05, 0x88, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x55, +0x4a, 0xf0, 0x78, 0xf4, 0xe6, 0x3d, 0x03, 0x04, +0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0xb6, +0x16, 0xe5, 0x4e, 0x94, 0x12, 0x36, 0x0a, 0x43, +0x7c, 0xf3, 0x00, 0x9d, 0x9e, 0x63, 0x77, 0xe3, +0x01, 0xef, 0xf1, 0xa2, 0x09, 0x4f, 0xdd, 0x6c, +0x96, 0x59, 0xe4, 0xe9, 0xa2, 0xf0, 0x59, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x37, 0x01, 0x22, -0x21, 0x07, 0x14, 0xb5, 0xc9, 0x2b, 0xc3, 0x5a, -0x75, 0x56, 0x20, 0xa0, 0xaf, 0xc0, 0x0e, 0x20, -0x50, 0x5c, 0xd5, 0x96, 0x3f, 0xce, 0x63, 0xc0, -0x1e, 0xae, 0x25, 0x60, 0xb7, 0xec, 0xcb, 0xc2, -0xab, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, -0x01, 0x22, 0x21, 0xa6, 0x01, 0xcf, 0x5c, 0x38, -0xf6, 0x03, 0x30, 0x3e, 0x7e, 0x7f, 0xbc, 0x65, -0x29, 0x37, 0x8b, 0x30, 0xa6, 0x1b, 0x2f, 0x4c, -0xd4, 0x91, 0xb4, 0x29, 0xfe, 0xf4, 0x0c, 0x65, -0xca, 0x95, 0x33, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x39, 0x01, 0x22, 0x21, 0xea, 0xb6, 0x06, -0x92, 0xac, 0x91, 0x85, 0xbb, 0xc2, 0x52, 0x4e, -0x47, 0x21, 0xd8, 0x8b, 0xb6, 0x56, 0xe2, 0x81, -0x41, 0x46, 0x95, 0xac, 0xbe, 0xd0, 0xbb, 0xc9, -0xba, 0x88, 0x02, 0x52, 0x32, 0x00, 0x03, 0x04, +0x21, 0x28, 0xd6, 0x40, 0xf2, 0x0d, 0x08, 0x67, +0xb2, 0x12, 0x21, 0xc6, 0xf7, 0x20, 0x89, 0xf1, +0x81, 0x7f, 0x06, 0xb1, 0xaa, 0x24, 0x1d, 0xdd, +0x17, 0x7f, 0xdb, 0xb2, 0x49, 0x55, 0xdd, 0x70, +0x0e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, +0x01, 0x22, 0x21, 0x7f, 0xe2, 0x66, 0x42, 0x93, +0xd8, 0x22, 0x3e, 0x23, 0xf3, 0x01, 0xc7, 0x17, +0xe5, 0x31, 0x3b, 0xb3, 0x58, 0x8f, 0x58, 0xfc, +0xf9, 0xb0, 0x2a, 0xf6, 0xa0, 0x31, 0x14, 0x15, +0x75, 0xb3, 0x6c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x39, 0x01, 0x22, 0x21, 0x3e, 0x00, 0xc2, +0x11, 0x8b, 0x85, 0x4c, 0xf4, 0x5a, 0x03, 0x9e, +0x1d, 0xc4, 0xcc, 0xf2, 0x64, 0x75, 0xaa, 0x83, +0x5a, 0x8f, 0xb0, 0xfe, 0x34, 0x58, 0xeb, 0x33, +0x2f, 0xbe, 0xa8, 0x40, 0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0xf4, -0xf3, 0x59, 0x97, 0xdb, 0x38, 0x72, 0xcc, 0xfa, -0x9d, 0x29, 0x61, 0x80, 0xc0, 0x81, 0xde, 0x21, -0xcd, 0x0c, 0x34, 0xc9, 0x1b, 0xd5, 0xdb, 0x0c, -0xd2, 0xe8, 0x08, 0xc3, 0x1f, 0x00, 0xe9, 0x00, +0x7d, 0x7c, 0xd8, 0x01, 0x07, 0xb6, 0x38, 0x1a, +0x02, 0x49, 0x02, 0x15, 0x78, 0x69, 0x40, 0x77, +0x7b, 0x75, 0x7a, 0xf2, 0xfc, 0xa2, 0xf5, 0x4a, +0x73, 0x56, 0xfb, 0xbc, 0xb1, 0x45, 0x90, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3b, 0x01, 0x22, -0x21, 0x21, 0xfd, 0xda, 0xe9, 0xa1, 0xb9, 0x60, -0xc5, 0x31, 0xa7, 0xd5, 0x6a, 0xcc, 0x52, 0x67, -0x66, 0xe9, 0x5d, 0x12, 0x6b, 0xd7, 0x65, 0xfd, -0x63, 0x0e, 0x2f, 0xda, 0x9c, 0xd6, 0xb0, 0xf3, -0x66, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, -0x01, 0x22, 0x21, 0x29, 0x77, 0x45, 0x50, 0x5e, -0x3e, 0xed, 0xe7, 0x7a, 0x1b, 0x55, 0x0d, 0x2c, -0xc4, 0xe7, 0x29, 0xa6, 0xfd, 0x18, 0xa6, 0xc3, -0x5a, 0xc0, 0x30, 0x9d, 0x01, 0x39, 0x57, 0xd0, -0xdd, 0x4d, 0x36, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x3d, 0x01, 0x22, 0x21, 0x9a, 0x4d, 0x3c, -0xf8, 0xa7, 0xbd, 0xcf, 0x16, 0x2d, 0xf3, 0x2f, -0x98, 0x3c, 0xd2, 0x4c, 0xd1, 0x62, 0x61, 0x2f, -0xb2, 0xcf, 0x01, 0x00, 0x5d, 0xa0, 0xad, 0x44, -0x9e, 0xf8, 0xf0, 0x63, 0x22, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0xaa, -0x6c, 0x57, 0x93, 0xba, 0xb2, 0x6a, 0x02, 0xd5, -0xa3, 0xe1, 0x34, 0x0f, 0xb6, 0xe1, 0xbf, 0x76, -0x90, 0xd3, 0x52, 0x62, 0x60, 0xd9, 0x89, 0xb3, -0x0a, 0x06, 0x96, 0x09, 0x29, 0x89, 0xdf, 0x00, +0x21, 0x0b, 0x02, 0xbc, 0xc2, 0xb4, 0x9b, 0x84, +0x36, 0x58, 0xe2, 0xb4, 0xa0, 0x55, 0x0e, 0xd7, +0x02, 0x3d, 0x89, 0x29, 0x6d, 0x68, 0xcf, 0xdc, +0x4d, 0xd1, 0x0f, 0xed, 0x42, 0x4b, 0x8c, 0xeb, +0x08, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, +0x01, 0x22, 0x21, 0xd1, 0x5a, 0x6c, 0xe3, 0xcb, +0x24, 0xc5, 0xfb, 0xa5, 0xde, 0xb7, 0x85, 0x34, +0xcd, 0x1d, 0x62, 0x01, 0x4d, 0x4d, 0x35, 0x19, +0x83, 0xac, 0xd1, 0xf1, 0x71, 0xb1, 0xe7, 0x6c, +0x40, 0x46, 0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x3d, 0x01, 0x22, 0x21, 0x02, 0x2a, 0x38, +0xcc, 0xd5, 0x53, 0xf8, 0x20, 0xf2, 0x2a, 0xc4, +0xd3, 0x09, 0xe9, 0xec, 0x9c, 0xd7, 0x52, 0xd2, +0xfd, 0x12, 0x23, 0xf0, 0x95, 0x6d, 0xf2, 0xd6, +0xdc, 0x4f, 0x00, 0x07, 0x15, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0xe4, +0x35, 0xb3, 0x0e, 0x92, 0x86, 0x3f, 0xe5, 0x8e, +0x35, 0xfe, 0x87, 0x78, 0xac, 0xf2, 0xc9, 0x25, +0xa8, 0x29, 0x24, 0xf3, 0x9d, 0xea, 0xa6, 0xf9, +0x10, 0x62, 0xc9, 0x19, 0x87, 0xf3, 0xd1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3f, 0x01, 0x22, -0x21, 0xf6, 0x3e, 0x4a, 0xbd, 0x46, 0x93, 0xd2, -0x09, 0xb5, 0xf8, 0xf1, 0xbf, 0xfa, 0x72, 0x19, -0xc1, 0x2d, 0x2a, 0x58, 0xd5, 0x89, 0x86, 0xb6, -0x43, 0xf6, 0x8b, 0x48, 0x84, 0x3a, 0xea, 0x5a, -0x6a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, -0x01, 0x22, 0x21, 0x1e, 0xeb, 0xd6, 0x87, 0x9e, -0xe1, 0x4c, 0xf1, 0xaf, 0x99, 0x1a, 0x5b, 0x98, -0x6c, 0x97, 0x7f, 0x84, 0x79, 0x2a, 0xc4, 0xb3, -0x2e, 0xaf, 0x38, 0xd1, 0x05, 0xd9, 0xcf, 0x16, -0x80, 0x4d, 0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x41, 0x01, 0x22, 0x21, 0xcf, 0xbf, 0x25, -0xbc, 0xb2, 0x81, 0x73, 0xc2, 0xd6, 0xa8, 0x9c, -0x6d, 0x70, 0xc9, 0xee, 0xfc, 0x70, 0x35, 0xc0, -0xc6, 0x9e, 0x93, 0x0e, 0x4d, 0xaf, 0x33, 0xbc, -0xd9, 0x65, 0x95, 0x96, 0x06, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0x6d, -0x6c, 0x8c, 0x17, 0xae, 0xf5, 0xb0, 0x24, 0x2f, -0xb0, 0x38, 0xe3, 0x1a, 0xd3, 0x2f, 0x83, 0x0b, -0x76, 0x8f, 0xfa, 0x68, 0x5e, 0x90, 0x6e, 0x85, -0x79, 0x5b, 0xaa, 0xf5, 0x3c, 0xbb, 0x9b, 0x00, +0x21, 0x56, 0x60, 0x2c, 0x54, 0x58, 0x81, 0x97, +0x58, 0x2c, 0xf5, 0x08, 0x6b, 0x94, 0x66, 0xa1, +0xb9, 0x91, 0x50, 0x4f, 0x99, 0x3b, 0xb1, 0x60, +0x0d, 0xdd, 0x0f, 0x46, 0x76, 0xe7, 0xc2, 0x40, +0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, +0x01, 0x22, 0x21, 0x8d, 0x60, 0xf9, 0x60, 0xa5, +0x4d, 0x6a, 0xfb, 0x5e, 0x1a, 0xd7, 0xeb, 0x7a, +0x44, 0x11, 0x43, 0xd7, 0xaf, 0x72, 0x3d, 0x1d, +0x8f, 0x9e, 0xd5, 0x82, 0x66, 0xc6, 0xb7, 0x3d, +0xd0, 0x36, 0x59, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x41, 0x01, 0x22, 0x21, 0x8c, 0x89, 0xd3, +0x83, 0xc4, 0x10, 0xdf, 0xa2, 0x22, 0x48, 0x5d, +0x6e, 0x2a, 0x8d, 0xc5, 0xd6, 0x51, 0xdd, 0xb9, +0xdf, 0x4f, 0x47, 0xee, 0x63, 0xbb, 0xe6, 0x15, +0x92, 0x31, 0x36, 0x1b, 0xcd, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0x97, +0xef, 0xc4, 0x65, 0x05, 0x75, 0xb1, 0x76, 0xd8, +0xb6, 0xd9, 0x3f, 0xc8, 0xc4, 0xb2, 0xe6, 0xd8, +0xca, 0x74, 0xe8, 0x26, 0x37, 0x85, 0x4d, 0x2c, +0x24, 0xc0, 0xee, 0x9b, 0x00, 0xa5, 0xc6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x43, 0x01, 0x22, -0x21, 0xa2, 0xb1, 0x4a, 0x29, 0xe5, 0x8d, 0xa5, -0x44, 0xa7, 0xe0, 0xaa, 0xdc, 0xc6, 0x7f, 0xe6, -0x71, 0x70, 0xec, 0xb2, 0x5f, 0x3f, 0x1b, 0xf8, -0xd0, 0x58, 0xcd, 0x8c, 0xd4, 0xaa, 0xb0, 0x0d, -0x1e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, -0x01, 0x22, 0x21, 0xcd, 0xb2, 0xd5, 0x38, 0x95, -0x0c, 0xf1, 0xf0, 0xd5, 0x0b, 0xd8, 0x4c, 0x8d, -0x10, 0x10, 0x0c, 0xaa, 0x00, 0x27, 0x60, 0x9a, -0x07, 0x78, 0x59, 0xc9, 0xce, 0xb0, 0xf5, 0xe6, -0x52, 0xd1, 0x29, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x45, 0x01, 0x22, 0x21, 0x98, 0x66, 0x05, -0x4e, 0x21, 0xac, 0x92, 0x26, 0x19, 0x83, 0xc8, -0x71, 0x5a, 0x7c, 0x82, 0xbf, 0x96, 0x5d, 0x4b, -0xa2, 0x8c, 0x61, 0xdd, 0x3e, 0x57, 0x8b, 0x62, -0xc0, 0x16, 0x1f, 0x73, 0xed, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0x09, -0xcf, 0x11, 0xf8, 0xbe, 0xfc, 0x62, 0xeb, 0x99, -0x07, 0x93, 0x95, 0x2d, 0x6a, 0xb3, 0x40, 0x61, -0x51, 0x74, 0xe8, 0x70, 0x89, 0xf6, 0x4d, 0x92, -0x0e, 0xca, 0x8e, 0x1f, 0xc5, 0x1f, 0xcb, 0x00, +0x21, 0x92, 0x00, 0xa5, 0xc9, 0x94, 0xf9, 0xdb, +0x00, 0x47, 0x32, 0x56, 0x92, 0x48, 0x3d, 0x0f, +0xde, 0x8a, 0x8c, 0x32, 0x2c, 0x9b, 0xa9, 0x4f, +0x00, 0x33, 0x9f, 0x42, 0x1d, 0x54, 0xa5, 0x6e, +0xc6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, +0x01, 0x22, 0x21, 0x4c, 0xa5, 0x90, 0xf6, 0xef, +0xe4, 0x13, 0x0f, 0xa9, 0x9f, 0x47, 0xd9, 0x97, +0x04, 0xe9, 0x63, 0x39, 0x46, 0x9e, 0x2d, 0x51, +0x1a, 0x26, 0xce, 0x1d, 0xda, 0x82, 0x2a, 0xb1, +0x65, 0xa7, 0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x45, 0x01, 0x22, 0x21, 0xa6, 0xfe, 0x71, +0x24, 0xea, 0xc3, 0x8e, 0xf5, 0x01, 0x2b, 0xee, +0xb9, 0x38, 0xaf, 0x29, 0x27, 0x36, 0x58, 0x39, +0x47, 0x03, 0xd3, 0x93, 0xac, 0xab, 0x4c, 0x5a, +0x8e, 0x39, 0x90, 0x90, 0x1a, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0xfa, +0xaf, 0x9c, 0x21, 0xce, 0x7a, 0x95, 0xcd, 0x32, +0xe3, 0x76, 0xa9, 0xfa, 0x34, 0xb4, 0xb8, 0x87, +0x9e, 0xbf, 0xd6, 0x09, 0x98, 0x03, 0x3d, 0xf3, +0x68, 0x0f, 0x8f, 0x5d, 0x65, 0x6a, 0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x47, 0x01, 0x22, -0x21, 0xd8, 0x67, 0xea, 0x36, 0x4a, 0x1a, 0xa1, -0xaf, 0xf2, 0x4b, 0x23, 0x24, 0xcf, 0xaa, 0x5e, -0xee, 0x4b, 0x7c, 0x62, 0xe3, 0xa4, 0x33, 0xd1, -0x0e, 0xdb, 0xd1, 0xfe, 0xab, 0x26, 0x8c, 0x2c, -0x77, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, -0x01, 0x22, 0x21, 0xc4, 0x8f, 0xd9, 0xfb, 0x0d, -0x20, 0xcb, 0x05, 0xbd, 0x4b, 0x42, 0x5b, 0x2b, -0xfa, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd3, 0x8b, 0xff, 0xd1, -0xbb, 0x54, 0x9c, 0xb6, 0x03, 0x04, 0x51, 0x02, -0x00, 0x49, 0x01, 0x22, 0x21, 0xa0, 0x1a, 0x0e, -0xe4, 0x86, 0x59, 0x77, 0xaf, 0xd6, 0xec, 0x01, -0xba, 0x87, 0x4e, 0xf7, 0x8e, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x16, -0x78, 0xe9, 0x90, 0x11, 0xad, 0x32, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0xee, -0x37, 0x37, 0xf5, 0x7d, 0x41, 0x4c, 0x3b, 0x81, -0xbf, 0x46, 0xe2, 0x3c, 0xe8, 0xb5, 0x79, 0xa6, -0x8f, 0x34, 0x57, 0xa1, 0xdc, 0x7f, 0x0f, 0x8f, -0x2c, 0xd5, 0xd6, 0xa2, 0x6a, 0x76, 0x63, 0x00, +0x21, 0x21, 0x24, 0xe5, 0x3f, 0x57, 0xe3, 0xc9, +0x68, 0x0e, 0x1c, 0xd2, 0x6d, 0xe0, 0x65, 0x10, +0x87, 0x51, 0x77, 0x5c, 0xc6, 0xde, 0xe2, 0x46, +0x4a, 0x72, 0x99, 0xb3, 0xd7, 0x08, 0x9c, 0xb1, +0x01, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, +0x01, 0x22, 0x21, 0xbd, 0xc8, 0x91, 0x81, 0xed, +0xd5, 0x08, 0x02, 0xa6, 0x3c, 0xf0, 0xa8, 0x20, +0x8d, 0x68, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xbd, 0x51, 0x52, 0x78, +0xcb, 0x8c, 0x62, 0x1e, 0x03, 0x04, 0x51, 0x02, +0x00, 0x49, 0x01, 0x22, 0x21, 0x2f, 0x0d, 0x90, +0x7a, 0x27, 0x98, 0x62, 0x42, 0x7f, 0x9b, 0xfa, +0x9c, 0xf7, 0x4c, 0xc2, 0x34, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x5e, +0xf1, 0xf9, 0x53, 0xa1, 0x56, 0xd4, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0xec, +0x49, 0x99, 0x6b, 0x3e, 0x42, 0x8a, 0x51, 0x09, +0xa6, 0x5d, 0xf6, 0x73, 0x1f, 0xe4, 0xc4, 0xca, +0xf0, 0x47, 0x47, 0x8d, 0xeb, 0x7f, 0x5f, 0x40, +0x18, 0x42, 0xfe, 0x7f, 0x1f, 0x70, 0x52, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4b, 0x01, 0x22, -0x21, 0x66, 0xb7, 0x99, 0xb4, 0x57, 0x89, 0xc5, -0x94, 0xf8, 0x80, 0xb7, 0xed, 0xd2, 0x0d, 0x68, -0xc6, 0x3c, 0x98, 0x2c, 0xa7, 0xdb, 0x01, 0x3a, -0xe0, 0x37, 0x82, 0x2b, 0x5c, 0x09, 0xf2, 0x39, -0x59, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, -0x01, 0x22, 0x21, 0x79, 0x68, 0xdd, 0x6a, 0xfb, -0xc4, 0x71, 0x80, 0xe8, 0xda, 0x8b, 0x73, 0x4b, -0x94, 0xe0, 0x3f, 0x56, 0xb8, 0xc4, 0xd2, 0x3d, -0x61, 0x39, 0x44, 0x9c, 0x25, 0xf0, 0xd6, 0x79, -0x2f, 0xff, 0x6e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x4d, 0x01, 0x22, 0x21, 0xfd, 0xf8, 0x9c, -0xaa, 0x34, 0x66, 0xf9, 0xc3, 0xcb, 0x7c, 0x23, -0xba, 0x32, 0xf3, 0x35, 0x60, 0x00, 0x1b, 0xf0, -0xca, 0xa2, 0x59, 0x0c, 0x58, 0x65, 0x27, 0x30, -0x61, 0x62, 0xd2, 0xb2, 0x9f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x1d, -0x00, 0x53, 0xb5, 0x51, 0x20, 0xf1, 0x10, 0xb7, -0x87, 0x63, 0x02, 0x96, 0x85, 0x05, 0xe6, 0xd1, -0x7f, 0xdf, 0x05, 0xb2, 0x6c, 0xba, 0xd1, 0x4c, -0x7c, 0xcb, 0xf0, 0x29, 0x17, 0xcd, 0x6b, 0x00, +0x21, 0xb2, 0xb6, 0xdf, 0xe3, 0xec, 0xb2, 0xe4, +0x6e, 0xfa, 0x34, 0x49, 0x12, 0xcd, 0x60, 0x61, +0x9d, 0x9e, 0xdb, 0x4b, 0xcc, 0xfb, 0x3c, 0xaa, +0xa1, 0xbc, 0x69, 0xc1, 0x54, 0x57, 0xac, 0x71, +0x86, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, +0x01, 0x22, 0x21, 0x57, 0x04, 0x09, 0x15, 0xcb, +0xd1, 0xfa, 0x07, 0xf4, 0xb3, 0x4e, 0x04, 0xa6, +0xf8, 0xe8, 0x4c, 0x3b, 0x2f, 0x2d, 0xc2, 0x26, +0x6e, 0xf1, 0x91, 0x5c, 0x02, 0x89, 0x10, 0x12, +0x6f, 0x75, 0x2e, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x4d, 0x01, 0x22, 0x21, 0xaa, 0x5e, 0xb2, +0x62, 0x51, 0x1e, 0xaf, 0xbe, 0x56, 0x49, 0x6c, +0x0c, 0x04, 0x7b, 0x55, 0x3a, 0x06, 0x68, 0x12, +0x66, 0x5d, 0xe4, 0x68, 0xf5, 0x99, 0xeb, 0x2b, +0x2b, 0xf0, 0x34, 0x0e, 0x14, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x5b, +0x4c, 0xf0, 0x4e, 0x13, 0x1c, 0xe0, 0x51, 0xbf, +0xd2, 0xe1, 0x39, 0xfb, 0x61, 0x8d, 0x17, 0x44, +0x71, 0x62, 0x4f, 0x6d, 0x37, 0x58, 0xdc, 0x1e, +0xdc, 0x45, 0x1d, 0x2d, 0xb7, 0x49, 0xba, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4f, 0x01, 0x22, -0x21, 0xcc, 0xa4, 0xa8, 0x0b, 0x8a, 0xf3, 0x30, -0xf5, 0x27, 0x74, 0x45, 0xc0, 0x02, 0x3a, 0xa3, -0x04, 0xca, 0xfa, 0xf7, 0x9d, 0x5c, 0xaa, 0xc4, -0x58, 0xba, 0x9f, 0xf6, 0x89, 0x47, 0x0f, 0x9e, -0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, -0x01, 0x22, 0x21, 0xdf, 0xdb, 0xce, 0x37, 0x60, -0xad, 0xca, 0x53, 0x55, 0xf6, 0x9d, 0x04, 0x03, -0xa8, 0x9a, 0x4f, 0x42, 0x90, 0x42, 0xa4, 0x40, -0x6b, 0x0d, 0x95, 0xd9, 0x2c, 0x1b, 0xdd, 0x6a, -0x74, 0x3f, 0x4a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x51, 0x01, 0x22, 0x21, 0x9a, 0x6e, 0x99, -0xf3, 0x66, 0x3e, 0x71, 0xf4, 0xd0, 0x0b, 0x9c, -0x89, 0xec, 0x61, 0x4b, 0xa1, 0x96, 0xc7, 0x81, -0x9c, 0x11, 0xb5, 0x9d, 0xb0, 0x3b, 0x8c, 0x6e, -0x1c, 0x2e, 0x45, 0x14, 0x00, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0xfb, -0x67, 0x96, 0x5a, 0x75, 0x3f, 0xae, 0x4a, 0x02, -0xb5, 0x96, 0x11, 0xf8, 0x28, 0x8d, 0x5a, 0xc7, -0x35, 0x02, 0x01, 0x92, 0xae, 0xc4, 0xb5, 0x68, -0x4d, 0x6a, 0x91, 0x94, 0x6a, 0xde, 0x6f, 0x00, +0x21, 0x90, 0xd7, 0xb9, 0x81, 0xdf, 0x85, 0x8c, +0xdd, 0xd0, 0x70, 0x41, 0x7a, 0x9a, 0x4f, 0x67, +0x45, 0x84, 0x5e, 0x6d, 0xe1, 0x32, 0x78, 0x14, +0xfa, 0x85, 0x55, 0x0b, 0x91, 0xfd, 0x94, 0xa4, +0xeb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, +0x01, 0x22, 0x21, 0x21, 0x8a, 0x03, 0x85, 0xd0, +0x07, 0xe0, 0x7e, 0x16, 0x6a, 0x02, 0xd5, 0xa5, +0x86, 0xfe, 0x27, 0xa5, 0xac, 0x01, 0x52, 0xbe, +0xd6, 0x27, 0x22, 0xce, 0x8e, 0x24, 0x6a, 0x0f, +0x17, 0xb7, 0x02, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x51, 0x01, 0x22, 0x21, 0xdd, 0x93, 0x77, +0x1c, 0x3d, 0x2b, 0x7f, 0x16, 0x04, 0x93, 0x3a, +0x39, 0xaa, 0xbf, 0x39, 0xd2, 0x01, 0xd8, 0x39, +0xfb, 0x97, 0xe9, 0x22, 0xe5, 0x2e, 0x91, 0x37, +0x6e, 0xf2, 0xa3, 0x27, 0x17, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0xbc, +0x3c, 0x5e, 0x76, 0x28, 0x64, 0x8f, 0xd2, 0x51, +0x21, 0x84, 0xa2, 0x34, 0x30, 0x42, 0xff, 0xf5, +0x05, 0x98, 0xa9, 0xe8, 0xc7, 0xe9, 0xc1, 0xf5, +0x8d, 0x4b, 0x71, 0x9f, 0x5a, 0x71, 0x69, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x53, 0x01, 0x22, -0x21, 0x29, 0x38, 0x35, 0xda, 0x0d, 0x99, 0x83, -0x56, 0xc0, 0x43, 0xfb, 0x05, 0x86, 0xf1, 0xe9, -0xf5, 0xda, 0x84, 0x2c, 0xae, 0xa3, 0x04, 0x50, -0xc9, 0x8f, 0x0f, 0x0b, 0xc0, 0xc4, 0x77, 0x49, -0x10, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, -0x01, 0x22, 0x21, 0x7a, 0x1f, 0xa3, 0xef, 0x59, -0xf2, 0xfb, 0xb2, 0xc4, 0xb9, 0x34, 0xb3, 0x31, -0xe0, 0xe1, 0xa3, 0xed, 0xc1, 0xea, 0xb8, 0xd6, -0x0e, 0x51, 0x73, 0x8e, 0xa6, 0xcf, 0xc5, 0x61, -0xf5, 0xdd, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x55, 0x01, 0x22, 0x21, 0xac, 0x16, 0xe4, -0x89, 0x11, 0xc8, 0x5a, 0x71, 0xec, 0x5e, 0xda, -0xb4, 0x02, 0x27, 0x1b, 0x45, 0x7d, 0xe2, 0xa9, -0xcd, 0xd0, 0x56, 0x8b, 0xf9, 0x0b, 0xaf, 0xa7, -0xf3, 0xee, 0xcd, 0xc6, 0xc0, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x9f, -0xb4, 0x20, 0x7a, 0x73, 0xfc, 0xf1, 0x1b, 0xb6, -0xf3, 0x73, 0x69, 0x81, 0x36, 0xcd, 0x14, 0x68, -0xa6, 0xdc, 0x1a, 0x34, 0x7f, 0x0a, 0xb7, 0xcb, -0x7d, 0x1e, 0x6d, 0x5b, 0xfd, 0x2d, 0x50, 0x00, +0x21, 0xa8, 0xd0, 0x24, 0x7c, 0xc6, 0x22, 0xa2, +0xc1, 0xd1, 0x1b, 0x86, 0xe8, 0xe2, 0x76, 0xda, +0xb9, 0xe1, 0x2a, 0xad, 0x8d, 0xd7, 0xdf, 0x8b, +0x42, 0x55, 0x25, 0xa2, 0xd4, 0x2f, 0x7c, 0xe3, +0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, +0x01, 0x22, 0x21, 0x41, 0x96, 0xf3, 0xf8, 0xd1, +0x66, 0x1e, 0x95, 0xf4, 0x01, 0xae, 0x52, 0x74, +0xaf, 0x47, 0x1c, 0x7d, 0x09, 0xd6, 0x52, 0x9a, +0xe8, 0xb8, 0x8a, 0xac, 0xaa, 0xf7, 0x91, 0xfa, +0xe1, 0xc1, 0xdc, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x55, 0x01, 0x22, 0x21, 0xde, 0xab, 0x47, +0x53, 0x4b, 0xfb, 0xf1, 0x9e, 0x72, 0x39, 0x5b, +0x7d, 0x79, 0x46, 0xda, 0xc3, 0xc4, 0x85, 0xd6, +0xaa, 0xae, 0xd0, 0xdc, 0x71, 0x50, 0xf8, 0xd5, +0x35, 0x7d, 0x6e, 0xec, 0x03, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x3a, +0xb1, 0x47, 0x13, 0xea, 0xd4, 0x01, 0x6b, 0xa0, +0x37, 0x65, 0x72, 0x59, 0x66, 0x24, 0xa2, 0x35, +0x4a, 0x90, 0xe6, 0x27, 0x53, 0x56, 0x83, 0xf1, +0x40, 0xad, 0x47, 0xf0, 0xc9, 0xc2, 0xad, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x57, 0x01, 0x22, -0x21, 0x9c, 0x87, 0xfe, 0x4b, 0xb4, 0xe1, 0xaf, -0x0b, 0xe6, 0x01, 0x29, 0xee, 0xf3, 0x38, 0x20, -0xad, 0x87, 0xb8, 0xa9, 0x33, 0xb2, 0xf3, 0x89, -0x45, 0x07, 0xad, 0x10, 0x5f, 0xaa, 0xfd, 0x82, -0x89, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, -0x01, 0x22, 0x21, 0x89, 0x5a, 0x75, 0xe2, 0xab, -0x84, 0xc2, 0x6f, 0xd5, 0xe2, 0x0e, 0x82, 0x0f, -0xef, 0x8b, 0xc1, 0x5d, 0x76, 0x54, 0xa4, 0x99, -0x9a, 0xea, 0x7d, 0xdf, 0xee, 0x95, 0x8c, 0xba, -0xbb, 0x14, 0x59, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x59, 0x01, 0x22, 0x21, 0x31, 0x17, 0x99, -0x16, 0x2f, 0xa2, 0x42, 0xaf, 0xbe, 0xd2, 0x7e, -0x27, 0x12, 0xcd, 0x09, 0x54, 0x33, 0xe9, 0x29, -0xce, 0xfe, 0x2e, 0xce, 0x2f, 0x08, 0xcc, 0x8c, -0x9e, 0x5d, 0x6b, 0x53, 0xa1, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0x2f, -0xd1, 0x70, 0x4f, 0x85, 0x0b, 0xd2, 0xca, 0x3d, -0xfc, 0xbd, 0xa9, 0x98, 0x28, 0xf7, 0x71, 0xc1, -0xfc, 0x2d, 0xa3, 0x6d, 0x61, 0x15, 0x36, 0x73, -0x16, 0x79, 0xe0, 0xa2, 0xf3, 0x4a, 0xe7, 0x00, +0x21, 0x9c, 0x5d, 0x92, 0x6b, 0x6a, 0x14, 0x6a, +0xe1, 0xd9, 0x31, 0x54, 0xdb, 0x05, 0xb4, 0x9e, +0xa2, 0x65, 0xfb, 0x80, 0x71, 0xb8, 0x95, 0x33, +0x65, 0x97, 0x04, 0x1b, 0xd3, 0xec, 0x96, 0xb2, +0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, +0x01, 0x22, 0x21, 0xeb, 0x26, 0xfb, 0xe5, 0x5a, +0x34, 0xb4, 0xbf, 0x56, 0x87, 0x14, 0x35, 0xbb, +0x13, 0x07, 0x51, 0x3b, 0xba, 0xb2, 0x44, 0x1b, +0xca, 0x78, 0xcb, 0xdb, 0x95, 0xbf, 0xb8, 0xdc, +0x5b, 0x73, 0x12, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x59, 0x01, 0x22, 0x21, 0x78, 0x90, 0xf9, +0xa0, 0xba, 0x65, 0x97, 0xfb, 0x79, 0x89, 0x3e, +0xa9, 0x5c, 0xe3, 0xdb, 0x36, 0x9b, 0x65, 0x45, +0x68, 0xd0, 0x1a, 0x60, 0x88, 0x19, 0xb1, 0x27, +0x8f, 0x73, 0x77, 0x51, 0xb3, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0x76, +0x25, 0x2d, 0x86, 0x58, 0x2f, 0xbc, 0xe5, 0x22, +0xd4, 0xf1, 0xb7, 0x46, 0xb6, 0xc9, 0x7a, 0x31, +0xa3, 0x35, 0x67, 0x59, 0xe3, 0xe3, 0x65, 0xd4, +0x59, 0x4b, 0x4d, 0x9b, 0x18, 0xac, 0x4e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5b, 0x01, 0x22, -0x21, 0xe3, 0x5b, 0xde, 0x49, 0x2f, 0xba, 0xae, -0xa3, 0x3e, 0xa1, 0xfd, 0xa0, 0xfd, 0x20, 0x24, -0x6f, 0xf1, 0xfc, 0xdd, 0x00, 0x27, 0xea, 0x9e, -0x7c, 0xb1, 0x9c, 0x17, 0x5f, 0x43, 0x2c, 0x35, -0x67, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, -0x01, 0x22, 0x21, 0x39, 0x20, 0xc6, 0xd6, 0x4b, -0x0c, 0xd7, 0xe9, 0x56, 0xcd, 0x01, 0xfd, 0xa7, -0xbd, 0x4d, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x50, 0x14, 0x9c, 0xb7, -0xa7, 0x03, 0x60, 0x48, 0x03, 0x04, 0x51, 0x02, -0x00, 0x5d, 0x01, 0x22, 0x21, 0x3b, 0x4b, 0x3f, -0x1b, 0xb0, 0x23, 0xd7, 0x30, 0x79, 0x5d, 0x2a, -0x0f, 0xd5, 0x2c, 0xfb, 0xc2, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xf4, -0x9d, 0x8d, 0x9a, 0x05, 0xf0, 0x63, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0x81, -0x15, 0x81, 0xf3, 0xa6, 0x49, 0xc2, 0x06, 0x92, -0xc0, 0xec, 0xcd, 0x50, 0x04, 0xff, 0x90, 0xc3, -0x42, 0x01, 0x39, 0x3a, 0xc6, 0x7d, 0x3c, 0xd0, -0xcb, 0xfe, 0xef, 0xed, 0xf7, 0x47, 0x9c, 0x00, +0x21, 0xce, 0xbc, 0x4e, 0xdf, 0xf6, 0x04, 0x8b, +0xf0, 0x3e, 0xc4, 0xac, 0x72, 0x57, 0x94, 0xf2, +0x97, 0x69, 0x52, 0x83, 0x31, 0xd4, 0x97, 0x6e, +0xb5, 0x4f, 0xc2, 0x14, 0xfe, 0xec, 0xe9, 0x96, +0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, +0x01, 0x22, 0x21, 0x28, 0x46, 0x76, 0x70, 0x66, +0x20, 0xd7, 0x47, 0x09, 0xd9, 0x3f, 0xb9, 0x76, +0x93, 0xc9, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x03, 0xde, 0xb3, 0x7f, +0xac, 0x61, 0x79, 0x5b, 0x03, 0x04, 0x51, 0x02, +0x00, 0x5d, 0x01, 0x22, 0x21, 0xa9, 0xaf, 0x75, +0xb4, 0xd3, 0x71, 0x5c, 0xab, 0x10, 0xb3, 0x2a, +0x0a, 0xef, 0x8d, 0x9d, 0x8c, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xba, +0xe6, 0xc5, 0x38, 0xd4, 0x30, 0x5b, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0xee, +0xfd, 0x06, 0xdd, 0xa4, 0x68, 0x78, 0x75, 0x24, +0x5d, 0x51, 0xde, 0xe3, 0xf2, 0x43, 0x75, 0x4c, +0x98, 0x58, 0x73, 0x49, 0x9d, 0xde, 0x0e, 0x93, +0x3b, 0xb7, 0x76, 0x2b, 0x33, 0x2b, 0x75, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5f, 0x01, 0x22, -0x21, 0x65, 0x7a, 0xbe, 0xae, 0xe7, 0x2d, 0xef, -0x04, 0x10, 0xc2, 0xf0, 0x8e, 0xb3, 0x43, 0xe8, -0xf5, 0xde, 0x16, 0xe2, 0xe7, 0xa8, 0x6c, 0x01, -0x60, 0xea, 0xc7, 0x15, 0xeb, 0xa2, 0xbb, 0x42, -0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, -0x01, 0x22, 0x21, 0x19, 0x32, 0x84, 0xd9, 0xf3, -0x6d, 0xc5, 0xd6, 0xea, 0x3a, 0x68, 0x4a, 0x5c, -0x73, 0x9e, 0xa0, 0x4f, 0xb3, 0xc7, 0x7b, 0x67, -0x36, 0xd3, 0x17, 0x82, 0x4a, 0xb9, 0x11, 0x4b, -0xa0, 0x53, 0xe8, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x61, 0x01, 0x22, 0x21, 0x0b, 0x84, 0xa6, -0x54, 0x4a, 0xf4, 0x52, 0x9d, 0xda, 0xa1, 0xfe, -0x9a, 0xef, 0xb3, 0x4d, 0xa1, 0x26, 0xa3, 0x1a, -0xaa, 0x76, 0x06, 0xb0, 0x3d, 0xfb, 0x85, 0x2b, -0xaa, 0xf4, 0x37, 0xf9, 0x75, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0x69, -0xf5, 0x96, 0xd4, 0xa8, 0x84, 0x07, 0xad, 0xbc, -0x2b, 0x82, 0xae, 0xe7, 0x04, 0xef, 0x98, 0xce, -0x19, 0x3c, 0x21, 0x4c, 0x68, 0xd0, 0x4e, 0x25, -0xc1, 0xad, 0xc4, 0xaa, 0x04, 0x61, 0x6a, 0x00, +0x21, 0x9f, 0x0b, 0x7e, 0x44, 0x5e, 0x5f, 0x41, +0xe5, 0xc5, 0xc6, 0x46, 0x83, 0xe5, 0x24, 0x3b, +0x24, 0xde, 0x83, 0xb7, 0x68, 0x8d, 0x0b, 0x6b, +0x19, 0x24, 0xbf, 0x95, 0xa1, 0xb3, 0xda, 0x7b, +0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, +0x01, 0x22, 0x21, 0x4a, 0xf0, 0x5b, 0x7f, 0x13, +0xa7, 0x69, 0x67, 0x22, 0x39, 0xf2, 0x86, 0xe8, +0xb7, 0x2c, 0x87, 0x76, 0x21, 0xba, 0xea, 0x0f, +0x92, 0x06, 0xb5, 0xaf, 0x83, 0xd7, 0xf6, 0xb7, +0xda, 0x12, 0x7c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x61, 0x01, 0x22, 0x21, 0x40, 0x21, 0xe7, +0xd5, 0xba, 0x87, 0x4d, 0xbc, 0x5b, 0x4c, 0x44, +0x37, 0x17, 0x24, 0x67, 0x01, 0x68, 0x1b, 0xd7, +0x24, 0x19, 0xa2, 0xdc, 0x83, 0x90, 0xb4, 0xe5, +0x89, 0xb5, 0x0d, 0x50, 0xb2, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0xf2, +0x46, 0x8b, 0xc4, 0xbe, 0x23, 0xe8, 0x49, 0xb7, +0x62, 0x5c, 0xc9, 0xa8, 0xb3, 0xb0, 0x07, 0xf0, +0x18, 0x09, 0x3d, 0x63, 0x7e, 0x4b, 0xdb, 0xea, +0x30, 0x76, 0x84, 0x09, 0x39, 0xb8, 0xb6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x63, 0x01, 0x22, -0x21, 0x6b, 0xfa, 0x9c, 0x57, 0x9c, 0x76, 0xaf, -0x3a, 0x91, 0xe7, 0xcd, 0xe1, 0xdf, 0x4f, 0x69, -0x37, 0x5f, 0xf0, 0xea, 0xcf, 0x55, 0x74, 0xbe, -0xc6, 0x73, 0xea, 0x3d, 0x2d, 0x93, 0x74, 0xc0, -0x7c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, -0x01, 0x22, 0x21, 0xad, 0x3a, 0x70, 0x1e, 0xc1, -0xbe, 0x3b, 0x53, 0x11, 0xd9, 0x6e, 0x1b, 0x98, -0xde, 0x67, 0x81, 0x7d, 0xb0, 0x3f, 0x3d, 0xed, -0xd7, 0xa3, 0xdf, 0x4c, 0x47, 0x4a, 0x7a, 0x13, -0x40, 0xc0, 0x30, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x65, 0x01, 0x22, 0x21, 0x2e, 0x60, 0x20, -0x87, 0xa2, 0x73, 0xdc, 0xc1, 0xdf, 0xff, 0x8d, -0xbe, 0x3e, 0x07, 0x91, 0x78, 0x94, 0x55, 0xfb, -0x94, 0xc6, 0x84, 0xb5, 0x29, 0x31, 0x6e, 0x05, -0x7b, 0x70, 0x45, 0x2f, 0x37, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0x82, -0x05, 0xba, 0x80, 0x6c, 0xba, 0xec, 0x03, 0xa9, -0x27, 0x0a, 0x2f, 0xc7, 0x67, 0xa1, 0xc0, 0x19, -0x15, 0x12, 0x9c, 0xf2, 0x92, 0x9d, 0x40, 0x05, -0x41, 0xcc, 0x8f, 0xd4, 0x05, 0x8a, 0xb9, 0x00, +0x21, 0xf4, 0x6f, 0x81, 0x16, 0xb1, 0xf9, 0x6b, +0x6b, 0x80, 0xd4, 0x39, 0x41, 0x8e, 0xdc, 0x67, +0xbe, 0xca, 0x74, 0x53, 0x3a, 0xa6, 0xc1, 0x87, +0x19, 0x67, 0xa4, 0xea, 0x58, 0xed, 0x76, 0x95, +0x99, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, +0x01, 0x22, 0x21, 0x85, 0x33, 0x78, 0x5d, 0x68, +0xb4, 0x34, 0xea, 0xb4, 0x64, 0xe8, 0xca, 0xc7, +0xa0, 0xa0, 0x68, 0xa2, 0xa2, 0x0f, 0xfc, 0xd4, +0xa9, 0x95, 0x5e, 0x43, 0x4b, 0xc5, 0x01, 0xf6, +0x25, 0x3a, 0x93, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x65, 0x01, 0x22, 0x21, 0xf7, 0x62, 0x84, +0x0c, 0x9b, 0xa6, 0xfb, 0x6a, 0xac, 0x84, 0xdb, +0x47, 0x58, 0xff, 0x7a, 0x5c, 0xf4, 0xc5, 0x1f, +0x98, 0x10, 0x59, 0x08, 0xc0, 0x13, 0xb9, 0x6a, +0x38, 0xfb, 0xfe, 0xcf, 0xcb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0x8f, +0x4a, 0x86, 0xbd, 0x95, 0x8a, 0x7f, 0x3d, 0xa0, +0x8b, 0x5c, 0x35, 0x5d, 0x70, 0x71, 0x1b, 0xa5, +0xaf, 0x07, 0xab, 0xdf, 0x81, 0x4a, 0x22, 0xf9, +0xe1, 0xde, 0xc2, 0xa5, 0x6f, 0x8b, 0x73, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x67, 0x01, 0x22, -0x21, 0xf8, 0x41, 0x2e, 0x67, 0xd2, 0xf0, 0xa8, -0x2b, 0xa9, 0x79, 0xae, 0xaa, 0xf7, 0x6e, 0xc6, -0x80, 0x63, 0x1d, 0x60, 0xe3, 0xf2, 0xe2, 0x03, -0x4c, 0x8a, 0xc5, 0x13, 0x37, 0x5e, 0xcf, 0x82, -0xf8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, -0x01, 0x22, 0x21, 0x7c, 0x96, 0x7d, 0x16, 0x57, -0x95, 0x28, 0x80, 0x88, 0x8b, 0xad, 0x35, 0xad, -0x92, 0xe1, 0x47, 0x03, 0xd9, 0xb4, 0xe1, 0x5d, -0xae, 0x84, 0xa8, 0x44, 0x6d, 0x57, 0x20, 0x78, -0xb3, 0xf4, 0xae, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x69, 0x01, 0x22, 0x21, 0xf3, 0x9b, 0x2f, -0xc3, 0xdd, 0x66, 0x4f, 0xb3, 0xab, 0xe7, 0xe8, -0x96, 0x2f, 0x03, 0x8a, 0x60, 0x7d, 0x9a, 0x5f, -0xc4, 0x9a, 0x53, 0x64, 0x8a, 0x4e, 0xa9, 0x05, -0x15, 0x93, 0xe9, 0xc5, 0x60, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0x6b, -0xae, 0x68, 0xa2, 0x71, 0x55, 0x3c, 0xe6, 0xd3, -0xc6, 0x19, 0x0f, 0x3c, 0x1c, 0x26, 0xc5, 0x5c, -0x48, 0x9a, 0x0d, 0x0a, 0x7c, 0x67, 0xd9, 0xa2, -0x39, 0xce, 0xda, 0x01, 0x50, 0xaa, 0x81, 0x00, +0x21, 0xe9, 0x62, 0xa6, 0x27, 0xa9, 0xb2, 0xa8, +0xc0, 0xed, 0x35, 0xad, 0xe6, 0xef, 0x5e, 0x6c, +0x7b, 0x21, 0x11, 0x20, 0x07, 0x33, 0x91, 0xb0, +0xcb, 0x9f, 0xab, 0xaa, 0x56, 0x32, 0x0c, 0xc5, +0xc0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, +0x01, 0x22, 0x21, 0xbe, 0xe1, 0x34, 0x98, 0x2d, +0xff, 0xa0, 0x66, 0x55, 0x32, 0x77, 0xb3, 0xee, +0xc0, 0x53, 0xe4, 0xf4, 0x37, 0x85, 0xfb, 0x65, +0x25, 0xe4, 0x1c, 0x7a, 0x35, 0x8d, 0xaa, 0x76, +0x0b, 0x95, 0xb1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x69, 0x01, 0x22, 0x21, 0x40, 0x83, 0x82, +0xcf, 0x9d, 0x74, 0xa6, 0x64, 0x18, 0x15, 0xa8, +0x83, 0x5c, 0x2e, 0xc0, 0xda, 0x6e, 0xe0, 0x75, +0x73, 0xef, 0x11, 0x13, 0x74, 0xcf, 0x2c, 0x4d, +0x8e, 0x17, 0x61, 0x99, 0xe6, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0xee, +0x4e, 0xb4, 0xf5, 0xb1, 0x49, 0x34, 0xf7, 0x91, +0x34, 0xcf, 0x7b, 0x8e, 0x5d, 0x36, 0xc5, 0xe1, +0x1c, 0x6d, 0xb2, 0xc7, 0x4f, 0xe8, 0x3d, 0x29, +0xdf, 0x68, 0x1a, 0x3d, 0xd6, 0xd4, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6b, 0x01, 0x22, -0x21, 0x0b, 0x05, 0x7f, 0x25, 0x9c, 0x7d, 0x68, -0xa6, 0xdb, 0x06, 0xa4, 0x55, 0x0d, 0x3d, 0x00, -0xd4, 0x98, 0x58, 0x8a, 0xc3, 0x30, 0xdb, 0x16, -0x0e, 0x64, 0x9f, 0xfb, 0x31, 0x52, 0x76, 0x83, -0xd0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, -0x01, 0x22, 0x21, 0x1e, 0x75, 0x08, 0xff, 0x52, -0x63, 0xe2, 0xd0, 0x67, 0x5d, 0x95, 0x45, 0x8b, -0xdf, 0xd4, 0xf3, 0xb0, 0x0d, 0x89, 0xf9, 0xb0, -0xce, 0x51, 0x31, 0x41, 0xa1, 0x04, 0xfd, 0x76, -0x55, 0xf6, 0xea, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x6d, 0x01, 0x22, 0x21, 0x6b, 0x1d, 0xdc, -0x7e, 0x49, 0x9b, 0x17, 0x39, 0x03, 0x5b, 0x18, -0x3c, 0x3d, 0xd1, 0x5d, 0x9c, 0xc6, 0x7d, 0x7b, -0x58, 0x60, 0xec, 0xbb, 0x3d, 0x75, 0x79, 0x63, -0x3c, 0x4f, 0x99, 0x82, 0xfe, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0x8c, -0x55, 0xca, 0xe7, 0x75, 0xeb, 0x90, 0x42, 0x9f, -0xf0, 0x87, 0x54, 0x77, 0xcf, 0x7e, 0x5f, 0x6e, -0x69, 0xe9, 0xce, 0xb8, 0x23, 0xd3, 0x19, 0x00, -0x1f, 0xf4, 0x20, 0x5a, 0xf4, 0x2d, 0x94, 0x00, +0x21, 0x4c, 0xda, 0xd6, 0x5f, 0xdd, 0x46, 0x30, +0x88, 0x0b, 0xa7, 0x81, 0x9a, 0xca, 0xd4, 0x24, +0x33, 0x23, 0x4a, 0x9b, 0x1b, 0xaf, 0xce, 0xcd, +0xaf, 0x59, 0x31, 0x1a, 0x6c, 0x98, 0xd5, 0xd5, +0x23, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, +0x01, 0x22, 0x21, 0x65, 0x42, 0x99, 0x04, 0xde, +0x01, 0x38, 0xd5, 0xe6, 0xb0, 0x71, 0xea, 0x2e, +0xc2, 0x49, 0xbe, 0x8f, 0xcb, 0xf2, 0x2d, 0xb5, +0x94, 0x53, 0x25, 0x37, 0xcb, 0x2f, 0x79, 0x1e, +0x03, 0x1b, 0x9e, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x6d, 0x01, 0x22, 0x21, 0x32, 0x0c, 0x48, +0xc2, 0xf1, 0xc0, 0x8f, 0x15, 0x06, 0x53, 0x2d, +0x04, 0xce, 0x0f, 0x65, 0xbc, 0xb7, 0xc9, 0x02, +0x78, 0x48, 0xa5, 0x52, 0x7a, 0x0e, 0x52, 0x46, +0x5f, 0x38, 0x4b, 0xb9, 0xff, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0x79, +0xf3, 0x2d, 0xe4, 0xd0, 0x51, 0x49, 0x74, 0x75, +0xcc, 0xad, 0x7f, 0x8f, 0x6d, 0x45, 0x9a, 0x17, +0x32, 0x6f, 0x9c, 0x4a, 0x86, 0xfd, 0xa1, 0x8b, +0x74, 0x5f, 0x39, 0x17, 0xb8, 0x66, 0x56, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6f, 0x01, 0x22, -0x21, 0x39, 0x09, 0xec, 0x2b, 0xc8, 0xf8, 0x3d, -0xd5, 0x45, 0xe7, 0x30, 0x5f, 0x97, 0xc7, 0x9e, -0x6d, 0x28, 0x2a, 0x6c, 0x4b, 0x35, 0x89, 0xf6, -0xbc, 0xfc, 0x0c, 0xf1, 0xfb, 0xfa, 0x45, 0x80, -0xbe, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, -0x01, 0x22, 0x21, 0x77, 0x1e, 0x88, 0x80, 0x94, -0x5c, 0x4a, 0xb8, 0xaa, 0xaf, 0xf5, 0x1f, 0xdf, -0xe9, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x81, 0x87, 0x54, 0x52, -0x07, 0x02, 0xe2, 0xc0, 0x03, 0x04, 0x51, 0x02, -0x00, 0x71, 0x01, 0x22, 0x21, 0x23, 0xe5, 0x3e, -0xed, 0x7f, 0xe1, 0x47, 0xd1, 0x9d, 0xa9, 0x19, -0x69, 0x18, 0x86, 0x71, 0x85, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xf0, -0x92, 0x33, 0x3d, 0x97, 0x52, 0x7f, 0x03, 0x04, -0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0xe5, -0x88, 0x9a, 0xd3, 0x2d, 0x38, 0x20, 0xcd, 0x2a, -0x97, 0x8d, 0x69, 0x99, 0x08, 0x48, 0xbb, 0xbd, -0x0b, 0x05, 0x54, 0xf0, 0x07, 0xa6, 0xc8, 0x29, -0xe7, 0x1c, 0x09, 0x23, 0x2a, 0xf8, 0x72, 0x00, +0x21, 0x67, 0xb4, 0x71, 0xc0, 0xf6, 0xd9, 0xa3, +0x5a, 0xfb, 0xb4, 0x5b, 0x89, 0xed, 0xba, 0xe7, +0x70, 0xbc, 0xe4, 0x15, 0x9d, 0xfe, 0x7f, 0x47, +0xd6, 0x30, 0x30, 0x30, 0x35, 0x0c, 0x73, 0x6b, +0x23, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, +0x01, 0x22, 0x21, 0xc9, 0x6d, 0x00, 0x99, 0x3b, +0x1f, 0xf8, 0x80, 0x31, 0x17, 0x3c, 0xca, 0x4d, +0x3e, 0x06, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xaf, 0x02, 0xd1, 0x44, +0x59, 0xf6, 0xfc, 0xf4, 0x03, 0x04, 0x51, 0x02, +0x00, 0x71, 0x01, 0x22, 0x21, 0xc0, 0x79, 0x21, +0xd0, 0x47, 0x66, 0x21, 0xaf, 0x02, 0xae, 0x8f, +0x63, 0x59, 0x16, 0xde, 0x67, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x22, +0x33, 0x61, 0x90, 0x51, 0xe1, 0x4f, 0x03, 0x04, +0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0x19, +0x0b, 0x14, 0x3f, 0x42, 0xd7, 0x5a, 0x2e, 0xd3, +0x86, 0xfe, 0x36, 0x7e, 0x47, 0x78, 0x58, 0xdb, +0x5e, 0xbf, 0xaa, 0xd0, 0xdb, 0xbd, 0x15, 0xf2, +0x84, 0xbc, 0x05, 0x4d, 0x44, 0xca, 0x74, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x73, 0x01, 0x22, -0x21, 0x92, 0xf4, 0x5a, 0x12, 0x6a, 0x1a, 0x46, -0x46, 0xd4, 0xb8, 0x7d, 0x16, 0x05, 0xb6, 0x4f, -0xb7, 0x9f, 0x16, 0xbc, 0x10, 0xe8, 0x38, 0x38, -0x57, 0x41, 0x19, 0x1a, 0xca, 0x73, 0xe2, 0xd7, -0x8e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, -0x01, 0x22, 0x21, 0x9f, 0x15, 0x82, 0x08, 0x70, -0x7f, 0xd7, 0xb5, 0xb9, 0x31, 0xc2, 0xa8, 0x35, -0x87, 0x8e, 0xd3, 0xcf, 0xde, 0x66, 0x0d, 0x8d, -0xe5, 0x06, 0x4d, 0x4e, 0xcd, 0x16, 0x0a, 0xcc, -0x14, 0xed, 0xb4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x75, 0x01, 0x22, 0x21, 0x56, 0xbc, 0x8d, -0xe8, 0xfc, 0x26, 0xa0, 0x1b, 0x51, 0xf1, 0xf3, -0xfd, 0x74, 0x20, 0x9e, 0x4a, 0x62, 0xe5, 0x68, -0x1e, 0x0a, 0x3c, 0x91, 0x22, 0x94, 0xa0, 0x5d, -0x51, 0x72, 0x79, 0x33, 0x0a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0xb6, -0x9e, 0x68, 0x44, 0x43, 0x33, 0xb3, 0xf2, 0xfd, -0xc3, 0x07, 0x8d, 0x30, 0xfd, 0x6c, 0xea, 0xc9, -0x67, 0x2d, 0x69, 0x41, 0xe7, 0xfe, 0x0b, 0x25, -0x57, 0x03, 0x32, 0x84, 0x4e, 0x03, 0x4a, 0x00, +0x21, 0x9a, 0x1e, 0x90, 0xa0, 0xe4, 0x3a, 0xe5, +0xa5, 0xd2, 0x53, 0xce, 0xf1, 0x43, 0x0e, 0x62, +0xf4, 0xb5, 0x10, 0x37, 0xd1, 0xe9, 0xa0, 0xb3, +0x2f, 0x27, 0xf6, 0xf9, 0x7b, 0xa6, 0x23, 0x8f, +0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, +0x01, 0x22, 0x21, 0x8c, 0x7c, 0x7f, 0x7f, 0xad, +0x93, 0xb8, 0x1c, 0xf3, 0xd7, 0xad, 0xfa, 0xe9, +0x00, 0x69, 0x4e, 0xd5, 0x68, 0xec, 0x79, 0x20, +0x42, 0x8b, 0xab, 0x82, 0xcb, 0x7a, 0xfe, 0xeb, +0x6a, 0xc8, 0xa6, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x75, 0x01, 0x22, 0x21, 0xcf, 0x82, 0x29, +0x1f, 0x10, 0xdc, 0x57, 0x09, 0xdf, 0x9f, 0x26, +0x1d, 0x2e, 0x97, 0x47, 0x1e, 0xc0, 0xfb, 0x79, +0x1c, 0x9d, 0x4a, 0xcf, 0x45, 0x4f, 0xee, 0xf8, +0x3e, 0x8a, 0xc7, 0x93, 0x19, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0x3e, +0xbb, 0x08, 0x23, 0xda, 0x54, 0x97, 0x21, 0x7d, +0xee, 0xf0, 0xb1, 0x61, 0x44, 0xa7, 0xf3, 0x04, +0x7a, 0x64, 0x61, 0x02, 0x74, 0x8c, 0xc3, 0xcd, +0x5a, 0x4e, 0x26, 0x3f, 0x31, 0x81, 0x37, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x77, 0x01, 0x22, -0x21, 0x9a, 0x99, 0xf9, 0xd3, 0x0b, 0xa8, 0xad, -0xe8, 0xb0, 0xdf, 0x4d, 0x73, 0xa3, 0xb8, 0x92, -0x93, 0xf7, 0x59, 0x1e, 0x03, 0x33, 0xd3, 0xa3, -0xf1, 0x2f, 0x1e, 0xa9, 0xe1, 0x9c, 0xf6, 0x04, -0x53, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, -0x01, 0x22, 0x21, 0x83, 0x2d, 0xe3, 0x40, 0x8d, -0x76, 0xdf, 0x80, 0xf1, 0x0e, 0x43, 0x0d, 0xc6, -0xa3, 0x03, 0xbc, 0xbb, 0x94, 0x5f, 0x89, 0xd3, -0xd0, 0x6a, 0x64, 0x95, 0xc1, 0x3c, 0xad, 0x42, -0x86, 0xc2, 0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x79, 0x01, 0x22, 0x21, 0x69, 0x40, 0xad, -0x0b, 0xf5, 0xb3, 0x8c, 0x51, 0x30, 0xfe, 0x9d, -0xae, 0x92, 0x2d, 0x06, 0x0e, 0xe2, 0xf7, 0x8b, -0x5b, 0xab, 0x69, 0x85, 0xef, 0xf3, 0x8b, 0x4a, -0x6c, 0x49, 0xfd, 0xf3, 0x74, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0xb1, -0x6f, 0x50, 0x4c, 0xed, 0xef, 0xe7, 0x34, 0x67, -0x8d, 0xad, 0xda, 0x60, 0x8d, 0x21, 0x2a, 0xb9, -0xc2, 0xf8, 0x01, 0x71, 0x34, 0x58, 0x06, 0x2f, -0xba, 0xfd, 0xd6, 0x27, 0x72, 0x6e, 0x0c, 0x00, +0x21, 0x48, 0x35, 0x49, 0xa6, 0x71, 0x56, 0x70, +0x79, 0x94, 0x80, 0xa7, 0x75, 0x58, 0x5b, 0xef, +0x04, 0xff, 0x1b, 0x39, 0xe5, 0xa9, 0x3a, 0x5d, +0x39, 0x70, 0xe7, 0x9a, 0x28, 0xf5, 0x15, 0x98, +0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, +0x01, 0x22, 0x21, 0x94, 0x4d, 0x9c, 0xe5, 0x70, +0xd1, 0x6d, 0xf6, 0x2e, 0x00, 0xc6, 0xb6, 0x2a, +0xa1, 0x1e, 0xa0, 0x32, 0x90, 0x13, 0xc8, 0x26, +0x51, 0xb2, 0x82, 0xe0, 0x4e, 0x98, 0xc2, 0xcb, +0xe7, 0x2e, 0xbe, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x79, 0x01, 0x22, 0x21, 0x29, 0xcf, 0x33, +0xc5, 0xe9, 0x67, 0x3b, 0xf8, 0x8f, 0xca, 0x76, +0xc2, 0x96, 0x59, 0xc5, 0x77, 0x8d, 0xdf, 0x16, +0x78, 0x3c, 0x48, 0xc9, 0x6e, 0xaa, 0xba, 0x15, +0xc5, 0xd8, 0x1d, 0xfa, 0x15, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0xfe, +0xea, 0x46, 0xec, 0x5c, 0x6a, 0x22, 0x88, 0xe7, +0x67, 0x10, 0x7a, 0x34, 0x44, 0x3e, 0xa8, 0x52, +0x7e, 0x49, 0x08, 0x2f, 0x18, 0x87, 0xad, 0xad, +0xb6, 0x27, 0x8d, 0x78, 0x9e, 0xec, 0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7b, 0x01, 0x22, -0x21, 0xda, 0x9e, 0xe4, 0xc7, 0x00, 0x32, 0x9e, -0xc6, 0xdf, 0xe7, 0xe6, 0x62, 0xf5, 0x51, 0xef, -0xb4, 0x68, 0x96, 0x9c, 0xf5, 0x72, 0xbe, 0x61, -0xc1, 0x68, 0xef, 0xad, 0x6c, 0x2c, 0xed, 0xc7, -0x5a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, -0x01, 0x22, 0x21, 0x5c, 0xb3, 0xdb, 0xdc, 0x29, -0xf2, 0x24, 0xfc, 0xe8, 0x6c, 0x2b, 0xcb, 0x2c, -0x64, 0x85, 0xc7, 0xb3, 0xf1, 0x49, 0x75, 0x7a, -0xd7, 0x59, 0xe7, 0xa0, 0xc4, 0xa2, 0x47, 0x44, -0xbc, 0xa5, 0xc6, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x7d, 0x01, 0x22, 0x21, 0xd5, 0xbc, 0xd6, -0xaa, 0x02, 0x4f, 0xd2, 0x9b, 0x01, 0xdd, 0x0e, -0x76, 0x68, 0xe1, 0x22, 0x81, 0x8c, 0xd5, 0x2e, -0x39, 0x71, 0x6c, 0x21, 0x14, 0x9d, 0x1a, 0x76, -0xd4, 0x0c, 0x3f, 0x17, 0x0d, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0xce, -0x2c, 0x4f, 0x1e, 0x8c, 0x9c, 0x83, 0x2e, 0x2b, -0x5c, 0x99, 0xbe, 0x8f, 0xad, 0x7a, 0xfe, 0xda, -0x34, 0x86, 0xb7, 0x8d, 0x82, 0x62, 0x3a, 0x72, -0x04, 0xa6, 0x32, 0xcb, 0x85, 0x3c, 0x82, 0x00, +0x21, 0x16, 0xa5, 0x97, 0x11, 0x56, 0xbc, 0x9e, +0x4f, 0x99, 0x49, 0x44, 0xb5, 0x0a, 0x5a, 0x24, +0xb1, 0x7a, 0x17, 0x35, 0xc0, 0xa6, 0x98, 0x0e, +0x70, 0xb4, 0xc3, 0x3e, 0xcf, 0x00, 0x9a, 0xe5, +0x0a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, +0x01, 0x22, 0x21, 0xd7, 0x38, 0x5f, 0x34, 0xa3, +0xf4, 0xc7, 0x0c, 0xbd, 0xa2, 0x37, 0x55, 0x70, +0x34, 0x31, 0x8b, 0x5e, 0x32, 0xd0, 0x9c, 0x5b, +0xdf, 0x5e, 0x7c, 0x31, 0xd8, 0x38, 0x9d, 0x01, +0x8b, 0xf7, 0x21, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x7d, 0x01, 0x22, 0x21, 0x67, 0x8b, 0x08, +0xf3, 0x85, 0xf6, 0x88, 0xc8, 0x25, 0xad, 0xda, +0x86, 0xc7, 0x6e, 0xee, 0x37, 0xa5, 0x03, 0xd3, +0xce, 0x66, 0xe0, 0xc9, 0x48, 0x2e, 0x5e, 0x7c, +0x9a, 0xd2, 0x66, 0x35, 0x8c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0x0c, +0x7a, 0x51, 0x7c, 0x35, 0x2e, 0xca, 0xb3, 0xad, +0x55, 0x3a, 0x74, 0xc6, 0xe0, 0xdd, 0xbc, 0x89, +0xe5, 0xc1, 0x85, 0x30, 0x79, 0x9a, 0x64, 0xa2, +0x14, 0xee, 0x25, 0x55, 0x52, 0xfa, 0xa2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7f, 0x01, 0x22, -0x21, 0xe5, 0x85, 0xc3, 0x60, 0x3a, 0x7d, 0xcb, -0x90, 0xfd, 0x52, 0x26, 0x48, 0x94, 0xa4, 0x9a, -0xac, 0x31, 0x84, 0x06, 0xf5, 0x1b, 0x3c, 0xf2, -0x4f, 0x11, 0x8c, 0xdd, 0x54, 0x6c, 0x74, 0xa3, -0xb2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, -0x01, 0x22, 0x21, 0xc4, 0xc9, 0xb5, 0x67, 0x02, -0x06, 0xf9, 0xfe, 0x93, 0x7d, 0xfb, 0x97, 0x9e, -0x4d, 0xcd, 0x4c, 0xcf, 0x5e, 0x48, 0x32, 0x01, -0x7d, 0x88, 0x64, 0x5e, 0x3d, 0x59, 0xc1, 0xf7, -0x2d, 0x45, 0x36, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x81, 0x01, 0x22, 0x21, 0x3f, 0xa3, 0xa2, -0xe5, 0x43, 0x52, 0xa4, 0xf5, 0x8f, 0xd8, 0x0f, -0x7c, 0xfc, 0x12, 0x2e, 0xb4, 0x01, 0xd6, 0x47, -0x58, 0x20, 0x22, 0x65, 0x8c, 0x85, 0x48, 0xbb, -0xad, 0xeb, 0x00, 0x07, 0xad, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0x61, -0xe2, 0x85, 0xed, 0xb5, 0x75, 0xae, 0x50, 0x6a, -0x53, 0x9e, 0x71, 0x68, 0x32, 0x6a, 0xe0, 0xd2, -0xdf, 0x93, 0x7d, 0x5e, 0x3e, 0xf8, 0x56, 0x1e, -0xd9, 0xd7, 0x4f, 0x36, 0x70, 0xb0, 0xd4, 0x00, +0x21, 0xaf, 0x60, 0x23, 0xb1, 0xd4, 0x06, 0xb5, +0x2b, 0x1e, 0x91, 0x87, 0x07, 0x57, 0xb6, 0x97, +0xb4, 0xf6, 0x28, 0xaa, 0x9c, 0xba, 0x6e, 0x80, +0xf7, 0x83, 0x9e, 0x97, 0x0e, 0x54, 0x41, 0x06, +0xc3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, +0x01, 0x22, 0x21, 0x76, 0xf6, 0xea, 0xcb, 0x67, +0x0c, 0xd6, 0xc3, 0xfe, 0xf6, 0x7e, 0xe5, 0xb1, +0x7b, 0xff, 0x29, 0x0e, 0x43, 0xf0, 0x70, 0xff, +0xac, 0xbd, 0x50, 0xeb, 0x5b, 0x5b, 0xb3, 0xb3, +0x07, 0x8c, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x81, 0x01, 0x22, 0x21, 0x24, 0x39, 0x68, +0xc1, 0xb6, 0x48, 0x74, 0xa5, 0x80, 0x75, 0x48, +0xf1, 0x84, 0xdd, 0xb7, 0xcf, 0x08, 0xd9, 0xea, +0xa0, 0x9f, 0xca, 0xee, 0x75, 0x83, 0xc9, 0x87, +0x93, 0xa1, 0x5b, 0xb6, 0xb9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0x9b, +0xd0, 0xd3, 0x7a, 0xf5, 0x7f, 0x7f, 0x23, 0x79, +0xf2, 0x42, 0xbf, 0x46, 0xe5, 0x73, 0x3f, 0xd9, +0x4c, 0xb8, 0xad, 0xf3, 0x5d, 0x04, 0x57, 0x5a, +0x3e, 0x9e, 0xa0, 0xc3, 0x98, 0x49, 0x36, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x83, 0x01, 0x22, -0x21, 0xb9, 0x9f, 0xbc, 0xba, 0x17, 0xdd, 0xe4, -0x35, 0x13, 0x4b, 0x00, 0xc9, 0xa2, 0xb6, 0xdf, -0x83, 0x2a, 0x75, 0x5f, 0xfa, 0x3f, 0xa4, 0x58, -0xf1, 0xc9, 0x7d, 0xd7, 0x54, 0x61, 0x17, 0x3d, -0xf5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, -0x01, 0x22, 0x21, 0x5a, 0x38, 0xa8, 0xff, 0x2f, -0x74, 0x5c, 0x51, 0xa2, 0x2f, 0xb1, 0x78, 0x72, -0x4a, 0xa6, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x19, 0xfe, 0x25, 0x42, -0xdc, 0xa3, 0xe8, 0x69, 0x03, 0x04, 0x51, 0x02, -0x00, 0x85, 0x01, 0x22, 0x21, 0x08, 0xdb, 0x1b, -0x58, 0x2e, 0xed, 0x2e, 0x79, 0xd2, 0xf2, 0xb7, -0xc7, 0xde, 0xc2, 0xc9, 0x6e, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xbe, -0xa2, 0x0f, 0x00, 0x75, 0x16, 0x2a, 0x03, 0x04, -0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0x82, -0x22, 0x24, 0xcf, 0x83, 0x3b, 0x24, 0x6b, 0xd4, -0x84, 0xfa, 0xcd, 0x3e, 0x3d, 0xb6, 0x9b, 0x26, -0x22, 0x3d, 0x6a, 0x28, 0xea, 0x72, 0x0f, 0xb8, -0x7e, 0x13, 0x16, 0x06, 0x4a, 0x18, 0x1b, 0x00, +0x21, 0x55, 0xfe, 0x10, 0x38, 0x6a, 0x28, 0x7d, +0x1a, 0x78, 0xe4, 0x75, 0xde, 0xb8, 0x9d, 0x27, +0x53, 0xbf, 0x3c, 0x6a, 0x74, 0x25, 0xb4, 0xaf, +0xfa, 0xd6, 0x70, 0xf7, 0x47, 0xcb, 0x21, 0x21, +0x49, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, +0x01, 0x22, 0x21, 0x72, 0x64, 0x24, 0x39, 0x51, +0x0e, 0xab, 0x9d, 0x35, 0xdd, 0xb4, 0x60, 0x02, +0xba, 0x30, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x42, 0xd1, 0xac, 0xbc, +0x76, 0x02, 0xb8, 0x30, 0x03, 0x04, 0x51, 0x02, +0x00, 0x85, 0x01, 0x22, 0x21, 0x5c, 0x42, 0xe7, +0x14, 0x7a, 0xa4, 0x88, 0xed, 0xad, 0xc3, 0x59, +0x27, 0x65, 0x37, 0x8e, 0x3d, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x54, +0xa7, 0x9a, 0xcb, 0x25, 0x97, 0xfd, 0x03, 0x04, +0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0x1c, +0xd0, 0xed, 0x77, 0x1b, 0x3e, 0x6a, 0x6d, 0xde, +0x4c, 0x34, 0x8a, 0x98, 0x61, 0x33, 0xcc, 0xf0, +0xf0, 0xa7, 0x4a, 0x6d, 0xb0, 0x5f, 0x15, 0x11, +0x6d, 0xc0, 0x7a, 0xff, 0x40, 0xe1, 0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x87, 0x01, 0x22, -0x21, 0x1d, 0xf9, 0xb0, 0x51, 0xda, 0xc4, 0x4c, -0xed, 0xd6, 0x72, 0xca, 0xa6, 0x8b, 0x1a, 0xfe, -0x78, 0xb0, 0xa9, 0x31, 0xeb, 0x04, 0x48, 0xb9, -0x6c, 0x18, 0xc6, 0x66, 0xc5, 0xbf, 0x5c, 0xb1, -0x7b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, -0x01, 0x22, 0x21, 0xb7, 0x61, 0x0a, 0x88, 0x08, -0x4a, 0x10, 0xe8, 0x62, 0x75, 0x9e, 0x04, 0x27, -0x10, 0x23, 0x6a, 0x79, 0x6c, 0x07, 0xc8, 0x30, -0x58, 0xb8, 0xe8, 0x91, 0xe1, 0xb3, 0x30, 0x06, -0xf3, 0xca, 0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x89, 0x01, 0x22, 0x21, 0xe6, 0x11, 0x0b, -0x25, 0x52, 0xbf, 0x4b, 0xc7, 0xfc, 0xe6, 0x7d, -0x48, 0x92, 0xe0, 0xa4, 0x54, 0x36, 0x9c, 0x89, -0x71, 0x78, 0x87, 0xd0, 0x40, 0x88, 0x6c, 0xfa, -0x35, 0xa4, 0x18, 0x39, 0x1a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0x95, -0xce, 0xa7, 0xc0, 0x43, 0xf4, 0xcf, 0xe4, 0x87, -0xe7, 0x62, 0x29, 0x3f, 0x88, 0x72, 0x4c, 0x27, -0x3d, 0xe7, 0x06, 0xa4, 0x6b, 0xd5, 0xfd, 0xd1, -0xf0, 0xf5, 0xfc, 0x0e, 0xc8, 0xe5, 0xdf, 0x00, +0x21, 0x94, 0x5d, 0x8e, 0x09, 0xdd, 0xd9, 0x8e, +0x2e, 0xd6, 0xb6, 0x3e, 0x43, 0x19, 0xef, 0xe6, +0xee, 0xd1, 0xc1, 0xb1, 0x15, 0x90, 0x21, 0xf5, +0xe4, 0x26, 0x29, 0xaa, 0x02, 0xac, 0x6d, 0x32, +0x1a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, +0x01, 0x22, 0x21, 0xaa, 0xc4, 0x33, 0xd2, 0x1b, +0x81, 0x0a, 0xc6, 0x7e, 0x76, 0x89, 0xf5, 0xed, +0xdc, 0x78, 0x3a, 0xb9, 0xfc, 0x07, 0x0f, 0x95, +0x97, 0x76, 0x74, 0x0b, 0xf6, 0xc1, 0xd2, 0x3b, +0x1b, 0xf5, 0xfe, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x89, 0x01, 0x22, 0x21, 0xc9, 0x71, 0x5a, +0x2b, 0xe4, 0x6d, 0x15, 0x1e, 0xf6, 0x5e, 0xe5, +0x31, 0xca, 0x08, 0x64, 0xa2, 0x3f, 0xee, 0x6a, +0xad, 0x73, 0xd2, 0x7e, 0xc7, 0x16, 0xfe, 0x3b, +0xbb, 0xc3, 0xbc, 0xc4, 0x5d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0xa3, +0x21, 0x13, 0x78, 0xfb, 0x77, 0x0c, 0xe5, 0x65, +0x44, 0x48, 0x90, 0xa2, 0x9f, 0x1e, 0xe0, 0xf2, +0x20, 0x9a, 0xd7, 0xb9, 0x15, 0x1e, 0x7a, 0xef, +0xbe, 0xea, 0x55, 0x01, 0xd5, 0x01, 0x3e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8b, 0x01, 0x22, -0x21, 0xe8, 0x24, 0x95, 0xdb, 0xed, 0xe5, 0x66, -0x29, 0xbc, 0xf7, 0x33, 0xf1, 0x2f, 0x34, 0xb9, -0x89, 0xb8, 0xc5, 0x1c, 0x3f, 0x60, 0xe5, 0xe3, -0x54, 0xd5, 0x25, 0x6a, 0x19, 0x59, 0x52, 0x6e, -0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, -0x01, 0x22, 0x21, 0x6e, 0xa5, 0xb7, 0x60, 0x4f, -0x56, 0x55, 0x39, 0xda, 0x10, 0x6b, 0x57, 0xfd, -0x92, 0x40, 0x6c, 0x12, 0x7c, 0x6c, 0x28, 0x43, -0xe9, 0x8f, 0x82, 0x84, 0x1c, 0xfc, 0x41, 0x64, -0xa7, 0x97, 0x09, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x8d, 0x01, 0x22, 0x21, 0xb8, 0x2b, 0xa5, -0xf2, 0xbf, 0x8d, 0xde, 0x2a, 0x23, 0x9e, 0xf4, -0xe4, 0x68, 0xe2, 0xa7, 0xba, 0x8f, 0xa9, 0xfb, -0x12, 0x5f, 0xd4, 0x11, 0x46, 0x5f, 0x61, 0x21, -0xb1, 0x2a, 0xb6, 0x99, 0x1b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x3e, -0x20, 0xca, 0x4f, 0xda, 0xc5, 0x45, 0xa7, 0x2a, -0x54, 0xf9, 0x03, 0xb8, 0x3e, 0xc2, 0x44, 0x2c, -0x7a, 0x78, 0x40, 0x1f, 0x6c, 0xd4, 0xcb, 0x03, -0xd8, 0x6a, 0xcd, 0xcf, 0x7a, 0x9e, 0x2a, 0x00, +0x21, 0x1e, 0x51, 0x55, 0xb7, 0xfa, 0x9a, 0x00, +0xf1, 0x1b, 0x71, 0xf4, 0x9f, 0xab, 0x2d, 0xc5, +0x0d, 0x81, 0x81, 0xb3, 0xc2, 0x50, 0xfa, 0x19, +0x97, 0x42, 0xc6, 0xb4, 0xdf, 0x85, 0xee, 0x18, +0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, +0x01, 0x22, 0x21, 0xcc, 0x8b, 0x36, 0xc6, 0xed, +0x08, 0x6c, 0xbf, 0x3a, 0x88, 0x7f, 0x78, 0x9f, +0xea, 0x30, 0x0b, 0xc8, 0xb1, 0x63, 0x95, 0x40, +0xc0, 0x35, 0x3c, 0x88, 0x5a, 0x75, 0x2e, 0xb1, +0xfe, 0xfe, 0x80, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x8d, 0x01, 0x22, 0x21, 0x81, 0xae, 0x2d, +0xdf, 0xbf, 0x6b, 0x9f, 0xa5, 0x0f, 0xdb, 0x65, +0x48, 0xaa, 0xc0, 0xf1, 0x1e, 0x2f, 0x98, 0x8b, +0xbe, 0x5f, 0xaf, 0x92, 0xef, 0x34, 0x62, 0xf4, +0x22, 0xa3, 0x30, 0x59, 0xcb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x32, +0x5a, 0x2a, 0x3b, 0xc3, 0xb7, 0xb9, 0xec, 0xfa, +0x8f, 0x72, 0x5c, 0x82, 0x26, 0xb0, 0xee, 0xb5, +0x86, 0xd8, 0x47, 0x15, 0xc1, 0x11, 0x98, 0x4d, +0xed, 0x6d, 0x27, 0x4d, 0xb7, 0x79, 0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8f, 0x01, 0x22, -0x21, 0x6d, 0x3b, 0x2c, 0xc6, 0x93, 0x25, 0xaf, -0xc2, 0x3a, 0x88, 0x92, 0x80, 0xe9, 0xc4, 0x4d, -0xfe, 0x95, 0xe0, 0xda, 0xd9, 0x0b, 0xf6, 0x48, -0x3e, 0xbb, 0x35, 0x62, 0x1c, 0x3b, 0x48, 0xfb, -0xeb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, -0x01, 0x22, 0x21, 0x77, 0x46, 0xf6, 0x1c, 0xa8, -0x56, 0x7a, 0x3c, 0xa3, 0xde, 0x01, 0xc7, 0x5a, -0x31, 0xcf, 0x81, 0x22, 0x8a, 0xa6, 0x64, 0xe4, -0x2a, 0xf9, 0xa7, 0xe1, 0x0f, 0x93, 0xd5, 0xc9, -0xc6, 0x65, 0x95, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x91, 0x01, 0x22, 0x21, 0xdc, 0xb2, 0x1d, -0xcb, 0x9c, 0xe5, 0xf0, 0x0e, 0xf9, 0x15, 0x99, -0x36, 0x4a, 0x96, 0x37, 0xa5, 0x39, 0x8d, 0x6d, -0x45, 0xea, 0xeb, 0x23, 0x2a, 0x39, 0x32, 0x6f, -0xde, 0x63, 0xf4, 0xd7, 0x07, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0xb5, -0x40, 0x96, 0xdf, 0x73, 0xe5, 0xf3, 0x4e, 0xb9, -0x27, 0xfc, 0x16, 0xb3, 0xe3, 0x83, 0x33, 0x1a, -0xb4, 0xd8, 0x4a, 0x11, 0x97, 0xb6, 0xcc, 0x5e, -0x09, 0xc5, 0x0b, 0xd2, 0x48, 0x8e, 0x75, 0x00, +0x21, 0x37, 0x26, 0xe6, 0x4a, 0xd1, 0xc0, 0x9f, +0x82, 0xae, 0x03, 0x3d, 0x21, 0x0a, 0xf6, 0xdc, +0x4e, 0x4f, 0x3d, 0x27, 0xd9, 0x95, 0x2c, 0xe0, +0x98, 0x14, 0x6b, 0x32, 0x9c, 0xab, 0x40, 0x9d, +0x90, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, +0x01, 0x22, 0x21, 0x6c, 0xb0, 0x53, 0xa2, 0xd3, +0xa6, 0x42, 0x8d, 0x24, 0xf2, 0xe8, 0x66, 0xb2, +0x30, 0x6c, 0xec, 0xc4, 0xf7, 0x55, 0x73, 0x03, +0x32, 0x49, 0x58, 0x53, 0x23, 0x75, 0x04, 0x79, +0x7e, 0xbe, 0x10, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x91, 0x01, 0x22, 0x21, 0xb2, 0x4f, 0xa3, +0x2d, 0x56, 0x74, 0x4b, 0x82, 0xb6, 0x80, 0x1d, +0x59, 0x6a, 0x34, 0xe1, 0xaa, 0x19, 0x17, 0x8d, +0x25, 0x9e, 0xc8, 0xa9, 0x22, 0x97, 0xcf, 0x02, +0x23, 0x80, 0x29, 0x91, 0xa5, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0x15, +0xdf, 0xa2, 0xf2, 0x83, 0xca, 0x90, 0xf3, 0x22, +0xe1, 0xc2, 0x87, 0x91, 0x76, 0xf8, 0xc7, 0x8f, +0x2c, 0xca, 0x3f, 0xad, 0xad, 0x61, 0xd0, 0x2c, +0x8e, 0x87, 0x91, 0xc0, 0x39, 0xea, 0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x93, 0x01, 0x22, -0x21, 0x97, 0xf5, 0x86, 0x79, 0x3f, 0x92, 0xfd, -0xf7, 0xd1, 0xb3, 0x8d, 0x81, 0xe1, 0x6e, 0xdf, -0x43, 0x43, 0x3d, 0x42, 0xf8, 0xdc, 0xdb, 0x43, -0x42, 0xa5, 0x13, 0xc9, 0xa8, 0x37, 0x70, 0x0e, -0x7b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, -0x01, 0x22, 0x21, 0x20, 0x5b, 0x37, 0xe7, 0x94, -0x07, 0x20, 0x0c, 0xe3, 0x17, 0x35, 0x16, 0x08, -0x87, 0x92, 0xa4, 0x72, 0xe0, 0x0b, 0x83, 0x4d, -0x9e, 0x46, 0x65, 0x6c, 0x35, 0xe9, 0xe8, 0xa4, -0xe6, 0xfe, 0x71, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x95, 0x01, 0x22, 0x21, 0xc4, 0x3f, 0x98, -0xbe, 0x41, 0x56, 0x77, 0xa3, 0x0e, 0x83, 0xac, -0xd7, 0x42, 0x7a, 0x84, 0x62, 0x8f, 0x10, 0x08, -0xe0, 0xbc, 0x0e, 0x87, 0x3f, 0x90, 0x5f, 0xdb, -0x1b, 0xee, 0x05, 0x97, 0x05, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0xdd, -0x6e, 0xc8, 0xbe, 0xe6, 0xd1, 0xd2, 0x56, 0x20, -0x5d, 0x48, 0xe9, 0xde, 0xcc, 0xf3, 0x93, 0xf5, -0x23, 0x12, 0xe2, 0xb2, 0x99, 0xa7, 0xbb, 0x72, -0x6d, 0x5a, 0xd2, 0x9d, 0x97, 0x25, 0xc7, 0x00, +0x21, 0x63, 0xaa, 0x9c, 0xe1, 0x17, 0x2e, 0x4b, +0x49, 0xdc, 0x77, 0xca, 0x09, 0x78, 0x93, 0xeb, +0x31, 0x78, 0xe0, 0xe4, 0x70, 0xcb, 0xe1, 0xed, +0xc0, 0xdc, 0xca, 0xa3, 0xb4, 0x1e, 0xac, 0x5e, +0x41, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, +0x01, 0x22, 0x21, 0xa1, 0x15, 0xc7, 0xf1, 0xe4, +0x8e, 0xc1, 0x13, 0xb9, 0x4c, 0x01, 0xc7, 0xe4, +0xe5, 0xfb, 0xeb, 0xce, 0xc9, 0xcf, 0x57, 0x7f, +0xe0, 0x68, 0x1d, 0x5d, 0x89, 0xbc, 0xd9, 0xdd, +0x87, 0x07, 0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x95, 0x01, 0x22, 0x21, 0x51, 0x42, 0x44, +0x5b, 0xae, 0xb5, 0x23, 0x72, 0xd8, 0xa5, 0x8a, +0x67, 0x5c, 0x7f, 0xf5, 0xbb, 0xe8, 0x85, 0x7f, +0xe0, 0xde, 0x42, 0xd8, 0x7b, 0xa3, 0x97, 0x98, +0x16, 0x5c, 0xe9, 0x5a, 0x8a, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0x8b, +0x0e, 0xc2, 0x13, 0x2b, 0x51, 0x80, 0x17, 0x8d, +0xae, 0x06, 0xcb, 0x8b, 0x99, 0xc1, 0x6d, 0x9e, +0x28, 0xee, 0x32, 0x44, 0xaa, 0x7f, 0x86, 0x7a, +0x8d, 0x22, 0x1f, 0x68, 0x14, 0x78, 0x11, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x97, 0x01, 0x22, -0x21, 0x78, 0xb0, 0xc4, 0x58, 0x7d, 0x5f, 0x33, -0x3d, 0xdc, 0xc4, 0xbb, 0xd1, 0x0a, 0xfd, 0xaf, -0xd7, 0x49, 0x20, 0xbc, 0x1e, 0xe0, 0x88, 0xa5, -0x46, 0x36, 0xfc, 0xb3, 0xfc, 0xbe, 0xd6, 0xab, -0x07, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, -0x01, 0x22, 0x21, 0x49, 0x6d, 0xe3, 0xf7, 0x3b, -0x0b, 0x39, 0x5d, 0x5b, 0xa6, 0x51, 0xa8, 0xfb, -0x31, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x5b, 0x8a, 0xf6, 0xaf, -0x43, 0xf6, 0xd4, 0xb5, 0x03, 0x04, 0x51, 0x02, -0x00, 0x99, 0x01, 0x22, 0x21, 0x23, 0xeb, 0xe9, -0x3f, 0x74, 0x7a, 0x15, 0xc9, 0x5d, 0xf8, 0x41, -0xae, 0xfa, 0xde, 0x1c, 0x7e, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x4a, -0x71, 0x3c, 0x5b, 0x9b, 0xdb, 0xd9, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0xb9, -0x23, 0x0e, 0x3d, 0x57, 0x42, 0x7d, 0x0e, 0x37, -0x38, 0xf3, 0xb9, 0x03, 0x6c, 0xc2, 0x76, 0x89, -0x57, 0x8f, 0xfd, 0xd3, 0xf9, 0x0a, 0x9f, 0x4b, -0x44, 0x55, 0x50, 0xd8, 0x73, 0x65, 0x01, 0x00, +0x21, 0xf5, 0xa7, 0xc3, 0x9e, 0x3f, 0x4f, 0x58, +0x98, 0xa4, 0xf5, 0x44, 0x6d, 0xcf, 0x7d, 0x83, +0xa3, 0x04, 0x66, 0xb3, 0x4d, 0x3b, 0xa5, 0x7d, +0xb7, 0x56, 0xb0, 0x83, 0xeb, 0x03, 0x4d, 0x2d, +0xa8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, +0x01, 0x22, 0x21, 0x54, 0x07, 0x4e, 0xf7, 0xb9, +0xcf, 0x41, 0xa3, 0x29, 0x7f, 0xd9, 0x5e, 0xde, +0x28, 0x93, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x17, 0xbc, 0xb4, 0x59, +0xf4, 0x1e, 0x36, 0xf1, 0x03, 0x04, 0x51, 0x02, +0x00, 0x99, 0x01, 0x22, 0x21, 0x24, 0xbb, 0x03, +0xf1, 0x37, 0xd5, 0xac, 0x42, 0xcd, 0xf9, 0x62, +0x8c, 0xd9, 0x95, 0xa3, 0xe2, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0xeb, +0x31, 0x93, 0x72, 0xf8, 0x6b, 0x3b, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0xe0, +0x9b, 0x31, 0x7f, 0x1d, 0x90, 0x65, 0x71, 0x19, +0xe0, 0x66, 0xc9, 0x55, 0x30, 0xfd, 0xe3, 0x28, +0xc5, 0x6d, 0xc9, 0x0d, 0x69, 0x67, 0xc2, 0x8b, +0x76, 0xaf, 0xa5, 0xda, 0x73, 0x77, 0x45, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9b, 0x01, 0x22, -0x21, 0xf3, 0x7b, 0x23, 0x0a, 0x95, 0xfe, 0xb0, -0x5d, 0x9f, 0x1d, 0xe8, 0x98, 0x9b, 0xc3, 0x2e, -0xf2, 0xce, 0x41, 0x0d, 0xf8, 0xa2, 0x48, 0x80, -0x5c, 0x13, 0x0c, 0x77, 0xd3, 0x2a, 0x30, 0x0f, -0x64, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, -0x01, 0x22, 0x21, 0x01, 0x28, 0xe9, 0x5e, 0x45, -0x35, 0x56, 0xc3, 0x66, 0x49, 0x8e, 0x6c, 0x06, -0x4d, 0xe2, 0xfd, 0x0d, 0x8c, 0x4c, 0x93, 0x80, -0x7c, 0xbc, 0x5b, 0x6b, 0x2a, 0xe7, 0xe0, 0x2f, -0x8d, 0x5a, 0xa2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x9d, 0x01, 0x22, 0x21, 0x9c, 0xd3, 0x12, -0x65, 0xf4, 0x9b, 0x6a, 0x4d, 0x98, 0x87, 0x6f, -0xb6, 0x86, 0xee, 0xc5, 0x78, 0x38, 0x31, 0x3f, -0x06, 0x27, 0x26, 0xf0, 0x70, 0xfa, 0xaa, 0xd9, -0xcc, 0x89, 0xad, 0x31, 0xba, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0xdd, -0x92, 0xde, 0xbd, 0xeb, 0xdb, 0x0b, 0x4f, 0x37, -0x5e, 0xb9, 0xb5, 0x91, 0x03, 0x50, 0xe0, 0xc9, -0xeb, 0x29, 0x5b, 0x13, 0x39, 0x7f, 0xe0, 0xd0, -0x0b, 0xab, 0xe8, 0x25, 0xb4, 0xa7, 0x9a, 0x00, +0x21, 0x67, 0xae, 0x09, 0xc6, 0xc3, 0x87, 0xe8, +0x6b, 0xcc, 0x85, 0x76, 0x85, 0xaf, 0x6e, 0x41, +0x7b, 0x6d, 0xbd, 0xe1, 0x19, 0x19, 0xf9, 0x39, +0x07, 0xfd, 0x18, 0x8c, 0x56, 0x6b, 0x52, 0x19, +0x46, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, +0x01, 0x22, 0x21, 0xb9, 0x37, 0xe4, 0xd9, 0xce, +0xfd, 0xa0, 0x83, 0xca, 0x98, 0x0c, 0x6d, 0x96, +0xba, 0x97, 0xf7, 0x6d, 0x39, 0xc0, 0x77, 0xb6, +0x5a, 0x02, 0x91, 0x39, 0x9f, 0xd0, 0xfe, 0xcd, +0x1f, 0xc9, 0xb7, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x9d, 0x01, 0x22, 0x21, 0x2b, 0x99, 0xfe, +0xf1, 0x48, 0x55, 0x49, 0x84, 0x3e, 0xab, 0x6c, +0xdc, 0x1e, 0xcb, 0x14, 0x35, 0xc5, 0x82, 0xb6, +0xf6, 0xa9, 0x44, 0xf3, 0xca, 0x2a, 0xd3, 0x54, +0x50, 0xa4, 0x3e, 0x8a, 0x08, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0x3d, +0xc9, 0x40, 0xb7, 0xd9, 0xcc, 0x9e, 0xa7, 0x68, +0x7b, 0x26, 0x44, 0x07, 0xad, 0x4c, 0x53, 0xf3, +0x1a, 0x17, 0x75, 0x79, 0x5a, 0xe7, 0x25, 0x9a, +0xd8, 0x1a, 0x50, 0x06, 0xe3, 0xf9, 0xef, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9f, 0x01, 0x22, -0x21, 0xaf, 0xf8, 0xc9, 0x77, 0x46, 0x35, 0x19, -0x7d, 0x06, 0xb2, 0xc9, 0x48, 0xd8, 0x7d, 0xf5, -0x3f, 0xe2, 0xbf, 0x62, 0x5b, 0x4f, 0xcf, 0x7f, -0x3d, 0xa8, 0x5e, 0x51, 0xaf, 0x05, 0x0f, 0x85, -0x62, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, -0x01, 0x22, 0x21, 0x87, 0x44, 0x33, 0xcd, 0x16, -0x68, 0xad, 0x4a, 0xfa, 0x3a, 0xca, 0x1e, 0xde, -0x7c, 0x37, 0xf1, 0x08, 0x88, 0x7c, 0x40, 0x56, -0x9a, 0x21, 0xaf, 0x6a, 0x45, 0xef, 0x61, 0xeb, -0x7c, 0xc4, 0x52, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa1, 0x01, 0x22, 0x21, 0x1e, 0x46, 0xb1, -0x38, 0x2c, 0xc3, 0x91, 0x15, 0x4b, 0x2d, 0xc0, -0x92, 0x5b, 0x4c, 0xd5, 0x5e, 0xdc, 0xbd, 0x7a, -0x9e, 0x73, 0x04, 0xd4, 0x63, 0xed, 0xad, 0x29, -0x6e, 0xfa, 0x0e, 0xf7, 0xcc, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xae, -0x40, 0x69, 0x4c, 0x7f, 0x9a, 0x23, 0x47, 0x9f, -0x67, 0xf5, 0x1d, 0x64, 0x33, 0xc8, 0xad, 0x07, -0xf8, 0x0a, 0x22, 0x38, 0x9f, 0xe8, 0x45, 0x37, -0xef, 0x10, 0x3d, 0x06, 0x79, 0x4b, 0x46, 0x00, +0x21, 0x6e, 0x7c, 0x83, 0x64, 0x14, 0x4c, 0x91, +0x36, 0xae, 0x63, 0xc5, 0x83, 0xd6, 0xa4, 0xfc, +0xfd, 0x07, 0x82, 0x0b, 0x13, 0xc7, 0xc1, 0x96, +0x57, 0x42, 0x2e, 0x90, 0x77, 0xe2, 0xf6, 0x97, +0x85, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, +0x01, 0x22, 0x21, 0xa2, 0x4b, 0x55, 0xcb, 0x35, +0x65, 0x7b, 0x6b, 0xd2, 0x1a, 0x91, 0x68, 0x75, +0x3f, 0x71, 0x30, 0x83, 0xbe, 0x28, 0x9e, 0x78, +0x1f, 0xbc, 0x38, 0x59, 0x06, 0x0f, 0x98, 0x64, +0xd2, 0x1d, 0x15, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa1, 0x01, 0x22, 0x21, 0x5a, 0x62, 0x90, +0x4f, 0x2a, 0x2f, 0xfb, 0x55, 0x11, 0xde, 0xae, +0x57, 0x8d, 0x7d, 0x2b, 0x52, 0x17, 0x78, 0x45, +0xc3, 0x59, 0x0f, 0xda, 0x12, 0xdc, 0x8c, 0x1e, +0x12, 0x16, 0x18, 0x2c, 0x87, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0x0f, +0xbb, 0x1a, 0x15, 0xaa, 0xa2, 0xb1, 0x79, 0x9a, +0xac, 0xf0, 0xbf, 0xa0, 0x23, 0xb6, 0xc9, 0x3e, +0x3f, 0x85, 0x7b, 0x77, 0xbb, 0x53, 0xe6, 0xaa, +0x7a, 0x6a, 0x40, 0xc2, 0x9f, 0xf3, 0xff, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa3, 0x01, 0x22, -0x21, 0x96, 0x37, 0x72, 0x9b, 0x69, 0x5b, 0xdb, -0x44, 0xa9, 0x08, 0x38, 0x9f, 0x9e, 0x39, 0xd0, -0x9b, 0xcd, 0xa5, 0xf7, 0x16, 0x40, 0x82, 0x4d, -0xa6, 0xa2, 0xf2, 0xed, 0xb7, 0x0d, 0x0a, 0x08, -0xa0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, -0x01, 0x22, 0x21, 0xbc, 0x1b, 0x53, 0x33, 0xd2, -0xbf, 0x44, 0xf2, 0x3c, 0xd7, 0xaf, 0x89, 0x25, -0xad, 0x62, 0x00, 0x42, 0xe9, 0x25, 0xac, 0x63, -0x21, 0xfa, 0xa1, 0x3f, 0x0a, 0x44, 0x2f, 0x10, -0x48, 0x0f, 0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa5, 0x01, 0x22, 0x21, 0xa7, 0x42, 0x28, -0x6c, 0x0d, 0x76, 0x3d, 0xef, 0x9a, 0xaf, 0xb6, -0xa2, 0x1f, 0xbc, 0x31, 0xbb, 0xb1, 0x27, 0xee, -0x14, 0x09, 0x7b, 0x1f, 0x46, 0xbd, 0xb2, 0x7f, -0x15, 0x32, 0xe6, 0x27, 0x5c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0x94, -0x80, 0xd9, 0xfc, 0x19, 0xb0, 0x39, 0xd6, 0xd7, -0x11, 0xf9, 0x68, 0x9e, 0xec, 0x0a, 0x71, 0x0b, -0x4d, 0x9d, 0xc3, 0x36, 0x06, 0x24, 0xa4, 0x76, -0xd1, 0x20, 0x6e, 0xb1, 0xfa, 0xe0, 0xfa, 0x00, +0x21, 0xd9, 0xf9, 0xeb, 0xc8, 0x6f, 0xec, 0x7c, +0x62, 0x58, 0x42, 0xe4, 0x33, 0x3b, 0x6e, 0xeb, +0xa6, 0xdf, 0x79, 0x83, 0x32, 0xe0, 0xaf, 0x3c, +0xe2, 0x40, 0x6c, 0xc7, 0x13, 0x5a, 0x4d, 0x0e, +0x7c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, +0x01, 0x22, 0x21, 0x6b, 0x29, 0x99, 0xac, 0xeb, +0x63, 0x86, 0x73, 0x34, 0xfc, 0x34, 0xd9, 0x2d, +0x9a, 0xe0, 0x44, 0x53, 0xa4, 0xc1, 0x4e, 0xab, +0x1c, 0x14, 0xe7, 0x48, 0xaa, 0x04, 0x6f, 0x4f, +0xc4, 0x45, 0x73, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa5, 0x01, 0x22, 0x21, 0xd4, 0x32, 0x5f, +0x4e, 0xa5, 0xee, 0x32, 0xa4, 0x83, 0x16, 0xd6, +0x6a, 0x69, 0x9c, 0x1f, 0x26, 0x92, 0x09, 0xa6, +0xe2, 0xe2, 0x00, 0x58, 0xfe, 0x46, 0xb1, 0x0e, +0x89, 0x33, 0x19, 0x01, 0xb4, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0xfb, +0xc5, 0x6a, 0xed, 0x57, 0xbd, 0x77, 0x7d, 0xe2, +0x0e, 0x23, 0x0a, 0x09, 0x88, 0x23, 0x13, 0xb0, +0x12, 0x59, 0x6d, 0x57, 0x21, 0x33, 0x75, 0x99, +0xf0, 0xba, 0xd5, 0xe7, 0x69, 0x51, 0x9b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa7, 0x01, 0x22, -0x21, 0x1b, 0xd8, 0xcc, 0xba, 0xbf, 0xb0, 0x9d, -0x3e, 0x72, 0xd5, 0x91, 0xbb, 0xbd, 0x24, 0x3d, -0x90, 0xc7, 0x6a, 0x42, 0xb0, 0xcb, 0x8c, 0x35, -0xa3, 0x51, 0x7e, 0x9f, 0x12, 0x31, 0xfd, 0x5a, -0xf3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, -0x01, 0x22, 0x21, 0x7b, 0xd6, 0x8e, 0x81, 0xf8, -0xb3, 0x6a, 0xce, 0x29, 0x55, 0x47, 0xd4, 0xfe, -0x6a, 0x1b, 0x87, 0x42, 0x4a, 0x11, 0x48, 0xfb, -0x91, 0x85, 0xbe, 0xfc, 0xd1, 0x99, 0x82, 0x08, -0x74, 0xaa, 0x81, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa9, 0x01, 0x22, 0x21, 0x0e, 0x8c, 0x05, -0x81, 0x8b, 0x8e, 0x85, 0x6f, 0x4c, 0x9f, 0xa6, -0x30, 0x38, 0xde, 0x2a, 0xfe, 0xe4, 0x39, 0xdf, -0x95, 0xdf, 0x22, 0x15, 0xc6, 0x9a, 0xba, 0x92, -0x49, 0xa2, 0xf2, 0xce, 0x76, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x5f, -0x42, 0x80, 0x0e, 0xd9, 0x57, 0x48, 0xcb, 0xf7, -0x5c, 0x14, 0x83, 0x1f, 0x84, 0xe0, 0x7c, 0xd5, -0x65, 0x02, 0xfa, 0x1a, 0xe6, 0x93, 0xca, 0xfd, -0x6e, 0x5e, 0x4f, 0x31, 0xb8, 0x4e, 0x7d, 0x00, +0x21, 0x67, 0xec, 0xfd, 0x86, 0x49, 0x3c, 0x21, +0xfa, 0xd1, 0x3e, 0x4b, 0x46, 0x76, 0x97, 0x65, +0x88, 0x33, 0x2a, 0x10, 0xb5, 0xeb, 0xab, 0xc6, +0xbf, 0xfb, 0x9e, 0x22, 0x2c, 0xe7, 0xef, 0xc5, +0x14, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, +0x01, 0x22, 0x21, 0x8d, 0xc1, 0xa0, 0xb9, 0x30, +0x41, 0x91, 0xba, 0xea, 0x25, 0x91, 0x6b, 0x9b, +0xe6, 0x0f, 0xb3, 0x1b, 0x97, 0x82, 0xf9, 0x89, +0xe4, 0xcf, 0x70, 0x62, 0xa1, 0x9e, 0x5d, 0x9f, +0x07, 0x80, 0x70, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa9, 0x01, 0x22, 0x21, 0x8c, 0x99, 0xad, +0x87, 0x18, 0x1e, 0xd5, 0x2b, 0xf2, 0xde, 0xdd, +0x48, 0xe1, 0xea, 0xea, 0x2d, 0xa5, 0x47, 0x25, +0xc0, 0x2a, 0xe3, 0xc3, 0xb1, 0x5c, 0xfd, 0x96, +0x84, 0x7a, 0x9c, 0x9e, 0xb6, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x57, +0x51, 0xf7, 0x00, 0xf2, 0x01, 0x53, 0x7d, 0x3b, +0xaa, 0x94, 0xba, 0x25, 0x7b, 0x03, 0xeb, 0xa4, +0x72, 0x12, 0x7b, 0x34, 0xe6, 0xec, 0xf2, 0x18, +0xa4, 0x5a, 0x19, 0x27, 0x0c, 0x4a, 0xaf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xab, 0x01, 0x22, -0x21, 0xa9, 0x77, 0xac, 0xc8, 0xf1, 0x58, 0x0b, -0x5c, 0xaa, 0xa3, 0x11, 0xef, 0x96, 0x64, 0x87, -0x85, 0xf6, 0x0f, 0xe6, 0xaa, 0xae, 0x20, 0x00, -0x85, 0xbe, 0x03, 0xcf, 0x4f, 0xcd, 0x17, 0xa2, -0x7a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, -0x01, 0x22, 0x21, 0x37, 0x58, 0x18, 0x47, 0x71, -0xef, 0x33, 0xc2, 0xfb, 0xf7, 0xb0, 0x04, 0xb5, -0x32, 0xe1, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xe1, 0x75, 0xb7, 0xfd, -0xb5, 0x9b, 0x41, 0x7d, 0x03, 0x04, 0x51, 0x02, -0x00, 0xad, 0x01, 0x22, 0x21, 0x92, 0x4c, 0x2c, -0xb1, 0x4a, 0x95, 0x63, 0x12, 0x66, 0x5e, 0xad, -0x6a, 0xa5, 0xf6, 0x12, 0x63, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xf0, -0x57, 0x53, 0x37, 0x89, 0x6f, 0x8a, 0x03, 0x04, -0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0x95, -0x1d, 0xbe, 0x2d, 0x3a, 0x19, 0x40, 0xb0, 0x60, -0x29, 0x4c, 0xbe, 0x88, 0x34, 0x8a, 0x0f, 0x8d, -0xcb, 0x02, 0x52, 0x1a, 0x3f, 0xb7, 0x17, 0xbc, -0x28, 0x1f, 0x17, 0xae, 0x8e, 0x0d, 0xec, 0x00, +0x21, 0x6d, 0x4e, 0x14, 0x98, 0x00, 0x79, 0xe0, +0xc4, 0x1d, 0xfa, 0xf3, 0x19, 0xe6, 0x37, 0xc3, +0x0a, 0x7e, 0x38, 0x96, 0x31, 0x4f, 0x6f, 0xd7, +0x38, 0x50, 0x3d, 0x4c, 0xfa, 0x98, 0xfd, 0x92, +0x11, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, +0x01, 0x22, 0x21, 0x5f, 0x90, 0x22, 0xe9, 0xfb, +0xd9, 0x5f, 0xce, 0x99, 0x0a, 0xc0, 0x61, 0x62, +0x7a, 0x69, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x3e, 0xb5, 0xd0, 0xe5, +0xfe, 0x7d, 0xbd, 0x4c, 0x03, 0x04, 0x51, 0x02, +0x00, 0xad, 0x01, 0x22, 0x21, 0x97, 0x36, 0x25, +0x15, 0x57, 0xf8, 0x02, 0x4f, 0x69, 0x13, 0x3b, +0x6a, 0x12, 0x45, 0x61, 0x42, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x1b, +0x44, 0xc8, 0xfe, 0xfe, 0x69, 0xf3, 0x03, 0x04, +0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0xeb, +0x7a, 0x86, 0x69, 0x20, 0x79, 0x28, 0x4d, 0x91, +0xcb, 0x5a, 0x6f, 0xd8, 0x10, 0xe6, 0xad, 0x2c, +0x2e, 0xb9, 0x82, 0x29, 0xcd, 0x2c, 0xf6, 0xd7, +0x55, 0x80, 0x48, 0xdf, 0xb0, 0x86, 0x97, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xaf, 0x01, 0x22, -0x21, 0xb6, 0xa7, 0x8a, 0xd8, 0x2b, 0x20, 0xf6, -0x6b, 0x4e, 0xab, 0xdf, 0x98, 0xfb, 0x82, 0xac, -0x73, 0x03, 0x8d, 0xc4, 0x86, 0x9b, 0xfd, 0x91, -0x8e, 0xf8, 0x92, 0xd8, 0x1f, 0x1a, 0x98, 0x22, -0x17, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, -0x01, 0x22, 0x21, 0x5b, 0x27, 0x56, 0xa7, 0x6a, -0x99, 0x0c, 0xe1, 0x7b, 0x28, 0x98, 0x06, 0x16, -0xb6, 0xd7, 0xbe, 0xfb, 0xdf, 0x81, 0x17, 0xa2, -0x98, 0x48, 0x70, 0xd6, 0x37, 0x61, 0x99, 0x8a, -0x5b, 0x54, 0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb1, 0x01, 0x22, 0x21, 0x70, 0x92, 0x85, -0x05, 0x7b, 0x27, 0xce, 0x33, 0xb0, 0xb0, 0x75, -0x2e, 0x38, 0x79, 0x60, 0xcc, 0x24, 0x85, 0x1a, -0x1e, 0x29, 0x01, 0x18, 0xba, 0x0e, 0x9a, 0x80, -0x08, 0xb2, 0x4a, 0x07, 0x51, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0x81, -0xdb, 0x22, 0x63, 0x47, 0xc8, 0xa3, 0x07, 0x7c, -0x43, 0x04, 0xe0, 0x9d, 0x93, 0x33, 0xfb, 0x49, -0x2d, 0xa5, 0x74, 0x79, 0x76, 0x33, 0xde, 0xd6, -0xba, 0x00, 0xec, 0x2a, 0xc5, 0x15, 0x5d, 0x00, +0x21, 0x45, 0x66, 0xb9, 0x06, 0x72, 0xe5, 0x8e, +0x2a, 0x99, 0x84, 0xe3, 0x6f, 0x20, 0x1f, 0x03, +0xbe, 0xf9, 0x3e, 0x84, 0xac, 0x10, 0x8e, 0x50, +0xda, 0x55, 0x77, 0x54, 0xb2, 0x2c, 0x41, 0xf8, +0x6a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, +0x01, 0x22, 0x21, 0xcf, 0x26, 0x71, 0xff, 0x65, +0xf7, 0x97, 0x97, 0xde, 0xe3, 0xa6, 0xec, 0xb5, +0xc4, 0xff, 0x14, 0xfb, 0x34, 0xea, 0xf8, 0x99, +0xa1, 0x0b, 0xcb, 0x17, 0xbf, 0x36, 0x81, 0x86, +0xe6, 0xc5, 0xa7, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb1, 0x01, 0x22, 0x21, 0x63, 0xaf, 0x7d, +0x31, 0xd0, 0x1e, 0x96, 0xae, 0xd5, 0x2b, 0x5a, +0xcf, 0xc5, 0x23, 0xb5, 0x8c, 0x50, 0x53, 0x07, +0xf7, 0xef, 0xd5, 0x90, 0xf8, 0x68, 0x2e, 0x97, +0x76, 0x4d, 0xcf, 0xac, 0x7b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0x20, +0x8d, 0x22, 0x87, 0x6b, 0xdb, 0xea, 0xe4, 0x6f, +0xa4, 0x47, 0x0e, 0x39, 0xe5, 0xf4, 0x05, 0x19, +0xd2, 0x0a, 0x77, 0x1b, 0xd5, 0x5b, 0xe6, 0x6d, +0x4d, 0x21, 0xc1, 0x68, 0x35, 0xa9, 0xee, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb3, 0x01, 0x22, -0x21, 0x4e, 0xa0, 0xc8, 0x33, 0xd3, 0x24, 0xae, -0xe4, 0xd6, 0xa3, 0x8c, 0xba, 0xfa, 0x95, 0xef, -0x06, 0x39, 0x1b, 0x45, 0x58, 0x37, 0x0e, 0xc0, -0xf7, 0x0d, 0x4a, 0x2d, 0x9a, 0xd2, 0x84, 0x35, -0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, -0x01, 0x22, 0x21, 0x03, 0x5a, 0xe1, 0x2c, 0xc6, -0xc5, 0xed, 0xa1, 0x46, 0xfe, 0xfc, 0x86, 0xb8, -0x48, 0x62, 0xab, 0x2d, 0x5a, 0x96, 0x0c, 0xa0, -0x4d, 0x3b, 0x27, 0x8e, 0xa8, 0x29, 0x10, 0xdd, -0xf1, 0xe4, 0xed, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb5, 0x01, 0x22, 0x21, 0x7c, 0x49, 0xf4, -0x6c, 0x20, 0x56, 0x6c, 0xb5, 0x0e, 0xde, 0xdb, -0xbd, 0x8e, 0xbd, 0xd5, 0x26, 0x30, 0xf6, 0xc0, -0x27, 0x46, 0x4f, 0x75, 0x57, 0x6a, 0xf8, 0x52, -0xee, 0x00, 0xb4, 0xc4, 0x22, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0x5b, -0xaf, 0x8c, 0x0e, 0x60, 0x4a, 0xdf, 0x5c, 0x98, -0xfc, 0x56, 0x84, 0xb7, 0x1a, 0xe6, 0x31, 0xbd, -0xb4, 0xd1, 0xfb, 0xfe, 0xeb, 0xa4, 0x7e, 0x98, -0x81, 0x88, 0xa9, 0x6a, 0x31, 0x5a, 0xff, 0x00, +0x21, 0x1b, 0x3d, 0x96, 0xa4, 0x8e, 0x6f, 0xee, +0x81, 0x91, 0xcc, 0x39, 0x33, 0x8e, 0x4d, 0x93, +0xbd, 0xda, 0xc3, 0xd2, 0x3d, 0x6d, 0xaa, 0x57, +0xcb, 0x05, 0x89, 0x2f, 0x6a, 0x25, 0xb0, 0xb8, +0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, +0x01, 0x22, 0x21, 0x58, 0x53, 0x5f, 0x0b, 0x42, +0x14, 0xf4, 0x16, 0xed, 0x24, 0x76, 0x84, 0x59, +0x36, 0xf9, 0xfa, 0x33, 0xca, 0x66, 0x71, 0x8d, +0x4c, 0x16, 0x14, 0x32, 0xfc, 0x2a, 0x1d, 0x81, +0xfe, 0x68, 0x72, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb5, 0x01, 0x22, 0x21, 0x9d, 0x40, 0xd0, +0x3e, 0xd1, 0x11, 0x31, 0xa9, 0xfb, 0xbd, 0xfc, +0x9a, 0xea, 0x09, 0xaa, 0x7d, 0xb7, 0x89, 0x57, +0x0c, 0x16, 0x8b, 0x1b, 0x78, 0x9c, 0x0d, 0xdc, +0xaf, 0xd0, 0x1b, 0x59, 0x63, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0xa9, +0x5b, 0x52, 0xd3, 0x89, 0x23, 0xf5, 0x52, 0xfc, +0xea, 0xbf, 0xb8, 0xf4, 0xbd, 0xc2, 0xb1, 0x94, +0xc0, 0xee, 0x95, 0x72, 0x1f, 0x34, 0x84, 0x81, +0xf5, 0xc3, 0x55, 0x29, 0x5d, 0x86, 0x43, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb7, 0x01, 0x22, -0x21, 0x6e, 0xa3, 0x6b, 0xfe, 0x6b, 0x11, 0x63, -0x1f, 0x3b, 0x52, 0xc5, 0xea, 0xf5, 0xff, 0x96, -0xd9, 0xde, 0x6c, 0x88, 0x37, 0x15, 0x9d, 0x81, -0x43, 0x49, 0xf3, 0x97, 0xe6, 0x9b, 0xdd, 0x72, -0xba, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, -0x01, 0x22, 0x21, 0x14, 0xab, 0x0d, 0x75, 0x95, -0xc4, 0x61, 0x77, 0x87, 0x94, 0xb3, 0xeb, 0xdd, -0x73, 0xd4, 0x1b, 0x77, 0x61, 0xad, 0xf0, 0xa4, -0x07, 0xbc, 0xac, 0x4a, 0x8e, 0x45, 0x01, 0x40, -0x8a, 0x90, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb9, 0x01, 0x22, 0x21, 0xa4, 0xfa, 0x92, -0xf4, 0x69, 0x36, 0xd5, 0x21, 0x1c, 0x22, 0x2a, -0x48, 0x11, 0x2e, 0x85, 0xa3, 0xc3, 0x50, 0x12, -0x3c, 0xd4, 0xa3, 0x55, 0x28, 0x6b, 0x41, 0x20, -0x7f, 0x3e, 0xf0, 0xa3, 0x28, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0x96, -0x69, 0x18, 0xd4, 0xc3, 0xfc, 0x85, 0x73, 0x05, -0x62, 0x49, 0xf4, 0x89, 0xe2, 0x6f, 0x85, 0x7f, -0x70, 0x24, 0xbd, 0x84, 0x53, 0x63, 0x42, 0x72, -0xd0, 0x65, 0x0c, 0xeb, 0x0d, 0xc6, 0x25, 0x00, +0x21, 0xbe, 0x42, 0xaa, 0x6b, 0x27, 0xe8, 0xd3, +0x0b, 0x25, 0x6b, 0x49, 0x4a, 0x30, 0x3d, 0x9c, +0x20, 0x88, 0x22, 0x5e, 0xff, 0x75, 0x1c, 0x9d, +0x0d, 0x38, 0xf6, 0x24, 0x1e, 0xe1, 0x0b, 0xa2, +0x41, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, +0x01, 0x22, 0x21, 0x15, 0x20, 0x4c, 0x4b, 0xbb, +0x27, 0x71, 0x05, 0x4c, 0xf9, 0x94, 0x78, 0x37, +0xae, 0x3c, 0xc0, 0x05, 0x69, 0x69, 0x64, 0xe2, +0xe9, 0x86, 0x81, 0xd6, 0x45, 0xf9, 0xef, 0x45, +0x9d, 0x62, 0xac, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb9, 0x01, 0x22, 0x21, 0x70, 0xad, 0xcb, +0x9d, 0x48, 0xb5, 0xba, 0xab, 0x46, 0xfe, 0xac, +0x0e, 0xe2, 0x82, 0x80, 0xdd, 0x9d, 0xac, 0x69, +0xb5, 0x0a, 0x3f, 0x56, 0xf9, 0xd1, 0xcf, 0xad, +0x54, 0x8b, 0x51, 0x16, 0x63, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0xcd, +0x9b, 0xba, 0xb8, 0xc1, 0x25, 0x1f, 0xbd, 0x1a, +0xca, 0xe7, 0xa2, 0xdd, 0x82, 0xaf, 0x00, 0xc0, +0x4c, 0x2e, 0xd4, 0x7b, 0xc3, 0x30, 0x57, 0x26, +0xc6, 0x96, 0x18, 0x41, 0xa5, 0x9c, 0xba, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbb, 0x01, 0x22, -0x21, 0xd9, 0x65, 0xf0, 0x55, 0xdc, 0xd8, 0x9d, -0x25, 0x83, 0x27, 0x37, 0x52, 0x51, 0xe2, 0x01, -0xc8, 0x9f, 0x9f, 0x3f, 0xba, 0x9a, 0xa8, 0x1a, -0xff, 0x02, 0xc0, 0xaa, 0x52, 0xe6, 0xfb, 0x44, -0x70, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, -0x01, 0x22, 0x21, 0x2d, 0x33, 0xd4, 0x52, 0xe1, -0x86, 0xcd, 0xeb, 0x11, 0x9a, 0xe1, 0xf4, 0x6c, -0xc3, 0xb9, 0x90, 0x25, 0x54, 0xad, 0xfb, 0xc2, -0x4b, 0x6c, 0x70, 0x78, 0xa0, 0x4e, 0xfa, 0x2c, -0x6a, 0x46, 0xeb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xbd, 0x01, 0x22, 0x21, 0x2e, 0xc0, 0x62, -0x40, 0x02, 0xef, 0xbb, 0x75, 0x7e, 0xc9, 0x98, -0xd0, 0xa5, 0x43, 0x50, 0x99, 0x23, 0xef, 0x20, -0x8b, 0xca, 0x33, 0x19, 0x45, 0xa5, 0xa0, 0xef, -0xc8, 0x72, 0x0d, 0xd7, 0xd5, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0x0a, -0x45, 0xd1, 0x3e, 0xd4, 0xef, 0x57, 0xc0, 0x63, -0x88, 0x2f, 0x3a, 0x23, 0x57, 0x4f, 0xcf, 0xc0, -0xfb, 0x14, 0x3c, 0x50, 0x32, 0x39, 0x12, 0x70, -0xea, 0xff, 0xe5, 0x2e, 0x92, 0x81, 0x2b, 0x00, +0x21, 0x49, 0x32, 0x68, 0xeb, 0xfc, 0x26, 0x34, +0x74, 0x58, 0x10, 0xf7, 0x72, 0x5c, 0x02, 0x4a, +0xa9, 0x52, 0x58, 0x17, 0x58, 0x2c, 0x90, 0xbf, +0xea, 0x87, 0xda, 0x55, 0x24, 0x15, 0x31, 0x6f, +0x20, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, +0x01, 0x22, 0x21, 0x2a, 0x59, 0x69, 0x08, 0x0d, +0x16, 0xc0, 0xcf, 0x17, 0x20, 0x21, 0x47, 0x0d, +0x60, 0xbe, 0x27, 0x55, 0x3f, 0xe0, 0x00, 0x48, +0x57, 0xe1, 0xc1, 0x13, 0xc1, 0xc9, 0x80, 0x93, +0x16, 0xa7, 0x1f, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xbd, 0x01, 0x22, 0x21, 0x98, 0xda, 0x7b, +0x49, 0xd7, 0x62, 0xfa, 0xff, 0x7b, 0x16, 0x75, +0x97, 0x1a, 0x8b, 0xab, 0xc6, 0xba, 0x89, 0x06, +0x5b, 0xb0, 0xc8, 0x1b, 0xe8, 0x80, 0x31, 0x73, +0x22, 0xa3, 0x97, 0xe4, 0x3b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0x8c, +0xe7, 0x94, 0x41, 0xa9, 0x62, 0xb1, 0xab, 0xd3, +0xa5, 0xad, 0x7b, 0x6b, 0x0a, 0xc4, 0x18, 0xfd, +0xb7, 0x1a, 0x9f, 0x4d, 0x31, 0x99, 0x8a, 0xc1, +0xde, 0x19, 0xb9, 0x92, 0x8b, 0x62, 0x35, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbf, 0x01, 0x22, -0x21, 0xbf, 0x0d, 0x72, 0xf3, 0xa1, 0x55, 0xe8, -0x93, 0xbc, 0x19, 0x23, 0x37, 0x90, 0x63, 0x93, -0x91, 0xfc, 0xd6, 0x91, 0xbf, 0x34, 0xa5, 0x35, -0xae, 0x10, 0x0c, 0xeb, 0x2a, 0x7c, 0x08, 0x61, -0x61, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, -0x01, 0x22, 0x21, 0xa0, 0x3a, 0x08, 0xd6, 0xb1, -0xad, 0x58, 0x13, 0xa4, 0x48, 0x41, 0x17, 0x3d, -0xf1, 0xe2, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x4c, 0xc6, 0x03, 0xfe, -0x0e, 0xe6, 0xa2, 0xac, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc1, 0x01, 0x22, 0x21, 0x35, 0x1f, 0xd0, -0x61, 0x2c, 0xdc, 0x68, 0xf2, 0x66, 0xa7, 0x00, -0xda, 0xa9, 0xc8, 0xe0, 0x0d, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x4c, -0xef, 0x30, 0xe2, 0xc8, 0x50, 0x02, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0xaa, -0x95, 0x68, 0xff, 0x10, 0x8a, 0x69, 0x0d, 0xdd, -0x12, 0xc6, 0x61, 0x01, 0xc6, 0x78, 0x4e, 0x9f, -0xd8, 0x3a, 0x5c, 0x6b, 0xef, 0x4b, 0x03, 0xba, -0x28, 0x71, 0xaa, 0x1c, 0x3a, 0x6f, 0xe8, 0x00, +0x21, 0x7b, 0x51, 0xfb, 0x60, 0x7a, 0xab, 0x63, +0xff, 0x89, 0xd1, 0x74, 0x3b, 0xfb, 0x66, 0x85, +0x81, 0x94, 0x5c, 0xbe, 0x80, 0x72, 0xe0, 0xb4, +0xae, 0x05, 0x48, 0xb8, 0x35, 0x07, 0xe0, 0xe0, +0x45, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, +0x01, 0x22, 0x21, 0x4c, 0xd3, 0xd4, 0xbc, 0xcd, +0x21, 0x22, 0x78, 0x0f, 0x94, 0xa4, 0xa0, 0x03, +0x2a, 0xa7, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xd5, 0x6d, +0x3a, 0xdb, 0x3c, 0xed, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc1, 0x01, 0x22, 0x21, 0xf9, 0x78, 0xc7, +0x92, 0x1f, 0x74, 0x6b, 0x64, 0x0e, 0x41, 0x50, +0xc1, 0x4f, 0xe2, 0xf9, 0xf8, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xf2, +0x09, 0x5f, 0xbc, 0xa4, 0x05, 0xde, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0x73, +0x61, 0xf0, 0xad, 0x6a, 0xfc, 0x7a, 0xfe, 0x3f, +0x9b, 0x63, 0xc2, 0xd7, 0xda, 0xfe, 0x0d, 0xa9, +0x44, 0x22, 0xf7, 0xa7, 0x4d, 0x1d, 0x4e, 0xf4, +0xcb, 0xb7, 0xd9, 0xf1, 0xc9, 0xc9, 0xde, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc3, 0x01, 0x22, -0x21, 0x1e, 0x77, 0xf1, 0x75, 0x74, 0x9e, 0xfb, -0x87, 0x79, 0x8c, 0xd7, 0xc2, 0xa3, 0x78, 0xa5, -0x5b, 0x18, 0x3c, 0x54, 0x6c, 0x3e, 0x58, 0x3d, -0x79, 0x8a, 0x91, 0xc8, 0xc5, 0xd5, 0x14, 0xb0, -0xa7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, -0x01, 0x22, 0x21, 0x1f, 0x8a, 0x2f, 0xa9, 0xf8, -0x3d, 0xd6, 0x0c, 0xa6, 0x1c, 0x65, 0xaf, 0x86, -0x12, 0x5a, 0x5e, 0xc1, 0xda, 0x4a, 0x06, 0xa9, -0x91, 0x57, 0xdc, 0x8f, 0x44, 0x86, 0xa1, 0xa1, -0x37, 0xd0, 0x78, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc5, 0x01, 0x22, 0x21, 0x15, 0x24, 0x18, -0x4b, 0xef, 0xdb, 0x4e, 0x2a, 0x58, 0x31, 0xca, -0x00, 0xbe, 0xb5, 0x83, 0xb2, 0x1a, 0xf9, 0xf0, -0xe7, 0x5e, 0xe0, 0xbd, 0x28, 0x30, 0x3f, 0x3b, -0xd5, 0x8e, 0x9b, 0x37, 0x00, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0xf2, -0x4a, 0x24, 0x0c, 0xd7, 0x48, 0x66, 0xee, 0x9a, -0x21, 0xe0, 0x28, 0x96, 0x7c, 0x7e, 0xc2, 0xc3, -0x88, 0xdf, 0x93, 0xca, 0xb7, 0x0b, 0xed, 0xf6, -0xc8, 0x42, 0x38, 0x18, 0x08, 0x83, 0x7e, 0x00, +0x21, 0x5d, 0x27, 0x31, 0x94, 0x64, 0x23, 0xe5, +0xc0, 0x38, 0xb7, 0x74, 0x02, 0xf1, 0x05, 0x76, +0x51, 0x85, 0xe4, 0x84, 0x7f, 0x16, 0xe4, 0x90, +0x50, 0xbc, 0x7e, 0x0d, 0xdd, 0x89, 0x4f, 0xa7, +0xbc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, +0x01, 0x22, 0x21, 0xcb, 0x79, 0xcc, 0xcf, 0x73, +0x9d, 0x48, 0x8f, 0x92, 0xbf, 0xeb, 0x39, 0x76, +0xea, 0x1d, 0x7d, 0x87, 0xb2, 0xac, 0x0d, 0x2b, +0x55, 0x8f, 0xed, 0x7e, 0x25, 0x1b, 0xf2, 0x88, +0x9e, 0xc2, 0xed, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc5, 0x01, 0x22, 0x21, 0x68, 0x5d, 0x4d, +0x82, 0x61, 0x3b, 0xcb, 0x1b, 0x40, 0x4d, 0xb5, +0xad, 0xf4, 0xad, 0xac, 0x2d, 0x5c, 0x52, 0xab, +0xd5, 0x00, 0x69, 0x35, 0x61, 0x49, 0x8a, 0x5d, +0x8f, 0x43, 0x44, 0x4f, 0x2b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0x6e, +0x02, 0x32, 0xc5, 0xa0, 0x42, 0x71, 0x47, 0xba, +0x66, 0x21, 0x79, 0xf7, 0x1e, 0xb3, 0xcf, 0x3e, +0xad, 0x35, 0x4f, 0x1f, 0x73, 0x48, 0x7d, 0x79, +0x2c, 0x1b, 0x15, 0x67, 0x80, 0x36, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc7, 0x01, 0x22, -0x21, 0x77, 0xb7, 0x5e, 0x5d, 0x40, 0xd2, 0xcf, -0x2e, 0x5c, 0x9a, 0xd8, 0x49, 0xbf, 0x28, 0xb4, -0x02, 0xc2, 0x17, 0xfc, 0xc5, 0xbe, 0x93, 0xe9, -0x02, 0xda, 0x5b, 0x02, 0x54, 0xdd, 0xba, 0xe3, -0x7c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, -0x01, 0x22, 0x21, 0xd0, 0x35, 0xb5, 0x51, 0x64, -0xf4, 0xfb, 0x47, 0xe4, 0xfe, 0xa4, 0x0f, 0x7f, -0x23, 0xba, 0x72, 0x5f, 0x48, 0xec, 0x51, 0x2e, -0x5a, 0xc8, 0xa1, 0x88, 0x21, 0xac, 0xe2, 0xfd, -0x47, 0xa4, 0xc2, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc9, 0x01, 0x22, 0x21, 0x72, 0x0e, 0x80, -0xd6, 0x99, 0x54, 0xcc, 0x50, 0x97, 0xa3, 0xd2, -0x2d, 0xd0, 0x16, 0xb0, 0x5b, 0xf3, 0x01, 0x41, -0x5a, 0x40, 0x43, 0x4a, 0xac, 0xab, 0x82, 0xa4, -0x97, 0xf5, 0x5b, 0x98, 0x99, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0x93, -0xac, 0xbb, 0xac, 0xf9, 0xa8, 0x8b, 0xad, 0x61, -0x56, 0x2b, 0x84, 0x9a, 0xf2, 0x54, 0x1d, 0x72, -0x1e, 0x87, 0xe5, 0x86, 0xeb, 0xfe, 0x61, 0xfd, -0xde, 0x0f, 0x7d, 0xc1, 0xab, 0x9d, 0x23, 0x00, +0x21, 0xc9, 0xae, 0xcc, 0xf4, 0x48, 0xeb, 0xb6, +0xd4, 0x1f, 0x0c, 0x3e, 0x34, 0x72, 0xcf, 0xf0, +0x25, 0xdd, 0x35, 0xc6, 0xb0, 0x09, 0xc4, 0xa9, +0x93, 0x1f, 0xf4, 0xcf, 0xf6, 0x88, 0x5f, 0x6a, +0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, +0x01, 0x22, 0x21, 0x9e, 0x9a, 0xd6, 0x2b, 0xad, +0x46, 0xc7, 0x45, 0xcb, 0x3a, 0x62, 0x56, 0x76, +0xb0, 0xa1, 0xb6, 0xb9, 0x57, 0x08, 0xf0, 0x22, +0xae, 0xb5, 0xd2, 0x8f, 0xc3, 0x66, 0x8e, 0xe9, +0x52, 0x5c, 0x82, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc9, 0x01, 0x22, 0x21, 0xeb, 0x35, 0xa3, +0xd8, 0x2a, 0x95, 0x3b, 0xe1, 0xee, 0xc9, 0xf3, +0x2b, 0xdc, 0xa5, 0x98, 0xed, 0xe0, 0x41, 0x31, +0x8c, 0x65, 0xcb, 0x73, 0x69, 0x27, 0x5f, 0xde, +0xc4, 0x1d, 0x2f, 0x90, 0x74, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0x3e, +0x90, 0x75, 0x3a, 0x9a, 0x9f, 0x1c, 0xc9, 0x08, +0xc3, 0x22, 0xb5, 0xb8, 0xc0, 0x1e, 0x74, 0xfb, +0xee, 0x12, 0xaf, 0xf7, 0xaf, 0x2f, 0xaa, 0x9e, +0x78, 0x7a, 0x51, 0x40, 0x5d, 0xf0, 0xa6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcb, 0x01, 0x22, -0x21, 0x6c, 0x31, 0xce, 0x13, 0x63, 0x36, 0x7a, -0x05, 0x6e, 0x8b, 0xc0, 0x01, 0x24, 0xad, 0x56, -0x60, 0xc6, 0xb0, 0xeb, 0xfe, 0xb9, 0x25, 0xd8, -0x4f, 0xa0, 0x93, 0xcc, 0xac, 0x21, 0x97, 0x3c, -0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, -0x01, 0x22, 0x21, 0xe7, 0xee, 0x28, 0x86, 0xd1, -0x3f, 0x10, 0xdb, 0x4d, 0xf2, 0xc2, 0x04, 0x01, -0x80, 0xfc, 0x06, 0x98, 0xad, 0xba, 0x0d, 0xa7, -0xb0, 0x61, 0x1a, 0x82, 0x29, 0x50, 0x6d, 0x61, -0x0c, 0xb5, 0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xcd, 0x01, 0x22, 0x21, 0x49, 0x2e, 0x43, -0x01, 0x44, 0xda, 0xbe, 0x02, 0xd0, 0x9e, 0x9a, -0x87, 0x44, 0x03, 0x4f, 0x32, 0xa8, 0xe6, 0xda, -0x5c, 0x1a, 0xfd, 0x16, 0x7f, 0x6e, 0x9e, 0xbf, -0x93, 0xe4, 0x37, 0x76, 0x0a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0x8c, -0x36, 0x4d, 0x8f, 0x35, 0x29, 0xc9, 0xe3, 0x22, -0x70, 0xbb, 0x5a, 0x60, 0xc4, 0x40, 0xdb, 0xa5, -0x90, 0x84, 0xdb, 0x0e, 0xb3, 0x96, 0x50, 0x07, -0x8e, 0x90, 0x0c, 0x71, 0x69, 0x01, 0x2f, 0x00, +0x21, 0x70, 0xec, 0xd9, 0x2e, 0xa4, 0xbf, 0x28, +0x12, 0xd3, 0x18, 0x4b, 0x6f, 0x49, 0xf8, 0xad, +0x58, 0x93, 0x2c, 0x29, 0xe4, 0xd1, 0xac, 0x8b, +0x59, 0x9e, 0x1c, 0x20, 0x10, 0x0e, 0xe7, 0x83, +0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, +0x01, 0x22, 0x21, 0x2a, 0xa8, 0xbe, 0x96, 0x47, +0x13, 0x7a, 0x2a, 0x91, 0xbb, 0xb0, 0xa1, 0x91, +0xc5, 0xcb, 0xe2, 0xa4, 0xdc, 0x3f, 0xc6, 0xbb, +0x1b, 0xef, 0x9c, 0xbd, 0x5d, 0x00, 0x20, 0x9d, +0xc2, 0x71, 0x45, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xcd, 0x01, 0x22, 0x21, 0x23, 0x01, 0x15, +0xcd, 0x36, 0x34, 0xcc, 0x7b, 0x71, 0x04, 0xe8, +0xd1, 0xc2, 0x1e, 0xb2, 0x5b, 0x94, 0x0e, 0x0e, +0x28, 0x35, 0xcf, 0xbd, 0x59, 0x80, 0x0f, 0xbd, +0x1e, 0xc6, 0x83, 0xb7, 0x8f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0xa4, +0xc3, 0xda, 0x16, 0x7e, 0xbb, 0xc6, 0x43, 0xd1, +0xcd, 0x1c, 0x69, 0x8d, 0xcb, 0xc5, 0x07, 0x45, +0x85, 0x89, 0xe9, 0x24, 0x67, 0x63, 0x9d, 0x54, +0x07, 0xa9, 0xee, 0xc0, 0x7f, 0x14, 0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcf, 0x01, 0x22, -0x21, 0x0d, 0x30, 0xa0, 0xcd, 0x2f, 0x4e, 0x77, -0x8b, 0x57, 0xe3, 0xcb, 0x22, 0x6b, 0xee, 0x05, -0x56, 0xe8, 0x1a, 0x9a, 0x7e, 0x6f, 0xce, 0xc9, -0x3c, 0xbb, 0x3b, 0xf9, 0x12, 0x6d, 0x40, 0xba, -0xea, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, -0x01, 0x22, 0x21, 0x42, 0xc3, 0xbd, 0xd2, 0xeb, -0x64, 0x7b, 0xf4, 0x02, 0xd8, 0x35, 0x99, 0xba, -0xe8, 0x93, 0x02, 0x2a, 0xef, 0x33, 0x1b, 0xe3, -0x4c, 0x1b, 0xbe, 0xae, 0x5c, 0xa1, 0xee, 0xf3, -0x66, 0x3b, 0x4d, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd1, 0x01, 0x22, 0x21, 0xdd, 0x70, 0xd5, -0x8b, 0xd5, 0xe6, 0x1f, 0x15, 0xfd, 0x67, 0x9a, -0x4c, 0x6b, 0xb3, 0xaa, 0x54, 0xee, 0x49, 0x4c, -0x43, 0xca, 0x3f, 0xb4, 0x4b, 0xe7, 0xf9, 0xad, -0x7a, 0xc6, 0x15, 0xb6, 0xfa, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x2f, -0x91, 0x63, 0x2d, 0x73, 0x5e, 0xbe, 0xed, 0x67, -0x25, 0xb6, 0xfc, 0xb8, 0xbb, 0x6f, 0x54, 0xf6, -0x41, 0x01, 0x3a, 0xcf, 0x8d, 0x08, 0x4c, 0x46, -0x63, 0xd6, 0x2c, 0xb5, 0xd1, 0x18, 0xc1, 0x00, +0x21, 0xc8, 0x51, 0x9b, 0x6b, 0xff, 0x3e, 0x68, +0x39, 0x8d, 0x72, 0xfa, 0x67, 0x15, 0x7f, 0x80, +0x6b, 0x3a, 0xaa, 0x5e, 0xee, 0xa3, 0xc1, 0x7a, +0xa9, 0x2b, 0x27, 0xac, 0x42, 0xc5, 0xb8, 0xa9, +0x50, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, +0x01, 0x22, 0x21, 0x14, 0xa1, 0x50, 0x6b, 0xd3, +0x93, 0x11, 0x5e, 0xa2, 0x11, 0x56, 0x42, 0x95, +0xd8, 0x54, 0x76, 0xe9, 0x99, 0x29, 0x4f, 0x19, +0x60, 0xf6, 0x5b, 0x1f, 0xf1, 0x9c, 0x41, 0x22, +0xe3, 0x1a, 0x75, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd1, 0x01, 0x22, 0x21, 0xd4, 0xde, 0x05, +0x90, 0xc2, 0x4a, 0x2c, 0x88, 0xdb, 0x67, 0x00, +0xcd, 0x52, 0x97, 0x36, 0x54, 0xcd, 0x00, 0xa8, +0x4d, 0x3c, 0xdb, 0x80, 0x52, 0xa9, 0xa5, 0xcf, +0xce, 0x93, 0x7c, 0x65, 0x67, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x03, +0x43, 0x90, 0xdc, 0xe7, 0x8e, 0x68, 0xe7, 0x39, +0xd8, 0x02, 0x05, 0x6b, 0x6a, 0xc3, 0xc7, 0x46, +0xe0, 0x05, 0xaa, 0x16, 0x59, 0x09, 0x0a, 0xe7, +0x6f, 0xb2, 0x59, 0x37, 0x5e, 0x71, 0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd3, 0x01, 0x22, -0x21, 0x27, 0x4b, 0xc2, 0x87, 0x90, 0x4d, 0x1a, -0xa7, 0xae, 0xd0, 0xd7, 0x25, 0x1e, 0x78, 0x09, -0x43, 0xed, 0xb9, 0xb8, 0x81, 0x57, 0x57, 0xb6, -0x84, 0x17, 0x1f, 0x23, 0x18, 0x63, 0xba, 0xa3, -0x71, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, -0x01, 0x22, 0x21, 0x7f, 0x83, 0x28, 0xd4, 0xac, -0xb8, 0x6e, 0xb1, 0x7a, 0x91, 0xd3, 0xaf, 0x14, -0xf4, 0x6c, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xb3, 0xdb, 0x21, 0x2b, -0x5a, 0xe1, 0x6d, 0xfc, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd5, 0x01, 0x22, 0x21, 0x20, 0x04, 0xb1, -0x34, 0x5b, 0xcf, 0xd4, 0x9f, 0x66, 0x7a, 0x8d, -0x05, 0xda, 0x0f, 0xc5, 0x85, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x49, -0xf8, 0x26, 0x90, 0x58, 0xc3, 0x6f, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0xd6, -0x1a, 0xbb, 0x1d, 0x36, 0x45, 0x91, 0x32, 0x93, -0x6b, 0x13, 0x71, 0xdd, 0x5e, 0xb0, 0x1d, 0x8e, -0x78, 0x17, 0x63, 0x81, 0xbf, 0xa7, 0x4a, 0x52, -0x46, 0x33, 0x44, 0x2c, 0x5b, 0xf1, 0x78, 0x00, +0x21, 0xa2, 0xd5, 0x06, 0xb9, 0x32, 0x29, 0xd8, +0x82, 0x72, 0x7a, 0x68, 0x2f, 0xd9, 0x07, 0x6e, +0xb9, 0x35, 0xc5, 0xf1, 0xc2, 0x42, 0x42, 0x7b, +0xb1, 0x3f, 0x77, 0xcf, 0xbf, 0xba, 0xdf, 0x82, +0x9b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, +0x01, 0x22, 0x21, 0x60, 0xfc, 0x91, 0xe5, 0x82, +0x25, 0x33, 0x0e, 0x10, 0x49, 0x1e, 0x10, 0x33, +0x83, 0x5a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xc4, 0xad, 0x71, 0x59, +0xea, 0x38, 0x1c, 0xfa, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd5, 0x01, 0x22, 0x21, 0x9f, 0xd2, 0x85, +0x04, 0xa4, 0xd5, 0x7e, 0xda, 0x2c, 0x5a, 0x21, +0x54, 0x5e, 0x37, 0x59, 0xee, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x05, +0x53, 0xb7, 0xca, 0x2c, 0xf0, 0x3f, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0xa4, +0x24, 0xcf, 0x75, 0x0b, 0x42, 0xcb, 0xab, 0x18, +0x70, 0xa3, 0xc1, 0x47, 0xae, 0x4d, 0x5d, 0x51, +0xff, 0x57, 0xb2, 0x56, 0xaa, 0xfc, 0x08, 0x65, +0x68, 0x9f, 0x6b, 0xd0, 0xd9, 0xb9, 0x06, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd7, 0x01, 0x22, -0x21, 0x7a, 0xf5, 0xd9, 0xd2, 0x68, 0x30, 0x05, -0x2b, 0x24, 0xcc, 0x91, 0x1f, 0xb7, 0xbb, 0x1f, -0x5b, 0x37, 0xc6, 0x7e, 0x2a, 0x8c, 0xac, 0x5a, -0x02, 0x5f, 0xba, 0x98, 0xa9, 0x8b, 0x7c, 0x82, -0x26, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, -0x01, 0x22, 0x21, 0xba, 0x24, 0x5f, 0xfc, 0xee, -0x23, 0x65, 0x81, 0x01, 0x89, 0x1f, 0xfd, 0xdb, -0xed, 0x7a, 0x23, 0x94, 0x0c, 0x80, 0xb6, 0xe0, -0x20, 0x0f, 0xc5, 0x1e, 0x80, 0xb0, 0x64, 0x46, -0x03, 0x36, 0x24, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd9, 0x01, 0x22, 0x21, 0xdf, 0x08, 0x8c, -0xa6, 0xfb, 0x5e, 0x25, 0xad, 0x7e, 0xe0, 0x09, -0x4e, 0x5c, 0xcc, 0xe0, 0x4b, 0x19, 0xfd, 0xba, -0x7a, 0x65, 0x21, 0x6a, 0x49, 0x50, 0xf3, 0xcf, -0xa6, 0x80, 0xf7, 0x55, 0xdd, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0xea, -0x8d, 0xf3, 0x54, 0xeb, 0x22, 0x73, 0xc7, 0x92, -0xc4, 0xe8, 0x47, 0x8a, 0xd1, 0xab, 0x9d, 0xa6, -0x43, 0xc3, 0xfc, 0x33, 0x75, 0xaa, 0xfa, 0x20, -0x5d, 0xce, 0x68, 0x3c, 0x7b, 0x10, 0x14, 0x00, +0x21, 0x56, 0x7d, 0xe0, 0x84, 0xc8, 0xed, 0xfc, +0xe1, 0xfc, 0x4e, 0xac, 0xb6, 0x22, 0x1b, 0x4e, +0x7d, 0x15, 0xc3, 0x77, 0x75, 0xdc, 0x9d, 0x0f, +0xa8, 0x68, 0x7d, 0xee, 0xda, 0xde, 0x49, 0xf7, +0x46, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, +0x01, 0x22, 0x21, 0xd1, 0xbb, 0x40, 0xb2, 0xbb, +0xfd, 0xcd, 0x02, 0x79, 0x44, 0xed, 0x00, 0xc5, +0x5c, 0xed, 0x3b, 0x27, 0xd7, 0x12, 0x58, 0xe5, +0x2c, 0x20, 0x73, 0x01, 0xd8, 0x6d, 0xa1, 0x42, +0x6d, 0x08, 0x63, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd9, 0x01, 0x22, 0x21, 0x40, 0x4a, 0x7a, +0xbb, 0x43, 0xfb, 0x55, 0x87, 0xe6, 0x70, 0x2a, +0x6c, 0x8f, 0x21, 0xe7, 0x96, 0x26, 0xb1, 0xfe, +0xdc, 0x40, 0x91, 0xb5, 0xc7, 0xbf, 0x03, 0x00, +0x1d, 0x00, 0x59, 0x85, 0x79, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0xed, +0xb3, 0x9a, 0x87, 0x8a, 0xb0, 0xff, 0x98, 0x9c, +0x72, 0x6e, 0x36, 0xe8, 0x58, 0x60, 0x18, 0x75, +0x97, 0x8d, 0xae, 0x2c, 0x1b, 0x58, 0xf6, 0x24, +0xc4, 0x43, 0x0a, 0x21, 0xd7, 0x6b, 0xfd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdb, 0x01, 0x22, -0x21, 0x73, 0x5e, 0xbc, 0x80, 0x57, 0x67, 0xf7, -0x2a, 0x31, 0xaf, 0xe1, 0xd9, 0x60, 0xb3, 0xc5, -0x9c, 0xf0, 0xb3, 0x95, 0x02, 0xaf, 0xab, 0xa6, -0xae, 0x2d, 0xe1, 0xe8, 0x57, 0xbe, 0xa0, 0x01, -0x5f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, -0x01, 0x22, 0x21, 0xcb, 0x1c, 0xf4, 0x60, 0x05, -0x4c, 0x97, 0x31, 0x02, 0x07, 0x70, 0x09, 0x83, -0x0b, 0xc9, 0x9a, 0xe8, 0x1a, 0xb2, 0x23, 0x29, -0x16, 0x46, 0x80, 0xdb, 0x76, 0xfb, 0x44, 0x40, -0x19, 0xc1, 0xff, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xdd, 0x01, 0x22, 0x21, 0x85, 0xf8, 0x25, -0x87, 0xc1, 0x42, 0x28, 0x96, 0xa6, 0xbc, 0xb4, -0x34, 0x01, 0x79, 0xe6, 0xcb, 0x83, 0xab, 0xa2, -0xdf, 0xb9, 0x78, 0xee, 0x4d, 0xb1, 0xbc, 0x54, -0x65, 0x5f, 0xff, 0xf6, 0xd5, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0x33, -0xee, 0x02, 0xab, 0xac, 0xe9, 0x76, 0x4d, 0x6f, -0xf4, 0xef, 0xcc, 0xf3, 0xbc, 0x2b, 0x5d, 0xf2, -0xd5, 0xba, 0x44, 0xe7, 0xe7, 0x11, 0xc8, 0xad, -0x46, 0xb9, 0x6d, 0x52, 0xc3, 0xe2, 0x86, 0x00, +0x21, 0x42, 0x63, 0xf8, 0x4e, 0x17, 0xba, 0x4a, +0x6e, 0x12, 0x68, 0x61, 0xd0, 0x31, 0x46, 0x25, +0x6f, 0x58, 0x7b, 0x90, 0x43, 0xb0, 0xc3, 0x1a, +0x1b, 0xeb, 0x02, 0xc5, 0xec, 0xfd, 0x2c, 0xba, +0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, +0x01, 0x22, 0x21, 0x37, 0x38, 0xad, 0xc0, 0xc0, +0x8e, 0x87, 0xad, 0x39, 0xf0, 0x4e, 0x95, 0xd3, +0x79, 0xea, 0xf4, 0x7e, 0xb2, 0x78, 0xb8, 0xdc, +0x87, 0x95, 0x82, 0xf8, 0x3e, 0xca, 0x22, 0x97, +0x60, 0x07, 0xb2, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xdd, 0x01, 0x22, 0x21, 0x13, 0x9c, 0xf0, +0x43, 0x41, 0xc7, 0x9e, 0x4c, 0x7c, 0xf2, 0x08, +0xe9, 0xe4, 0x29, 0xa1, 0x7f, 0xd7, 0x8d, 0x52, +0x13, 0x34, 0x4c, 0x22, 0x8a, 0xc2, 0x05, 0x98, +0x3d, 0xdc, 0x86, 0x0f, 0x3e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0x7d, +0x9e, 0x1e, 0xf0, 0xc7, 0x3e, 0x4f, 0x66, 0x5a, +0x3d, 0xc6, 0x62, 0xb6, 0xb3, 0x37, 0x2e, 0x61, +0xdf, 0xc6, 0xa8, 0xf0, 0x48, 0x08, 0x02, 0x53, +0x9a, 0xd0, 0xc3, 0xc3, 0x37, 0x0d, 0x82, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdf, 0x01, 0x22, -0x21, 0xac, 0xe9, 0x84, 0x77, 0xe9, 0x0d, 0x1d, -0xe2, 0xbf, 0xb7, 0xcb, 0x4e, 0xd0, 0x8e, 0xa6, -0xab, 0x77, 0xc1, 0xc8, 0x05, 0x77, 0x86, 0x8f, -0x09, 0x77, 0xbc, 0x15, 0x64, 0x17, 0xfb, 0xb6, -0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, -0x01, 0x22, 0x21, 0x3b, 0xa6, 0x19, 0xb7, 0xdb, -0xf8, 0xd5, 0x23, 0xbb, 0xf9, 0xed, 0x27, 0x39, -0xab, 0x0b, 0x04, 0xd6, 0xb0, 0x10, 0x3e, 0xe7, -0x86, 0xf1, 0x84, 0x79, 0x8a, 0xb2, 0xb5, 0x79, -0xea, 0x49, 0xdb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe1, 0x01, 0x22, 0x21, 0x2d, 0x77, 0x0f, -0xf0, 0x6b, 0x09, 0xbf, 0x57, 0x0d, 0x42, 0x1a, -0x0e, 0xd9, 0x2e, 0x18, 0x32, 0xa5, 0x24, 0x2e, -0xab, 0xaa, 0xc7, 0x75, 0x08, 0x4b, 0x53, 0x68, -0x68, 0xd8, 0xe7, 0x7c, 0x30, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0xb5, -0xf9, 0xff, 0x70, 0xfc, 0x96, 0x2c, 0xbe, 0x87, -0xef, 0x28, 0x1f, 0xd3, 0x1b, 0x4d, 0x02, 0x5a, -0x1e, 0x2f, 0x82, 0x49, 0xbe, 0x59, 0xf4, 0x74, -0xd9, 0x02, 0x96, 0xae, 0xb5, 0xf2, 0x09, 0x00, +0x21, 0x18, 0xa8, 0x55, 0xce, 0xdc, 0x2e, 0xb6, +0xcb, 0x5b, 0x7c, 0x7c, 0x02, 0xa9, 0x89, 0xb1, +0x68, 0x1a, 0x4b, 0x60, 0xe0, 0xc6, 0xbd, 0xf6, +0x89, 0xd1, 0x94, 0x90, 0x9f, 0x59, 0x0b, 0x67, +0x65, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, +0x01, 0x22, 0x21, 0xf6, 0x20, 0x20, 0x10, 0xce, +0x2b, 0x7c, 0xd8, 0x55, 0x23, 0xde, 0xb8, 0x59, +0x49, 0xc1, 0x01, 0xbb, 0x4b, 0x89, 0xc3, 0xb6, +0xa6, 0x85, 0xf5, 0xa5, 0x65, 0x98, 0xc2, 0xc2, +0x11, 0xe9, 0xef, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe1, 0x01, 0x22, 0x21, 0xdf, 0xf8, 0xe0, +0x78, 0xd0, 0x72, 0xf5, 0x28, 0xe5, 0x11, 0xe5, +0x14, 0x93, 0xe4, 0xe9, 0x1f, 0x4e, 0xf3, 0x88, +0x04, 0x15, 0x8b, 0x36, 0xcd, 0x75, 0xe0, 0x9b, +0xbe, 0xdc, 0xdb, 0x3d, 0x8a, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0xa2, +0x1a, 0x22, 0xff, 0x69, 0x19, 0xb8, 0xcb, 0xea, +0x82, 0x96, 0x92, 0xae, 0x35, 0xb4, 0xfd, 0xf9, +0x5e, 0x3e, 0x91, 0x3d, 0x32, 0xbc, 0x11, 0x40, +0x11, 0x6a, 0x8f, 0x1d, 0xdf, 0xf3, 0x01, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe3, 0x01, 0x22, -0x21, 0x84, 0x4f, 0x3d, 0x01, 0x8d, 0x98, 0xf7, -0x5e, 0x45, 0x7f, 0x80, 0xa6, 0x61, 0x8a, 0x98, -0xbe, 0xdd, 0xbd, 0x0f, 0x26, 0xa7, 0x7a, 0x90, -0x35, 0x89, 0x8a, 0x7c, 0xe5, 0x14, 0xab, 0xe4, -0x76, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, -0x01, 0x22, 0x21, 0x90, 0xc4, 0xa4, 0x3d, 0xb5, -0x0c, 0xc2, 0xb7, 0xa2, 0x78, 0x43, 0xf9, 0x4f, -0x00, 0xc2, 0xf9, 0xef, 0x9a, 0xa4, 0x37, 0x82, -0x57, 0x99, 0x4d, 0xb9, 0x17, 0xb5, 0xe8, 0x15, -0xeb, 0x1a, 0xb5, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe5, 0x01, 0x22, 0x21, 0x8a, 0xee, 0x01, -0xa4, 0xe8, 0xbc, 0x2d, 0x84, 0xb1, 0x09, 0x43, -0xce, 0x3d, 0xae, 0x7b, 0x15, 0x92, 0x7f, 0xd6, -0x31, 0xd6, 0xbd, 0x1d, 0xcd, 0x06, 0x4b, 0x67, -0x64, 0xa4, 0x89, 0xf6, 0x4c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0xdd, -0xca, 0x8e, 0xa8, 0xbe, 0xca, 0x58, 0xa8, 0xf6, -0x5c, 0x5c, 0xab, 0xb3, 0x87, 0xda, 0x57, 0xb4, -0x84, 0x20, 0xd2, 0x8d, 0x1c, 0x73, 0x46, 0xf5, -0x4d, 0xbe, 0x8a, 0x2c, 0x92, 0x5f, 0x0d, 0x00, +0x21, 0xe9, 0x22, 0x60, 0xe9, 0x32, 0x06, 0x9c, +0x05, 0x4b, 0xd9, 0xec, 0x8e, 0x97, 0x21, 0xdb, +0x70, 0xb5, 0x44, 0x9e, 0xc4, 0xd1, 0x46, 0xc9, +0x96, 0x32, 0x14, 0x9c, 0x24, 0x30, 0x33, 0xd2, +0x1d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, +0x01, 0x22, 0x21, 0xb0, 0x9f, 0x94, 0x3e, 0x22, +0xcc, 0x23, 0xd5, 0x6a, 0xba, 0xca, 0x5b, 0xa7, +0xf9, 0x39, 0x77, 0xb8, 0x69, 0x79, 0xc7, 0x60, +0xf3, 0xa7, 0x3e, 0xe1, 0xc4, 0x16, 0xbd, 0xfe, +0x40, 0x8d, 0x68, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe5, 0x01, 0x22, 0x21, 0x8e, 0xac, 0x8a, +0x86, 0xf5, 0x8b, 0xb6, 0x2c, 0x6c, 0xf6, 0x04, +0xf2, 0xa3, 0x44, 0x46, 0x75, 0x8f, 0xcb, 0x08, +0x65, 0x2b, 0xd6, 0x01, 0xbe, 0x59, 0x20, 0x3f, +0x57, 0xa1, 0xe5, 0xf9, 0xe9, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x3c, +0x45, 0xcb, 0xf7, 0xfb, 0x65, 0x37, 0x90, 0x61, +0x38, 0xd4, 0x3c, 0x82, 0x39, 0xcc, 0x80, 0xb3, +0x1b, 0x35, 0x74, 0xa1, 0xb3, 0x46, 0x1a, 0xb6, +0x4c, 0xc5, 0x2f, 0x17, 0xbc, 0x69, 0xd9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe7, 0x01, 0x22, -0x21, 0x93, 0xc9, 0x90, 0x24, 0x21, 0xfd, 0x5f, -0x93, 0x69, 0x3c, 0xdb, 0x5a, 0xf5, 0x90, 0x55, -0x1b, 0x60, 0x3c, 0x43, 0xb5, 0x02, 0x93, 0x1e, -0x2d, 0x09, 0x58, 0xd9, 0xd6, 0x22, 0x5b, 0x07, -0xfb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, -0x01, 0x22, 0x21, 0x2c, 0x36, 0x22, 0x8e, 0x7b, -0xd6, 0x12, 0x20, 0x89, 0x3a, 0xb3, 0x2d, 0x68, -0x44, 0xb7, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x42, 0x91, 0x84, 0x73, -0x41, 0x4c, 0xf7, 0xa5, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe9, 0x01, 0x22, 0x21, 0xb3, 0xef, 0x47, -0x67, 0x5f, 0xc8, 0x85, 0xf4, 0xd3, 0x69, 0xd6, -0xa2, 0x4d, 0x34, 0x6d, 0x1e, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x8d, -0x50, 0xb4, 0x91, 0xbb, 0xf2, 0x0b, 0x03, 0x04, -0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0xe6, -0x7e, 0x2b, 0x1d, 0x94, 0xcb, 0x69, 0x48, 0x21, -0x7a, 0x13, 0x99, 0x21, 0x79, 0xc9, 0x59, 0x17, -0xd4, 0x20, 0xbc, 0xca, 0x11, 0x43, 0xb0, 0x73, -0xff, 0xe0, 0x64, 0xfc, 0xd6, 0xfe, 0x05, 0x00, +0x21, 0x9d, 0x8e, 0x6a, 0xcb, 0x95, 0x58, 0xb9, +0x4a, 0x33, 0x37, 0x34, 0x41, 0xc6, 0x5d, 0x24, +0x8e, 0x6f, 0xbd, 0x94, 0xf8, 0x0a, 0x40, 0x36, +0xcf, 0x47, 0x72, 0xc9, 0x0b, 0x7e, 0x1b, 0xf5, +0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, +0x01, 0x22, 0x21, 0x73, 0x77, 0x49, 0x60, 0x4f, +0x31, 0x71, 0x37, 0x64, 0x04, 0xb0, 0x66, 0x29, +0x3e, 0x5d, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x22, 0xbb, 0xc5, 0x8a, +0x99, 0xf1, 0x0d, 0x2c, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe9, 0x01, 0x22, 0x21, 0xe8, 0xf2, 0xca, +0xaf, 0x48, 0xda, 0xec, 0xf0, 0x78, 0xfb, 0xd6, +0xa0, 0x2b, 0xc7, 0xc9, 0xf7, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0xfd, +0x09, 0xce, 0xac, 0x4e, 0xd3, 0x25, 0x03, 0x04, +0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0xe2, +0xfc, 0x5c, 0xa3, 0x6e, 0x0d, 0x3f, 0xe2, 0x2f, +0x0c, 0x33, 0x0d, 0x34, 0xca, 0x29, 0x50, 0x65, +0xf4, 0x8e, 0x32, 0xd4, 0x5d, 0xd1, 0x26, 0x3f, +0xd5, 0x32, 0xc8, 0xbf, 0xcd, 0x08, 0x31, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xeb, 0x01, 0x22, -0x21, 0x20, 0xdd, 0x53, 0x8d, 0xba, 0x2a, 0xb9, -0xcd, 0x02, 0x42, 0x9f, 0x99, 0x90, 0x7f, 0x0b, -0x3b, 0x29, 0xcc, 0x83, 0x51, 0xaa, 0xdf, 0x26, -0x72, 0x3c, 0x10, 0xc2, 0xd7, 0xbf, 0xbe, 0xd0, -0x5a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, -0x01, 0x22, 0x21, 0xaf, 0xe1, 0x25, 0x6f, 0x71, -0xdd, 0x59, 0x2d, 0x69, 0xdd, 0x3b, 0x47, 0x8d, -0xe0, 0x6b, 0x11, 0x59, 0xa5, 0x37, 0x37, 0xd5, -0xcc, 0xf2, 0xe8, 0x6a, 0x21, 0xe1, 0x1d, 0x91, -0x03, 0xa7, 0x3e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xed, 0x01, 0x22, 0x21, 0x56, 0xe1, 0x25, -0xb4, 0x7f, 0x46, 0x92, 0x10, 0xad, 0x1c, 0x9d, -0x8b, 0x97, 0xf0, 0xb4, 0xe9, 0x69, 0x90, 0x2b, -0x5c, 0xcf, 0x9b, 0x34, 0x23, 0xbf, 0xc3, 0x25, -0x41, 0xeb, 0x93, 0x0d, 0x0f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0xab, -0x40, 0x47, 0xe5, 0x5e, 0x79, 0x27, 0x63, 0xc2, -0x97, 0xc9, 0x36, 0xa0, 0x60, 0xc4, 0x27, 0x86, -0x13, 0x36, 0x11, 0xe3, 0x15, 0xc9, 0x57, 0x04, -0x6d, 0x8c, 0xc7, 0x40, 0xee, 0xf4, 0x4d, 0x00, +0x21, 0x87, 0x37, 0xd3, 0x66, 0x2f, 0x9a, 0x53, +0xb1, 0x87, 0xe7, 0x11, 0x5e, 0xc8, 0x75, 0x0c, +0x60, 0xb1, 0x79, 0x45, 0xb3, 0x42, 0x85, 0x5a, +0x65, 0xfe, 0xe2, 0xd8, 0x77, 0xab, 0x41, 0x41, +0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, +0x01, 0x22, 0x21, 0x15, 0x93, 0x1b, 0xdf, 0xe5, +0xf0, 0xaa, 0xb4, 0x87, 0x50, 0xba, 0x74, 0xfb, +0xbe, 0xc4, 0x31, 0x54, 0xb7, 0x30, 0xd1, 0x77, +0x2f, 0xa2, 0x22, 0xc8, 0x2b, 0x46, 0x63, 0xb3, +0x4a, 0x21, 0x53, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xed, 0x01, 0x22, 0x21, 0x6b, 0x30, 0x70, +0x46, 0xbd, 0xf9, 0x5e, 0xe0, 0x8e, 0xca, 0xc0, +0x3e, 0x8b, 0x4f, 0x9c, 0xfd, 0x22, 0xd7, 0x23, +0x96, 0x68, 0x4c, 0x39, 0xe4, 0xf7, 0x12, 0x0d, +0xa4, 0xa6, 0x96, 0x26, 0x52, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0x3c, +0x7a, 0xfc, 0x20, 0xf7, 0x16, 0xe7, 0x56, 0x8e, +0xf9, 0xdc, 0xd8, 0x50, 0x2c, 0xda, 0x49, 0x82, +0x65, 0xab, 0x12, 0x70, 0x2d, 0xd6, 0x3f, 0x95, +0xc2, 0x05, 0x76, 0x95, 0xd2, 0xcd, 0xff, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xef, 0x01, 0x22, -0x21, 0x9e, 0xf0, 0x73, 0x49, 0x8b, 0xe4, 0xaf, -0xc1, 0x8f, 0xf1, 0x99, 0x42, 0x4e, 0xfb, 0x59, -0x89, 0x84, 0x0e, 0x02, 0x7f, 0x4b, 0xc9, 0xf9, -0xdd, 0xba, 0x78, 0x8f, 0x94, 0xf6, 0x45, 0xfc, -0xa7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, -0x01, 0x22, 0x21, 0xd6, 0xe4, 0x44, 0x17, 0x63, -0xdb, 0xd5, 0x18, 0x21, 0x13, 0x45, 0x51, 0xab, -0x8c, 0xcd, 0x9f, 0x69, 0x52, 0xe6, 0xca, 0x1d, -0x23, 0xfa, 0xcd, 0x67, 0x79, 0x66, 0x04, 0x27, -0xba, 0x03, 0x73, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf1, 0x01, 0x22, 0x21, 0xc3, 0xa2, 0x8b, -0xfd, 0x69, 0xa3, 0xa6, 0x8d, 0x74, 0x69, 0x8e, -0x27, 0xb9, 0xb8, 0xe7, 0xed, 0xc5, 0xc9, 0x2d, -0x4c, 0x7e, 0xeb, 0x12, 0x50, 0x1c, 0x6d, 0x4c, -0x15, 0x74, 0xd6, 0x1b, 0x06, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0xd3, -0x57, 0x1f, 0x6e, 0x55, 0x21, 0x45, 0x50, 0x63, -0xeb, 0x5a, 0xc7, 0xbb, 0xa9, 0xde, 0xfe, 0x9f, -0x81, 0x17, 0x5b, 0x11, 0x2a, 0x13, 0xf9, 0xfe, -0x24, 0x7e, 0x9d, 0xd5, 0xd8, 0x0f, 0xdc, 0x00, +0x21, 0x2f, 0xaf, 0x2a, 0x8e, 0x54, 0x2e, 0x28, +0xf5, 0x78, 0x58, 0xa5, 0xf7, 0x15, 0x0c, 0xfd, +0x9c, 0x23, 0x17, 0xd2, 0xce, 0x1c, 0x05, 0xbd, +0x5e, 0xd4, 0x31, 0xea, 0xd0, 0xc4, 0xd3, 0x9d, +0xd4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf0, +0x01, 0x22, 0x21, 0x8a, 0x43, 0x1a, 0x27, 0xc2, +0x9c, 0xd7, 0x57, 0xc0, 0xca, 0x7d, 0xae, 0xe9, +0xce, 0x3f, 0x01, 0x1a, 0xb2, 0xd3, 0x7f, 0x6e, +0xde, 0x8c, 0x9c, 0x21, 0x76, 0x90, 0x75, 0xbb, +0x51, 0x2c, 0xc0, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf1, 0x01, 0x22, 0x21, 0x6b, 0x67, 0xfd, +0x04, 0xa4, 0x1b, 0xc1, 0x43, 0x32, 0xab, 0x51, +0x35, 0x91, 0x81, 0x82, 0xc4, 0x35, 0x2c, 0xcb, +0xa2, 0x96, 0xdf, 0x61, 0x3a, 0x7e, 0x01, 0xcc, +0xec, 0xa1, 0xec, 0xa7, 0xc0, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf2, 0x01, 0x22, 0x21, 0x3d, +0x61, 0xc4, 0x86, 0x3c, 0x3e, 0x8f, 0x3a, 0x36, +0xea, 0x09, 0xf3, 0x02, 0x03, 0x30, 0x28, 0xfa, +0xdd, 0x71, 0x45, 0x36, 0x4d, 0x5f, 0x67, 0xbb, +0x85, 0x8e, 0xa1, 0xf2, 0x81, 0xd9, 0x1d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf3, 0x01, 0x22, -0x21, 0xf3, 0x38, 0x7f, 0x0e, 0xf1, 0x79, 0x46, -0xdb, 0xe7, 0x6a, 0xdc, 0xad, 0x89, 0x99, 0xa8, -0x53, 0xfc, 0x78, 0xca, 0xec, 0x7c, 0x13, 0x49, -0x12, 0x28, 0xf0, 0x14, 0x19, 0xef, 0x7b, 0x81, -0x68, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, -0x01, 0x22, 0x21, 0x4c, 0xc4, 0x0c, 0x07, 0x7e, -0xae, 0x6c, 0x59, 0xc0, 0x71, 0xc2, 0x24, 0x0e, -0xa8, 0x60, 0xf7, 0x9e, 0x74, 0x19, 0xae, 0x26, -0x69, 0xc9, 0x2a, 0x68, 0x68, 0x6c, 0x3c, 0x9e, -0x71, 0x0d, 0x47, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf5, 0x01, 0x22, 0x21, 0xfb, 0xbd, 0x86, -0x84, 0x0a, 0xac, 0x12, 0xa4, 0x4e, 0x27, 0x22, -0x02, 0x38, 0x84, 0xe9, 0xb9, 0xb0, 0x97, 0x01, -0xb4, 0x75, 0xd8, 0xe2, 0x04, 0xaf, 0x1f, 0xb0, -0x86, 0x31, 0x91, 0x4c, 0x67, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0xc3, -0x50, 0x91, 0xe1, 0x38, 0xbe, 0xb1, 0x27, 0xa2, -0x0b, 0x83, 0xb2, 0x92, 0x46, 0x36, 0x34, 0x76, -0x6d, 0xd6, 0x62, 0xce, 0xe6, 0x79, 0x5b, 0x5a, -0x95, 0xfc, 0xd0, 0xa0, 0xcb, 0xad, 0x17, 0x00, +0x21, 0x0c, 0x21, 0xc2, 0xd7, 0xfe, 0xb3, 0x33, +0xd8, 0x66, 0x87, 0x8d, 0x27, 0x98, 0xf4, 0x04, +0x7c, 0x74, 0x5a, 0x66, 0xb0, 0x1e, 0x3b, 0xe4, +0x4a, 0x5d, 0x64, 0x29, 0x33, 0xb4, 0x79, 0x29, +0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf4, +0x01, 0x22, 0x21, 0x33, 0xf2, 0xd5, 0xd6, 0x76, +0x4d, 0x94, 0x23, 0x3f, 0x80, 0x60, 0x8e, 0xe8, +0x85, 0xc1, 0x33, 0x29, 0xfc, 0x35, 0x8b, 0xb8, +0xa5, 0x7a, 0xec, 0xa7, 0xf7, 0x91, 0x19, 0x27, +0xdc, 0xa0, 0xaf, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf5, 0x01, 0x22, 0x21, 0x9c, 0xd8, 0xb6, +0xda, 0xe6, 0xb4, 0x87, 0xb7, 0x24, 0xfa, 0xb1, +0x96, 0x78, 0xa5, 0xa2, 0xd4, 0x0b, 0xfd, 0xc1, +0x54, 0x73, 0x16, 0xfd, 0x35, 0xb5, 0x95, 0xe9, +0xeb, 0x7f, 0xe2, 0xd5, 0x90, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xf6, 0x01, 0x22, 0x21, 0x04, +0x49, 0x76, 0xb2, 0x17, 0x37, 0x27, 0x48, 0xb7, +0x44, 0xae, 0xc0, 0xdf, 0xd2, 0x49, 0x53, 0xf3, +0xc9, 0x4b, 0x48, 0x11, 0x09, 0x66, 0xc1, 0xb5, +0x71, 0x24, 0xf1, 0x12, 0x49, 0x27, 0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf7, 0x01, 0x22, -0x21, 0x66, 0xa5, 0xa0, 0x0c, 0xc9, 0x69, 0xc7, -0xf8, 0x0a, 0xd0, 0x5c, 0x7c, 0xa6, 0x7f, 0x99, -0x2d, 0x82, 0x91, 0xe2, 0xac, 0xc6, 0x7d, 0x8b, -0x42, 0x2f, 0x0d, 0x2a, 0xc0, 0xca, 0xb3, 0x03, -0x1d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, -0x01, 0x22, 0x21, 0x05, 0xda, 0x63, 0x97, 0xe7, -0xaf, 0x92, 0x40, 0x8a, 0x75, 0x91, 0x37, 0xb0, -0x44, 0x09, 0xdf, 0x4d, 0x30, 0x15, 0xbd, 0x26, -0x60, 0x82, 0x08, 0xc7, 0x06, 0xcc, 0xe9, 0xea, -0xa1, 0x8f, 0x32, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xf9, 0x01, 0x22, 0x21, 0xd1, 0xcb, 0xc7, -0x1a, 0x6e, 0xf2, 0xcd, 0x22, 0xad, 0xa1, 0xe8, -0x15, 0xe8, 0x58, 0x19, 0xb0, 0x25, 0xe6, 0x10, -0x50, 0x96, 0xd6, 0x69, 0xb4, 0x98, 0x72, 0x96, -0x77, 0xf8, 0x0e, 0x38, 0xe3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0xd8, -0x19, 0xb9, 0xa5, 0xe6, 0x4a, 0x00, 0xc0, 0xe5, -0x7d, 0x66, 0xbc, 0x24, 0x65, 0x5e, 0xf0, 0x69, -0x6d, 0x10, 0x66, 0x58, 0xf0, 0x95, 0x51, 0x37, -0x37, 0x34, 0x56, 0x8b, 0xd6, 0x1e, 0xce, 0x00, +0x21, 0x8a, 0x6d, 0xd3, 0x22, 0x44, 0x5e, 0xae, +0x02, 0x07, 0x9b, 0x77, 0x27, 0x0f, 0xa7, 0x1e, +0xb1, 0x4a, 0x46, 0x2f, 0xa7, 0xa4, 0x39, 0x1f, +0xdc, 0x21, 0x47, 0x8d, 0x2f, 0x22, 0x7b, 0x61, +0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xf8, +0x01, 0x22, 0x21, 0xda, 0xf1, 0xb1, 0x50, 0x32, +0xce, 0x4e, 0xcb, 0xfb, 0xa2, 0x40, 0x27, 0xbe, +0xc2, 0xe1, 0xdc, 0x57, 0xe7, 0x8c, 0x0f, 0x62, +0x2b, 0xaa, 0x31, 0xae, 0x36, 0xc0, 0x8e, 0xed, +0x03, 0xc3, 0x86, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xf9, 0x01, 0x22, 0x21, 0xb0, 0xd9, 0x68, +0xc6, 0x4c, 0x1a, 0xf3, 0xb6, 0x79, 0x9c, 0xe7, +0x2b, 0xef, 0x00, 0xe8, 0x71, 0x7c, 0x58, 0x31, +0x73, 0xed, 0xe3, 0xfa, 0xcf, 0x17, 0x86, 0x1f, +0x1b, 0x20, 0xc7, 0x01, 0x9b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfa, 0x01, 0x22, 0x21, 0x12, +0x78, 0x73, 0xf7, 0x85, 0xf2, 0x98, 0x5f, 0xf9, +0x44, 0xf5, 0x62, 0x39, 0x85, 0x31, 0xa9, 0x4a, +0x3c, 0x6a, 0x39, 0x6c, 0xf0, 0x03, 0x61, 0xe4, +0xee, 0x13, 0x81, 0x28, 0xcf, 0x27, 0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfb, 0x01, 0x22, -0x21, 0x57, 0x04, 0x8e, 0xad, 0x43, 0x7e, 0xed, -0xda, 0x78, 0x83, 0xd7, 0x59, 0xef, 0xa9, 0xa4, -0xc5, 0xbc, 0x2b, 0x79, 0xa4, 0x85, 0xcf, 0x59, -0xff, 0xf1, 0x00, 0xfb, 0x39, 0x3a, 0x09, 0x15, -0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, -0x01, 0x22, 0x21, 0xa0, 0x98, 0xca, 0xcf, 0x0b, -0x32, 0x5b, 0xfe, 0x40, 0x07, 0x88, 0xa1, 0x2e, -0xcd, 0x89, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x0b, 0x62, 0xca, 0xa0, -0x67, 0x77, 0xd0, 0xce, 0x03, 0x04, 0x51, 0x02, -0x00, 0xfd, 0x01, 0x22, 0x21, 0x48, 0x97, 0x6f, -0xc9, 0x3f, 0x8d, 0x70, 0x15, 0x83, 0xcc, 0x35, -0x73, 0x7c, 0x73, 0xb4, 0x7c, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xe6, -0x44, 0xb2, 0x1c, 0xa6, 0xda, 0xa3, 0x03, 0x04, -0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0x3f, -0x73, 0x7f, 0xab, 0x09, 0x97, 0xde, 0x1b, 0x1e, -0x87, 0x53, 0x49, 0xc8, 0x9c, 0xf7, 0x35, 0x11, -0xce, 0x81, 0x7c, 0x47, 0x5c, 0x5a, 0x60, 0x6f, -0xb7, 0x34, 0x97, 0x6a, 0xfa, 0x20, 0x68, 0x00, +0x21, 0x9c, 0xa6, 0x64, 0xeb, 0x4b, 0xe7, 0x0b, +0x25, 0x15, 0xd6, 0x55, 0x7d, 0xb3, 0x3f, 0x75, +0x4e, 0xaa, 0x5e, 0x23, 0x68, 0x1f, 0x1a, 0x01, +0x4a, 0xa2, 0x51, 0xaa, 0xf4, 0x03, 0xc9, 0x5a, +0x59, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xfc, +0x01, 0x22, 0x21, 0x3c, 0xb6, 0xa5, 0x1b, 0x23, +0x02, 0x22, 0x9e, 0x22, 0xf1, 0x5b, 0xca, 0xf8, +0x64, 0x75, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x51, 0xcb, 0xa6, 0x2a, +0xac, 0x9c, 0x42, 0x3d, 0x03, 0x04, 0x51, 0x02, +0x00, 0xfd, 0x01, 0x22, 0x21, 0x78, 0xea, 0xc3, +0xf2, 0xb1, 0x2d, 0x27, 0x9f, 0x5d, 0xc8, 0x1a, +0x54, 0x59, 0x69, 0x64, 0xaa, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0d, +0x62, 0x97, 0x1a, 0x27, 0x49, 0x1d, 0x03, 0x04, +0x51, 0x02, 0x00, 0xfe, 0x01, 0x22, 0x21, 0x0a, +0x4b, 0xb1, 0x40, 0xe8, 0xad, 0x47, 0x69, 0xf7, +0x37, 0xb8, 0xc3, 0x89, 0x3d, 0x72, 0x76, 0x62, +0xd7, 0xc9, 0x25, 0xd2, 0xf2, 0x91, 0xd8, 0xef, +0x25, 0x05, 0x42, 0x3d, 0xe3, 0xcb, 0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xff, 0x01, 0x22, -0x21, 0x26, 0x6c, 0x25, 0x35, 0x4f, 0x9f, 0x63, -0xce, 0x89, 0x3c, 0x56, 0x8e, 0x76, 0x17, 0xba, -0x89, 0x84, 0x08, 0x4a, 0xe2, 0xfd, 0x98, 0xd1, -0xbc, 0x07, 0xe2, 0x65, 0xb2, 0x1e, 0xed, 0x34, -0xac, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, -0x01, 0x22, 0x21, 0xfa, 0x30, 0xec, 0x1f, 0x9a, -0xf0, 0x2b, 0xc1, 0xd3, 0x91, 0xb4, 0x6c, 0x3f, -0x42, 0x43, 0xcf, 0xd3, 0x73, 0x87, 0xdf, 0x2d, -0xa5, 0x7d, 0x0e, 0x27, 0x88, 0x54, 0x8c, 0xaa, -0x1b, 0x51, 0xef, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x01, 0x01, 0x22, 0x21, 0x48, 0x90, 0xfd, -0x52, 0x09, 0xae, 0x39, 0x27, 0x29, 0xaf, 0x6e, -0x59, 0x47, 0x1e, 0xb7, 0x1f, 0x10, 0xd1, 0x03, -0x23, 0x76, 0xcf, 0xf4, 0xac, 0x5b, 0xa0, 0xc3, -0xd3, 0x26, 0xee, 0x7e, 0xc9, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0x38, -0xc5, 0x5b, 0xa3, 0x76, 0x8b, 0x88, 0x2f, 0x18, -0x80, 0x63, 0xf4, 0x51, 0xed, 0x98, 0x70, 0x4a, -0xe3, 0xf1, 0x6f, 0xb0, 0x55, 0xdb, 0x68, 0xe8, -0x5b, 0x1d, 0xf0, 0x2f, 0x9a, 0xdb, 0x0c, 0x00, +0x21, 0x75, 0xd3, 0xb7, 0x47, 0x59, 0x65, 0x26, +0x47, 0x55, 0x91, 0xc5, 0xd7, 0xb8, 0xc4, 0x59, +0x84, 0xe0, 0x59, 0x74, 0x24, 0x58, 0x9c, 0xfb, +0x5a, 0x7d, 0x42, 0xa3, 0x58, 0x56, 0xc4, 0xb1, +0xfd, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x00, +0x01, 0x22, 0x21, 0xa8, 0xcf, 0x57, 0xa2, 0x7f, +0x3a, 0xd1, 0xc7, 0xc8, 0xf6, 0x31, 0x5b, 0xfa, +0x58, 0x52, 0x46, 0xdc, 0x29, 0xb7, 0xec, 0x37, +0xcb, 0xbf, 0x35, 0xc0, 0xff, 0x12, 0xae, 0x1e, +0xb1, 0x54, 0x64, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x01, 0x01, 0x22, 0x21, 0xcf, 0xac, 0x70, +0xa6, 0xaf, 0x18, 0x92, 0x83, 0x59, 0x5d, 0xd9, +0xae, 0x31, 0x58, 0x25, 0xe2, 0x54, 0x21, 0x68, +0x6b, 0xad, 0xd7, 0x02, 0x26, 0x8d, 0x77, 0x86, +0xee, 0xd8, 0xb0, 0xf2, 0xf1, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x02, 0x01, 0x22, 0x21, 0xdc, +0xf4, 0xda, 0xa9, 0xa5, 0x5b, 0xe1, 0x7d, 0x31, +0x86, 0x8a, 0x4e, 0x05, 0x88, 0x8d, 0x28, 0x9a, +0xad, 0xde, 0x6e, 0x1e, 0x11, 0xd4, 0x1f, 0x05, +0x63, 0x73, 0x0d, 0x73, 0x93, 0xcb, 0x05, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x03, 0x01, 0x22, -0x21, 0xe3, 0x48, 0x89, 0x98, 0x08, 0xf7, 0x07, -0xa3, 0xee, 0x76, 0x0f, 0xf3, 0x1c, 0x99, 0xbf, -0x2b, 0x04, 0xe9, 0xd4, 0xc2, 0x9b, 0xe7, 0xcd, -0x06, 0x08, 0xe5, 0x7e, 0xba, 0x9a, 0xc0, 0x53, -0x86, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, -0x01, 0x22, 0x21, 0x31, 0x11, 0x80, 0x04, 0x5e, -0x86, 0xd3, 0x39, 0x8e, 0xa5, 0x9c, 0xbc, 0x8a, -0xf3, 0x43, 0x14, 0xce, 0x51, 0x07, 0xc1, 0x66, -0xe7, 0x13, 0x9e, 0xcf, 0x5d, 0x80, 0x7c, 0x57, -0x85, 0x1e, 0x6f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x05, 0x01, 0x22, 0x21, 0x20, 0x2a, 0x39, -0x10, 0x4d, 0xee, 0x7e, 0x8a, 0x97, 0xf3, 0x27, -0x60, 0x6c, 0x03, 0x93, 0xa0, 0x3b, 0x66, 0x94, -0x24, 0x41, 0xde, 0x50, 0x93, 0x6e, 0x3b, 0x09, -0xd0, 0x90, 0xe4, 0xfa, 0x55, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0xb7, -0x85, 0xd5, 0x24, 0x03, 0x0b, 0xb7, 0xef, 0xeb, -0xae, 0xee, 0x49, 0xbb, 0x89, 0x06, 0x90, 0x91, -0xf7, 0x50, 0x7c, 0x34, 0xe2, 0x3a, 0xf2, 0x67, -0x49, 0xb8, 0xdf, 0x76, 0x8c, 0xa0, 0xaa, 0x00, +0x21, 0x4b, 0x21, 0xf1, 0x5f, 0xfd, 0x03, 0xb4, +0xab, 0xcf, 0xa1, 0xb4, 0x3c, 0x2f, 0xbe, 0xd9, +0xf1, 0x95, 0x0e, 0x7d, 0x2a, 0xe5, 0xdd, 0xfc, +0x16, 0xc1, 0xbf, 0xc7, 0x96, 0x09, 0x2a, 0x97, +0x18, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x04, +0x01, 0x22, 0x21, 0xb3, 0x7d, 0xe4, 0xbd, 0x91, +0xa9, 0x9e, 0xbb, 0xa6, 0x6e, 0xfd, 0xd3, 0x26, +0x9a, 0x27, 0xcc, 0xfd, 0xa3, 0xdf, 0x3f, 0x76, +0x0d, 0x48, 0x47, 0x29, 0x88, 0x54, 0x3f, 0xf0, +0x4e, 0x0d, 0x66, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x05, 0x01, 0x22, 0x21, 0xd3, 0x41, 0x17, +0x4e, 0x8b, 0xc4, 0x1e, 0xee, 0x09, 0xaa, 0x77, +0x79, 0x61, 0xa3, 0x44, 0x50, 0x52, 0x68, 0x12, +0x14, 0x24, 0x33, 0xd5, 0x28, 0x5c, 0x86, 0x77, +0x43, 0x46, 0xdc, 0x51, 0xf8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x06, 0x01, 0x22, 0x21, 0x8d, +0x1b, 0xf0, 0xae, 0xd4, 0xf7, 0x07, 0xc2, 0x5b, +0x39, 0x57, 0x6b, 0x73, 0x44, 0x90, 0xba, 0x30, +0xe6, 0x71, 0x7f, 0xd0, 0x2f, 0x53, 0x62, 0xc6, +0x3b, 0x9f, 0xe3, 0x1f, 0x71, 0xf4, 0xb1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x07, 0x01, 0x22, -0x21, 0xa4, 0x52, 0xeb, 0xed, 0xd6, 0x15, 0x26, -0xc0, 0xe5, 0xd3, 0x07, 0x98, 0xe7, 0x01, 0xde, -0x4f, 0x1d, 0x3f, 0x82, 0x27, 0xb6, 0xd9, 0xa4, -0xfd, 0xa6, 0x07, 0x82, 0x3a, 0x3b, 0x36, 0x2d, -0x0f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, -0x01, 0x22, 0x21, 0x3b, 0xe2, 0x7d, 0x67, 0x04, -0xd3, 0x7b, 0xf6, 0xbf, 0xec, 0x6c, 0xbe, 0x5d, -0x4b, 0x72, 0x64, 0xc3, 0x56, 0x9c, 0xd9, 0x36, -0xba, 0x4d, 0xbf, 0xa9, 0x4b, 0x20, 0x31, 0xf6, -0x4e, 0xbd, 0x39, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x09, 0x01, 0x22, 0x21, 0xd3, 0xc8, 0xc8, -0x49, 0x0c, 0x48, 0x49, 0x60, 0x84, 0xfe, 0x40, -0x13, 0x67, 0xdc, 0xff, 0xd2, 0x1f, 0x29, 0xaa, -0xc6, 0x7b, 0x45, 0x0c, 0xa4, 0x3c, 0x45, 0x57, -0xe2, 0x14, 0xe6, 0x4f, 0xc2, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0xb9, -0xa4, 0xf8, 0x91, 0x55, 0xa0, 0x4a, 0x58, 0x4f, -0x12, 0x90, 0x53, 0xb8, 0x07, 0x32, 0xc8, 0x0c, -0x50, 0x36, 0xd7, 0x8d, 0x71, 0xa0, 0x12, 0x02, -0x24, 0xee, 0xd1, 0x3a, 0x13, 0x5c, 0xc4, 0x00, +0x21, 0x4d, 0xfe, 0xda, 0xf6, 0xd2, 0x71, 0x74, +0x7d, 0xe6, 0x52, 0x5e, 0x1a, 0x76, 0x58, 0x4c, +0xf9, 0xbc, 0x54, 0x59, 0x11, 0x76, 0x43, 0x27, +0xe9, 0xf2, 0xbf, 0x32, 0xb3, 0xe0, 0x61, 0xa4, +0xe0, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x08, +0x01, 0x22, 0x21, 0x8c, 0x75, 0xda, 0x83, 0x1f, +0x6b, 0xb8, 0x5e, 0x9b, 0x28, 0x65, 0x99, 0x7d, +0xac, 0x75, 0xdf, 0x79, 0x3d, 0x5b, 0x48, 0x39, +0xe4, 0x66, 0xeb, 0xcf, 0xf3, 0x70, 0x85, 0xae, +0xd9, 0x61, 0x24, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x09, 0x01, 0x22, 0x21, 0x12, 0x6a, 0x7d, +0x0a, 0xcf, 0x51, 0x50, 0x39, 0x1a, 0x7a, 0xc0, +0xb9, 0x8c, 0x61, 0x52, 0x41, 0x01, 0x9b, 0x31, +0x29, 0x6b, 0xa6, 0x05, 0x8b, 0x95, 0x58, 0x91, +0x06, 0xdb, 0x00, 0x34, 0xa1, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0a, 0x01, 0x22, 0x21, 0x17, +0x8b, 0xe9, 0xb3, 0x49, 0xe0, 0x88, 0xb0, 0x89, +0x91, 0x7d, 0xb3, 0xc2, 0x0d, 0x43, 0x43, 0x59, +0xcd, 0xda, 0xfe, 0xe9, 0x53, 0x2a, 0x32, 0xba, +0xb2, 0x7d, 0xcf, 0x53, 0x2e, 0xf1, 0x4d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0b, 0x01, 0x22, -0x21, 0xe0, 0x1d, 0x2f, 0xc0, 0xb2, 0x1c, 0x6b, -0xb4, 0x2e, 0xd8, 0x21, 0xe0, 0x61, 0x55, 0xf4, -0x73, 0xba, 0x82, 0x12, 0x9a, 0x0d, 0xca, 0xe6, -0x2e, 0xf6, 0xf5, 0x5f, 0xe9, 0x8a, 0xa1, 0x2d, -0xef, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, -0x01, 0x22, 0x21, 0xf7, 0x0a, 0x28, 0x90, 0xaf, -0xa8, 0x5d, 0xbe, 0xfb, 0x85, 0xb2, 0x36, 0xd8, -0xc5, 0xd0, 0x44, 0x3c, 0x1c, 0xb0, 0x47, 0x45, -0x4e, 0xc1, 0xc9, 0xf6, 0x6e, 0x23, 0xa1, 0xcc, -0x5f, 0x93, 0xaf, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x0d, 0x01, 0x22, 0x21, 0x7e, 0x7c, 0x47, -0x69, 0x97, 0xe6, 0x52, 0x89, 0xfc, 0xfb, 0xd6, -0x54, 0x70, 0x51, 0x5c, 0xbe, 0xbf, 0xe0, 0x84, -0x17, 0x60, 0x3d, 0x40, 0xab, 0x95, 0x03, 0xca, -0x1b, 0x15, 0x86, 0x16, 0xa5, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0x56, -0x83, 0x56, 0x3f, 0x41, 0xb8, 0x75, 0x95, 0x18, -0x2f, 0x31, 0x93, 0x50, 0x0a, 0x35, 0x51, 0x94, -0x7a, 0xc9, 0xec, 0xc6, 0x04, 0xeb, 0x38, 0xca, -0x71, 0xb7, 0x97, 0xb0, 0x46, 0xbb, 0x99, 0x00, +0x21, 0xb9, 0x13, 0x06, 0x6b, 0x66, 0x64, 0x62, +0x7e, 0x55, 0x7e, 0xbd, 0x43, 0xff, 0x17, 0xa8, +0x4e, 0x2a, 0x15, 0x81, 0xd1, 0x07, 0x33, 0xa7, +0x8a, 0xc2, 0x5b, 0xd3, 0xed, 0x4d, 0x08, 0x1a, +0xce, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0c, +0x01, 0x22, 0x21, 0x73, 0x83, 0xda, 0x43, 0x21, +0xa3, 0xa9, 0xac, 0x0c, 0x04, 0x46, 0x7f, 0x01, +0x19, 0xa9, 0x8c, 0x7a, 0xa7, 0x69, 0xa2, 0xc4, +0xc1, 0x99, 0xb9, 0x96, 0x13, 0xe6, 0x74, 0xba, +0xdb, 0xa0, 0x51, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x0d, 0x01, 0x22, 0x21, 0x19, 0xd7, 0xf6, +0x9a, 0x5b, 0x9b, 0x09, 0x94, 0xf0, 0xa9, 0xc9, +0x95, 0x69, 0xa4, 0xd5, 0xdf, 0x5d, 0xa8, 0x49, +0xb2, 0x3c, 0x14, 0x8d, 0x62, 0xe7, 0x74, 0x5c, +0x4b, 0x1e, 0x59, 0xaa, 0x57, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x0e, 0x01, 0x22, 0x21, 0xf1, +0x05, 0x55, 0x2e, 0xbb, 0x22, 0xfd, 0x30, 0xc9, +0x87, 0x3b, 0xae, 0x95, 0x85, 0x3e, 0x4e, 0xbf, +0x03, 0x67, 0x2d, 0x71, 0x26, 0x04, 0x29, 0x4f, +0x47, 0x21, 0x35, 0xb3, 0x04, 0xa9, 0x3f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x0f, 0x01, 0x22, -0x21, 0x92, 0x74, 0x42, 0xb7, 0x6b, 0xcf, 0x4f, -0x0e, 0x43, 0x82, 0xd5, 0xef, 0x71, 0x9a, 0xb3, -0x35, 0x3a, 0x81, 0x62, 0xa5, 0x79, 0xb0, 0x66, -0xee, 0xc8, 0xcd, 0x33, 0x96, 0xac, 0xe5, 0xcf, -0xf7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, -0x01, 0x22, 0x21, 0xf2, 0x0f, 0x36, 0xa3, 0x99, -0x76, 0x43, 0x95, 0x52, 0xa2, 0x05, 0x46, 0x45, -0x5b, 0xb9, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x5d, 0xb1, 0x11, 0x7b, -0xbf, 0xe9, 0x16, 0x74, 0x03, 0x04, 0x51, 0x02, -0x00, 0x11, 0x01, 0x22, 0x21, 0x1c, 0x38, 0x6b, -0x52, 0x5c, 0x55, 0xb9, 0xcc, 0xcf, 0xd2, 0xf0, -0xeb, 0x71, 0xda, 0xf1, 0xc3, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xa5, -0x66, 0x32, 0xb0, 0xd1, 0x51, 0x21, 0x03, 0x04, -0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0x70, -0xfa, 0x60, 0xc1, 0xcd, 0x2e, 0x9f, 0x0c, 0x72, -0xd5, 0x8c, 0xd9, 0xfa, 0x0f, 0x36, 0x2e, 0x7f, -0xb4, 0x7b, 0x17, 0xd9, 0xb8, 0x69, 0x1e, 0xe5, -0x93, 0x4b, 0x8f, 0xfa, 0x98, 0x2c, 0x1a, 0x00, +0x21, 0xe0, 0xe8, 0xac, 0x74, 0x17, 0x3f, 0x62, +0x7f, 0xf3, 0xd6, 0x28, 0x1c, 0x1b, 0x1c, 0xc2, +0x43, 0xb0, 0x58, 0x78, 0x01, 0xf8, 0x68, 0xa1, +0x99, 0x20, 0x46, 0xae, 0x85, 0x39, 0xb9, 0x2b, +0xd8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x10, +0x01, 0x22, 0x21, 0x9c, 0xe4, 0x27, 0xac, 0xa1, +0xe0, 0xa7, 0x26, 0x1e, 0x36, 0xd9, 0x7e, 0x34, +0x4d, 0x3c, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x84, 0x8d, 0xbc, 0x2d, +0xcb, 0xbc, 0xe2, 0xa4, 0x03, 0x04, 0x51, 0x02, +0x00, 0x11, 0x01, 0x22, 0x21, 0x26, 0xd3, 0xf0, +0xe9, 0x9c, 0x99, 0xa7, 0x4d, 0x7d, 0x58, 0x0d, +0x72, 0x54, 0xd4, 0x1b, 0x74, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x9c, +0x55, 0x37, 0x15, 0x80, 0x86, 0x6b, 0x03, 0x04, +0x51, 0x02, 0x00, 0x12, 0x01, 0x22, 0x21, 0x58, +0x03, 0xee, 0x04, 0x8e, 0x21, 0x12, 0xdf, 0xda, +0x4a, 0x31, 0xce, 0x35, 0x07, 0xd6, 0xe9, 0x9b, +0xda, 0xaa, 0xf2, 0x9c, 0x21, 0xd4, 0x43, 0x87, +0xfb, 0x6a, 0xb6, 0x43, 0x6f, 0x30, 0x8d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x13, 0x01, 0x22, -0x21, 0xc2, 0x28, 0x1c, 0x15, 0xd7, 0xba, 0xbb, -0x20, 0x27, 0x68, 0x50, 0x7c, 0x99, 0x94, 0xdb, -0x1c, 0x42, 0x27, 0x52, 0x58, 0xce, 0x49, 0xed, -0xa1, 0x3e, 0x6a, 0x0d, 0x70, 0xb5, 0xa1, 0xb7, -0x52, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, -0x01, 0x22, 0x21, 0x0c, 0xa6, 0x4f, 0x59, 0xa9, -0xaf, 0xf3, 0xac, 0x70, 0xdd, 0x5e, 0x10, 0x3b, -0x9b, 0xec, 0x19, 0x04, 0x68, 0x55, 0xf6, 0x18, -0x33, 0xd6, 0x5e, 0xe9, 0xec, 0xde, 0x62, 0xa6, -0x08, 0x6b, 0x67, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x15, 0x01, 0x22, 0x21, 0x6e, 0x8d, 0x4c, -0x9f, 0xb1, 0xa1, 0x68, 0x4c, 0x32, 0x0e, 0x86, -0x33, 0xc0, 0xa9, 0xd6, 0xce, 0x2d, 0xd8, 0x33, -0x0b, 0xf6, 0x60, 0xcb, 0x51, 0x81, 0xd5, 0xa9, -0x61, 0x87, 0xd1, 0x19, 0xb4, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x8c, -0x9a, 0x12, 0x5e, 0xc1, 0xf1, 0x73, 0x19, 0x0a, -0x08, 0xfb, 0x9b, 0x4c, 0xd1, 0x06, 0xa4, 0x6e, -0x0f, 0xa4, 0x65, 0xff, 0xba, 0x35, 0xd6, 0x6b, -0xbb, 0xba, 0x69, 0x49, 0x30, 0x25, 0x61, 0x00, +0x21, 0xce, 0x6e, 0x67, 0xa9, 0xd5, 0xc5, 0xe5, +0x37, 0x61, 0x1d, 0x5c, 0x60, 0x43, 0x93, 0x36, +0x92, 0xe0, 0x0f, 0x1d, 0xed, 0x36, 0x6e, 0xf7, +0x25, 0x5d, 0x7b, 0xd9, 0x33, 0x41, 0x7a, 0x58, +0xf7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x14, +0x01, 0x22, 0x21, 0x35, 0xbb, 0xbc, 0xd5, 0x1b, +0x4d, 0xba, 0x43, 0x9e, 0xb3, 0x98, 0xca, 0xd7, +0xbd, 0x89, 0xd8, 0x3e, 0xdf, 0xf9, 0x64, 0x6d, +0x43, 0x54, 0x89, 0x41, 0x04, 0x03, 0xe7, 0xc5, +0xcd, 0x44, 0x5a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x15, 0x01, 0x22, 0x21, 0xf0, 0x82, 0x3a, +0xbc, 0x61, 0x13, 0x13, 0x96, 0x71, 0x00, 0x38, +0xb9, 0xe2, 0x88, 0x04, 0x17, 0x63, 0x23, 0x7c, +0x97, 0x04, 0xeb, 0x36, 0x88, 0x62, 0x8e, 0x5e, +0x99, 0xbb, 0xe8, 0x14, 0x7f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x16, 0x01, 0x22, 0x21, 0x55, +0x34, 0x3a, 0x73, 0x09, 0xc8, 0xb8, 0xb2, 0x77, +0xaf, 0xbc, 0x29, 0x98, 0xc9, 0xa8, 0x7e, 0xf8, +0x98, 0x52, 0x67, 0xd1, 0x0c, 0x31, 0x00, 0xe0, +0xb7, 0x1c, 0x8a, 0xaf, 0xb7, 0x4f, 0xf1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x17, 0x01, 0x22, -0x21, 0x26, 0xbe, 0xd2, 0xb8, 0x59, 0x40, 0xc8, -0x38, 0x23, 0x59, 0xf4, 0x74, 0x6c, 0x12, 0x9d, -0xff, 0xc7, 0x59, 0xfd, 0xd0, 0x95, 0x86, 0xb5, -0x04, 0xc3, 0x57, 0xd1, 0xb8, 0x80, 0x1c, 0xb3, -0xaf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, -0x01, 0x22, 0x21, 0x33, 0x28, 0xf5, 0x68, 0x50, -0xb3, 0x60, 0xdb, 0x39, 0x8f, 0x58, 0x86, 0x6d, -0x77, 0xb0, 0x17, 0xfd, 0x26, 0x44, 0xda, 0xb6, -0x15, 0xf0, 0x22, 0x23, 0xe0, 0x8d, 0x83, 0x9c, -0x60, 0xf3, 0x32, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x19, 0x01, 0x22, 0x21, 0x14, 0xe1, 0x3e, -0x6b, 0xe1, 0xd5, 0x2e, 0x03, 0x58, 0xd8, 0xe7, -0x84, 0xcb, 0x83, 0x3f, 0x04, 0xbd, 0x2c, 0x27, -0x38, 0x3b, 0x57, 0x82, 0xfc, 0x9b, 0x2f, 0x4d, -0xa0, 0xbe, 0x72, 0x3f, 0xb0, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0xc2, -0x25, 0x70, 0xfb, 0x3c, 0xdd, 0x2e, 0xb2, 0xc8, -0x89, 0x3a, 0x87, 0x01, 0x0e, 0xec, 0xab, 0xc5, -0xbb, 0xcc, 0xb1, 0xa7, 0x4f, 0xba, 0x88, 0xda, -0xb6, 0xef, 0xb9, 0x71, 0x90, 0x37, 0x3a, 0x00, +0x21, 0xaa, 0x82, 0x20, 0xb0, 0xc7, 0xe0, 0xe2, +0xd9, 0x74, 0xf1, 0xc8, 0x32, 0xde, 0x4d, 0x9c, +0xe6, 0x67, 0x66, 0xc2, 0xe8, 0xbb, 0xdd, 0x42, +0x48, 0x48, 0x11, 0x7c, 0x1c, 0x5c, 0x37, 0x91, +0xc2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x18, +0x01, 0x22, 0x21, 0x72, 0x79, 0x99, 0x78, 0x11, +0x44, 0xa7, 0x2e, 0xa0, 0x41, 0x0c, 0x29, 0x2d, +0xa9, 0xa4, 0x69, 0x69, 0x83, 0xd9, 0xc3, 0x8c, +0xc0, 0x35, 0x54, 0x2e, 0x05, 0xaf, 0x05, 0x05, +0xeb, 0x1b, 0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x19, 0x01, 0x22, 0x21, 0x10, 0xa1, 0x17, +0x6b, 0x2c, 0xdb, 0xb4, 0xe8, 0x76, 0x5c, 0x38, +0x17, 0x14, 0x8a, 0xa4, 0x40, 0x4f, 0x50, 0x6e, +0x2a, 0x30, 0x98, 0x80, 0x34, 0x77, 0x5b, 0xc9, +0xf0, 0x5c, 0x10, 0xa1, 0x39, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1a, 0x01, 0x22, 0x21, 0xe9, +0x4f, 0xdc, 0x30, 0x31, 0xda, 0xdd, 0x1d, 0x31, +0xc3, 0x48, 0x2d, 0xdf, 0xf8, 0x28, 0xa5, 0x6d, +0xec, 0xaa, 0x3b, 0xb2, 0x4f, 0xd8, 0x6e, 0x41, +0xe5, 0xd1, 0x2c, 0xa4, 0x9c, 0x14, 0x19, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1b, 0x01, 0x22, -0x21, 0xee, 0x88, 0xb1, 0xe7, 0x2b, 0xa9, 0xb8, -0xa2, 0x01, 0xc3, 0x7e, 0xdf, 0xf8, 0xa4, 0x30, -0x71, 0x2a, 0x6f, 0x1c, 0x52, 0xcf, 0xe1, 0x05, -0x54, 0xfd, 0xbb, 0xe6, 0x26, 0x29, 0x0e, 0xd8, -0x3b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, -0x01, 0x22, 0x21, 0x7b, 0xb0, 0x1c, 0x9f, 0x7d, -0x83, 0x7c, 0x2d, 0xbc, 0x3f, 0x47, 0xef, 0xf1, -0x53, 0x35, 0x2d, 0xf1, 0xf5, 0x04, 0x3d, 0xb7, -0x75, 0x31, 0xac, 0xa8, 0x51, 0xa6, 0xd1, 0x82, -0x42, 0x9a, 0xaa, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x1d, 0x01, 0x22, 0x21, 0xed, 0x41, 0x63, -0x86, 0x40, 0x73, 0xa4, 0x21, 0x8f, 0x0e, 0xca, -0x01, 0x3e, 0x23, 0x6e, 0xb4, 0x1b, 0xe4, 0x1b, -0x88, 0xfe, 0x6e, 0x0c, 0x52, 0x19, 0x1f, 0x05, -0x3b, 0x9c, 0x62, 0xcd, 0xe3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0x48, -0xf5, 0x92, 0xe3, 0x70, 0x32, 0x14, 0x4d, 0xea, -0xe5, 0x19, 0x30, 0x4b, 0x97, 0x5b, 0x6b, 0x88, -0x66, 0xe1, 0xd4, 0x10, 0x6c, 0x51, 0x6e, 0xc1, -0x42, 0x4e, 0x5d, 0xb7, 0xdf, 0xa9, 0x66, 0x00, +0x21, 0x91, 0x65, 0x9f, 0xfd, 0xd9, 0x29, 0xe6, +0x62, 0x78, 0xa6, 0x46, 0x69, 0xb3, 0x58, 0xa0, +0x78, 0x4c, 0x1e, 0x89, 0xd4, 0xd2, 0x99, 0x2c, +0x35, 0x68, 0x1f, 0x09, 0xb5, 0x88, 0x56, 0x80, +0xa7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1c, +0x01, 0x22, 0x21, 0x98, 0xe7, 0x20, 0xe2, 0xad, +0x96, 0x63, 0xb0, 0x6f, 0x11, 0x3c, 0x06, 0xea, +0x9b, 0x4d, 0x32, 0xad, 0xde, 0xf9, 0xca, 0xd9, +0x00, 0xb2, 0x74, 0x3d, 0xfe, 0x08, 0xed, 0xa2, +0xf5, 0xb7, 0xe2, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x1d, 0x01, 0x22, 0x21, 0x76, 0xe9, 0xe5, +0xa5, 0x82, 0x4f, 0xc4, 0x8e, 0x55, 0x25, 0xb2, +0xc9, 0x6b, 0x5e, 0x31, 0x4d, 0x06, 0x01, 0x1b, +0x39, 0x07, 0x95, 0xba, 0xc5, 0x73, 0xbc, 0xb2, +0x80, 0x4a, 0x2a, 0xd1, 0x8f, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x1e, 0x01, 0x22, 0x21, 0x0d, +0x8b, 0xd8, 0x46, 0xe4, 0x92, 0x13, 0x4d, 0x7b, +0xec, 0xd6, 0x59, 0xe5, 0x5c, 0x45, 0x39, 0xd0, +0x0e, 0x86, 0x9c, 0x75, 0x91, 0x69, 0x9b, 0xcf, +0x05, 0x36, 0xe4, 0xf9, 0x8b, 0x88, 0x95, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x1f, 0x01, 0x22, -0x21, 0x8e, 0x43, 0xcb, 0xd8, 0x77, 0xfe, 0xd7, -0x17, 0x3e, 0x80, 0x06, 0xb4, 0x33, 0x9f, 0xf3, -0x29, 0xba, 0xbd, 0xda, 0x9a, 0x47, 0xd5, 0xdf, -0x77, 0xd8, 0x75, 0x48, 0xf7, 0xfd, 0xc5, 0x72, -0x85, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, -0x01, 0x22, 0x21, 0x2d, 0x96, 0x39, 0x40, 0x66, -0x3a, 0xcf, 0x90, 0x6f, 0x9f, 0x7c, 0x33, 0x79, -0x92, 0x14, 0xca, 0xc9, 0x8a, 0xc2, 0xdc, 0xeb, -0x8b, 0x3d, 0x30, 0x08, 0x90, 0x69, 0x97, 0xa0, -0x81, 0x62, 0xec, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x21, 0x01, 0x22, 0x21, 0xb5, 0xae, 0x44, -0x35, 0xa7, 0x78, 0xcd, 0xfd, 0x87, 0x87, 0x7a, -0xbe, 0x97, 0xb7, 0x56, 0x1f, 0x6e, 0xd7, 0x66, -0xe0, 0x90, 0x53, 0x26, 0xdb, 0xac, 0xce, 0x69, -0xee, 0x3d, 0xe8, 0x9c, 0xbb, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0xde, -0x10, 0x36, 0x6e, 0x96, 0xfa, 0xd5, 0x3b, 0x43, -0xb9, 0x07, 0xec, 0x56, 0x90, 0x38, 0x98, 0x7a, -0xcd, 0x0c, 0xf6, 0xd5, 0xfe, 0xff, 0x23, 0x2c, -0x71, 0x4a, 0x1c, 0x7c, 0xc9, 0x0b, 0xb7, 0x00, +0x21, 0x4c, 0xc7, 0x83, 0xb3, 0x35, 0x08, 0x53, +0x96, 0x78, 0xd1, 0x7e, 0x2e, 0x9a, 0xa2, 0x6d, +0x73, 0xc8, 0xa3, 0xf3, 0xce, 0xd2, 0x8a, 0x63, +0x7c, 0xea, 0x95, 0x76, 0xdc, 0x6a, 0xb2, 0x7a, +0xa2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x20, +0x01, 0x22, 0x21, 0xd2, 0xd4, 0x97, 0x35, 0x49, +0xf8, 0xb7, 0x8c, 0x27, 0xd7, 0xad, 0x96, 0x39, +0x61, 0xd2, 0x18, 0x31, 0x61, 0xe1, 0xda, 0x63, +0xcc, 0xce, 0x8c, 0x09, 0xe5, 0x0b, 0x22, 0x6a, +0xdc, 0xa7, 0xd1, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x21, 0x01, 0x22, 0x21, 0xee, 0x6c, 0xd7, +0x85, 0xe4, 0x12, 0x81, 0x5c, 0x56, 0xa4, 0x20, +0x2a, 0xcc, 0x2d, 0xc1, 0x21, 0x97, 0xa2, 0x52, +0x38, 0x84, 0x80, 0xe5, 0xc6, 0xef, 0x7b, 0xf3, +0x81, 0x01, 0x57, 0xb4, 0xfa, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x22, 0x01, 0x22, 0x21, 0x2d, +0x33, 0x1e, 0x91, 0xcb, 0xeb, 0x32, 0x59, 0x91, +0xdf, 0xaf, 0x03, 0x5e, 0x90, 0x59, 0xe1, 0xe6, +0xd5, 0xf9, 0xe9, 0x61, 0xc4, 0x73, 0x8d, 0x12, +0xa0, 0xab, 0x0b, 0x84, 0xab, 0x6b, 0x02, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x23, 0x01, 0x22, -0x21, 0x60, 0x8a, 0xad, 0xc5, 0x74, 0x1f, 0xde, -0x65, 0xd7, 0xcc, 0xbb, 0x9a, 0xf5, 0x64, 0x29, -0x63, 0x20, 0x21, 0xa3, 0x07, 0xdd, 0x55, 0x2c, -0x5c, 0xb6, 0x67, 0x47, 0xdb, 0xc3, 0x3b, 0x2f, -0x72, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, -0x01, 0x22, 0x21, 0x35, 0xbc, 0x0d, 0x76, 0x14, -0x63, 0x96, 0x15, 0xbe, 0x08, 0xa8, 0xf7, 0x35, -0xc5, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x80, 0x71, 0xf5, 0xe5, -0x33, 0x47, 0xd5, 0x38, 0x03, 0x04, 0x51, 0x02, -0x00, 0x25, 0x01, 0x22, 0x21, 0xc4, 0xf5, 0x19, -0x21, 0x1d, 0xf6, 0xe8, 0x06, 0xaf, 0xfa, 0xab, -0xf2, 0x4c, 0x01, 0x83, 0x99, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xdb, -0xca, 0x57, 0xd8, 0x1e, 0x59, 0xd9, 0x03, 0x04, -0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0x5b, -0xf0, 0xf9, 0xdf, 0xe9, 0x17, 0xff, 0x6a, 0xe2, -0xdf, 0x18, 0x58, 0x5e, 0xdb, 0xfd, 0x1d, 0xb4, -0xd7, 0x9b, 0xec, 0xd8, 0x47, 0xe7, 0x5b, 0xcd, -0xae, 0xec, 0xff, 0x60, 0x55, 0x53, 0xd1, 0x00, +0x21, 0xf6, 0x5b, 0x6d, 0x7c, 0x63, 0xae, 0x5a, +0xc5, 0xe5, 0x55, 0xce, 0xb2, 0xda, 0x01, 0xee, +0x1d, 0xcb, 0xd2, 0xc5, 0x3e, 0xd3, 0x1c, 0x52, +0xa7, 0x6f, 0x35, 0x73, 0xeb, 0x28, 0x2a, 0x8f, +0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x24, +0x01, 0x22, 0x21, 0x3e, 0xe8, 0xf0, 0x94, 0xf2, +0xb9, 0xee, 0x6a, 0xef, 0xe3, 0x1d, 0xc9, 0x2a, +0xc8, 0xd2, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xa3, 0x8a, 0xc6, 0x1b, +0x9d, 0x67, 0xbb, 0xa3, 0x03, 0x04, 0x51, 0x02, +0x00, 0x25, 0x01, 0x22, 0x21, 0x5e, 0x37, 0xcc, +0x35, 0x95, 0xbc, 0xfe, 0xcc, 0xf6, 0x2a, 0x4f, +0x47, 0xc1, 0x3d, 0x39, 0xdc, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x60, +0x78, 0xec, 0x42, 0x09, 0xce, 0xce, 0x03, 0x04, +0x51, 0x02, 0x00, 0x26, 0x01, 0x22, 0x21, 0x29, +0x10, 0x21, 0xd6, 0x60, 0xe8, 0x87, 0x6b, 0xcb, +0x0c, 0xa7, 0x68, 0x56, 0x89, 0xc5, 0xe0, 0x0c, +0xde, 0x03, 0xbb, 0xf6, 0x53, 0x42, 0x2b, 0x72, +0x8b, 0xac, 0xd8, 0x8e, 0x60, 0xf2, 0x52, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x27, 0x01, 0x22, -0x21, 0xb6, 0x9e, 0x7c, 0x3b, 0x01, 0xfb, 0xc3, -0x34, 0x1e, 0x2d, 0x4c, 0x1e, 0xc3, 0x51, 0x0b, -0xd3, 0xda, 0xc9, 0x38, 0x89, 0x50, 0xee, 0x79, -0xa9, 0x24, 0x38, 0xe9, 0x4a, 0x23, 0x65, 0xf9, -0x22, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, -0x01, 0x22, 0x21, 0x9e, 0xde, 0x41, 0xd5, 0x23, -0x6b, 0xb8, 0x0c, 0xb2, 0x48, 0xec, 0x49, 0x7e, -0xd0, 0xea, 0xd4, 0x15, 0x1e, 0x2f, 0x18, 0x6d, -0xb1, 0xa7, 0x70, 0x0b, 0x07, 0xcd, 0xf1, 0x29, -0xcf, 0xfb, 0x98, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x29, 0x01, 0x22, 0x21, 0x9d, 0x7d, 0x7e, -0x6a, 0x56, 0x3e, 0x58, 0x76, 0x45, 0x5d, 0x46, -0x06, 0x21, 0x9e, 0xda, 0x8d, 0x56, 0xdc, 0x81, -0xd3, 0xc4, 0x1a, 0x62, 0x06, 0x8b, 0x0c, 0xf0, -0x11, 0xfd, 0x53, 0x2f, 0x8b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x5e, -0x92, 0x3d, 0x2b, 0xaf, 0x6b, 0x3a, 0x78, 0xc9, -0xde, 0xd7, 0x34, 0x4c, 0x9b, 0x1a, 0x9e, 0x02, -0xdd, 0x55, 0x67, 0x82, 0x49, 0x69, 0xf3, 0xd0, -0xa8, 0x9b, 0x67, 0xd2, 0xa6, 0xc1, 0x84, 0x00, +0x21, 0x66, 0x70, 0xd1, 0xd4, 0xe7, 0x24, 0xaa, +0x65, 0x35, 0x46, 0x6f, 0xef, 0xe5, 0xe6, 0x80, +0x12, 0xb1, 0xfe, 0x0a, 0x2a, 0x95, 0xe3, 0xb6, +0x2b, 0x8f, 0x38, 0x6d, 0x14, 0x95, 0x5c, 0x23, +0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x28, +0x01, 0x22, 0x21, 0x11, 0x28, 0xcf, 0x98, 0x2a, +0x13, 0x74, 0x3d, 0xbe, 0x3c, 0x21, 0xa4, 0xb8, +0xb8, 0x81, 0x93, 0xab, 0x1e, 0x6a, 0xc3, 0xcf, +0x16, 0x4b, 0x54, 0xbc, 0x01, 0x6a, 0x71, 0x93, +0xc7, 0x30, 0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x29, 0x01, 0x22, 0x21, 0x9a, 0x13, 0x46, +0x33, 0xa8, 0x44, 0x02, 0x5b, 0x10, 0x1d, 0x4e, +0xb4, 0xec, 0x22, 0x4a, 0xb5, 0xb1, 0x94, 0x2a, +0xc9, 0x3f, 0x8e, 0xf8, 0xcc, 0xe2, 0x8c, 0x3c, +0x64, 0x92, 0x7d, 0x7e, 0xde, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2a, 0x01, 0x22, 0x21, 0x6e, +0xe9, 0x53, 0x0b, 0xdb, 0xaf, 0xaf, 0x71, 0x10, +0x53, 0x27, 0xe0, 0x18, 0x91, 0xf1, 0x10, 0x9d, +0xbb, 0xac, 0xb0, 0x84, 0xc0, 0xd8, 0x00, 0x38, +0x61, 0xee, 0xc2, 0x35, 0x05, 0x38, 0xde, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2b, 0x01, 0x22, -0x21, 0x23, 0x77, 0x65, 0x34, 0xb1, 0x0d, 0x99, -0x82, 0x58, 0x50, 0x51, 0xf5, 0xa4, 0x2c, 0xbb, -0x50, 0x52, 0xeb, 0xa2, 0x55, 0x33, 0x68, 0xca, -0x74, 0x38, 0xd8, 0x1b, 0xab, 0xbc, 0x78, 0x83, -0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, -0x01, 0x22, 0x21, 0x50, 0x05, 0xf4, 0xa8, 0x94, -0x69, 0x60, 0xf9, 0x75, 0x8d, 0x6d, 0xcc, 0xc1, -0x36, 0x1f, 0xf5, 0xd0, 0xac, 0xec, 0xcb, 0xd3, -0x46, 0xed, 0x29, 0xe4, 0xe8, 0x43, 0xbd, 0x19, -0xf0, 0x50, 0x90, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x2d, 0x01, 0x22, 0x21, 0xca, 0x04, 0x63, -0x00, 0x36, 0x78, 0x80, 0x2b, 0x08, 0x3d, 0x56, -0x69, 0x37, 0x5c, 0x78, 0x35, 0x17, 0x02, 0xaa, -0x17, 0x01, 0xa6, 0xb3, 0xea, 0xb1, 0x38, 0x4b, -0x2e, 0x6f, 0x55, 0x0a, 0xa6, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0x82, -0x57, 0xc5, 0xe1, 0xf8, 0xff, 0x52, 0x28, 0xfe, -0x6a, 0x46, 0xb2, 0x89, 0x6c, 0xd2, 0xd3, 0x91, -0xbd, 0xc1, 0x72, 0x63, 0xa4, 0xc3, 0x0e, 0xfd, -0xac, 0xd8, 0x0f, 0x95, 0xb9, 0x53, 0x5c, 0x00, +0x21, 0x21, 0x81, 0x1d, 0x36, 0x6b, 0x3e, 0xbc, +0x1f, 0x29, 0x0d, 0x7e, 0x15, 0xf1, 0xc8, 0x7b, +0x96, 0x89, 0x9a, 0xdc, 0x21, 0x9d, 0x1d, 0x25, +0x67, 0x17, 0x0d, 0x17, 0x46, 0xd3, 0xb2, 0xd6, +0x40, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2c, +0x01, 0x22, 0x21, 0x30, 0xcb, 0xc4, 0xc6, 0x31, +0x52, 0x85, 0xd3, 0xe7, 0x84, 0x36, 0xe4, 0xa6, +0x4e, 0xff, 0x3f, 0xd5, 0xad, 0x00, 0x92, 0x59, +0xbc, 0xdf, 0x08, 0x91, 0x59, 0x42, 0x80, 0x27, +0x14, 0x4c, 0x4b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x2d, 0x01, 0x22, 0x21, 0x56, 0xe5, 0xfc, +0x34, 0x84, 0x5a, 0x4a, 0xfe, 0x05, 0xb8, 0x5b, +0xa4, 0x64, 0xb3, 0xec, 0xe7, 0x52, 0x6f, 0x94, +0x45, 0xf0, 0x6a, 0x7f, 0xe7, 0x6d, 0xed, 0xcd, +0xfa, 0x43, 0x91, 0x84, 0x77, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x2e, 0x01, 0x22, 0x21, 0xb6, +0x01, 0x59, 0xf7, 0xa0, 0x8e, 0x83, 0xc3, 0xe1, +0xf2, 0x0f, 0xab, 0x50, 0xc6, 0x32, 0x94, 0xa0, +0xb6, 0x1e, 0x45, 0xa3, 0x9f, 0x4b, 0x26, 0x4b, +0x49, 0xa3, 0x60, 0x48, 0xe7, 0xcd, 0x97, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x2f, 0x01, 0x22, -0x21, 0x32, 0x76, 0x53, 0x4c, 0x6c, 0x7f, 0x30, -0x6e, 0xa7, 0x4a, 0x28, 0xcf, 0xd0, 0x17, 0x7e, -0x73, 0xa3, 0x59, 0x26, 0x41, 0xa5, 0x4b, 0x05, -0x09, 0x01, 0xd1, 0xb7, 0x05, 0xe4, 0x42, 0x1b, -0xed, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, -0x01, 0x22, 0x21, 0x57, 0x79, 0x1c, 0x50, 0xd9, -0xd0, 0xd3, 0x90, 0x6a, 0xd4, 0xc3, 0x58, 0x7e, -0xad, 0xb9, 0xd0, 0xcb, 0x70, 0x51, 0x9e, 0xa4, -0x51, 0xd1, 0xfb, 0x53, 0xcd, 0x0f, 0x03, 0xc2, -0x4e, 0x52, 0xa0, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x31, 0x01, 0x22, 0x21, 0x88, 0xd4, 0x5e, -0xdd, 0x79, 0xe6, 0x28, 0x5a, 0x13, 0x9b, 0xe4, -0xc6, 0x62, 0x1a, 0xd5, 0x3c, 0x53, 0xa1, 0x3c, -0x73, 0x4a, 0x07, 0xcf, 0x96, 0xdb, 0x03, 0xa4, -0xc5, 0x68, 0xc2, 0x86, 0xfe, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0xec, -0xe6, 0xdb, 0x37, 0x09, 0xdc, 0x30, 0x6a, 0xc8, -0x67, 0xf2, 0x69, 0xf7, 0x83, 0x2f, 0xdc, 0xf8, -0x08, 0xed, 0x10, 0xe9, 0xc6, 0x5d, 0x71, 0xc0, -0xce, 0x7d, 0x90, 0x86, 0xf0, 0xb5, 0x0d, 0x00, +0x21, 0xb4, 0x2a, 0xc6, 0x70, 0xac, 0x2b, 0x69, +0x44, 0x83, 0xaf, 0x20, 0x5b, 0x8b, 0x6a, 0xc4, +0xf9, 0x8c, 0xcf, 0x44, 0x46, 0xdc, 0x9c, 0x57, +0xcc, 0xf9, 0xb4, 0xe1, 0x65, 0x06, 0xa0, 0x35, +0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x30, +0x01, 0x22, 0x21, 0x54, 0x46, 0x02, 0x5e, 0x70, +0x78, 0x9c, 0x23, 0x79, 0x01, 0xaf, 0x73, 0x85, +0x20, 0x1f, 0x00, 0xe5, 0xd5, 0xb6, 0x4e, 0xf2, +0xa7, 0xaa, 0xb0, 0x70, 0x78, 0xbe, 0x2e, 0x5d, +0x8a, 0xe3, 0xcd, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x31, 0x01, 0x22, 0x21, 0x19, 0x7b, 0x6e, +0x40, 0xf4, 0x3e, 0xc9, 0x4c, 0xbb, 0x9c, 0x25, +0x70, 0xbb, 0x1c, 0x99, 0x83, 0x82, 0xbb, 0x4e, +0xb7, 0xe1, 0xb0, 0x75, 0xe7, 0x47, 0x7f, 0x04, +0xe7, 0x51, 0xc5, 0x3a, 0x03, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x32, 0x01, 0x22, 0x21, 0x9c, +0x99, 0x5b, 0xd3, 0x0f, 0x4f, 0xfb, 0x26, 0x01, +0x94, 0xc1, 0x77, 0xd1, 0x5d, 0x13, 0xdb, 0xcf, +0xeb, 0x1d, 0xdf, 0xf0, 0x0b, 0xf3, 0xe4, 0x79, +0x83, 0xe0, 0x45, 0x92, 0x5a, 0x7f, 0xca, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x33, 0x01, 0x22, -0x21, 0x5c, 0x41, 0x1a, 0x75, 0x36, 0x40, 0x17, -0x6b, 0xc5, 0x39, 0xa1, 0x0f, 0x3e, 0x73, 0x8a, -0x59, 0xfb, 0x8e, 0x78, 0xac, 0xcc, 0xf2, 0xcc, -0x08, 0x1d, 0xf1, 0xb5, 0xa0, 0xad, 0xea, 0xff, -0x21, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, -0x01, 0x22, 0x21, 0x5a, 0xdd, 0x2e, 0xcf, 0x71, -0x23, 0x6c, 0x52, 0x93, 0xa5, 0xad, 0x2c, 0xb3, -0x1f, 0x29, 0xab, 0x38, 0xa8, 0x2f, 0x77, 0x9c, -0x52, 0x79, 0x60, 0xfa, 0x94, 0xb1, 0x38, 0x8e, -0x7e, 0x26, 0x80, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x35, 0x01, 0x22, 0x21, 0x7a, 0x46, 0xd4, -0x77, 0x24, 0x64, 0x82, 0x2f, 0x81, 0xf8, 0x68, -0x5b, 0xdf, 0x24, 0xac, 0x26, 0x2d, 0x9c, 0xd7, -0xfb, 0xaa, 0xb5, 0x5c, 0x3b, 0xa9, 0x28, 0x1b, -0xd8, 0xec, 0xfc, 0x53, 0x40, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0xfa, -0x1a, 0x4a, 0x5d, 0xcb, 0x67, 0xbd, 0x06, 0x50, -0xc1, 0xdd, 0x72, 0x70, 0x9a, 0x49, 0xb8, 0x09, -0xb2, 0xdf, 0x92, 0x01, 0x25, 0x83, 0xe4, 0x10, -0x36, 0x6c, 0xaf, 0x07, 0x7a, 0x52, 0x7d, 0x00, +0x21, 0x78, 0x0b, 0x75, 0xbb, 0x36, 0x32, 0x05, +0x18, 0x88, 0xbd, 0x21, 0x5e, 0x90, 0x14, 0xde, +0xdf, 0xff, 0x4c, 0xa4, 0x20, 0x31, 0x78, 0xed, +0x10, 0xf1, 0xa9, 0x14, 0x64, 0xb3, 0x11, 0x7a, +0x29, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x34, +0x01, 0x22, 0x21, 0x3f, 0x3f, 0x61, 0xe1, 0x5d, +0xd4, 0xf9, 0xde, 0x16, 0x82, 0xff, 0x90, 0x91, +0x1d, 0xc1, 0xeb, 0xc3, 0xac, 0xc1, 0x9e, 0xcf, +0xac, 0x23, 0x69, 0x4a, 0x10, 0x30, 0x04, 0x2e, +0xc8, 0x76, 0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x35, 0x01, 0x22, 0x21, 0xa9, 0x9c, 0x1c, +0xa6, 0x73, 0xbc, 0xe8, 0x37, 0xa1, 0xc3, 0xcb, +0x17, 0x35, 0x2d, 0x68, 0xf6, 0xc9, 0x48, 0x40, +0xac, 0xb4, 0xbc, 0x50, 0x69, 0x99, 0x95, 0x8b, +0xc2, 0xbc, 0xc4, 0xbf, 0x5b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x36, 0x01, 0x22, 0x21, 0xf2, +0x4c, 0x2d, 0x92, 0xf4, 0x5d, 0xb4, 0xa1, 0x4d, +0xe7, 0x6f, 0xd2, 0xfd, 0xf4, 0x86, 0x9f, 0x12, +0x8d, 0x28, 0x05, 0x46, 0x8d, 0x54, 0xf8, 0xfd, +0x7e, 0xb2, 0xb9, 0xda, 0x30, 0x85, 0x80, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x37, 0x01, 0x22, -0x21, 0x69, 0xb7, 0xda, 0x56, 0xdd, 0x0c, 0x3d, -0xd6, 0xf2, 0xef, 0x40, 0xc3, 0x63, 0xfa, 0xe4, -0xac, 0xa3, 0xe9, 0xd7, 0x7c, 0x95, 0x3d, 0xae, -0x0e, 0x3b, 0x16, 0x3c, 0x40, 0x4e, 0x6e, 0x68, -0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, -0x01, 0x22, 0x21, 0x56, 0x03, 0x5c, 0x68, 0x1f, -0x5d, 0x8f, 0xe9, 0x44, 0x51, 0xc3, 0xa1, 0x81, -0x59, 0x91, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x45, 0xf0, 0x7e, 0x16, -0x4e, 0x29, 0x2d, 0x7d, 0x03, 0x04, 0x51, 0x02, -0x00, 0x39, 0x01, 0x22, 0x21, 0xfe, 0x02, 0xba, -0xb4, 0xf8, 0xb6, 0x26, 0x8f, 0xc9, 0xa5, 0x10, -0xb8, 0xc1, 0xeb, 0xc3, 0x49, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x19, -0xf2, 0xc3, 0xbc, 0xeb, 0x75, 0x7a, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0x24, -0x96, 0x25, 0x0e, 0xb9, 0x53, 0x69, 0x10, 0xd0, -0x4e, 0x78, 0xb4, 0xfc, 0x6b, 0xe9, 0x54, 0x6e, -0x97, 0x30, 0xfb, 0x60, 0xe1, 0xef, 0xbe, 0xba, -0xf8, 0x0a, 0xe9, 0x9d, 0xda, 0x7c, 0x5d, 0x00, +0x21, 0x02, 0xbb, 0xd0, 0x70, 0x97, 0x93, 0xd7, +0x8e, 0x6d, 0xf8, 0x56, 0xc8, 0xd3, 0x07, 0xd9, +0x78, 0xe0, 0x6b, 0xa0, 0x21, 0xf7, 0x46, 0x3a, +0xed, 0xa8, 0xb9, 0x7e, 0xba, 0xbf, 0x86, 0xd7, +0x56, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x38, +0x01, 0x22, 0x21, 0x87, 0xaf, 0x54, 0xdb, 0x72, +0xd0, 0xad, 0x3e, 0x05, 0x44, 0x49, 0x44, 0x14, +0xe1, 0x29, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x0c, 0x71, 0x47, 0x85, +0x0a, 0x90, 0x61, 0x81, 0x03, 0x04, 0x51, 0x02, +0x00, 0x39, 0x01, 0x22, 0x21, 0x85, 0x97, 0xf7, +0x47, 0x44, 0x37, 0xc0, 0xa6, 0xa5, 0x81, 0x5f, +0x15, 0x3e, 0x2d, 0xe3, 0x5e, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0xee, +0xc8, 0xa8, 0x00, 0x77, 0xa6, 0xff, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3a, 0x01, 0x22, 0x21, 0x55, +0xf7, 0x9c, 0x33, 0x63, 0x27, 0x1d, 0x26, 0xca, +0x34, 0x95, 0x35, 0xcc, 0xc5, 0x07, 0x15, 0xab, +0x9f, 0x45, 0x18, 0x65, 0x11, 0x96, 0x99, 0x28, +0x19, 0x1c, 0x1d, 0x9b, 0xc5, 0xcc, 0x07, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3b, 0x01, 0x22, -0x21, 0x69, 0x13, 0xd6, 0x5d, 0xdd, 0xcc, 0x73, -0xca, 0x12, 0x45, 0xdf, 0x30, 0xc2, 0x6d, 0x07, -0x4d, 0x07, 0x35, 0xd5, 0x91, 0xa7, 0xcd, 0xb5, -0x48, 0xe8, 0x38, 0x04, 0x2e, 0x9f, 0x05, 0x2e, -0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, -0x01, 0x22, 0x21, 0x5a, 0xcd, 0x67, 0xa7, 0x89, -0x0f, 0x66, 0xd6, 0x1e, 0xd8, 0xb7, 0x88, 0xa8, -0x93, 0x93, 0x27, 0x61, 0x26, 0xf9, 0xa1, 0xb7, -0xf6, 0x90, 0x12, 0xb6, 0xc4, 0x1d, 0xd4, 0x81, -0x65, 0xed, 0xc4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x3d, 0x01, 0x22, 0x21, 0x48, 0x58, 0x72, -0x71, 0x41, 0x86, 0xe9, 0x7e, 0x75, 0x02, 0x6c, -0x30, 0x0f, 0xae, 0x8d, 0x15, 0xb3, 0xb4, 0x1c, -0xae, 0x89, 0x29, 0x2a, 0x11, 0xcf, 0x94, 0x0d, -0x31, 0x80, 0xfd, 0x5b, 0xb1, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0xbf, -0xb7, 0xd3, 0xa9, 0xb1, 0x5e, 0xc3, 0x89, 0xa6, -0xb1, 0xcb, 0x72, 0x8f, 0xd5, 0x16, 0xb1, 0x9a, -0x2f, 0xe5, 0x34, 0x64, 0x33, 0x12, 0x75, 0xd8, -0xfb, 0xf1, 0xda, 0xea, 0x49, 0xe0, 0x9e, 0x00, +0x21, 0x21, 0xf9, 0xc6, 0x2e, 0x0e, 0xbc, 0xe2, +0x06, 0x09, 0x66, 0x06, 0x2b, 0x07, 0x3d, 0x27, +0x0a, 0xff, 0x2a, 0xaa, 0x92, 0x16, 0xe3, 0xd4, +0x5c, 0x3d, 0x70, 0x27, 0x6f, 0x86, 0x04, 0xf9, +0x26, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3c, +0x01, 0x22, 0x21, 0x07, 0x75, 0x4c, 0x0a, 0x08, +0xa9, 0xbd, 0xff, 0x99, 0xf1, 0xee, 0x1a, 0x5b, +0xae, 0x0e, 0x33, 0x41, 0x3d, 0xd6, 0x1a, 0x6f, +0x76, 0x67, 0xdb, 0x42, 0xbd, 0x7a, 0x21, 0x4f, +0xdb, 0xff, 0xac, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x3d, 0x01, 0x22, 0x21, 0x71, 0xc7, 0x61, +0xe2, 0x33, 0x5a, 0xd3, 0x45, 0x61, 0x1c, 0xf5, +0xe3, 0x1a, 0x2d, 0xd4, 0x37, 0xbc, 0xd2, 0x36, +0x17, 0xb1, 0xaf, 0x4e, 0x82, 0xd2, 0x7c, 0xed, +0xeb, 0xb4, 0xed, 0x15, 0xc1, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x3e, 0x01, 0x22, 0x21, 0x00, +0x07, 0xea, 0x47, 0x5f, 0x56, 0xce, 0x45, 0x49, +0xe6, 0x7f, 0x53, 0x54, 0xf5, 0x5e, 0x0a, 0xd6, +0x66, 0x98, 0xe1, 0x28, 0xe0, 0x9c, 0xd1, 0x9b, +0x60, 0xec, 0x70, 0xef, 0xa7, 0xe8, 0x83, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x3f, 0x01, 0x22, -0x21, 0x7d, 0xdc, 0xa1, 0x89, 0x00, 0x9c, 0x18, -0x4e, 0x8d, 0x40, 0x5a, 0xdd, 0x42, 0xce, 0xc6, -0x05, 0x6f, 0x88, 0x98, 0x16, 0xeb, 0x60, 0xbb, -0xb4, 0xa7, 0x8b, 0xcc, 0xfb, 0xe5, 0x06, 0x79, -0xe3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, -0x01, 0x22, 0x21, 0x9c, 0x41, 0x89, 0x70, 0x48, -0x1c, 0x03, 0xcf, 0x3b, 0xc5, 0x09, 0xdf, 0xe7, -0xef, 0x60, 0x35, 0xea, 0x19, 0x24, 0x0c, 0x67, -0xa7, 0x8e, 0x86, 0x0a, 0xdc, 0x88, 0x21, 0x84, -0xc4, 0x07, 0x0d, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x41, 0x01, 0x22, 0x21, 0xd7, 0xfb, 0x28, -0x62, 0xaa, 0xcf, 0xd7, 0xdb, 0x0b, 0x4d, 0xea, -0x2d, 0x1d, 0x37, 0x21, 0x48, 0x51, 0x7e, 0x7a, -0xca, 0x74, 0xd6, 0x0b, 0x66, 0x1f, 0x23, 0x20, -0x50, 0xcc, 0xa7, 0xce, 0x6d, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0xed, -0xe7, 0xd7, 0x02, 0x70, 0xc3, 0x0c, 0xb2, 0xe8, -0xab, 0x23, 0x83, 0x06, 0x6f, 0x7c, 0x6a, 0x52, -0xc2, 0xcc, 0x41, 0x25, 0xc6, 0x6b, 0x07, 0xbe, -0x72, 0xbc, 0xeb, 0x18, 0xb7, 0x2f, 0x7e, 0x00, +0x21, 0x60, 0xa2, 0x29, 0xac, 0xc3, 0xed, 0xf5, +0x9d, 0x3e, 0xa9, 0x66, 0xf1, 0x5f, 0x22, 0xe1, +0xaa, 0x3d, 0x6c, 0x74, 0x36, 0x74, 0x5b, 0xf8, +0xab, 0x13, 0x10, 0x27, 0x8f, 0xa6, 0x02, 0x7f, +0xa7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x40, +0x01, 0x22, 0x21, 0xd0, 0xff, 0x54, 0x64, 0xd2, +0x1f, 0x29, 0x6d, 0x6c, 0xaf, 0x7c, 0x0d, 0x70, +0xc9, 0xc5, 0xae, 0xaf, 0xac, 0xff, 0x3a, 0x07, +0xcd, 0x47, 0x05, 0x5e, 0x63, 0xfa, 0xd5, 0x4c, +0x76, 0xc4, 0xae, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x41, 0x01, 0x22, 0x21, 0x80, 0x87, 0xbb, +0x2d, 0x3c, 0xdf, 0x21, 0x44, 0x0e, 0x36, 0x00, +0xf5, 0xd6, 0xa3, 0x1c, 0xb4, 0x18, 0xc1, 0x2e, +0x96, 0x8d, 0xa2, 0x16, 0x1a, 0xf3, 0x07, 0x3b, +0x49, 0xc4, 0x70, 0xae, 0x53, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x42, 0x01, 0x22, 0x21, 0x7e, +0x84, 0x55, 0xe3, 0xac, 0xd0, 0x3d, 0xee, 0x92, +0x30, 0xc8, 0xdd, 0x06, 0xb1, 0xb5, 0xf9, 0x76, +0x6e, 0x27, 0x62, 0xd3, 0x22, 0x62, 0xe9, 0x00, +0x4d, 0x2b, 0x99, 0x94, 0x29, 0x04, 0x6e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x43, 0x01, 0x22, -0x21, 0xb1, 0x7f, 0xf3, 0xa6, 0xac, 0x0a, 0xca, -0x7f, 0xab, 0x04, 0x9d, 0x82, 0x1b, 0x1b, 0xe3, -0x6b, 0x1d, 0xba, 0x34, 0x8b, 0xb3, 0xd5, 0x19, -0x64, 0xaf, 0xa6, 0x21, 0xb5, 0x7f, 0xed, 0x44, -0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, -0x01, 0x22, 0x21, 0xa8, 0x98, 0xb0, 0x07, 0xa4, -0x58, 0x1d, 0x12, 0x6a, 0x26, 0x21, 0x46, 0xd5, -0x3d, 0x1d, 0xa2, 0xab, 0x8c, 0xca, 0x22, 0xdc, -0x2b, 0x33, 0x74, 0x9f, 0x8e, 0x1f, 0x6a, 0xfa, -0xdb, 0x88, 0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x45, 0x01, 0x22, 0x21, 0xea, 0xb3, 0x63, -0xcf, 0xd3, 0x53, 0x31, 0x38, 0x61, 0x96, 0x88, -0xb9, 0x74, 0x37, 0xd3, 0x50, 0xf1, 0x40, 0x8b, -0x20, 0xdb, 0xbf, 0x63, 0x36, 0x4c, 0xe5, 0x82, -0xe1, 0xe5, 0xfe, 0x21, 0x1f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0xc6, -0xfb, 0x8a, 0x62, 0x88, 0xf9, 0xb8, 0xb0, 0xa7, -0x61, 0x2d, 0x72, 0xe0, 0x0b, 0xee, 0x7f, 0x65, -0xdb, 0x58, 0xaf, 0x7d, 0x66, 0x39, 0xae, 0x61, -0xcd, 0xa9, 0x1c, 0x0c, 0x28, 0x24, 0x43, 0x00, +0x21, 0xf2, 0xb9, 0x20, 0xed, 0x8e, 0xca, 0x5c, +0xea, 0x74, 0x3b, 0x8b, 0xcd, 0x75, 0xf5, 0x7a, +0x3b, 0x9e, 0x62, 0x2f, 0xde, 0xe6, 0x4e, 0x55, +0xa5, 0x2d, 0x74, 0x4a, 0x28, 0x45, 0xc8, 0x9b, +0x6f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x44, +0x01, 0x22, 0x21, 0x9d, 0xc1, 0xa6, 0x53, 0x2f, +0x71, 0x9d, 0xe4, 0xa5, 0xa0, 0x8b, 0x95, 0xa5, +0x71, 0x6d, 0x93, 0x3b, 0x8d, 0x48, 0xcc, 0x19, +0x45, 0xfa, 0x82, 0xad, 0xd4, 0xd4, 0xfc, 0x54, +0x7c, 0x2d, 0xa9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x45, 0x01, 0x22, 0x21, 0xf9, 0x30, 0xc9, +0x0c, 0x68, 0x8d, 0x86, 0xb8, 0xc6, 0x57, 0x62, +0x1d, 0x5e, 0x3b, 0x91, 0xa5, 0x0a, 0x99, 0x32, +0xf5, 0x3d, 0xdd, 0x3e, 0x0b, 0xc5, 0x0c, 0x59, +0x9b, 0x30, 0xbd, 0x65, 0x1e, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x46, 0x01, 0x22, 0x21, 0x3e, +0xf1, 0x17, 0xf9, 0x33, 0x34, 0xa6, 0x26, 0x7a, +0x02, 0x16, 0xdb, 0x8b, 0x47, 0xb3, 0x8b, 0xd6, +0xbd, 0xc1, 0xf5, 0x13, 0x68, 0xff, 0xd7, 0xb3, +0x68, 0x39, 0x61, 0x64, 0x39, 0x42, 0x60, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x47, 0x01, 0x22, -0x21, 0xac, 0x36, 0x92, 0xf1, 0x70, 0x5f, 0xd3, -0xd1, 0x44, 0xd3, 0x64, 0x12, 0x46, 0x67, 0xa9, -0x4f, 0x43, 0x5f, 0x09, 0xc6, 0xd5, 0xac, 0xd8, -0xf6, 0x8b, 0x08, 0x2a, 0x84, 0x22, 0xf9, 0x56, -0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, -0x01, 0x22, 0x21, 0xd6, 0x8a, 0xe6, 0xca, 0x66, -0xde, 0xfa, 0xc3, 0x96, 0x53, 0xde, 0x72, 0xc9, -0xf7, 0xce, 0x0a, 0xc6, 0x63, 0x33, 0x8e, 0x24, -0x5c, 0x1d, 0x02, 0x76, 0x6b, 0xda, 0x3c, 0xec, -0xae, 0xe4, 0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x49, 0x01, 0x22, 0x21, 0xe0, 0x0d, 0xaf, -0xd4, 0x81, 0xa1, 0x6b, 0xf0, 0x1b, 0x05, 0x19, -0x60, 0x63, 0xb5, 0x4a, 0x40, 0x66, 0xf4, 0x08, -0x91, 0x8c, 0x66, 0x15, 0xe6, 0x9b, 0x15, 0xd5, -0x36, 0xcd, 0x13, 0x4b, 0xc3, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0x78, -0x78, 0x11, 0xcf, 0x46, 0x50, 0x8c, 0x9b, 0x63, -0x02, 0xd0, 0xcb, 0x05, 0x86, 0x56, 0x87, 0x69, -0xf4, 0x23, 0x5a, 0xb5, 0x2d, 0x27, 0xc4, 0x44, -0x7b, 0x6d, 0xc3, 0xf6, 0x8a, 0x81, 0x90, 0x00, +0x21, 0xc1, 0x9e, 0xf5, 0xd3, 0xb5, 0x44, 0xff, +0x67, 0x4d, 0x81, 0x91, 0x69, 0x3d, 0xdb, 0x0c, +0xe4, 0x58, 0xd4, 0x08, 0xaa, 0x62, 0x6b, 0xf5, +0x51, 0x87, 0x75, 0xfd, 0x16, 0x01, 0xbb, 0x0c, +0x8c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x48, +0x01, 0x22, 0x21, 0x27, 0xc4, 0xf3, 0xbf, 0x4d, +0x65, 0x71, 0xd6, 0x52, 0x02, 0xb0, 0x43, 0xea, +0x95, 0xbc, 0x6a, 0x29, 0x42, 0x1a, 0x44, 0xd1, +0xb8, 0x5e, 0xd0, 0x1b, 0x90, 0x69, 0xe9, 0xee, +0xaa, 0xc0, 0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x49, 0x01, 0x22, 0x21, 0x57, 0x70, 0x37, +0x05, 0x8f, 0x87, 0xd0, 0xa5, 0x0b, 0x9a, 0x36, +0xf5, 0x0f, 0x03, 0x11, 0x8f, 0xb8, 0x64, 0x02, +0xb3, 0x04, 0x3b, 0xb4, 0x68, 0xc7, 0x9d, 0xc3, +0xc5, 0x25, 0x1a, 0x06, 0x94, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4a, 0x01, 0x22, 0x21, 0xd6, +0xbc, 0xed, 0x42, 0xc2, 0x07, 0xbf, 0xbc, 0x8b, +0x8e, 0x77, 0x68, 0xae, 0x37, 0x10, 0xd3, 0xd2, +0xf6, 0x1f, 0xe1, 0x7d, 0x82, 0xdf, 0x7e, 0x0e, +0xad, 0x00, 0xbf, 0x6e, 0x80, 0xed, 0x57, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4b, 0x01, 0x22, -0x21, 0xb5, 0xb7, 0x76, 0xe8, 0x0c, 0x40, 0xa8, -0xa9, 0x60, 0xb4, 0xd2, 0x8c, 0xb1, 0xab, 0x91, -0x6d, 0x60, 0xd0, 0x79, 0xd8, 0x1a, 0xd8, 0x33, -0xcc, 0xbd, 0xb1, 0x5b, 0x7a, 0x25, 0x17, 0xa6, -0xb2, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, -0x01, 0x22, 0x21, 0xad, 0x6d, 0x6b, 0x7b, 0x21, -0xc3, 0xdc, 0xf2, 0x94, 0xd0, 0x14, 0x37, 0x6e, -0x41, 0x8a, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1e, 0x71, 0xf4, 0xca, -0x5c, 0x71, 0x9b, 0xa4, 0x03, 0x04, 0x51, 0x02, -0x00, 0x4d, 0x01, 0x22, 0x21, 0xe2, 0xcd, 0x56, -0xb7, 0x4f, 0xc2, 0xd4, 0xc8, 0x12, 0x02, 0x75, -0x10, 0xc2, 0x26, 0x36, 0x09, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xdd, -0x36, 0x0f, 0x1b, 0x1c, 0x06, 0x3b, 0x03, 0x04, -0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x6c, -0x3b, 0x05, 0x80, 0x97, 0x81, 0x37, 0x2a, 0xf9, -0x36, 0xda, 0x2e, 0xee, 0x9d, 0xb7, 0x62, 0x12, -0x12, 0xcc, 0xd4, 0xb1, 0x2c, 0x30, 0x68, 0xa2, -0xfd, 0x7b, 0x13, 0x6a, 0xfb, 0x1a, 0xaa, 0x00, +0x21, 0xc7, 0xa8, 0x66, 0x46, 0xd2, 0x1e, 0x77, +0x0e, 0x37, 0xd3, 0x52, 0x4a, 0x43, 0xe9, 0xd6, +0x3a, 0x26, 0xe3, 0x87, 0xa5, 0x60, 0x59, 0xb2, +0x74, 0xcb, 0xee, 0xb6, 0x65, 0x22, 0xe8, 0x1d, +0x98, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4c, +0x01, 0x22, 0x21, 0x08, 0x4f, 0x80, 0x2e, 0x69, +0x4b, 0xf6, 0x3a, 0x06, 0xb8, 0xe7, 0x1f, 0x50, +0x43, 0xd5, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x95, 0xf0, 0x81, 0xb4, +0xaf, 0xfc, 0x7e, 0x7b, 0x03, 0x04, 0x51, 0x02, +0x00, 0x4d, 0x01, 0x22, 0x21, 0xda, 0xe3, 0xaf, +0x75, 0x0c, 0x21, 0x9f, 0x2d, 0x21, 0x36, 0xf9, +0x95, 0x6e, 0xe6, 0x7a, 0xb9, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2a, +0x29, 0x08, 0x52, 0xf9, 0xe0, 0xde, 0x03, 0x04, +0x51, 0x02, 0x00, 0x4e, 0x01, 0x22, 0x21, 0x62, +0xd1, 0x13, 0x0f, 0x6b, 0xde, 0x90, 0xc1, 0x02, +0x9b, 0x2b, 0x3c, 0x18, 0xd8, 0x44, 0xf7, 0xd8, +0x2e, 0x43, 0x9c, 0xfc, 0x89, 0xa9, 0x7e, 0xdc, +0x97, 0x0d, 0x71, 0x18, 0xd7, 0x3b, 0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x4f, 0x01, 0x22, -0x21, 0xf4, 0x03, 0x2c, 0x39, 0x8d, 0x2a, 0xa1, -0xdd, 0x2a, 0x28, 0xc1, 0xa0, 0x59, 0x25, 0x1b, -0xee, 0x42, 0x8c, 0x7e, 0xae, 0x83, 0x10, 0x86, -0x9f, 0xe4, 0x39, 0x9f, 0x5b, 0x98, 0x01, 0x5d, -0xee, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, -0x01, 0x22, 0x21, 0xd6, 0x53, 0xe0, 0x9f, 0xd2, -0x92, 0x36, 0x47, 0x89, 0xb7, 0xa8, 0xee, 0xd5, -0x83, 0x4a, 0x52, 0x61, 0xe5, 0xf2, 0x6f, 0xcc, -0x9c, 0x25, 0x10, 0x1b, 0x87, 0x81, 0x91, 0xce, -0xb5, 0x79, 0x68, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x51, 0x01, 0x22, 0x21, 0xa2, 0x1f, 0x1e, -0x22, 0x17, 0x83, 0x20, 0x1e, 0xf8, 0x28, 0x90, -0x71, 0x0f, 0x6f, 0x22, 0x5c, 0x69, 0xe9, 0xcc, -0x57, 0x94, 0x11, 0x23, 0xd7, 0x90, 0xcc, 0x12, -0x4f, 0x95, 0x3b, 0x72, 0x50, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0x9e, -0x94, 0xd1, 0x6d, 0x3d, 0xea, 0xe1, 0x63, 0x20, -0x32, 0x09, 0x97, 0xe8, 0x8e, 0x7b, 0xba, 0x38, -0xcb, 0xfa, 0x3b, 0xd2, 0x6b, 0x68, 0x3a, 0xde, -0xc9, 0x08, 0x12, 0x3e, 0xa0, 0x8d, 0xe5, 0x00, +0x21, 0xa9, 0xcf, 0x77, 0x56, 0x00, 0xc7, 0x02, +0x43, 0x1a, 0x6b, 0x44, 0x30, 0x77, 0xfe, 0xa0, +0x03, 0xe3, 0xcf, 0x27, 0xe8, 0x28, 0xe4, 0xd6, +0xbb, 0x15, 0x0f, 0x10, 0xb7, 0x5c, 0xfc, 0x83, +0x35, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x50, +0x01, 0x22, 0x21, 0x07, 0xf6, 0x51, 0x6d, 0x78, +0x79, 0x11, 0xf7, 0x35, 0xa3, 0x43, 0xb7, 0x82, +0xf2, 0x71, 0x98, 0xf0, 0x32, 0xd9, 0x2a, 0xf4, +0x9b, 0x9a, 0x3b, 0xc7, 0x91, 0x28, 0xb4, 0x32, +0xd6, 0xe1, 0xdc, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x51, 0x01, 0x22, 0x21, 0x15, 0x6d, 0xaa, +0x12, 0x8e, 0x0e, 0x46, 0x08, 0x4d, 0x90, 0xe2, +0x1b, 0xb4, 0xa7, 0x70, 0xb8, 0xd9, 0x36, 0x71, +0x77, 0x88, 0x07, 0x8f, 0x34, 0xb3, 0x14, 0x74, +0xda, 0xb7, 0x9c, 0x84, 0x4d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x52, 0x01, 0x22, 0x21, 0x85, +0xb4, 0xb9, 0xca, 0xf9, 0x57, 0xb8, 0x0c, 0xd9, +0x0e, 0xb9, 0x59, 0xd9, 0xbf, 0xe8, 0x57, 0xad, +0x33, 0xaf, 0x08, 0x91, 0x97, 0xa3, 0x17, 0x39, +0x80, 0x08, 0xfc, 0xe0, 0x41, 0x62, 0xec, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x53, 0x01, 0x22, -0x21, 0x39, 0xa3, 0x74, 0x4e, 0x03, 0xb1, 0x48, -0x0f, 0xb0, 0xab, 0xab, 0x3c, 0x6a, 0xa2, 0x1f, -0x2c, 0x72, 0x14, 0xa1, 0xf4, 0x96, 0x5b, 0xfb, -0x1e, 0xbf, 0x6d, 0xb6, 0xc1, 0x79, 0x7b, 0x3e, -0x21, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, -0x01, 0x22, 0x21, 0x08, 0x59, 0x91, 0x9f, 0xed, -0xbb, 0x07, 0xbe, 0x20, 0xea, 0x39, 0x97, 0xbf, -0xc7, 0xae, 0x66, 0x72, 0xc3, 0x0d, 0x43, 0x88, -0x8c, 0xd5, 0x44, 0x41, 0x22, 0x56, 0x9f, 0x10, -0x83, 0xd6, 0xb4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x55, 0x01, 0x22, 0x21, 0xe7, 0x96, 0x2b, -0x0c, 0xb0, 0x09, 0x0d, 0x09, 0x9c, 0x56, 0x32, -0x72, 0xd5, 0xb1, 0x74, 0x3c, 0x94, 0xbd, 0x74, -0x10, 0x82, 0x25, 0x47, 0xa1, 0x80, 0x00, 0x8d, -0xb1, 0x3a, 0x6c, 0xe2, 0x8c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0x84, -0x44, 0xe3, 0xd3, 0xdb, 0xd2, 0xee, 0xe5, 0xcb, -0x59, 0x7b, 0x02, 0x86, 0x9f, 0x60, 0x10, 0x9e, -0xb8, 0x6c, 0xff, 0x6d, 0x21, 0xc7, 0x35, 0x17, -0x21, 0xe1, 0xaf, 0x13, 0x67, 0xff, 0x56, 0x00, +0x21, 0x60, 0x98, 0x25, 0x5c, 0x09, 0x60, 0x03, +0x7b, 0xda, 0xfb, 0x7f, 0x19, 0x57, 0x08, 0xa4, +0xe6, 0xda, 0x3d, 0x01, 0x66, 0xff, 0x4c, 0xbe, +0xf0, 0xa3, 0x1f, 0x95, 0x7a, 0xdc, 0x8e, 0x17, +0x0c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x54, +0x01, 0x22, 0x21, 0xcb, 0x69, 0xf0, 0x2d, 0xb2, +0xe6, 0x01, 0xc2, 0xc4, 0x20, 0xd5, 0x48, 0x0d, +0x65, 0xfb, 0xb3, 0x36, 0x89, 0x56, 0xc2, 0xf9, +0x43, 0x1b, 0x86, 0xbf, 0xba, 0xd4, 0x35, 0xf7, +0x62, 0x51, 0xbf, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x55, 0x01, 0x22, 0x21, 0x92, 0xa1, 0x29, +0x08, 0x7b, 0x02, 0xd7, 0xe1, 0xbd, 0x65, 0x3c, +0x84, 0x2e, 0xcc, 0x33, 0x55, 0x56, 0xf7, 0x52, +0xef, 0x1a, 0x4b, 0x9e, 0xb7, 0xd5, 0x86, 0x6d, +0x63, 0xad, 0xdb, 0x3e, 0x28, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x56, 0x01, 0x22, 0x21, 0xd8, +0x73, 0xb6, 0x86, 0xa3, 0x7b, 0xea, 0xa8, 0xba, +0xd9, 0x46, 0x64, 0x7c, 0x0f, 0x8d, 0xfc, 0xca, +0x3b, 0x4f, 0x9a, 0xfc, 0xa9, 0xc5, 0x6a, 0x8f, +0x71, 0xd1, 0x15, 0x27, 0x27, 0x81, 0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x57, 0x01, 0x22, -0x21, 0xd1, 0x0a, 0xb5, 0x5d, 0x3e, 0x00, 0xa4, -0xdb, 0x4a, 0x7d, 0xb3, 0xa8, 0xfc, 0xd4, 0x2b, -0x8b, 0xbb, 0x31, 0xad, 0x9c, 0xb4, 0x69, 0x86, -0x9e, 0xe1, 0x8a, 0x8a, 0xba, 0xc0, 0x4f, 0x5f, -0x78, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, -0x01, 0x22, 0x21, 0xd5, 0x49, 0xe4, 0x97, 0x4c, -0x43, 0x92, 0x0b, 0xc3, 0x25, 0xae, 0x9f, 0x96, -0x95, 0xd2, 0x39, 0x6b, 0xdf, 0x9a, 0x7e, 0x17, -0xad, 0x58, 0x75, 0x12, 0xec, 0x14, 0x1c, 0xd2, -0xd6, 0xa2, 0x66, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x59, 0x01, 0x22, 0x21, 0x44, 0x17, 0xe0, -0xc9, 0x70, 0x5d, 0x3b, 0x95, 0x90, 0x28, 0x94, -0x36, 0x31, 0x8b, 0xe6, 0x9d, 0xb4, 0x65, 0xfb, -0x26, 0xd6, 0x42, 0xc3, 0x47, 0xd7, 0x16, 0x40, -0x32, 0xf8, 0xf9, 0x1b, 0x40, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0x6e, -0x10, 0x9f, 0x35, 0x39, 0xc6, 0x2d, 0x7f, 0x97, -0x52, 0x15, 0x80, 0x1d, 0x70, 0xe4, 0x9d, 0x6a, -0xe0, 0x4f, 0x7b, 0xe0, 0xa0, 0x9b, 0x41, 0xf7, -0x80, 0x08, 0xf9, 0xcc, 0xf7, 0x94, 0x1d, 0x00, +0x21, 0x49, 0x3f, 0x87, 0x71, 0xad, 0xe9, 0xc2, +0xf5, 0x45, 0x37, 0x45, 0x5e, 0x04, 0xab, 0x4d, +0x87, 0xd1, 0x44, 0xed, 0x27, 0xad, 0xb7, 0x0d, +0xaf, 0xb2, 0x46, 0x43, 0x3b, 0x28, 0x34, 0x72, +0x1b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x58, +0x01, 0x22, 0x21, 0xe9, 0x7a, 0xde, 0x9f, 0x95, +0x5d, 0xb8, 0x22, 0x2c, 0x83, 0x1b, 0x49, 0x43, +0xf0, 0x21, 0x7a, 0xac, 0x80, 0x90, 0xda, 0xaf, +0x6a, 0xd1, 0x6d, 0x20, 0x70, 0xa9, 0x43, 0x52, +0x40, 0x5c, 0xf8, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x59, 0x01, 0x22, 0x21, 0xd9, 0x22, 0xeb, +0xc2, 0xc8, 0x7c, 0x80, 0x93, 0x0f, 0x3c, 0x6c, +0xf9, 0xf8, 0xfb, 0x25, 0xd9, 0x28, 0xa3, 0x1e, +0xbe, 0xab, 0xee, 0x39, 0x9d, 0x85, 0xaa, 0x83, +0x69, 0x12, 0x9f, 0xbe, 0x51, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5a, 0x01, 0x22, 0x21, 0xbf, +0x74, 0xfd, 0x75, 0x65, 0xa6, 0x14, 0x68, 0x94, +0xa6, 0x32, 0x69, 0xb6, 0xd5, 0xda, 0xd5, 0xd2, +0xe5, 0xd5, 0xfb, 0xe2, 0xe2, 0x7e, 0xa2, 0x32, +0x17, 0xd3, 0x96, 0x65, 0xaa, 0xad, 0xd3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5b, 0x01, 0x22, -0x21, 0x72, 0xb8, 0x0a, 0x57, 0xf5, 0xab, 0xca, -0x01, 0x3b, 0xab, 0xa4, 0xd7, 0x63, 0x3a, 0xd8, -0xd6, 0xa4, 0x6e, 0xad, 0x2b, 0x51, 0x8f, 0xa4, -0x0f, 0x2f, 0x72, 0x8d, 0x2e, 0xea, 0x20, 0x07, -0xbe, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, -0x01, 0x22, 0x21, 0x04, 0x1e, 0x66, 0xd2, 0x00, -0xd9, 0x2c, 0xfa, 0x9f, 0xe1, 0x44, 0x02, 0x22, -0x1e, 0xde, 0x72, 0x5e, 0xb2, 0x63, 0xef, 0xe2, -0x29, 0x9b, 0xbc, 0x29, 0xac, 0xd7, 0x2b, 0x9d, -0x49, 0xf3, 0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x5d, 0x01, 0x22, 0x21, 0xe5, 0x21, 0x7a, -0x80, 0x3a, 0x2d, 0x12, 0xbb, 0x53, 0xee, 0xc0, -0xc4, 0xbc, 0xab, 0x2c, 0xe3, 0x80, 0x35, 0x34, -0xb8, 0x96, 0x69, 0x8f, 0xd7, 0x21, 0x06, 0xee, -0xe2, 0x16, 0x2c, 0x76, 0xe7, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0xa5, -0x3c, 0x39, 0x60, 0x9d, 0xbf, 0xb2, 0x3c, 0xb9, -0x00, 0x2f, 0x42, 0x7f, 0x39, 0xdf, 0xf3, 0x84, -0x7c, 0xcf, 0xcd, 0x52, 0x7d, 0x4b, 0x39, 0x1e, -0x58, 0x7d, 0x85, 0xfc, 0xc0, 0xba, 0xed, 0x00, +0x21, 0x93, 0xd5, 0x4a, 0xc4, 0x45, 0xaf, 0xca, +0x84, 0x75, 0x06, 0xcf, 0x81, 0x11, 0x37, 0xe3, +0x4f, 0x14, 0xa7, 0xa1, 0x9f, 0x6f, 0x8b, 0xf9, +0xa6, 0xd2, 0x25, 0xb3, 0xf3, 0x52, 0x30, 0xe8, +0xd4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5c, +0x01, 0x22, 0x21, 0x11, 0xb4, 0x3b, 0x71, 0xb5, +0xc7, 0x0d, 0xee, 0x46, 0xdb, 0xd7, 0xa3, 0x8d, +0xce, 0xeb, 0x36, 0x20, 0xfa, 0x56, 0x8c, 0x9e, +0xb8, 0x89, 0xea, 0xa7, 0x7e, 0x51, 0x3e, 0x53, +0x92, 0x6a, 0x42, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x5d, 0x01, 0x22, 0x21, 0x12, 0x27, 0x52, +0x34, 0x71, 0xb0, 0x7f, 0xb2, 0x86, 0x88, 0xf9, +0x52, 0x2e, 0x55, 0x33, 0xc1, 0x28, 0x40, 0xdd, +0x0e, 0xf0, 0x9b, 0xa6, 0x92, 0x32, 0xf9, 0x72, +0xb5, 0x27, 0x75, 0x3c, 0x37, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x5e, 0x01, 0x22, 0x21, 0x6e, +0xdb, 0xe7, 0xf5, 0xf1, 0xb0, 0x04, 0x8d, 0xfd, +0x7b, 0x15, 0x65, 0xf1, 0x3f, 0xde, 0x19, 0xe7, +0xe6, 0x69, 0xae, 0x8c, 0xb6, 0x75, 0x08, 0x1b, +0x6c, 0xc1, 0x8c, 0x57, 0x32, 0x9a, 0xdf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x5f, 0x01, 0x22, -0x21, 0x7c, 0x8f, 0x83, 0xed, 0x32, 0x97, 0x55, -0x24, 0xab, 0xaf, 0x8d, 0xae, 0x47, 0x86, 0x80, -0xcf, 0x6c, 0x6b, 0xd5, 0x47, 0x81, 0x4b, 0xf9, -0xc6, 0x63, 0x52, 0xae, 0xa6, 0x6a, 0x98, 0x60, -0xd7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, -0x01, 0x22, 0x21, 0xca, 0xe3, 0xad, 0xe2, 0x4b, -0xf0, 0xeb, 0xe6, 0x6a, 0xce, 0x51, 0x5a, 0x1b, -0x46, 0x91, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x54, 0x91, 0x65, 0x5f, -0x28, 0x06, 0x02, 0x70, 0x03, 0x04, 0x51, 0x02, -0x00, 0x61, 0x01, 0x22, 0x21, 0xda, 0x7e, 0x83, -0x67, 0xf7, 0x6e, 0x1d, 0x90, 0xf0, 0xce, 0x35, -0xa9, 0x3e, 0x7e, 0x64, 0xc1, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xbc, -0x39, 0x10, 0x5f, 0x90, 0x59, 0x18, 0x03, 0x04, -0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0xdb, -0x52, 0xa1, 0x09, 0x0d, 0xac, 0x97, 0xe4, 0x11, -0x38, 0x5e, 0x04, 0x82, 0x86, 0xf1, 0x6d, 0x4f, -0x1e, 0xb8, 0x07, 0xeb, 0x6a, 0x50, 0xc0, 0x73, -0xee, 0x5d, 0xee, 0xb5, 0x51, 0xaa, 0xf8, 0x00, +0x21, 0xff, 0xff, 0x6d, 0x9c, 0x12, 0x4a, 0x6e, +0xa7, 0x6c, 0x03, 0xd0, 0xf1, 0x99, 0x67, 0x5d, +0x0c, 0xfd, 0x41, 0xa4, 0x49, 0xf0, 0x1d, 0x8a, +0x58, 0xf1, 0x1b, 0x05, 0x51, 0x36, 0x64, 0x8c, +0x70, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x60, +0x01, 0x22, 0x21, 0x69, 0x52, 0x64, 0x6b, 0x55, +0xc8, 0x4a, 0x4d, 0x57, 0x1c, 0xb6, 0x74, 0xd7, +0xb6, 0xd6, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x79, 0xe5, 0x68, 0x0f, +0xde, 0xcb, 0xc5, 0x17, 0x03, 0x04, 0x51, 0x02, +0x00, 0x61, 0x01, 0x22, 0x21, 0x27, 0xa1, 0x0d, +0xde, 0xf2, 0x14, 0xa6, 0xd0, 0x6e, 0x84, 0x51, +0xbf, 0xd7, 0x89, 0xc2, 0xf6, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xdf, +0xb1, 0xb6, 0x5e, 0x5b, 0xfe, 0x8f, 0x03, 0x04, +0x51, 0x02, 0x00, 0x62, 0x01, 0x22, 0x21, 0x20, +0x2d, 0x46, 0xbe, 0x1b, 0xbc, 0xd0, 0x4e, 0xb3, +0xb2, 0x10, 0x88, 0x62, 0xc7, 0x0b, 0x53, 0x2b, +0xc4, 0x48, 0x60, 0xe4, 0x7a, 0xb2, 0xa0, 0xbe, +0x5f, 0xf5, 0x0a, 0x6e, 0x4e, 0x19, 0xe1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x63, 0x01, 0x22, -0x21, 0xbf, 0xed, 0x62, 0x68, 0x9b, 0x7e, 0x7a, -0x4a, 0x7e, 0x98, 0x6a, 0xb8, 0x5e, 0x17, 0x85, -0xb7, 0x08, 0x3c, 0x0a, 0x18, 0xdc, 0xc0, 0x05, -0x83, 0x09, 0x97, 0x68, 0x64, 0x1d, 0x57, 0x64, -0x01, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, -0x01, 0x22, 0x21, 0x7d, 0xd1, 0x45, 0x79, 0xc0, -0x9b, 0x62, 0x22, 0x83, 0x61, 0xa1, 0xfc, 0x85, -0x26, 0xbb, 0x3a, 0x7b, 0xe0, 0x0e, 0xd6, 0x01, -0xd8, 0x28, 0xbd, 0x1c, 0x83, 0xa2, 0x8e, 0x50, -0x63, 0x6a, 0xb4, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x65, 0x01, 0x22, 0x21, 0xcc, 0xf8, 0x04, -0x14, 0x28, 0x8e, 0x60, 0x9b, 0xae, 0x98, 0xb6, -0xb6, 0x40, 0xe1, 0xc4, 0xed, 0x26, 0x04, 0x9e, -0x72, 0xba, 0x3a, 0xd9, 0xd8, 0x21, 0xb1, 0xdb, -0x91, 0x28, 0xdf, 0x25, 0x46, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0xad, -0xed, 0x67, 0x2e, 0x4f, 0x27, 0x4c, 0x98, 0x58, -0x39, 0x55, 0xa3, 0xf9, 0x4f, 0x74, 0xb1, 0x5f, -0x63, 0x4b, 0xc5, 0xd2, 0xf4, 0x4b, 0x7c, 0xa0, -0xfa, 0x5c, 0x0e, 0x9c, 0x41, 0x1e, 0xac, 0x00, +0x21, 0xf7, 0x63, 0x6d, 0x95, 0xcb, 0x79, 0xcd, +0x87, 0x87, 0x0e, 0xb6, 0x2e, 0x5d, 0xd1, 0xc5, +0x29, 0xb3, 0xc8, 0xed, 0x84, 0xe3, 0x37, 0x35, +0x6b, 0x3d, 0xcf, 0xe4, 0x98, 0x22, 0x93, 0x69, +0x66, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x64, +0x01, 0x22, 0x21, 0x1e, 0xe0, 0x6c, 0x59, 0x80, +0xdf, 0x20, 0xbe, 0x22, 0xf3, 0x22, 0x8d, 0x6e, +0xf5, 0xa3, 0x5c, 0xea, 0x3a, 0x75, 0x10, 0xf2, +0xb9, 0xd5, 0x01, 0x3e, 0x1b, 0x12, 0xd5, 0xa0, +0xef, 0x87, 0x6e, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x65, 0x01, 0x22, 0x21, 0xab, 0x75, 0xf3, +0xb3, 0x4f, 0x9b, 0x7b, 0x91, 0x45, 0xa2, 0xda, +0x87, 0xe6, 0x9b, 0x32, 0xee, 0x59, 0x82, 0x6a, +0xc2, 0x34, 0x5d, 0x4c, 0xda, 0x6e, 0x8b, 0x06, +0x2e, 0x4d, 0x39, 0xfa, 0x7b, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x66, 0x01, 0x22, 0x21, 0xf1, +0x38, 0xdc, 0xb6, 0xed, 0xcb, 0xcf, 0x7d, 0xed, +0x6e, 0x7c, 0x2f, 0xdc, 0x14, 0xcf, 0xa5, 0xd4, +0x35, 0xc3, 0x6e, 0xc2, 0x25, 0x76, 0xc0, 0xa4, +0x32, 0x7d, 0x6b, 0xf6, 0xb0, 0x27, 0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x67, 0x01, 0x22, -0x21, 0x11, 0xfe, 0xa6, 0x75, 0x38, 0xe0, 0x1f, -0xd9, 0xf4, 0x0c, 0x5a, 0xaa, 0xf8, 0x4e, 0x0b, -0xb4, 0xdd, 0x58, 0x9d, 0xef, 0xa3, 0xb1, 0x3a, -0x38, 0x12, 0x27, 0x9c, 0xbf, 0x9f, 0x5c, 0x74, -0x3b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, -0x01, 0x22, 0x21, 0x91, 0xdb, 0x08, 0x2e, 0x7e, -0xc4, 0x3f, 0x22, 0x5d, 0xa9, 0xdc, 0x3d, 0xbf, -0xc7, 0xcf, 0x0c, 0x4c, 0x99, 0x9f, 0xe0, 0x98, -0x7c, 0x4b, 0x89, 0xec, 0x5c, 0xef, 0x19, 0x15, -0x1a, 0xa3, 0x62, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x69, 0x01, 0x22, 0x21, 0x6f, 0xcb, 0x57, -0x37, 0xcf, 0xb0, 0x52, 0xa6, 0xe7, 0xd9, 0x21, -0x1d, 0x67, 0x8f, 0xd6, 0xf2, 0xc0, 0x67, 0xa1, -0x61, 0x24, 0x8f, 0x44, 0x77, 0x84, 0xaf, 0x26, -0x24, 0x24, 0x80, 0x64, 0xcc, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0xf5, -0x76, 0xa7, 0xfd, 0x23, 0x25, 0xd2, 0x3c, 0xd9, -0xa0, 0x9d, 0xbf, 0x1a, 0x9c, 0x86, 0x0d, 0x96, -0x65, 0x11, 0x02, 0x48, 0xa2, 0xea, 0xab, 0xa0, -0xb3, 0xd4, 0x8a, 0x21, 0xa7, 0x23, 0xad, 0x00, +0x21, 0x29, 0x71, 0xad, 0xbf, 0x72, 0xb1, 0xb8, +0x53, 0x66, 0xb9, 0x9d, 0xde, 0x6e, 0xa5, 0x8d, +0x58, 0x7d, 0x52, 0x2a, 0x8c, 0x7a, 0xe6, 0xa3, +0xc6, 0xea, 0x82, 0x8b, 0xc9, 0xaf, 0x72, 0x94, +0x47, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x68, +0x01, 0x22, 0x21, 0x29, 0xb2, 0xc9, 0x3d, 0x56, +0xc2, 0x68, 0x38, 0xf6, 0x94, 0x20, 0x94, 0x56, +0x23, 0x35, 0x03, 0x21, 0xad, 0x5e, 0x2e, 0xba, +0xa8, 0x82, 0xa1, 0x18, 0x0d, 0x7e, 0xa3, 0xb5, +0x9b, 0x36, 0x8f, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x69, 0x01, 0x22, 0x21, 0xbe, 0xed, 0xf5, +0xad, 0xf0, 0x08, 0x2b, 0xd8, 0x48, 0x39, 0x5a, +0xe6, 0x8c, 0x4d, 0x7f, 0x59, 0xd4, 0x64, 0x6b, +0xe7, 0xcc, 0x8c, 0xbd, 0x2f, 0x71, 0xe3, 0xc9, +0x78, 0x1f, 0x52, 0xa2, 0x06, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6a, 0x01, 0x22, 0x21, 0x78, +0xdc, 0x16, 0x73, 0xd6, 0x0c, 0xe8, 0xf0, 0xdc, +0xf4, 0xb1, 0xc3, 0x6a, 0xe8, 0xce, 0xe7, 0x95, +0x81, 0x95, 0x19, 0x13, 0x05, 0x48, 0x57, 0x0e, +0xd6, 0x47, 0x4f, 0xb5, 0xd7, 0xe1, 0x3f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6b, 0x01, 0x22, -0x21, 0x69, 0x07, 0x8c, 0x1b, 0x97, 0x12, 0x70, -0x23, 0xa3, 0xe0, 0xff, 0xd5, 0x67, 0x08, 0xdc, -0x73, 0x33, 0x9e, 0x8a, 0xa5, 0x86, 0xaf, 0x1f, -0x1f, 0x63, 0xf2, 0x4d, 0x74, 0x0e, 0x2f, 0x03, -0xe8, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, -0x01, 0x22, 0x21, 0xfe, 0x1f, 0x64, 0x46, 0x84, -0xb1, 0x91, 0x3e, 0x24, 0xba, 0x1a, 0x10, 0x20, -0x52, 0xb7, 0x24, 0x4b, 0x8b, 0xeb, 0x89, 0x5f, -0x0a, 0xeb, 0x9e, 0xa8, 0x03, 0x1f, 0x04, 0x4e, -0x5c, 0xd5, 0x20, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x6d, 0x01, 0x22, 0x21, 0x5b, 0x9a, 0xbb, -0xa4, 0x52, 0x94, 0xfd, 0xf7, 0x42, 0x24, 0x01, -0x2b, 0xb6, 0x7e, 0xcb, 0x1a, 0x77, 0xce, 0x7f, -0xd8, 0x63, 0x7d, 0xa2, 0x75, 0x9b, 0xa5, 0x20, -0x5f, 0x9d, 0x87, 0x16, 0x2a, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0xd3, -0x58, 0x56, 0x61, 0x12, 0x85, 0xc2, 0xaa, 0xe4, -0xed, 0x46, 0x59, 0x75, 0x7c, 0xa9, 0x32, 0x32, -0x37, 0xf9, 0x4b, 0xcf, 0xad, 0xc3, 0xef, 0x9f, -0x17, 0x63, 0x3b, 0x97, 0xfa, 0xfb, 0xd0, 0x00, +0x21, 0xa9, 0x63, 0x6b, 0xf8, 0xa1, 0xea, 0x28, +0xde, 0xaf, 0x04, 0xea, 0xa8, 0xb6, 0xaf, 0x05, +0x69, 0x1d, 0xb4, 0x52, 0x28, 0x49, 0xb9, 0xb8, +0x85, 0x89, 0x37, 0x71, 0x1b, 0x26, 0x2b, 0x84, +0x6b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6c, +0x01, 0x22, 0x21, 0x8b, 0x12, 0xe9, 0xb8, 0x89, +0xef, 0xa3, 0x9d, 0xac, 0x6c, 0x6a, 0x22, 0x56, +0x1c, 0x0f, 0x16, 0x63, 0x90, 0x4f, 0xb1, 0x93, +0x98, 0x9c, 0x58, 0xb0, 0xeb, 0x97, 0x2e, 0x39, +0xd1, 0x56, 0x70, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x6d, 0x01, 0x22, 0x21, 0x00, 0x81, 0x61, +0x91, 0x37, 0x84, 0x9e, 0xa9, 0x60, 0x4c, 0xe3, +0xab, 0x4f, 0x50, 0xb1, 0xab, 0x37, 0x39, 0x44, +0xb6, 0x24, 0xc1, 0x53, 0xb6, 0x0c, 0x01, 0x44, +0x1c, 0x28, 0x10, 0x41, 0x45, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x6e, 0x01, 0x22, 0x21, 0xdc, +0x6e, 0x81, 0xa4, 0xf6, 0xa4, 0x45, 0x14, 0x19, +0x7e, 0x83, 0xe1, 0xee, 0x75, 0x9c, 0xb8, 0xa9, +0xe4, 0x7c, 0x64, 0x0c, 0x2f, 0xd0, 0x64, 0x63, +0xd2, 0x8d, 0xdd, 0x9c, 0x93, 0x73, 0x48, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x6f, 0x01, 0x22, -0x21, 0x79, 0xf7, 0xf3, 0xec, 0x1c, 0xfc, 0x85, -0xc2, 0xa1, 0xc4, 0xf1, 0x22, 0xd6, 0x7a, 0xe8, -0x53, 0x80, 0x6a, 0xc5, 0x3d, 0xea, 0x14, 0x0d, -0xbb, 0x79, 0x7f, 0xc4, 0x36, 0x57, 0xa2, 0x1e, -0x7b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, -0x01, 0x22, 0x21, 0x5a, 0xc8, 0xd0, 0x32, 0x14, -0xb3, 0x33, 0x25, 0x34, 0xe5, 0x68, 0xaa, 0xa2, -0x44, 0x95, 0x69, 0x0d, 0x72, 0xd4, 0xd2, 0x02, -0xab, 0x27, 0x38, 0x3f, 0x78, 0x01, 0xd7, 0x36, -0x97, 0x11, 0x59, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x71, 0x01, 0x22, 0x21, 0x66, 0x47, 0x0d, -0x46, 0x41, 0x24, 0x26, 0x29, 0xf1, 0x03, 0xba, -0xaa, 0xd9, 0xb8, 0xde, 0xf9, 0xb3, 0x91, 0x19, -0x2a, 0x2a, 0xbe, 0xfb, 0x3c, 0x77, 0x40, 0xd8, -0x22, 0xce, 0x94, 0xb1, 0xd7, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0xfe, -0x33, 0xcb, 0x5a, 0x6b, 0x8e, 0x6c, 0xe5, 0x7b, -0xc1, 0x6d, 0x36, 0x64, 0xd1, 0xe9, 0xc4, 0x7c, -0x50, 0x20, 0xa7, 0xba, 0xd0, 0x01, 0xb7, 0x31, -0x71, 0x36, 0x5f, 0xf8, 0xe8, 0xf8, 0x0d, 0x00, +0x21, 0xd8, 0x4c, 0xb6, 0x2d, 0x8d, 0x8a, 0x89, +0x6d, 0x34, 0x32, 0x45, 0x0e, 0xc7, 0xea, 0x22, +0xff, 0x1a, 0x41, 0xdd, 0xde, 0xc2, 0xe8, 0x49, +0xb1, 0x62, 0x6d, 0x1e, 0xf5, 0x65, 0x3d, 0x13, +0xcc, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x70, +0x01, 0x22, 0x21, 0xd7, 0xd8, 0x83, 0xfa, 0x8f, +0x96, 0xba, 0x82, 0x70, 0x5f, 0xcf, 0xac, 0xdf, +0x76, 0xe1, 0xa0, 0xad, 0x3a, 0x70, 0xa7, 0x3a, +0x35, 0x26, 0x19, 0x9f, 0x14, 0xe1, 0x79, 0xc3, +0x1c, 0x64, 0x50, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x71, 0x01, 0x22, 0x21, 0x49, 0x12, 0x04, +0xcb, 0xc2, 0xf4, 0x74, 0xb7, 0xec, 0x23, 0x1b, +0x3c, 0x62, 0x95, 0x64, 0x94, 0xa3, 0x25, 0xd0, +0xad, 0xb0, 0x31, 0xb2, 0xd9, 0xcb, 0x0a, 0x61, +0x64, 0x86, 0x6a, 0x62, 0xa0, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x72, 0x01, 0x22, 0x21, 0x7f, +0x4c, 0x22, 0xf9, 0x31, 0xcf, 0x3e, 0xc4, 0xad, +0xd9, 0x83, 0x81, 0xf6, 0x8e, 0x45, 0xdc, 0x39, +0xcf, 0x55, 0x6e, 0x7d, 0x2f, 0xf2, 0x4e, 0x02, +0xa1, 0xbb, 0xc7, 0xe5, 0x5d, 0x9b, 0x06, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x73, 0x01, 0x22, -0x21, 0x3e, 0x31, 0x9e, 0xbb, 0x87, 0x33, 0x90, -0x42, 0xf7, 0xc5, 0xa0, 0xe0, 0x30, 0xdf, 0xbd, -0x9a, 0xb4, 0x87, 0x47, 0xb6, 0x3b, 0x04, 0x04, -0x7f, 0xaa, 0xc5, 0xb9, 0xc6, 0xbf, 0xaa, 0xc9, -0x5d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, -0x01, 0x22, 0x21, 0x80, 0x43, 0xff, 0xba, 0x07, -0x96, 0x09, 0xe5, 0x2d, 0xc0, 0x8a, 0xe0, 0xde, -0x4a, 0xa9, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd1, 0xb9, 0x7a, 0xd3, -0x4d, 0x1a, 0xc7, 0x9a, 0x03, 0x04, 0x51, 0x02, -0x00, 0x75, 0x01, 0x22, 0x21, 0x3c, 0xaf, 0x23, -0x86, 0xcf, 0xcb, 0x73, 0xf8, 0xc7, 0x49, 0x4d, -0x09, 0xe0, 0x6b, 0xe4, 0x76, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x13, -0xcf, 0xba, 0x2d, 0x85, 0xa5, 0x0a, 0x03, 0x04, -0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0x9b, -0x11, 0x48, 0x8a, 0x1b, 0x03, 0x34, 0x47, 0xbf, -0x97, 0x68, 0x6b, 0xbe, 0xbd, 0x20, 0xe1, 0xf6, -0x96, 0xd4, 0x8b, 0x70, 0xaa, 0x55, 0x9b, 0x4a, -0x2e, 0x88, 0x12, 0x30, 0x74, 0xca, 0xe8, 0x00, +0x21, 0x0a, 0xd6, 0xf2, 0xc5, 0x38, 0x1d, 0x32, +0xc2, 0xb9, 0x74, 0x0e, 0x64, 0xbd, 0x05, 0x47, +0x19, 0x6e, 0xde, 0xb6, 0x17, 0xf7, 0x9d, 0xd6, +0x1f, 0x2b, 0xe0, 0x3b, 0x3e, 0xb9, 0x2a, 0x96, +0x73, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x74, +0x01, 0x22, 0x21, 0x73, 0xd5, 0x6e, 0x24, 0x75, +0xb7, 0x7f, 0x1a, 0x0b, 0xa4, 0xc0, 0x1d, 0xb3, +0x3f, 0xed, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1a, 0xf4, 0xb7, 0x1b, +0x83, 0x27, 0xf1, 0x90, 0x03, 0x04, 0x51, 0x02, +0x00, 0x75, 0x01, 0x22, 0x21, 0xe4, 0xfb, 0xe0, +0xd3, 0xa4, 0x2f, 0x75, 0xb4, 0x4b, 0xb7, 0xa8, +0x5b, 0x4f, 0x65, 0x0c, 0xaf, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xdc, +0x05, 0x50, 0xb3, 0x9b, 0x65, 0xff, 0x03, 0x04, +0x51, 0x02, 0x00, 0x76, 0x01, 0x22, 0x21, 0x6c, +0x6e, 0x42, 0x17, 0x8e, 0x94, 0x01, 0x5c, 0xb6, +0x6f, 0xab, 0xd3, 0xa2, 0xbc, 0xe9, 0x82, 0xb2, +0x69, 0xf9, 0x6b, 0x68, 0x49, 0xca, 0xfb, 0xc0, +0x2f, 0xb2, 0xb4, 0x01, 0xe6, 0x30, 0x2d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x77, 0x01, 0x22, -0x21, 0x02, 0x53, 0xdb, 0x8f, 0xf4, 0x87, 0xa5, -0xb8, 0xf8, 0x05, 0x2a, 0xe4, 0x72, 0xf9, 0xe5, -0xa5, 0x6f, 0xaf, 0xec, 0x4d, 0x96, 0x43, 0x26, -0x56, 0xaa, 0x0e, 0xf9, 0xfd, 0x88, 0xda, 0x79, -0x6f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, -0x01, 0x22, 0x21, 0xda, 0x7f, 0x89, 0x50, 0xe1, -0x93, 0x42, 0x6c, 0xae, 0xf9, 0xfa, 0x9b, 0x79, -0x9b, 0x71, 0x8f, 0x8b, 0xf4, 0x5b, 0x4e, 0x02, -0x56, 0xac, 0xfe, 0x69, 0x62, 0x07, 0x00, 0xa4, -0xca, 0xbf, 0xab, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x79, 0x01, 0x22, 0x21, 0x13, 0x62, 0x3f, -0x93, 0x12, 0x40, 0xb1, 0xb7, 0xf3, 0xa7, 0x29, -0x8e, 0x99, 0x32, 0x22, 0xf7, 0x9f, 0x95, 0xa5, -0x0d, 0x4e, 0x5b, 0xe5, 0x39, 0xef, 0x4a, 0x02, -0x49, 0x96, 0xf3, 0xb5, 0x61, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0xf2, -0x03, 0xf2, 0xcb, 0x25, 0xbe, 0x85, 0xb4, 0xe2, -0x10, 0x8b, 0xa0, 0xa8, 0x2b, 0x4a, 0xee, 0x15, -0x5b, 0xbe, 0x4f, 0x65, 0xe9, 0x6e, 0x1c, 0xdf, -0xd8, 0x7b, 0x03, 0x82, 0xa0, 0xc9, 0x67, 0x00, +0x21, 0x5f, 0x69, 0x33, 0x89, 0x85, 0x4f, 0xca, +0xd6, 0x6a, 0xf5, 0x03, 0xaf, 0x81, 0xc9, 0xa2, +0x60, 0xe3, 0x41, 0x13, 0x59, 0x6d, 0x53, 0x55, +0x08, 0x21, 0x81, 0x06, 0x68, 0x75, 0x64, 0x25, +0x3a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x78, +0x01, 0x22, 0x21, 0xbd, 0x1a, 0x43, 0x13, 0x25, +0x60, 0xe9, 0x98, 0x9a, 0x8d, 0x03, 0x51, 0xea, +0x7d, 0x70, 0x38, 0x4e, 0x2d, 0xe7, 0x0c, 0x15, +0x7b, 0xad, 0x7a, 0x13, 0x7e, 0x05, 0x4a, 0xd4, +0xe6, 0xd6, 0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x79, 0x01, 0x22, 0x21, 0x9e, 0x03, 0x5c, +0x8b, 0xc3, 0xad, 0x35, 0xbd, 0xd8, 0x89, 0x31, +0xe5, 0x62, 0x6e, 0x9f, 0x03, 0x5a, 0xaa, 0xf9, +0x4a, 0xf1, 0x58, 0x2e, 0xfc, 0xd1, 0xec, 0xa9, +0x12, 0x4b, 0x6f, 0x52, 0x7d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7a, 0x01, 0x22, 0x21, 0x7e, +0x32, 0x61, 0x4f, 0xbb, 0x95, 0x03, 0xa6, 0x09, +0x68, 0x0d, 0xbf, 0xe7, 0x90, 0xfb, 0x7c, 0x9a, +0xb6, 0x68, 0x26, 0x2f, 0x28, 0x78, 0x72, 0x4e, +0x9a, 0x08, 0x18, 0xc2, 0xb3, 0xf7, 0x86, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7b, 0x01, 0x22, -0x21, 0x25, 0x7c, 0x82, 0x4c, 0x8c, 0xaa, 0x04, -0x54, 0xf6, 0x12, 0x45, 0xdc, 0x73, 0xcb, 0x83, -0x1d, 0xff, 0xf3, 0xac, 0x8d, 0x8c, 0x78, 0x51, -0x9b, 0xea, 0x95, 0x30, 0xb2, 0x18, 0x7d, 0xf2, -0xc5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, -0x01, 0x22, 0x21, 0x8f, 0x01, 0xb4, 0x86, 0x57, -0x5b, 0xa7, 0x5f, 0x1a, 0xa4, 0x54, 0x9a, 0xca, -0x47, 0x59, 0x3f, 0x7d, 0x8a, 0x76, 0x41, 0x5e, -0xd7, 0xfa, 0x10, 0xd9, 0x40, 0x30, 0x3b, 0xa4, -0x33, 0x4f, 0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x7d, 0x01, 0x22, 0x21, 0x4a, 0xe7, 0x91, -0x4d, 0xd6, 0x8f, 0x80, 0xd6, 0x76, 0xb0, 0x9e, -0xbe, 0x52, 0x61, 0xdf, 0x48, 0x84, 0xe1, 0xdb, -0xf4, 0x07, 0x7e, 0x64, 0xc2, 0xa7, 0xec, 0x35, -0x01, 0x94, 0xe6, 0x5a, 0x13, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0x27, -0x7a, 0xef, 0x04, 0xf6, 0x50, 0xb9, 0xcd, 0x58, -0x67, 0xaf, 0xa1, 0xa9, 0xb5, 0x32, 0x7b, 0xad, -0x26, 0xc3, 0x5f, 0x20, 0x48, 0x03, 0xc8, 0x24, -0x50, 0x5c, 0xfb, 0x3a, 0x4a, 0xc2, 0x13, 0x00, +0x21, 0x3d, 0xa7, 0x3c, 0x7c, 0xa8, 0xfe, 0x21, +0x1f, 0xcf, 0x66, 0x74, 0xa9, 0x2a, 0xc6, 0xe1, +0x0f, 0x9f, 0xdd, 0x2e, 0x06, 0xd5, 0x46, 0xdb, +0x96, 0xbd, 0xd7, 0x18, 0x18, 0x92, 0x80, 0x55, +0xa5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7c, +0x01, 0x22, 0x21, 0xc3, 0x01, 0x01, 0x34, 0x4f, +0x44, 0xd7, 0xbb, 0x3e, 0x53, 0x76, 0xba, 0x66, +0x38, 0x10, 0xf6, 0x27, 0xf5, 0x75, 0x03, 0x5f, +0xd9, 0x8c, 0x7c, 0x04, 0x4b, 0x1b, 0x39, 0x53, +0x3a, 0xdd, 0x1f, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x7d, 0x01, 0x22, 0x21, 0xc4, 0x17, 0x7f, +0x29, 0x28, 0x4e, 0x95, 0xf7, 0x18, 0x9e, 0xb2, +0x8c, 0x02, 0x32, 0x76, 0x60, 0xb3, 0x23, 0xd2, +0x99, 0x3c, 0xd6, 0xad, 0x96, 0xe1, 0x89, 0x91, +0x3f, 0xcd, 0x22, 0x05, 0x6c, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x7e, 0x01, 0x22, 0x21, 0x3e, +0xcf, 0x42, 0xb2, 0x4c, 0xaf, 0x44, 0x3b, 0x00, +0x78, 0xc6, 0x19, 0xc4, 0xc2, 0xbf, 0x59, 0x6c, +0x39, 0x8b, 0xac, 0xae, 0x78, 0xc9, 0x4b, 0xfa, +0xf5, 0x2b, 0x5f, 0x05, 0xab, 0xc5, 0x11, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x7f, 0x01, 0x22, -0x21, 0x4a, 0x3d, 0xf9, 0xa2, 0x7d, 0x9d, 0xbd, -0xb1, 0x20, 0x71, 0x03, 0xc3, 0x07, 0xf7, 0xae, -0x41, 0x16, 0x4f, 0x34, 0xfb, 0x9a, 0xc2, 0x34, -0xa3, 0xff, 0x3f, 0x52, 0x2e, 0x81, 0x7d, 0xf3, -0x85, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, -0x01, 0x22, 0x21, 0x4a, 0xd0, 0xa1, 0x69, 0xc0, -0xec, 0xcf, 0xd5, 0x3e, 0x57, 0xc1, 0x40, 0x4c, -0xbc, 0x3d, 0xc8, 0x9d, 0x26, 0x7f, 0xc9, 0x1b, -0xbf, 0x49, 0x57, 0x5a, 0x3d, 0xca, 0xaa, 0xe1, -0x9b, 0x5b, 0x40, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x81, 0x01, 0x22, 0x21, 0x8b, 0xa4, 0x2d, -0x00, 0xd6, 0xa2, 0x03, 0x61, 0x10, 0xc1, 0x3a, -0x0c, 0xa8, 0x96, 0x33, 0x19, 0xe1, 0x48, 0x58, -0xb9, 0x49, 0xf1, 0x4f, 0x91, 0x9e, 0xc4, 0x1f, -0x07, 0x25, 0x96, 0x17, 0xbe, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0x7d, -0x68, 0x02, 0xe3, 0x8e, 0x7f, 0xf3, 0xc2, 0x91, -0x11, 0x02, 0xf0, 0xd5, 0xd4, 0x98, 0xdf, 0xf6, -0xc1, 0xbd, 0x2b, 0xb0, 0xb6, 0xe6, 0xc5, 0x75, -0xde, 0x62, 0x17, 0x0c, 0x34, 0x2e, 0x18, 0x00, +0x21, 0x05, 0xeb, 0x53, 0x64, 0xc8, 0x2a, 0x79, +0x87, 0x0b, 0xe8, 0x86, 0x6c, 0x08, 0x35, 0xa1, +0xb6, 0x06, 0x08, 0x4c, 0x0f, 0x8a, 0x14, 0x36, +0xc1, 0x4b, 0x02, 0x99, 0xc5, 0x64, 0xe4, 0xcf, +0x13, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x80, +0x01, 0x22, 0x21, 0x2c, 0x40, 0xa1, 0x6a, 0x99, +0x0b, 0x20, 0x96, 0xb4, 0xed, 0xe2, 0x27, 0x37, +0x0c, 0xeb, 0x4d, 0x1e, 0xb2, 0xc5, 0x43, 0x1a, +0x67, 0xa0, 0x4c, 0xb9, 0x76, 0xfd, 0x69, 0x15, +0xb0, 0x5a, 0x06, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x81, 0x01, 0x22, 0x21, 0x27, 0x35, 0xb4, +0xb9, 0x36, 0x67, 0x1c, 0xe3, 0xcc, 0x12, 0xd0, +0xf1, 0x50, 0xa9, 0x49, 0x25, 0x8a, 0x73, 0xeb, +0x00, 0xc2, 0x60, 0x15, 0xf8, 0x38, 0xd4, 0x1c, +0x11, 0xa0, 0xfd, 0x36, 0x90, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x82, 0x01, 0x22, 0x21, 0xe2, +0x50, 0x54, 0x8f, 0x1d, 0x71, 0x7d, 0xbe, 0xe5, +0x4a, 0x1d, 0x65, 0xbe, 0x00, 0x55, 0xb2, 0xba, +0x08, 0xd9, 0xcc, 0x09, 0xde, 0xc1, 0x25, 0x15, +0xa2, 0xf6, 0x8a, 0xce, 0xeb, 0x6c, 0x5e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x83, 0x01, 0x22, -0x21, 0xe5, 0x63, 0xee, 0x83, 0xe2, 0x4b, 0x24, -0xb7, 0x82, 0xad, 0xa7, 0x5b, 0xe8, 0x79, 0x7b, -0x5a, 0x93, 0x42, 0xcf, 0xda, 0x67, 0xd4, 0xa7, -0xff, 0x02, 0x3a, 0x7e, 0xe5, 0xd0, 0x88, 0x1e, -0x0f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, -0x01, 0x22, 0x21, 0x4c, 0xb6, 0xfd, 0x40, 0x8b, -0x85, 0x9b, 0x0e, 0x29, 0x35, 0x1e, 0x54, 0x59, -0x8d, 0x55, 0xa9, 0x19, 0x62, 0xb3, 0x3a, 0x3e, -0xbe, 0xfb, 0xe6, 0x61, 0x94, 0x44, 0xc3, 0x52, -0x38, 0xd8, 0x45, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x85, 0x01, 0x22, 0x21, 0x45, 0xef, 0xbe, -0x1e, 0xf8, 0xbc, 0x57, 0x3b, 0xbc, 0x60, 0xf3, -0x7f, 0x2e, 0xa9, 0xfa, 0x4e, 0x49, 0x32, 0x8a, -0xa3, 0xd7, 0x2b, 0x6a, 0x45, 0x87, 0xc1, 0xe2, -0x14, 0x27, 0x2d, 0xb3, 0x1c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0xad, -0x89, 0x7e, 0x4e, 0x52, 0x5e, 0xb9, 0x9c, 0xae, -0xf4, 0xf7, 0x64, 0x27, 0x64, 0x31, 0x9c, 0x5a, -0xbe, 0xab, 0xea, 0xcc, 0x06, 0x94, 0xd0, 0xbe, -0x29, 0xbb, 0x6c, 0x2a, 0x9e, 0x98, 0xaf, 0x00, +0x21, 0xc2, 0x69, 0x71, 0xdb, 0xe5, 0x4e, 0x79, +0xed, 0x1c, 0xa8, 0x16, 0x44, 0x7d, 0x13, 0xaa, +0xe5, 0xed, 0xba, 0x29, 0x42, 0xda, 0xc7, 0xbb, +0xbc, 0x1c, 0xd8, 0xab, 0xd6, 0x5f, 0xdf, 0x5b, +0xdf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x84, +0x01, 0x22, 0x21, 0x40, 0x03, 0xc0, 0x09, 0x2e, +0xe7, 0xbb, 0x96, 0xec, 0xa3, 0x3f, 0xc4, 0x98, +0x4e, 0x44, 0x21, 0x44, 0x9b, 0xd2, 0x15, 0x28, +0xdf, 0x67, 0xad, 0x83, 0xe4, 0x7b, 0x68, 0x01, +0x44, 0xc7, 0xc0, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x85, 0x01, 0x22, 0x21, 0x84, 0x9d, 0x3f, +0x74, 0xc0, 0x9c, 0x27, 0xb7, 0x5c, 0x51, 0x70, +0xb4, 0xed, 0x17, 0x4d, 0xc5, 0x3e, 0xfe, 0x33, +0x54, 0x70, 0x69, 0x87, 0xb4, 0x70, 0x4c, 0x66, +0x4d, 0x88, 0x16, 0xd2, 0x32, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x86, 0x01, 0x22, 0x21, 0xa3, +0x75, 0x09, 0x87, 0x65, 0xe0, 0xaf, 0x76, 0x7f, +0x17, 0x7d, 0x30, 0x4d, 0x6c, 0xa1, 0x97, 0xeb, +0x7d, 0x18, 0x98, 0xa1, 0xa1, 0x67, 0x27, 0xfd, +0xc4, 0xb7, 0xe1, 0x52, 0xb8, 0xd6, 0x92, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x87, 0x01, 0x22, -0x21, 0xc7, 0xc0, 0x2d, 0x89, 0x7b, 0x52, 0x44, -0xb1, 0x99, 0xf7, 0x3e, 0xcb, 0x73, 0x3e, 0xf5, -0xd5, 0xd1, 0x70, 0x71, 0x3d, 0x2d, 0x6f, 0x5e, -0x3b, 0x15, 0x47, 0x1d, 0xe6, 0xb2, 0x32, 0x19, -0xab, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, -0x01, 0x22, 0x21, 0x17, 0x83, 0x5c, 0x65, 0x45, -0x60, 0xfa, 0x4d, 0x8b, 0x28, 0x04, 0x63, 0x2a, -0x30, 0x66, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xb1, 0x59, 0xba, 0x3c, -0x49, 0x49, 0x38, 0x15, 0x03, 0x04, 0x51, 0x02, -0x00, 0x89, 0x01, 0x22, 0x21, 0xa9, 0xf9, 0x86, -0x1a, 0xf0, 0x1d, 0xec, 0xc0, 0x2b, 0xe5, 0x68, -0xef, 0xbe, 0xc3, 0x8e, 0x46, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x70, -0xcf, 0x0e, 0x7f, 0x4e, 0x58, 0x17, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0xa7, -0x01, 0x54, 0x36, 0x66, 0x09, 0x88, 0xbd, 0x02, -0x16, 0xed, 0xba, 0x91, 0x56, 0xc3, 0x21, 0x68, -0xa1, 0xaf, 0x3d, 0xea, 0x1e, 0x89, 0x53, 0x12, -0xd0, 0xbf, 0x9c, 0x97, 0x71, 0xa8, 0x5e, 0x00, +0x21, 0x5d, 0x27, 0xb9, 0x6e, 0xfb, 0x32, 0x4a, +0x0f, 0x40, 0xb5, 0xe0, 0xef, 0x3d, 0x42, 0x76, +0x01, 0x16, 0xed, 0xa8, 0xf3, 0xca, 0x8e, 0xef, +0x2e, 0x6e, 0xa1, 0xd6, 0x65, 0x78, 0x63, 0x9d, +0x55, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x88, +0x01, 0x22, 0x21, 0x22, 0x79, 0x1c, 0x12, 0x58, +0xca, 0xf2, 0xfc, 0xbd, 0x95, 0x23, 0x13, 0x85, +0xe5, 0xa5, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xa7, 0x36, 0x34, 0x64, +0x71, 0x20, 0x3a, 0x11, 0x03, 0x04, 0x51, 0x02, +0x00, 0x89, 0x01, 0x22, 0x21, 0xa4, 0xaa, 0x9e, +0xdf, 0x78, 0x2b, 0xc9, 0x18, 0x22, 0xfb, 0x84, +0xe8, 0x0d, 0x87, 0x18, 0x54, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x10, +0x09, 0x35, 0x46, 0xff, 0x65, 0xc0, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8a, 0x01, 0x22, 0x21, 0xaf, +0x14, 0x92, 0x20, 0x91, 0xe0, 0xe1, 0xcc, 0xc8, +0x6d, 0x65, 0x52, 0xb6, 0x42, 0x7e, 0xec, 0x6f, +0x82, 0xd8, 0xb1, 0xa6, 0xd7, 0x50, 0x0e, 0xa3, +0x34, 0xc0, 0xfa, 0xce, 0x11, 0x9b, 0x19, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8b, 0x01, 0x22, -0x21, 0x03, 0x19, 0x71, 0xe1, 0x39, 0x0d, 0xb5, -0xf4, 0x57, 0xc5, 0xed, 0xe8, 0xa6, 0x8e, 0x37, -0xd2, 0xac, 0x4c, 0x48, 0xd9, 0xc2, 0x96, 0x7d, -0x19, 0xa5, 0x11, 0x62, 0x96, 0xa0, 0x2e, 0xc9, -0x2a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, -0x01, 0x22, 0x21, 0xf4, 0xf9, 0x53, 0xa5, 0xfe, -0x82, 0xe0, 0x96, 0x25, 0xdf, 0xd2, 0xda, 0x74, -0x05, 0x06, 0x23, 0x19, 0x58, 0x61, 0xe9, 0xfc, -0x27, 0x12, 0xf9, 0x2d, 0x5e, 0xfc, 0xd9, 0xbe, -0xf7, 0x29, 0xce, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x8d, 0x01, 0x22, 0x21, 0x9a, 0x77, 0xc8, -0x7f, 0x88, 0xcd, 0x1b, 0x5c, 0x46, 0x31, 0x26, -0x2f, 0xf8, 0xea, 0x3d, 0x16, 0xf3, 0x9f, 0xc0, -0x09, 0xc7, 0x91, 0x48, 0x03, 0xe5, 0x38, 0xe5, -0xf0, 0xb5, 0x75, 0xf1, 0xb0, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x2b, -0x08, 0x8c, 0x2e, 0x29, 0x8f, 0x54, 0xee, 0x75, -0xcc, 0x68, 0xb3, 0x69, 0x8d, 0xf7, 0xf3, 0xe6, -0x6a, 0x0b, 0xdb, 0xf2, 0x76, 0x5b, 0x42, 0xc2, -0x3c, 0xa2, 0x7b, 0xb1, 0x9c, 0x22, 0x14, 0x00, +0x21, 0xa2, 0xc2, 0xd4, 0x9d, 0xff, 0xcd, 0x8e, +0x54, 0x30, 0x18, 0x58, 0x26, 0x63, 0x1d, 0xe1, +0xd9, 0xc1, 0x8b, 0xe0, 0x90, 0xf3, 0x5b, 0x87, +0x43, 0x6c, 0x98, 0xd8, 0x66, 0xb3, 0x15, 0x8c, +0x8e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8c, +0x01, 0x22, 0x21, 0xba, 0x85, 0x62, 0x92, 0xc8, +0x2c, 0xf2, 0xde, 0x50, 0xff, 0x02, 0xc6, 0xc7, +0xde, 0x0b, 0x25, 0xfc, 0x20, 0xea, 0xb1, 0x7b, +0xd2, 0x8b, 0x90, 0xb0, 0x95, 0x68, 0x72, 0x00, +0xab, 0x66, 0x3a, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x8d, 0x01, 0x22, 0x21, 0x23, 0x17, 0x45, +0xc9, 0x79, 0x27, 0xd2, 0x93, 0x89, 0xcb, 0xdb, +0xa1, 0x9f, 0x24, 0x9e, 0xb6, 0x07, 0xb9, 0xe9, +0xed, 0x84, 0x27, 0x69, 0xa2, 0xf1, 0x48, 0x6c, +0x2d, 0xd9, 0xcc, 0x50, 0x25, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x8e, 0x01, 0x22, 0x21, 0x58, +0xa7, 0xda, 0xe4, 0x45, 0x21, 0xfc, 0xf0, 0x7e, +0x21, 0x25, 0xf7, 0x73, 0xe1, 0x75, 0xcd, 0x23, +0x23, 0xf3, 0x0e, 0xb4, 0x10, 0x8b, 0x4f, 0x3c, +0xcc, 0x66, 0x0a, 0xce, 0x63, 0xc0, 0x11, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x8f, 0x01, 0x22, -0x21, 0x49, 0xb9, 0x79, 0xa3, 0x99, 0x19, 0x7c, -0x65, 0x7e, 0xa5, 0x54, 0x87, 0x2f, 0xab, 0xee, -0x57, 0x99, 0xab, 0xf4, 0x9e, 0xbf, 0xfa, 0xcd, -0xd5, 0x13, 0x0c, 0xca, 0xec, 0xdb, 0x13, 0x83, -0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, -0x01, 0x22, 0x21, 0x99, 0xc1, 0xdc, 0x83, 0x79, -0xda, 0xcc, 0x04, 0x1c, 0xa3, 0xc3, 0xaf, 0xd1, -0x3a, 0xe3, 0x7e, 0x92, 0xcb, 0x32, 0x89, 0x9a, -0xe4, 0xf2, 0x98, 0x5f, 0xb3, 0xa3, 0x0b, 0x60, -0xf5, 0xd7, 0x19, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x91, 0x01, 0x22, 0x21, 0x41, 0x07, 0x90, -0x8b, 0xc7, 0x60, 0x5f, 0x2b, 0xb0, 0xe7, 0xe6, -0xd7, 0x48, 0x78, 0xce, 0x7a, 0xcf, 0x75, 0xa4, -0x6a, 0x89, 0x14, 0x19, 0x8c, 0x15, 0x5c, 0xb6, -0x0e, 0xbf, 0x30, 0x29, 0x6c, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0xa1, -0xa1, 0xff, 0x4c, 0x76, 0x5c, 0x8e, 0xb9, 0xaa, -0xba, 0xdd, 0xd1, 0x3b, 0x1c, 0x9e, 0x11, 0x29, -0xda, 0x92, 0x3d, 0xa9, 0x62, 0x79, 0x46, 0x72, -0xbd, 0x88, 0xef, 0xd6, 0x8b, 0x12, 0x68, 0x00, +0x21, 0xa3, 0x68, 0xce, 0x0b, 0xd3, 0x95, 0x91, +0xdb, 0x5f, 0x5b, 0x1e, 0xc7, 0x99, 0xb5, 0x83, +0x20, 0x41, 0x40, 0x15, 0x56, 0x24, 0x3b, 0xfa, +0x4e, 0x6c, 0x32, 0x33, 0xe2, 0xf0, 0x53, 0xc4, +0x7e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x90, +0x01, 0x22, 0x21, 0x1c, 0x18, 0x69, 0xcb, 0x5b, +0x91, 0x00, 0x27, 0xab, 0x7d, 0xde, 0x08, 0x22, +0x44, 0xca, 0x45, 0xcd, 0x28, 0xcd, 0x02, 0xb2, +0x32, 0x56, 0xde, 0x40, 0x7f, 0x53, 0xf5, 0xf1, +0x17, 0x66, 0xa8, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x91, 0x01, 0x22, 0x21, 0x15, 0x48, 0xc3, +0x1d, 0x83, 0xd9, 0xe7, 0x0a, 0x4e, 0x49, 0x46, +0x49, 0xbc, 0xc9, 0x43, 0x19, 0x4f, 0x7d, 0x39, +0x69, 0x1f, 0xd7, 0xa9, 0xa3, 0x16, 0x54, 0xe1, +0x35, 0xc5, 0x10, 0x32, 0xdb, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x92, 0x01, 0x22, 0x21, 0x8f, +0x60, 0xe1, 0x03, 0x71, 0xc3, 0x3c, 0x4b, 0x24, +0x82, 0x71, 0xbd, 0xe4, 0x0b, 0xca, 0x57, 0xc9, +0xf3, 0xdf, 0x8d, 0x0a, 0x49, 0x88, 0x6e, 0x04, +0xd2, 0xd2, 0x88, 0xf0, 0x5a, 0xad, 0x9d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x93, 0x01, 0x22, -0x21, 0x29, 0x0b, 0xa2, 0xa0, 0xfd, 0x8e, 0x95, -0x05, 0xe4, 0xbb, 0xe3, 0xea, 0xea, 0x66, 0x4f, -0x0e, 0x8f, 0x91, 0x7f, 0x3b, 0xbd, 0xf2, 0xb3, -0xd8, 0x54, 0x8e, 0xd2, 0x77, 0xd4, 0x66, 0x81, -0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, -0x01, 0x22, 0x21, 0x6b, 0x25, 0x36, 0xd6, 0x6a, -0xd9, 0x43, 0x44, 0x4c, 0xd6, 0x4a, 0x52, 0x55, -0x3c, 0x01, 0xbe, 0x77, 0x32, 0xe2, 0x5f, 0xe6, -0x7d, 0xb6, 0xe0, 0x9c, 0x27, 0xd1, 0xc4, 0xc6, -0x37, 0xaf, 0x2a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x95, 0x01, 0x22, 0x21, 0xb0, 0x7d, 0x3d, -0xfb, 0xf8, 0x98, 0xb5, 0x3d, 0x73, 0x5a, 0xd3, -0xea, 0x35, 0x37, 0x31, 0x9a, 0xc4, 0x9b, 0x05, -0x84, 0x08, 0x3f, 0x99, 0x5f, 0xfd, 0xae, 0x64, -0xa1, 0x8b, 0xe1, 0xc0, 0x8b, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0x0f, -0x69, 0xd9, 0x19, 0x01, 0xb6, 0x3f, 0x4c, 0x8a, -0xea, 0x05, 0x0f, 0x99, 0x74, 0xfe, 0xd1, 0xf0, -0xea, 0xaf, 0xbb, 0xea, 0x3e, 0xf6, 0x0d, 0x62, -0xda, 0x7b, 0x80, 0xd3, 0x3f, 0x2a, 0x67, 0x00, +0x21, 0x8b, 0x51, 0x21, 0x6b, 0x3b, 0x5c, 0x61, +0x1d, 0xa9, 0x94, 0xce, 0x1a, 0x87, 0x72, 0xfa, +0xb3, 0xdd, 0x23, 0x54, 0xc6, 0x42, 0x4f, 0x76, +0xc6, 0x6a, 0x37, 0xf2, 0x7c, 0x9c, 0x59, 0xaf, +0xa4, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x94, +0x01, 0x22, 0x21, 0x7a, 0x43, 0x52, 0xb9, 0xa1, +0xf7, 0xd3, 0x60, 0xc8, 0x44, 0x29, 0x70, 0xc2, +0x78, 0x77, 0x47, 0x90, 0x7f, 0xce, 0x0f, 0xd4, +0xf6, 0xeb, 0xe7, 0x50, 0xbc, 0x64, 0xa4, 0x4f, +0x54, 0xd6, 0x69, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x95, 0x01, 0x22, 0x21, 0x04, 0x5c, 0x42, +0x7f, 0x84, 0x09, 0x78, 0x7f, 0x24, 0x3c, 0xd8, +0x7c, 0x43, 0x4f, 0x0e, 0x40, 0x59, 0xf3, 0x9e, +0x4a, 0x85, 0x7f, 0x59, 0x48, 0x62, 0xa0, 0xb5, +0x10, 0x1b, 0x7e, 0x0d, 0x04, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x96, 0x01, 0x22, 0x21, 0x7f, +0x73, 0x6e, 0x6c, 0xac, 0x54, 0x45, 0x50, 0x71, +0x23, 0x56, 0x5c, 0x02, 0xac, 0xc7, 0xd9, 0x3e, +0x9d, 0x80, 0x65, 0xee, 0x14, 0xe8, 0x93, 0x1a, +0x99, 0x69, 0x7e, 0x51, 0x40, 0x73, 0x04, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x97, 0x01, 0x22, -0x21, 0xe7, 0xe3, 0x09, 0x11, 0x89, 0xa9, 0x6e, -0xa8, 0xdb, 0x5b, 0x87, 0xc8, 0xe0, 0xdb, 0xb6, -0x8b, 0xc1, 0xb5, 0x45, 0x00, 0xdf, 0xe6, 0x5c, -0x6a, 0x63, 0x28, 0xee, 0x97, 0x70, 0x7f, 0x0b, -0xed, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, -0x01, 0x22, 0x21, 0x07, 0xa5, 0x45, 0xde, 0x3a, -0xec, 0xea, 0x07, 0x20, 0x50, 0x50, 0xc7, 0x32, -0x48, 0x50, 0x87, 0xb8, 0x65, 0xe4, 0xd7, 0xa4, -0x1a, 0xaa, 0x1f, 0xdb, 0x4c, 0xd1, 0x57, 0xc9, -0x8e, 0xbe, 0xbc, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0x99, 0x01, 0x22, 0x21, 0x48, 0x28, 0xcd, -0x66, 0xe8, 0xb6, 0x09, 0xc3, 0x50, 0xa8, 0x77, -0x26, 0x8c, 0x6f, 0x06, 0x7e, 0xed, 0x66, 0x1c, -0xb0, 0xbd, 0xc5, 0xed, 0xf1, 0x9a, 0x30, 0x40, -0x61, 0x30, 0xbb, 0xad, 0xca, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0x0e, -0x85, 0xb1, 0x01, 0x70, 0x4f, 0x57, 0x8f, 0x65, -0xc4, 0x1e, 0x52, 0xcd, 0xd0, 0x66, 0x6e, 0x85, -0xf9, 0xe6, 0x33, 0x04, 0x05, 0x88, 0x56, 0x4a, -0xdc, 0x3f, 0xf6, 0x20, 0xbb, 0xeb, 0x29, 0x00, +0x21, 0xa6, 0xd6, 0x61, 0xee, 0x72, 0xc1, 0x32, +0x18, 0xb8, 0x24, 0x14, 0xd2, 0x67, 0x7a, 0x4d, +0xe1, 0xa9, 0x31, 0xa4, 0xd0, 0x44, 0x86, 0x6b, +0xfd, 0x51, 0x16, 0x1b, 0x0c, 0xf6, 0x7c, 0x2c, +0x22, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x98, +0x01, 0x22, 0x21, 0xaa, 0xac, 0xd9, 0xd6, 0xd5, +0x91, 0x7e, 0x7a, 0xfe, 0x81, 0x6b, 0x02, 0x4a, +0x0b, 0x2f, 0x92, 0x95, 0x24, 0x32, 0x5c, 0x62, +0xbf, 0x84, 0x92, 0x4b, 0x3c, 0x31, 0x12, 0x70, +0xc8, 0xf0, 0x46, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0x99, 0x01, 0x22, 0x21, 0x83, 0xcc, 0x7c, +0xf9, 0x26, 0x17, 0xf8, 0x74, 0x06, 0xcf, 0x36, +0x36, 0x02, 0x14, 0xb4, 0xb1, 0x10, 0xc5, 0x17, +0x96, 0xdc, 0x97, 0x45, 0xf5, 0x94, 0x25, 0x87, +0x67, 0x03, 0xf7, 0xb2, 0x36, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9a, 0x01, 0x22, 0x21, 0xdd, +0x39, 0xc8, 0x66, 0x0e, 0xe6, 0x1d, 0x3f, 0xaf, +0xaa, 0x32, 0x54, 0xd8, 0x3f, 0x4a, 0x64, 0xbb, +0xca, 0xeb, 0xee, 0x12, 0x70, 0x38, 0x26, 0x7d, +0x6f, 0x7e, 0x0d, 0x3a, 0x04, 0x8f, 0x48, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9b, 0x01, 0x22, -0x21, 0xc3, 0xde, 0xe1, 0x6c, 0x39, 0xd2, 0x5c, -0x21, 0x6b, 0xe5, 0xf8, 0x6c, 0x64, 0xe9, 0x98, -0x5e, 0xaf, 0xa2, 0x0f, 0x8b, 0xce, 0xc6, 0x8b, -0x74, 0x60, 0xd6, 0xd2, 0x91, 0xe1, 0x58, 0xd5, -0x9b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, -0x01, 0x22, 0x21, 0x01, 0xba, 0x57, 0x77, 0xd7, -0xed, 0xc2, 0x61, 0x30, 0x28, 0x4e, 0x19, 0x9f, -0x09, 0x36, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x2a, 0xde, 0x0d, 0xa5, -0xf9, 0xa1, 0x24, 0x39, 0x03, 0x04, 0x51, 0x02, -0x00, 0x9d, 0x01, 0x22, 0x21, 0x58, 0x82, 0x6d, -0x37, 0xdc, 0x17, 0x71, 0x14, 0x4e, 0x49, 0xbd, -0x41, 0x97, 0x15, 0x82, 0x5a, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x1f, -0x4c, 0x23, 0x86, 0x1b, 0x34, 0x21, 0x03, 0x04, -0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0x44, -0x3a, 0xb4, 0x1b, 0xb1, 0x79, 0x44, 0x55, 0xc6, -0x61, 0x92, 0x19, 0xca, 0x6f, 0x65, 0xf1, 0x82, -0x5a, 0x2a, 0x69, 0x7d, 0xc9, 0x87, 0x59, 0x56, -0x46, 0x07, 0xd2, 0xc7, 0xa5, 0x2c, 0x05, 0x00, +0x21, 0xb8, 0x03, 0x13, 0x1b, 0x5f, 0x0b, 0xa9, +0xa9, 0x57, 0xd1, 0xcb, 0x0b, 0x04, 0xa3, 0xd1, +0x0e, 0x5b, 0x96, 0x19, 0x9f, 0x91, 0x15, 0x2a, +0xb5, 0x5d, 0xc4, 0x02, 0x2a, 0x13, 0xf3, 0x73, +0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9c, +0x01, 0x22, 0x21, 0x60, 0xcd, 0x1b, 0x80, 0x76, +0x52, 0x50, 0x35, 0xa6, 0x33, 0x4e, 0x4c, 0x51, +0xfd, 0xee, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x9c, 0xd2, 0xd5, 0x10, +0x4e, 0x5c, 0x1b, 0x83, 0x03, 0x04, 0x51, 0x02, +0x00, 0x9d, 0x01, 0x22, 0x21, 0xe4, 0x3f, 0x57, +0x15, 0xfa, 0x78, 0x52, 0x2f, 0x23, 0xc6, 0xcf, +0x60, 0x31, 0xf0, 0x2f, 0xfd, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x5a, +0x61, 0xd0, 0x4a, 0x71, 0x9f, 0xb5, 0x03, 0x04, +0x51, 0x02, 0x00, 0x9e, 0x01, 0x22, 0x21, 0xbd, +0x80, 0xc3, 0x3c, 0x2d, 0x90, 0x06, 0x8d, 0x28, +0x54, 0x67, 0x1a, 0x9c, 0xd7, 0xae, 0x2c, 0xda, +0x37, 0xd2, 0x32, 0xdc, 0x8c, 0x50, 0xb0, 0x8f, +0xe4, 0x92, 0xf5, 0xfb, 0x80, 0x58, 0xa1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0x9f, 0x01, 0x22, -0x21, 0x07, 0x9b, 0x31, 0xad, 0xd7, 0x7b, 0xdc, -0x6c, 0x0d, 0xee, 0x68, 0x8b, 0xd9, 0x1d, 0x62, -0x14, 0xe2, 0xb0, 0x98, 0xe4, 0xaf, 0x93, 0xee, -0x03, 0x23, 0xcc, 0xae, 0x8a, 0x16, 0xa4, 0x0e, -0x0e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, -0x01, 0x22, 0x21, 0x7a, 0xdc, 0x1a, 0x4a, 0x3b, -0x6e, 0xb2, 0xbc, 0xc6, 0x4f, 0x51, 0x1d, 0xf6, -0x1d, 0x71, 0xe1, 0xc5, 0xa2, 0xf1, 0x6e, 0xb6, -0x90, 0x13, 0x3b, 0x4d, 0x13, 0xfe, 0xe8, 0xe6, -0x7c, 0x78, 0xa8, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa1, 0x01, 0x22, 0x21, 0xd8, 0x67, 0xf4, -0x0b, 0xc5, 0xee, 0x02, 0x57, 0x42, 0x60, 0xb0, -0x8b, 0x6b, 0xa9, 0x7a, 0x2f, 0x31, 0x2c, 0xd1, -0x2e, 0x13, 0xaf, 0xe4, 0x36, 0x5f, 0xfd, 0xc0, -0x34, 0x74, 0x77, 0xcc, 0x2f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xa4, -0x74, 0x44, 0x94, 0x5b, 0xbf, 0x15, 0xc0, 0x52, -0xbb, 0xfc, 0x8f, 0x36, 0xc8, 0x0f, 0x6f, 0xd9, -0xfa, 0x1c, 0x83, 0x96, 0x88, 0x61, 0xa4, 0xec, -0xb4, 0xa8, 0xf2, 0x4f, 0xe8, 0xf5, 0x7a, 0x00, +0x21, 0x68, 0x26, 0xd0, 0x31, 0x57, 0x67, 0x08, +0x6b, 0x83, 0x4d, 0xf7, 0xed, 0xe7, 0x5d, 0xe3, +0x9c, 0xd3, 0x82, 0x0e, 0x1f, 0x19, 0x1c, 0x30, +0xfd, 0xfa, 0xd4, 0x72, 0x6d, 0x8d, 0x3a, 0x13, +0x22, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa0, +0x01, 0x22, 0x21, 0x6d, 0x83, 0x98, 0x0b, 0xa9, +0x1b, 0x22, 0x85, 0x80, 0x4d, 0x9d, 0xc9, 0x3d, +0x32, 0xa0, 0x07, 0xb0, 0x49, 0x65, 0xcb, 0xd1, +0xac, 0xcd, 0x22, 0x06, 0x5c, 0x58, 0xf7, 0x97, +0xa1, 0xec, 0x32, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa1, 0x01, 0x22, 0x21, 0xdf, 0xb4, 0x73, +0x6e, 0x8a, 0xf7, 0xaf, 0x58, 0xe1, 0xef, 0x33, +0xbd, 0x5f, 0x59, 0x61, 0xe8, 0x81, 0x2c, 0x16, +0xbf, 0x8a, 0xf1, 0x17, 0x6c, 0x93, 0xaa, 0x2c, +0x82, 0xe5, 0x94, 0xd4, 0x9d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa2, 0x01, 0x22, 0x21, 0xf4, +0x5a, 0x79, 0x49, 0xac, 0x63, 0x36, 0x5a, 0x87, +0x70, 0xba, 0xe4, 0xa7, 0xd3, 0xf2, 0xcd, 0x39, +0x95, 0xd2, 0x77, 0xa7, 0x64, 0xfe, 0x66, 0xd8, +0x5b, 0x87, 0x37, 0x5c, 0x54, 0x72, 0x4c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa3, 0x01, 0x22, -0x21, 0xc9, 0xf3, 0x61, 0x9d, 0xdc, 0x4e, 0x33, -0xfe, 0x13, 0x05, 0xfa, 0x59, 0x14, 0xdb, 0x7a, -0xc6, 0x01, 0xd5, 0xc0, 0xce, 0x03, 0x4e, 0x34, -0x0c, 0x57, 0x91, 0x67, 0xfa, 0xda, 0x0d, 0x82, -0x34, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, -0x01, 0x22, 0x21, 0xeb, 0x78, 0x10, 0x4d, 0xe5, -0x1e, 0x99, 0xc6, 0x11, 0xf2, 0xd8, 0x22, 0x18, -0xcb, 0x48, 0xf0, 0xd0, 0x8a, 0xc0, 0xb6, 0xdd, -0x07, 0xf8, 0xf9, 0x53, 0xac, 0x15, 0x10, 0x4a, -0x0e, 0x94, 0x8a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa5, 0x01, 0x22, 0x21, 0x42, 0x4c, 0xa2, -0x3b, 0xec, 0x7b, 0x26, 0x6c, 0x4c, 0xb4, 0xb7, -0xeb, 0xa5, 0xd6, 0x3c, 0xc7, 0x6b, 0x91, 0xf8, -0x88, 0xfa, 0xe8, 0x82, 0xbf, 0xb8, 0x4f, 0x30, -0xd4, 0x9f, 0xd5, 0x96, 0xb5, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0x48, -0xc1, 0x35, 0xe6, 0x23, 0x24, 0x1a, 0x89, 0x3a, -0xfd, 0x2f, 0x52, 0x76, 0xb5, 0x27, 0xa8, 0x42, -0xbc, 0x69, 0x3d, 0x74, 0xe1, 0x9c, 0x06, 0xc0, -0xe3, 0xee, 0x59, 0x4f, 0xec, 0x71, 0x9c, 0x00, +0x21, 0x65, 0xe4, 0x55, 0x92, 0xb0, 0xee, 0xc8, +0x0b, 0xa3, 0xd2, 0x6f, 0xa2, 0xe6, 0xeb, 0x51, +0xa2, 0x46, 0x07, 0xd0, 0xac, 0xfe, 0x8b, 0xec, +0x08, 0xba, 0xa2, 0xce, 0x2f, 0xaf, 0xb9, 0x4a, +0x1c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa4, +0x01, 0x22, 0x21, 0x64, 0x64, 0xb7, 0x5b, 0x05, +0xfa, 0x8a, 0x34, 0xf5, 0x44, 0x3e, 0x21, 0x43, +0x9e, 0xf8, 0xa1, 0xaf, 0x0b, 0x0c, 0x33, 0x93, +0xbd, 0xc4, 0xf9, 0xf5, 0x2c, 0xae, 0xdd, 0xec, +0x00, 0x60, 0xb6, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa5, 0x01, 0x22, 0x21, 0x6e, 0xb1, 0x57, +0x12, 0x6d, 0x40, 0x77, 0x24, 0xe3, 0xac, 0xc2, +0x8b, 0x39, 0x52, 0xab, 0xeb, 0x72, 0xe8, 0x09, +0x74, 0xc0, 0xa1, 0x5e, 0x0b, 0x37, 0x31, 0x41, +0xf9, 0x36, 0xac, 0x1f, 0x41, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xa6, 0x01, 0x22, 0x21, 0xe5, +0x86, 0x9a, 0x05, 0x55, 0xda, 0x08, 0x52, 0x70, +0xc0, 0xe1, 0xec, 0x21, 0x74, 0xb2, 0xda, 0x84, +0x38, 0xc2, 0x77, 0x09, 0x75, 0xf6, 0x9f, 0xb9, +0xf4, 0x4c, 0x4e, 0x93, 0x84, 0xcd, 0x99, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa7, 0x01, 0x22, -0x21, 0x43, 0x97, 0xf4, 0xee, 0x57, 0x26, 0x68, -0x84, 0x3f, 0xb2, 0xc7, 0xaa, 0xc3, 0x34, 0xff, -0x5c, 0xb2, 0x8b, 0xfb, 0x90, 0x1a, 0x3d, 0x43, -0xdd, 0x5b, 0x90, 0xc9, 0x1b, 0xd0, 0x0a, 0x6a, -0xae, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, -0x01, 0x22, 0x21, 0x91, 0x42, 0x3a, 0xf7, 0x8b, -0xfd, 0x5d, 0x10, 0x38, 0xa6, 0xb7, 0x50, 0x46, -0xcb, 0x9f, 0x84, 0xd1, 0x64, 0x37, 0xff, 0x82, -0x94, 0x7b, 0x73, 0xe3, 0xe6, 0xae, 0xd2, 0x94, -0x67, 0xb3, 0x38, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xa9, 0x01, 0x22, 0x21, 0x05, 0xb5, 0x1a, -0x31, 0x63, 0x00, 0xa0, 0xd6, 0x35, 0x71, 0x22, -0xaa, 0xa9, 0x6e, 0x22, 0x18, 0x95, 0x21, 0x11, -0x35, 0xfc, 0xed, 0x4e, 0xac, 0x3b, 0x7c, 0x71, -0x80, 0x69, 0xac, 0x29, 0xa9, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x2d, -0x30, 0xe8, 0x44, 0xfe, 0x80, 0xad, 0x14, 0xa9, -0x85, 0x1f, 0x69, 0x92, 0xca, 0x8c, 0xf7, 0xe9, -0x43, 0xb6, 0x1a, 0xc9, 0x38, 0xe9, 0xa1, 0x98, -0x9f, 0x32, 0x4e, 0x09, 0x81, 0x83, 0x6d, 0x00, +0x21, 0x57, 0xf4, 0xeb, 0xc7, 0x3c, 0xd7, 0x26, +0xc8, 0x7f, 0x4a, 0x96, 0x00, 0x19, 0x01, 0x1e, +0x34, 0xf4, 0x56, 0x13, 0xaa, 0xc5, 0xd0, 0xa2, +0x5e, 0x58, 0x98, 0x2f, 0xf8, 0x35, 0x1f, 0xcf, +0x62, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xa8, +0x01, 0x22, 0x21, 0x89, 0xfa, 0x24, 0x8a, 0x44, +0x4f, 0x5a, 0x60, 0xcb, 0x1a, 0x1c, 0x75, 0x28, +0x0f, 0x84, 0x72, 0x42, 0x94, 0xbd, 0x3b, 0x7a, +0x26, 0xa2, 0x45, 0x95, 0x2e, 0x8e, 0xd0, 0x6a, +0xd5, 0x80, 0x9d, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xa9, 0x01, 0x22, 0x21, 0xcf, 0xb1, 0x52, +0x9b, 0x3b, 0x86, 0xe7, 0xb8, 0x78, 0x5b, 0x67, +0x6b, 0x92, 0x5d, 0xe3, 0x27, 0x87, 0xed, 0x0d, +0x76, 0x3c, 0xb0, 0x6a, 0x84, 0xb2, 0xf7, 0xf2, +0x69, 0xda, 0x91, 0x2a, 0xad, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xaa, 0x01, 0x22, 0x21, 0x95, +0x63, 0x13, 0x24, 0xaf, 0x40, 0xd7, 0x85, 0x2e, +0xe4, 0x8b, 0xeb, 0xf2, 0x6d, 0x28, 0x30, 0x93, +0xac, 0x06, 0x7a, 0x56, 0x50, 0xcd, 0x1e, 0x02, +0x15, 0x54, 0x07, 0x7b, 0x23, 0x3e, 0x70, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xab, 0x01, 0x22, -0x21, 0x42, 0x2b, 0x8e, 0x80, 0x9c, 0x8f, 0xb6, -0x7a, 0xd2, 0xf3, 0xc7, 0x4e, 0x58, 0x73, 0x1d, -0x61, 0xe8, 0x63, 0xb3, 0x5c, 0x7e, 0x7c, 0x25, -0x75, 0xcf, 0x58, 0x53, 0x33, 0x7c, 0xe2, 0x37, -0xaa, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, -0x01, 0x22, 0x21, 0xb6, 0xdf, 0x72, 0x38, 0x8e, -0x18, 0x85, 0x09, 0x11, 0xd8, 0xb2, 0x46, 0xfd, -0x68, 0x59, 0xfd, 0xbe, 0x5d, 0xf4, 0xe3, 0x2a, -0x8c, 0xdb, 0xfa, 0x2d, 0x21, 0x54, 0x60, 0xa2, -0x18, 0x19, 0xea, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xad, 0x01, 0x22, 0x21, 0xcd, 0x1d, 0xfc, -0xf3, 0xc8, 0x39, 0x91, 0x39, 0x97, 0xa1, 0xb0, -0xe5, 0xa4, 0x33, 0x13, 0x2e, 0x07, 0xf6, 0xe2, -0xbd, 0x22, 0xb3, 0x75, 0x1c, 0x9f, 0x22, 0x4a, -0x63, 0xc8, 0x10, 0x63, 0x4e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0xa6, -0x0d, 0xaa, 0x4f, 0xa9, 0x4e, 0xee, 0x9c, 0x31, -0xbb, 0x30, 0x87, 0xcd, 0x31, 0x4d, 0x33, 0xa2, -0xe1, 0x37, 0x26, 0x55, 0xf6, 0x16, 0xbf, 0xb7, -0xaf, 0x26, 0x51, 0x4b, 0xad, 0x2f, 0x9c, 0x00, +0x21, 0x2f, 0x94, 0xce, 0xa7, 0xf9, 0xa6, 0xb3, +0x1b, 0xdf, 0x3b, 0x58, 0x6a, 0xd1, 0x3b, 0x4a, +0x20, 0x3a, 0x0e, 0xf9, 0x24, 0x87, 0x5d, 0x2b, +0xbe, 0x06, 0x2b, 0x97, 0x90, 0xd4, 0xb4, 0x6c, +0x39, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xac, +0x01, 0x22, 0x21, 0x9b, 0x34, 0xaf, 0xac, 0xbc, +0x8c, 0xb2, 0x31, 0xea, 0xb5, 0x3f, 0xc9, 0x2c, +0x07, 0x31, 0x3e, 0x9c, 0x8c, 0x82, 0x4b, 0x73, +0xda, 0x54, 0x1a, 0x49, 0x22, 0xfb, 0x92, 0x18, +0x9c, 0x95, 0xca, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xad, 0x01, 0x22, 0x21, 0x74, 0xed, 0x59, +0xd6, 0x48, 0xcc, 0x39, 0x95, 0xba, 0xfa, 0x8d, +0x5e, 0x9a, 0x04, 0x84, 0xa0, 0xf8, 0x42, 0xfb, +0xe4, 0x76, 0xc9, 0x17, 0xa4, 0x51, 0x6d, 0x7a, +0x95, 0xa5, 0xa5, 0x6d, 0x20, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xae, 0x01, 0x22, 0x21, 0xfa, +0x62, 0xf6, 0x6f, 0xb4, 0xec, 0xd2, 0xd6, 0x1a, +0x17, 0x9a, 0x87, 0x3b, 0x4b, 0x2c, 0x82, 0xac, +0xc4, 0x7f, 0x87, 0x21, 0xf8, 0xa6, 0x7f, 0x43, +0x19, 0x7d, 0x3c, 0x27, 0x24, 0x96, 0xc7, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xaf, 0x01, 0x22, -0x21, 0x1a, 0x77, 0xd8, 0x66, 0x9a, 0x41, 0x04, -0xb4, 0x20, 0x45, 0xf7, 0x48, 0xc7, 0xc1, 0x01, -0x6b, 0xf2, 0xa1, 0x5b, 0x6c, 0xa3, 0x32, 0x5f, -0x3d, 0x34, 0xea, 0xbd, 0x54, 0xad, 0x0a, 0xc7, -0x1e, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, -0x01, 0x22, 0x21, 0x1e, 0x10, 0x6b, 0x02, 0x73, -0x70, 0x55, 0xd1, 0xe1, 0xda, 0x47, 0x70, 0xa1, -0x88, 0x8e, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x63, 0xd1, 0x0f, 0xf3, -0xd4, 0xa7, 0x34, 0x70, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb1, 0x01, 0x22, 0x21, 0x4a, 0x18, 0x38, -0xb7, 0x8b, 0xcf, 0x8f, 0xb8, 0x1b, 0xf1, 0x68, -0x41, 0x3f, 0x13, 0x45, 0x2d, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xfc, -0x15, 0x08, 0x52, 0xcc, 0x2a, 0x2e, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0x7e, -0xc6, 0xa6, 0x18, 0xae, 0x61, 0xa3, 0x5e, 0xc2, -0x45, 0xad, 0x69, 0xd4, 0xfb, 0x08, 0x9d, 0xa2, -0xf9, 0x9f, 0x5f, 0xb0, 0x6d, 0xd9, 0xa7, 0x5c, -0x90, 0xd1, 0xd1, 0x88, 0x19, 0x8c, 0xea, 0x00, +0x21, 0xbf, 0x0a, 0x41, 0x06, 0xb6, 0xb8, 0xa8, +0x64, 0x78, 0x9a, 0xbd, 0x9f, 0xd6, 0xe6, 0xfc, +0x29, 0xc9, 0x63, 0x70, 0xff, 0xba, 0x93, 0x6c, +0x6c, 0xf2, 0x3e, 0x6a, 0xb2, 0x71, 0x49, 0x5c, +0x56, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb0, +0x01, 0x22, 0x21, 0xfe, 0x47, 0xba, 0x04, 0x25, +0x87, 0xfb, 0x10, 0xd1, 0xac, 0xeb, 0xc4, 0x38, +0x3f, 0x81, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0xc6, 0x36, +0x1f, 0x63, 0x8d, 0xb9, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb1, 0x01, 0x22, 0x21, 0x00, 0x40, 0x88, +0xe3, 0xbb, 0x78, 0x1b, 0xda, 0x60, 0x72, 0xd3, +0xdd, 0x17, 0x15, 0x2a, 0xcf, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xb1, +0x81, 0x65, 0x7a, 0x08, 0x8b, 0xd8, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb2, 0x01, 0x22, 0x21, 0x2c, +0x99, 0x4a, 0x54, 0x5b, 0x92, 0x9d, 0x71, 0x2c, +0x2a, 0x93, 0x80, 0x1c, 0x55, 0xe0, 0x51, 0x4c, +0x4a, 0x4a, 0x24, 0xaf, 0x73, 0xb2, 0xf6, 0x27, +0x47, 0x33, 0x81, 0xc6, 0x44, 0xed, 0xe3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb3, 0x01, 0x22, -0x21, 0xea, 0x51, 0xbb, 0xbd, 0x47, 0xce, 0x5e, -0x4e, 0x93, 0x7b, 0x08, 0x64, 0x87, 0x52, 0xe1, -0xac, 0x0b, 0x1b, 0x39, 0x8d, 0xa4, 0x74, 0x2f, -0x58, 0x84, 0x94, 0x1f, 0x73, 0x11, 0x28, 0x88, -0xf3, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, -0x01, 0x22, 0x21, 0xd1, 0x35, 0x59, 0x85, 0x6e, -0xb8, 0xe8, 0xa7, 0xa4, 0x06, 0xcb, 0x86, 0x51, -0x8a, 0x14, 0x27, 0x06, 0x2c, 0x76, 0xcf, 0xf3, -0x14, 0xf2, 0x22, 0xce, 0x6c, 0x3b, 0xc6, 0x4d, -0xdc, 0x80, 0x54, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb5, 0x01, 0x22, 0x21, 0x0e, 0x44, 0x16, -0x37, 0x4c, 0xdf, 0x3d, 0xc9, 0x20, 0xc3, 0x43, -0xd9, 0xe0, 0xcc, 0x67, 0x9b, 0xc2, 0xc5, 0xe7, -0xd8, 0x07, 0xe5, 0x9c, 0xcd, 0xb3, 0x13, 0x95, -0x0a, 0x62, 0x55, 0xf7, 0x45, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0x99, -0xb5, 0xbf, 0x77, 0xd7, 0x1a, 0x76, 0x80, 0x61, -0xe6, 0x38, 0x30, 0x07, 0xae, 0xb9, 0xa2, 0x30, -0xfe, 0xcc, 0x9f, 0x87, 0x73, 0x8a, 0xe0, 0x11, -0x5e, 0x9c, 0xf5, 0xf2, 0x5b, 0x31, 0xd2, 0x00, +0x21, 0x47, 0xfd, 0xc1, 0x3a, 0xbf, 0xf2, 0x8f, +0x27, 0x6b, 0x35, 0xad, 0x62, 0x44, 0xbf, 0xd0, +0x1e, 0xd6, 0xfe, 0x4c, 0x3a, 0x15, 0x63, 0xda, +0xb5, 0x7a, 0x8e, 0x9d, 0xa0, 0x7c, 0x95, 0x4f, +0x04, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb4, +0x01, 0x22, 0x21, 0x9d, 0xe8, 0x8e, 0x02, 0xfc, +0x45, 0x2e, 0x2c, 0x23, 0x04, 0xf9, 0xdf, 0x4e, +0x6b, 0x1c, 0xd3, 0xf5, 0x65, 0xe5, 0x6c, 0xbd, +0xf6, 0xab, 0x5f, 0x24, 0x81, 0x70, 0xba, 0x06, +0x11, 0xdc, 0x6c, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb5, 0x01, 0x22, 0x21, 0xc9, 0xb0, 0xe0, +0xd4, 0x21, 0x5a, 0xf6, 0xd5, 0x35, 0xe3, 0x21, +0x8a, 0xb9, 0x88, 0x69, 0x69, 0x0a, 0xba, 0x6c, +0x4f, 0x5d, 0x66, 0xa1, 0x85, 0xf4, 0x61, 0x0a, +0x6d, 0x2f, 0x43, 0x7e, 0x46, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xb6, 0x01, 0x22, 0x21, 0x80, +0x53, 0x94, 0x29, 0xc0, 0xc0, 0x12, 0x5c, 0xd5, +0x7a, 0x07, 0xe5, 0x40, 0x82, 0xf0, 0x75, 0x09, +0x46, 0x34, 0xcf, 0xe3, 0x0c, 0x36, 0x9b, 0x04, +0xfc, 0x0e, 0x67, 0xe0, 0x80, 0xf5, 0xe6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb7, 0x01, 0x22, -0x21, 0xbc, 0x28, 0x1e, 0x2f, 0x5a, 0x94, 0xc2, -0xe3, 0x2f, 0xe5, 0xeb, 0xcd, 0x3e, 0xda, 0x12, -0x3d, 0x15, 0xaa, 0x53, 0xf2, 0x06, 0xd5, 0x72, -0x1a, 0x96, 0x76, 0xbd, 0x40, 0x8c, 0xcd, 0x6d, -0xdf, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, -0x01, 0x22, 0x21, 0xe8, 0x5e, 0x59, 0x2e, 0x6a, -0xbf, 0x62, 0xe8, 0x1c, 0x46, 0x2b, 0xe7, 0x2d, -0xe0, 0x7a, 0x63, 0xd1, 0x7c, 0xed, 0x0b, 0x3d, -0xce, 0x1f, 0x69, 0xf9, 0x43, 0x87, 0x1e, 0x1a, -0x5b, 0xda, 0xb6, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xb9, 0x01, 0x22, 0x21, 0x1a, 0x2a, 0x78, -0xab, 0x8d, 0xd9, 0x0a, 0x20, 0x39, 0xbe, 0x2e, -0x3e, 0x40, 0xf6, 0x51, 0xd3, 0x43, 0xd7, 0x39, -0x18, 0xbc, 0x0d, 0x44, 0xd8, 0x1d, 0x60, 0xba, -0xc4, 0xbc, 0x78, 0x98, 0x33, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0xd0, -0x64, 0xe4, 0x8e, 0x6c, 0xd4, 0x47, 0x5c, 0x65, -0x73, 0xee, 0x0b, 0x46, 0x80, 0xd2, 0x06, 0x86, -0xe5, 0x19, 0xc4, 0xff, 0x22, 0x86, 0x57, 0x4c, -0xed, 0xa0, 0x0d, 0x7d, 0x6d, 0x60, 0x8a, 0x00, +0x21, 0x25, 0x72, 0x1c, 0xcf, 0x32, 0x46, 0xb3, +0xb8, 0x74, 0x27, 0x17, 0xc5, 0x39, 0xc7, 0x87, +0x81, 0x91, 0x0f, 0xe8, 0xdd, 0x76, 0x9d, 0xd4, +0xa7, 0xc7, 0x54, 0xc4, 0x23, 0xd0, 0xe7, 0x67, +0x35, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xb8, +0x01, 0x22, 0x21, 0xfe, 0x81, 0x60, 0x7d, 0x0a, +0xc9, 0x44, 0x50, 0x8c, 0x62, 0x51, 0x9a, 0x24, +0xa0, 0xd0, 0x3f, 0xa1, 0xcf, 0xca, 0x71, 0xfe, +0xe7, 0xff, 0x0b, 0xe4, 0x43, 0xb9, 0xd3, 0x89, +0xac, 0x58, 0x33, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xb9, 0x01, 0x22, 0x21, 0x94, 0x53, 0x7e, +0xa1, 0xe0, 0x70, 0xea, 0x86, 0x02, 0x42, 0x89, +0x8a, 0xad, 0x5a, 0xc2, 0x80, 0x52, 0x22, 0x8c, +0x95, 0x79, 0x68, 0x6f, 0x5b, 0x9d, 0x41, 0xd6, +0x83, 0xba, 0x59, 0x61, 0x46, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xba, 0x01, 0x22, 0x21, 0x15, +0xd5, 0x65, 0x8a, 0xd7, 0xb6, 0x7d, 0x20, 0x94, +0x76, 0x37, 0x12, 0x66, 0xc9, 0xa2, 0x2e, 0xab, +0x2f, 0x51, 0x79, 0x3c, 0x08, 0xe4, 0x14, 0x49, +0xb6, 0xe9, 0xd2, 0xda, 0x56, 0x67, 0x46, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbb, 0x01, 0x22, -0x21, 0x75, 0x12, 0x85, 0xaf, 0x41, 0x4b, 0xa1, -0xe2, 0x62, 0xf3, 0xf1, 0x75, 0xbd, 0xec, 0x33, -0x43, 0x95, 0x8b, 0x71, 0x91, 0xbe, 0x66, 0xb7, -0x14, 0x63, 0xa1, 0x43, 0xe3, 0x36, 0xb3, 0x28, -0x01, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, -0x01, 0x22, 0x21, 0x0d, 0x49, 0x08, 0x2c, 0x32, -0x23, 0x00, 0x29, 0x56, 0x97, 0xd2, 0x4d, 0xc2, -0x46, 0x62, 0x33, 0x79, 0x74, 0x8b, 0xdc, 0x3e, -0xe9, 0x1c, 0x35, 0xc3, 0x57, 0xed, 0x6f, 0x2d, -0x28, 0xc1, 0x88, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xbd, 0x01, 0x22, 0x21, 0xbf, 0xab, 0x48, -0x3b, 0x0b, 0xee, 0xe9, 0x48, 0x8f, 0xd9, 0x82, -0xf1, 0xdc, 0x63, 0xfc, 0x96, 0xc1, 0x03, 0x1f, -0x00, 0x48, 0xd2, 0xd5, 0x52, 0xdf, 0x25, 0x7a, -0xbf, 0xcd, 0xa8, 0x37, 0x68, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0xc2, -0xf5, 0x5b, 0xf5, 0xf6, 0x04, 0x6e, 0x04, 0xda, -0x51, 0xa2, 0x0d, 0xbd, 0x37, 0xca, 0xca, 0xc4, -0x78, 0x7c, 0xcd, 0xb9, 0xac, 0x4b, 0xd5, 0x61, -0xf0, 0xe4, 0xa3, 0xae, 0x3f, 0xe8, 0x46, 0x00, +0x21, 0xf6, 0xd6, 0x12, 0xa0, 0x7e, 0xd1, 0x6c, +0x19, 0x9d, 0xf8, 0x1d, 0x72, 0x3a, 0xc0, 0x3a, +0x04, 0xe1, 0x14, 0x88, 0x16, 0xdb, 0x69, 0x21, +0x67, 0xe9, 0x98, 0x03, 0x8d, 0x20, 0xe6, 0x9e, +0x7a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbc, +0x01, 0x22, 0x21, 0xe3, 0x62, 0x73, 0xd9, 0xdd, +0x3a, 0x16, 0x97, 0x97, 0xe8, 0x37, 0x11, 0x23, +0x2c, 0x0a, 0xcf, 0x25, 0x0a, 0xb0, 0x4f, 0xc3, +0x5c, 0x7c, 0x02, 0xab, 0xed, 0x4c, 0x87, 0x1e, +0xd1, 0x77, 0xc2, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xbd, 0x01, 0x22, 0x21, 0x30, 0xcf, 0x02, +0x5f, 0x7d, 0x6c, 0x35, 0xe0, 0x43, 0x3b, 0xab, +0xf9, 0xa6, 0x7b, 0xaf, 0x06, 0x23, 0x58, 0x70, +0xf8, 0x5a, 0x69, 0x23, 0x4f, 0xc8, 0x0b, 0x7e, +0x90, 0x52, 0xf4, 0x22, 0x6d, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xbe, 0x01, 0x22, 0x21, 0xd4, +0xa7, 0xa9, 0x6c, 0x1c, 0x49, 0x5b, 0xce, 0xc5, +0xcf, 0xb5, 0x5b, 0x7e, 0x2d, 0xaa, 0x93, 0x95, +0x64, 0xd7, 0xdd, 0x25, 0x9b, 0x01, 0x91, 0xe7, +0x96, 0xe5, 0x53, 0x77, 0x2b, 0x12, 0x76, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xbf, 0x01, 0x22, -0x21, 0xaa, 0x99, 0x82, 0xb2, 0x75, 0xd7, 0x23, -0xeb, 0x42, 0x3c, 0x5a, 0xcc, 0x89, 0x6b, 0xd0, -0x60, 0x9e, 0x31, 0x3b, 0x3c, 0x12, 0x30, 0x9c, -0x81, 0xd8, 0xed, 0xa4, 0xd3, 0x48, 0x6e, 0x85, -0x2a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, -0x01, 0x22, 0x21, 0x49, 0x89, 0x2e, 0x15, 0xc8, -0x0d, 0xeb, 0xf8, 0x37, 0x07, 0x34, 0xd4, 0xd2, -0xf5, 0x1f, 0x00, 0xea, 0x5a, 0x83, 0x23, 0x27, -0xd5, 0xd3, 0x6e, 0x1c, 0x58, 0x38, 0x6d, 0xed, -0xb7, 0xfa, 0xfa, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc1, 0x01, 0x22, 0x21, 0x80, 0x1c, 0x24, -0x29, 0xac, 0xce, 0x13, 0x34, 0x2f, 0xcc, 0x05, -0x88, 0x4c, 0x75, 0x9b, 0xd0, 0xc1, 0x2b, 0xf2, -0x2b, 0x1a, 0x59, 0x97, 0xeb, 0x28, 0xde, 0x81, -0x58, 0xdd, 0x58, 0x0f, 0xe6, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0x08, -0x16, 0xc6, 0x02, 0x43, 0x33, 0xab, 0xe5, 0x94, -0xcd, 0xbc, 0xca, 0x77, 0xa1, 0xf1, 0x38, 0xd7, -0x89, 0xa7, 0x15, 0xbe, 0x7b, 0xf0, 0x7d, 0xdb, -0xea, 0xe3, 0xee, 0xca, 0x69, 0xf2, 0x49, 0x00, +0x21, 0x64, 0x55, 0x7a, 0x6f, 0x29, 0xed, 0x2d, +0x76, 0x6b, 0x69, 0x0b, 0x49, 0xe2, 0xb5, 0x38, +0xac, 0xcc, 0x3d, 0x24, 0xd2, 0xe8, 0x7e, 0xbe, +0xd7, 0xfc, 0x27, 0xfd, 0xc1, 0x0b, 0xb4, 0xbb, +0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc0, +0x01, 0x22, 0x21, 0xef, 0xa2, 0x3c, 0x4d, 0xbd, +0x10, 0x66, 0x4c, 0xa0, 0xca, 0x41, 0xd9, 0xe1, +0xbc, 0xd7, 0xe3, 0xe1, 0x5d, 0x85, 0x11, 0xf6, +0xa5, 0x96, 0x41, 0xcd, 0x26, 0x38, 0x6f, 0x63, +0xf2, 0xc3, 0xb3, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc1, 0x01, 0x22, 0x21, 0x14, 0x29, 0x53, +0x07, 0xd2, 0x42, 0xfc, 0xf3, 0xfe, 0xff, 0xaf, +0x87, 0x22, 0x30, 0x50, 0x37, 0x4c, 0xfa, 0x32, +0xed, 0x65, 0xc8, 0x57, 0xd8, 0xa1, 0xdd, 0xd1, +0xae, 0xcc, 0xb1, 0x17, 0xac, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc2, 0x01, 0x22, 0x21, 0x5c, +0x94, 0x3f, 0xf5, 0x9d, 0xaa, 0x7d, 0xe5, 0x11, +0xa4, 0x89, 0xee, 0x0c, 0xab, 0x71, 0xaa, 0x59, +0x1d, 0x5e, 0xae, 0x98, 0x4a, 0x31, 0x6e, 0xee, +0xec, 0x30, 0x71, 0xfc, 0x6e, 0x91, 0xf9, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc3, 0x01, 0x22, -0x21, 0x68, 0xfc, 0x79, 0x88, 0xa1, 0xb6, 0x26, -0x50, 0x3e, 0x67, 0xd5, 0xc5, 0x82, 0xa1, 0x58, -0xcf, 0x44, 0x26, 0xe3, 0xf5, 0x9f, 0x79, 0xf2, -0x0f, 0x6f, 0x5d, 0x2b, 0x3b, 0x0b, 0xa3, 0x62, -0x30, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, -0x01, 0x22, 0x21, 0x14, 0xe3, 0xf7, 0x7d, 0xc5, -0x55, 0xaf, 0xf7, 0xb7, 0x30, 0xe7, 0x42, 0xf5, -0xeb, 0xe6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xaa, 0x31, 0xfd, 0x79, -0xa9, 0x39, 0x86, 0x88, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc5, 0x01, 0x22, 0x21, 0x2b, 0xea, 0xb9, -0x0d, 0x9d, 0x7c, 0x33, 0x0f, 0x27, 0xb1, 0x5e, -0x33, 0x79, 0x62, 0x1c, 0x2c, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x0e, -0xb4, 0x95, 0xf5, 0x65, 0x28, 0x56, 0x03, 0x04, -0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0xf9, -0x0c, 0x1d, 0xbe, 0x38, 0x01, 0xb8, 0xe3, 0xb8, -0xaa, 0xd4, 0x9c, 0xe6, 0x66, 0xb1, 0x3d, 0xec, -0x39, 0x00, 0xbf, 0xdd, 0x28, 0xb8, 0x0c, 0x53, -0x83, 0xcd, 0xbe, 0x82, 0xc8, 0x7a, 0xe3, 0x00, +0x21, 0xcb, 0x6a, 0xab, 0xc4, 0x67, 0x48, 0xa7, +0xe8, 0x11, 0x1a, 0x89, 0x89, 0x55, 0x00, 0x59, +0xb4, 0xcd, 0xa1, 0x77, 0xf5, 0x24, 0xc5, 0xd0, +0x57, 0x58, 0xaa, 0xcd, 0x46, 0x7a, 0x34, 0x14, +0x87, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc4, +0x01, 0x22, 0x21, 0x58, 0x3e, 0x0f, 0x7e, 0xf5, +0x5d, 0x90, 0x8b, 0x24, 0x11, 0xb6, 0xd1, 0xe8, +0xa7, 0x53, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x37, 0xf8, +0x6d, 0x9e, 0x9c, 0xee, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc5, 0x01, 0x22, 0x21, 0xc6, 0xc9, 0xa4, +0xbd, 0xb6, 0x99, 0x21, 0xea, 0x37, 0xb8, 0xfc, +0x33, 0x5a, 0xa9, 0x3e, 0x60, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdd, +0x3d, 0x37, 0xa2, 0x12, 0x28, 0xb1, 0x03, 0x04, +0x51, 0x02, 0x00, 0xc6, 0x01, 0x22, 0x21, 0xc9, +0xd8, 0xe8, 0xa8, 0xe7, 0xa3, 0xce, 0x0d, 0xe6, +0x54, 0x06, 0x48, 0x68, 0x56, 0xb4, 0x38, 0x4b, +0x97, 0x6a, 0xfd, 0x26, 0x81, 0x33, 0x25, 0xe0, +0x82, 0xe4, 0x24, 0x1d, 0xc8, 0xdb, 0x65, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc7, 0x01, 0x22, -0x21, 0xc8, 0xc0, 0x8d, 0x42, 0xee, 0x63, 0x28, -0x5c, 0xe2, 0x6e, 0x0e, 0x8b, 0xe6, 0x3f, 0xb1, -0x2c, 0x80, 0x20, 0x0d, 0x77, 0xcb, 0x8f, 0x17, -0xee, 0x54, 0x42, 0xf6, 0x4c, 0x87, 0xb2, 0xcb, -0x31, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, -0x01, 0x22, 0x21, 0x32, 0xf2, 0xd0, 0x07, 0x2a, -0xdf, 0x55, 0xf6, 0x71, 0x84, 0xad, 0xe3, 0x99, -0x3e, 0xa2, 0x7f, 0x93, 0xa8, 0xdb, 0x8b, 0xb7, -0x58, 0x19, 0xc2, 0xc0, 0x31, 0xa3, 0x2c, 0xab, -0x2d, 0xcb, 0x3f, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xc9, 0x01, 0x22, 0x21, 0x73, 0xe7, 0x3f, -0x71, 0x5b, 0x02, 0x19, 0xc5, 0x76, 0xca, 0x5e, -0x91, 0xb1, 0xcc, 0x85, 0xb5, 0xea, 0xe0, 0x2f, -0x50, 0x57, 0x97, 0xbb, 0x3c, 0xba, 0x9c, 0x8e, -0x93, 0x44, 0x87, 0x38, 0x2e, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0x70, -0x27, 0x12, 0x65, 0x32, 0x1b, 0x60, 0x7e, 0xdd, -0xf0, 0x82, 0xa0, 0x03, 0x7b, 0x3a, 0x98, 0xbd, -0x84, 0xb3, 0x3c, 0x58, 0xc3, 0x07, 0x23, 0xec, -0xeb, 0x5e, 0x9a, 0xa4, 0xdc, 0xd9, 0x34, 0x00, +0x21, 0x7a, 0x49, 0x0d, 0xa5, 0x2f, 0xd9, 0x57, +0x84, 0xae, 0x6d, 0x82, 0xfd, 0xef, 0x8b, 0x2f, +0x44, 0x73, 0xf1, 0x74, 0x48, 0x7a, 0x06, 0xa6, +0x08, 0x2e, 0x18, 0x84, 0x45, 0xa9, 0x80, 0xf4, +0x59, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xc8, +0x01, 0x22, 0x21, 0x4c, 0x35, 0x75, 0x99, 0xb2, +0x91, 0x74, 0xbf, 0x82, 0x16, 0x4d, 0x1a, 0x24, +0x5c, 0x84, 0x25, 0x54, 0x40, 0x29, 0x1e, 0x57, +0x88, 0x52, 0x49, 0x04, 0x30, 0xab, 0x77, 0xfe, +0xe5, 0x76, 0x15, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xc9, 0x01, 0x22, 0x21, 0x81, 0xf7, 0xfa, +0x09, 0xdd, 0x20, 0x52, 0x0e, 0xe7, 0x7a, 0x98, +0xb4, 0x7c, 0x9e, 0x36, 0xea, 0xe0, 0x11, 0x88, +0x46, 0x6f, 0xd3, 0xe3, 0x10, 0x3e, 0xf6, 0x26, +0x46, 0x51, 0xa6, 0xce, 0xe8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xca, 0x01, 0x22, 0x21, 0x5c, +0xfe, 0x50, 0x56, 0x5d, 0xa9, 0xab, 0xf7, 0x08, +0x81, 0xb7, 0x6e, 0x21, 0xef, 0x6d, 0x15, 0x11, +0x70, 0x99, 0x95, 0x1a, 0x19, 0x89, 0xab, 0xb8, +0x6c, 0x55, 0x6a, 0x45, 0x4f, 0x55, 0xac, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcb, 0x01, 0x22, -0x21, 0x6e, 0xe6, 0xce, 0x4a, 0x6a, 0x6f, 0x02, -0xaf, 0x5a, 0x3b, 0x9a, 0xa6, 0xad, 0xab, 0x45, -0x5a, 0x25, 0xfb, 0x0a, 0x1e, 0xe6, 0x9f, 0x2f, -0x3a, 0xc3, 0x92, 0x23, 0x18, 0x39, 0xc5, 0x72, -0x43, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, -0x01, 0x22, 0x21, 0x5f, 0x63, 0xd4, 0x14, 0x87, -0x8f, 0x14, 0xf3, 0x73, 0x19, 0xc1, 0x77, 0x72, -0xb2, 0xd1, 0x57, 0x07, 0xc4, 0x21, 0x4b, 0xba, -0x40, 0x0b, 0x1c, 0x2e, 0x87, 0xb2, 0xfd, 0xdb, -0xa1, 0x86, 0xbb, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xcd, 0x01, 0x22, 0x21, 0x14, 0x1d, 0x6f, -0xb0, 0x79, 0xab, 0x78, 0x71, 0x58, 0xf8, 0xa1, -0x8f, 0x89, 0x18, 0x97, 0x74, 0x62, 0x5d, 0xed, -0x1e, 0xcb, 0x49, 0x0d, 0x08, 0xc2, 0x6f, 0x6e, -0xda, 0x80, 0x4f, 0x1e, 0x2f, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0x3c, -0x7a, 0x07, 0xa1, 0x5c, 0xd8, 0x22, 0xf0, 0x01, -0x7b, 0xfe, 0x61, 0x8d, 0x2d, 0x2f, 0x2f, 0x9f, -0xe9, 0x45, 0x35, 0xf3, 0xc5, 0x25, 0x8d, 0x78, -0x17, 0x29, 0x31, 0xa5, 0x93, 0x0b, 0x30, 0x00, +0x21, 0x6f, 0x0f, 0x23, 0x8b, 0xee, 0x53, 0x18, +0xdb, 0x82, 0x8a, 0x87, 0x84, 0xf1, 0x07, 0xa0, +0x7a, 0x7b, 0x81, 0xc9, 0xf2, 0x70, 0x11, 0x74, +0xa7, 0xc5, 0x80, 0x1e, 0xda, 0x4d, 0x40, 0xa4, +0x98, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcc, +0x01, 0x22, 0x21, 0x89, 0x93, 0xfe, 0xbb, 0x42, +0x3e, 0xbe, 0x7e, 0xc8, 0xe8, 0xe6, 0xb6, 0x03, +0xeb, 0x53, 0xfe, 0x12, 0xae, 0x7e, 0xe7, 0x14, +0x02, 0x02, 0x77, 0x1b, 0xb1, 0x4b, 0x44, 0xf0, +0x92, 0xd6, 0xd9, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xcd, 0x01, 0x22, 0x21, 0x20, 0x7b, 0x6e, +0x6c, 0xc0, 0x06, 0xf4, 0x83, 0xb6, 0xc5, 0xd9, +0xe8, 0x65, 0xb6, 0x99, 0xd6, 0xcb, 0xd5, 0xee, +0x93, 0xdb, 0x6a, 0x14, 0x55, 0xf7, 0x92, 0x2a, +0x9e, 0xb1, 0x12, 0x4a, 0xbd, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xce, 0x01, 0x22, 0x21, 0xef, +0xa6, 0x11, 0xdc, 0x4d, 0x17, 0xf1, 0x8b, 0xb4, +0xe6, 0xc0, 0x6f, 0x5d, 0x1a, 0x7a, 0xae, 0xc6, +0x53, 0x95, 0x14, 0xf2, 0x2b, 0x9d, 0x24, 0xf7, +0xa5, 0xd4, 0x27, 0x84, 0x19, 0x5d, 0x7f, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xcf, 0x01, 0x22, -0x21, 0x9d, 0x67, 0x33, 0x3f, 0x51, 0x25, 0x80, -0xf0, 0xe0, 0x3d, 0x5e, 0x83, 0x22, 0x74, 0x94, -0x79, 0xf8, 0x17, 0x35, 0x58, 0x33, 0xf2, 0x27, -0x6f, 0x38, 0x65, 0x68, 0x5b, 0x24, 0xc0, 0xfa, -0x71, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, -0x01, 0x22, 0x21, 0xfe, 0xaf, 0x56, 0x03, 0x58, -0xf0, 0xe6, 0xf9, 0xee, 0x11, 0x38, 0x67, 0x04, -0x6e, 0x4f, 0x18, 0x83, 0x5b, 0xbd, 0x01, 0x06, -0xcb, 0x49, 0x87, 0xbc, 0x7a, 0xea, 0x2a, 0xf0, -0xdf, 0x80, 0x35, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd1, 0x01, 0x22, 0x21, 0x10, 0x6a, 0x4d, -0x39, 0xfc, 0xdc, 0xfb, 0x71, 0xb4, 0x5a, 0xd5, -0x8c, 0xe9, 0xb1, 0x5a, 0x39, 0x3b, 0x6b, 0x50, -0xd9, 0x4a, 0x1e, 0x3c, 0xad, 0x66, 0x9d, 0xb8, -0x11, 0xf5, 0xc8, 0x3d, 0x48, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x1e, -0x2c, 0xe7, 0xc2, 0x2e, 0xb1, 0x28, 0xd8, 0x56, -0xf1, 0x1c, 0xf0, 0x4f, 0x7a, 0x44, 0xb4, 0xe7, -0xab, 0x0b, 0x9e, 0xe1, 0xbe, 0x7e, 0x94, 0x94, -0xbb, 0x41, 0x4e, 0x61, 0x20, 0xb6, 0x08, 0x00, +0x21, 0x12, 0xcb, 0x87, 0xb1, 0xf6, 0x27, 0xd8, +0x22, 0xa2, 0xc4, 0x16, 0x41, 0x8e, 0xb7, 0x1a, +0xa1, 0x07, 0xbf, 0x34, 0x93, 0x3b, 0x88, 0xee, +0xda, 0x97, 0xe7, 0xf8, 0xa4, 0xa9, 0x1d, 0x5e, +0x8b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd0, +0x01, 0x22, 0x21, 0xd9, 0xfd, 0x7c, 0x05, 0x0f, +0x11, 0xde, 0xfa, 0xb3, 0x66, 0x1a, 0x2d, 0xe2, +0x69, 0x86, 0xcc, 0x2e, 0x53, 0x0a, 0xc2, 0xcb, +0xc8, 0x13, 0x7a, 0x0b, 0xe2, 0xbf, 0x64, 0x55, +0x81, 0x37, 0xff, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd1, 0x01, 0x22, 0x21, 0x98, 0x44, 0x17, +0x9a, 0xe1, 0x93, 0xf3, 0x43, 0x62, 0x76, 0x3e, +0xc8, 0xe4, 0x98, 0x39, 0xfe, 0x78, 0x24, 0x78, +0x66, 0x1b, 0xd6, 0x36, 0x35, 0xfa, 0x2e, 0xb9, +0x4c, 0x26, 0x89, 0x50, 0x33, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd2, 0x01, 0x22, 0x21, 0x2c, +0x51, 0x50, 0xc2, 0x25, 0x81, 0xc5, 0x45, 0x69, +0x4f, 0x2d, 0x94, 0xfc, 0xba, 0x48, 0x8f, 0x42, +0xf1, 0x96, 0x93, 0x2b, 0xff, 0x2d, 0x02, 0x91, +0x81, 0xcf, 0x18, 0x3e, 0x1c, 0x8a, 0xf6, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd3, 0x01, 0x22, -0x21, 0xae, 0x99, 0xa5, 0xc3, 0x73, 0xe4, 0x30, -0x1f, 0xd1, 0xeb, 0xc4, 0x43, 0xa0, 0xd3, 0x2a, -0x17, 0x27, 0x4c, 0xb6, 0xc7, 0x14, 0xde, 0x24, -0x3c, 0xd4, 0x00, 0x10, 0xb8, 0x33, 0xe4, 0x5a, -0x81, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, -0x01, 0x22, 0x21, 0xc3, 0x27, 0xdd, 0x80, 0x3b, -0xb8, 0x06, 0x47, 0x03, 0x9c, 0xbb, 0x13, 0xef, -0x4a, 0xc6, 0x60, 0xa8, 0x35, 0x66, 0x6d, 0x95, -0x47, 0x84, 0x60, 0x75, 0xbf, 0x5e, 0x9a, 0xf1, -0x73, 0x27, 0x35, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd5, 0x01, 0x22, 0x21, 0xf2, 0x03, 0x49, -0x3b, 0xfc, 0xe2, 0xca, 0x2f, 0xae, 0xef, 0xe9, -0xbc, 0xef, 0xab, 0x9d, 0x15, 0x4b, 0xab, 0xf3, -0xdf, 0xea, 0x9a, 0x6c, 0xb3, 0xb4, 0x09, 0x39, -0x49, 0x74, 0xca, 0xd1, 0x78, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0x9c, -0x3b, 0x51, 0xe4, 0xb1, 0x5f, 0x6e, 0xf1, 0xa2, -0x85, 0x59, 0xbf, 0xed, 0x07, 0x6a, 0xb4, 0x80, -0xa3, 0xe4, 0xc5, 0x15, 0x30, 0xe7, 0xdb, 0x64, -0x0d, 0xcf, 0x0e, 0x5e, 0x61, 0x23, 0x42, 0x00, +0x21, 0xe6, 0xc1, 0xcf, 0x40, 0xd3, 0x20, 0xe5, +0x8a, 0xbf, 0x5a, 0x1e, 0x51, 0x26, 0xd0, 0xa0, +0x7f, 0x8c, 0xa1, 0x0a, 0x5c, 0x3f, 0xef, 0xe2, +0x54, 0xd3, 0xa0, 0xd1, 0x49, 0x07, 0x07, 0xb9, +0x76, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd4, +0x01, 0x22, 0x21, 0x1f, 0xbe, 0xbf, 0xbf, 0x6f, +0xa4, 0x40, 0xe3, 0x3b, 0xde, 0xe4, 0x4f, 0x6a, +0x66, 0xe6, 0xfc, 0xcc, 0xdf, 0xe3, 0xd4, 0x6d, +0xd2, 0x5b, 0x2a, 0x45, 0x0d, 0xcf, 0x19, 0x7a, +0x8e, 0x2c, 0xbd, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd5, 0x01, 0x22, 0x21, 0xf6, 0xd5, 0x38, +0x91, 0xa9, 0x6d, 0x97, 0x1a, 0x34, 0xec, 0x31, +0x82, 0xef, 0xbb, 0x5d, 0x77, 0xb2, 0xb5, 0x98, +0x32, 0x73, 0xfb, 0x09, 0x23, 0x6f, 0xb6, 0x41, +0x9a, 0xfe, 0x75, 0x01, 0xc8, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xd6, 0x01, 0x22, 0x21, 0xef, +0x3f, 0x0b, 0x97, 0x77, 0x08, 0x5a, 0x51, 0x16, +0xe4, 0xdd, 0x8f, 0x8c, 0xc4, 0xb5, 0xdf, 0xc1, +0x9f, 0x16, 0x34, 0xcc, 0x23, 0x9b, 0xf6, 0xfc, +0x7c, 0x29, 0xaa, 0x25, 0xd9, 0x00, 0x02, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd7, 0x01, 0x22, -0x21, 0x01, 0x17, 0x83, 0x8a, 0x31, 0xab, 0xa8, -0x44, 0xb8, 0xed, 0x53, 0xfb, 0x8b, 0x9c, 0xc4, -0x0e, 0x1b, 0x00, 0x23, 0x56, 0xa5, 0x3a, 0x9c, -0xc9, 0x1c, 0x68, 0x44, 0x1f, 0x09, 0x93, 0xd7, -0xe1, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, -0x01, 0x22, 0x21, 0x23, 0x3c, 0x8b, 0x09, 0x55, -0xc2, 0x30, 0x73, 0xc0, 0x68, 0x6e, 0x0f, 0x65, -0x25, 0xa0, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x8b, 0x7e, 0xcb, 0x3c, -0x7c, 0xbb, 0x16, 0x74, 0x03, 0x04, 0x51, 0x02, -0x00, 0xd9, 0x01, 0x22, 0x21, 0xe6, 0x39, 0xb2, -0x17, 0x8a, 0xee, 0xa7, 0xba, 0x7c, 0xfa, 0xae, -0x17, 0x02, 0xce, 0x34, 0xa0, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x54, -0xda, 0xe5, 0xe4, 0x77, 0xb1, 0x7d, 0x03, 0x04, -0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0x42, -0x68, 0x2d, 0xc8, 0x91, 0xc1, 0x39, 0xe0, 0x11, -0xdc, 0xd5, 0x6c, 0xdf, 0x1a, 0x0d, 0x05, 0x96, -0xf2, 0xf4, 0xa0, 0xa9, 0x00, 0xc3, 0x19, 0x4b, -0xb6, 0x85, 0x9f, 0xc3, 0xcb, 0xe2, 0x2d, 0x00, +0x21, 0x0b, 0x88, 0x26, 0x7c, 0x95, 0x75, 0x1c, +0x4e, 0x4e, 0x73, 0xe1, 0x88, 0xb5, 0x3c, 0xc2, +0xc7, 0x04, 0x34, 0x94, 0x72, 0x31, 0xeb, 0xab, +0x12, 0xe3, 0x6c, 0x04, 0xbb, 0xd6, 0x4b, 0x72, +0x2b, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xd8, +0x01, 0x22, 0x21, 0x80, 0x17, 0x4d, 0xa7, 0x47, +0xdd, 0x44, 0x8d, 0xe2, 0x4d, 0xd2, 0x1b, 0xdc, +0x26, 0xf7, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 0xfb, 0x0e, +0xc1, 0x75, 0xe4, 0x2f, 0x03, 0x04, 0x51, 0x02, +0x00, 0xd9, 0x01, 0x22, 0x21, 0x74, 0x6c, 0xf9, +0x6c, 0x5f, 0xb7, 0x16, 0xb6, 0x4b, 0xfc, 0x9a, +0x74, 0x0d, 0x1b, 0x82, 0x06, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xed, +0x06, 0xab, 0x86, 0xc5, 0x3a, 0x74, 0x03, 0x04, +0x51, 0x02, 0x00, 0xda, 0x01, 0x22, 0x21, 0x64, +0xbc, 0x4a, 0xc2, 0xf9, 0xf6, 0x3e, 0x89, 0xad, +0x05, 0x3d, 0xc8, 0x7c, 0x05, 0x86, 0xb2, 0x79, +0x0b, 0xd6, 0x10, 0x37, 0x90, 0x22, 0x50, 0x0b, +0x54, 0xd4, 0xe6, 0x00, 0x35, 0xb8, 0x1d, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdb, 0x01, 0x22, -0x21, 0xa7, 0x54, 0xe2, 0xf0, 0x98, 0xbf, 0x67, -0x84, 0x1d, 0x74, 0x45, 0x22, 0xdd, 0xad, 0xc1, -0x5b, 0xd2, 0x6f, 0x1f, 0xbf, 0x71, 0x4a, 0x20, -0xb2, 0x26, 0xd8, 0x88, 0x59, 0xda, 0x03, 0x26, -0x44, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, -0x01, 0x22, 0x21, 0x7b, 0x1a, 0xc9, 0x0b, 0xb9, -0x5b, 0xfb, 0x61, 0x2f, 0x72, 0x04, 0x5f, 0xea, -0x8e, 0xb7, 0x5d, 0xd9, 0xc4, 0x23, 0xa8, 0x2c, -0x56, 0x57, 0xc2, 0x23, 0x43, 0x7a, 0x3c, 0x2a, -0x57, 0xae, 0xa3, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xdd, 0x01, 0x22, 0x21, 0x1f, 0x2c, 0x6a, -0x66, 0x0a, 0x68, 0x00, 0xfe, 0x8b, 0x5b, 0x29, -0x1c, 0xce, 0xb4, 0x03, 0x50, 0xd1, 0xab, 0xd8, -0x9f, 0xaf, 0xfe, 0x80, 0x17, 0xef, 0x40, 0x79, -0xcf, 0x3b, 0xf5, 0x47, 0x35, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0x58, -0xe8, 0x2b, 0xcb, 0x29, 0x26, 0x88, 0xf1, 0xc5, -0x02, 0x7d, 0x14, 0x9a, 0xff, 0x37, 0x54, 0xa5, -0x85, 0x43, 0x1d, 0xcd, 0xee, 0x45, 0x39, 0xe3, -0x4e, 0x16, 0xb8, 0xa1, 0x15, 0x31, 0xf1, 0x00, +0x21, 0xd8, 0x09, 0x05, 0x74, 0xd3, 0xdb, 0x00, +0xc1, 0x6a, 0xf1, 0xf2, 0x3b, 0x7e, 0xfc, 0xc3, +0xa8, 0x7b, 0x5d, 0x8a, 0x0f, 0x46, 0x5a, 0x85, +0xd1, 0x1e, 0x0a, 0xf0, 0xee, 0xfe, 0x14, 0x79, +0x4a, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdc, +0x01, 0x22, 0x21, 0x06, 0x6a, 0x15, 0x19, 0x18, +0x7a, 0xd5, 0x83, 0xbd, 0x33, 0xf3, 0xed, 0xf8, +0x49, 0x23, 0x4c, 0x35, 0x84, 0x34, 0xdc, 0xe5, +0x21, 0xd6, 0xf5, 0x48, 0x26, 0x81, 0x17, 0xa4, +0x03, 0x7e, 0x12, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xdd, 0x01, 0x22, 0x21, 0x6b, 0x17, 0xf1, +0xb5, 0xec, 0xe7, 0x7d, 0x7f, 0x37, 0xbb, 0x89, +0xf2, 0xaa, 0x50, 0xb5, 0xcd, 0x6a, 0xfc, 0xa2, +0x39, 0xbd, 0x85, 0x12, 0x93, 0x43, 0xd0, 0x32, +0xf3, 0x0f, 0xa5, 0x5e, 0x12, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xde, 0x01, 0x22, 0x21, 0x4d, +0xdb, 0xdd, 0xe6, 0x73, 0x91, 0x83, 0x29, 0x93, +0xd7, 0x37, 0x8e, 0xd0, 0x5d, 0x7b, 0x0f, 0x13, +0x64, 0x4c, 0x6f, 0x96, 0x81, 0xf0, 0x4c, 0x1c, +0x2d, 0xc3, 0x15, 0x3e, 0xea, 0xaf, 0x22, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xdf, 0x01, 0x22, -0x21, 0xae, 0x76, 0x44, 0xf7, 0x0c, 0x84, 0x0a, -0x50, 0xbf, 0x6c, 0x8f, 0xc2, 0xb1, 0x6a, 0x35, -0xca, 0xa9, 0x73, 0x29, 0x2d, 0x59, 0x5b, 0xd9, -0x71, 0x5d, 0x06, 0xe1, 0x82, 0x54, 0xf2, 0xe1, -0xae, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, -0x01, 0x22, 0x21, 0xac, 0x98, 0xb5, 0x4f, 0xff, -0x19, 0x4f, 0x7f, 0x05, 0xe3, 0x5a, 0xe1, 0xb2, -0x97, 0xb4, 0x90, 0xcc, 0x10, 0xe8, 0x16, 0x33, -0x74, 0xac, 0x21, 0xed, 0x1f, 0x66, 0x20, 0x09, -0x1c, 0xea, 0x0a, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe1, 0x01, 0x22, 0x21, 0x6d, 0x65, 0x72, -0xcc, 0x6d, 0xbb, 0xd8, 0x77, 0x80, 0x04, 0x55, -0xb3, 0x99, 0xf0, 0x09, 0x25, 0x1c, 0xdd, 0xa5, -0xe8, 0x85, 0xa0, 0x73, 0x92, 0xc4, 0x2b, 0x48, -0x56, 0x2e, 0x40, 0xaf, 0xbe, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0x5e, -0x4d, 0x79, 0x18, 0xdd, 0x6e, 0x45, 0x83, 0xaa, -0x64, 0x24, 0x0b, 0x03, 0x8c, 0x2a, 0x00, 0x25, -0xe3, 0xb4, 0x63, 0x9c, 0x7d, 0x0b, 0x1e, 0x20, -0x71, 0x73, 0x6b, 0xc3, 0xe6, 0x15, 0x1e, 0x00, +0x21, 0x26, 0x25, 0x28, 0x5f, 0x2a, 0xab, 0x94, +0x03, 0xf9, 0x59, 0x53, 0x44, 0x96, 0xc4, 0x9f, +0x2b, 0xf9, 0xac, 0x4d, 0xbd, 0xf6, 0xc4, 0x62, +0x87, 0x0b, 0xcd, 0x9a, 0x79, 0xdb, 0x41, 0xa9, +0xd5, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe0, +0x01, 0x22, 0x21, 0x99, 0x6f, 0xcc, 0x1e, 0xff, +0x44, 0xf3, 0x3f, 0xe1, 0xdf, 0xaa, 0x9c, 0x84, +0x80, 0x18, 0xb7, 0xec, 0x66, 0xe1, 0x4a, 0xe0, +0x5e, 0x25, 0x7e, 0xe6, 0x03, 0xe0, 0x99, 0x5f, +0x17, 0xea, 0xdd, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe1, 0x01, 0x22, 0x21, 0xdf, 0x69, 0x75, +0x7b, 0x62, 0x27, 0x6b, 0xb8, 0x06, 0x89, 0xdc, +0x0d, 0x98, 0xf2, 0xab, 0x51, 0x14, 0xb7, 0x61, +0x62, 0x22, 0xae, 0x38, 0x53, 0x17, 0xa9, 0x69, +0x47, 0x97, 0xe0, 0x30, 0xfd, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe2, 0x01, 0x22, 0x21, 0x20, +0x67, 0x2b, 0x14, 0x14, 0x0b, 0x1f, 0x72, 0xf7, +0xad, 0xab, 0x21, 0x23, 0x00, 0x19, 0xbc, 0x93, +0xc8, 0x35, 0xf9, 0x10, 0x5b, 0x39, 0x7c, 0x74, +0xa1, 0x20, 0x86, 0x76, 0x8a, 0x06, 0x77, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe3, 0x01, 0x22, -0x21, 0x76, 0x60, 0x42, 0x1f, 0x53, 0x85, 0x5d, -0x9e, 0x10, 0x70, 0x61, 0x7e, 0xe7, 0x67, 0xc2, -0x1c, 0x0a, 0x91, 0xe1, 0x1f, 0xa1, 0x00, 0xb1, -0x07, 0xfe, 0x3c, 0x16, 0x7c, 0x4d, 0xde, 0xd1, -0xae, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, -0x01, 0x22, 0x21, 0x3f, 0xf9, 0x9b, 0x52, 0x09, -0xfa, 0x67, 0x3f, 0xa7, 0x67, 0x58, 0xd0, 0xfd, -0x6d, 0x48, 0x74, 0x2a, 0x10, 0x1f, 0x5a, 0x12, -0xe4, 0x38, 0x23, 0xf5, 0xd8, 0x11, 0x6a, 0x69, -0xc6, 0xd8, 0x46, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe5, 0x01, 0x22, 0x21, 0x48, 0xed, 0xd2, -0xf3, 0x95, 0x95, 0xcf, 0x88, 0x7d, 0x52, 0x68, -0xa5, 0xf2, 0xc2, 0x75, 0x94, 0x25, 0x77, 0xd8, -0x7d, 0x9b, 0xec, 0xd3, 0xc3, 0xef, 0xde, 0x6b, -0xb0, 0x5f, 0xd1, 0x92, 0x47, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0x41, -0xd7, 0xf2, 0xc1, 0x91, 0xc5, 0xd7, 0xa9, 0x0d, -0xf9, 0xdf, 0x33, 0x4a, 0x4a, 0xcf, 0xab, 0xbe, -0x6f, 0xfe, 0xce, 0xdf, 0x2b, 0xed, 0xe4, 0x12, -0xf2, 0xad, 0x10, 0x77, 0x6c, 0x0c, 0xc5, 0x00, +0x21, 0xb0, 0x98, 0xce, 0x4f, 0x2c, 0x86, 0xbc, +0xad, 0x1d, 0x21, 0xf6, 0x45, 0x25, 0xb9, 0x8b, +0x7f, 0x02, 0x86, 0x4e, 0x96, 0x13, 0xbc, 0x28, +0x01, 0xc3, 0x85, 0x4b, 0x4b, 0x8a, 0xd7, 0xad, +0x30, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe4, +0x01, 0x22, 0x21, 0x85, 0xd9, 0xe1, 0x40, 0x27, +0x92, 0x82, 0xe1, 0x91, 0xbe, 0x1a, 0x94, 0x5a, +0x70, 0x0f, 0xc5, 0x5f, 0xb1, 0xbc, 0x2b, 0x49, +0xe6, 0x0a, 0xae, 0xe7, 0xc4, 0x76, 0x82, 0xa3, +0x7f, 0x98, 0xf3, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe5, 0x01, 0x22, 0x21, 0xce, 0x07, 0x88, +0x91, 0x07, 0x65, 0x93, 0xae, 0xe8, 0x27, 0xbe, +0x38, 0xa0, 0x00, 0x85, 0x5a, 0x83, 0xbc, 0xae, +0x46, 0xd3, 0xe8, 0xe7, 0x51, 0xe9, 0x93, 0x1e, +0x6c, 0x91, 0x66, 0xf8, 0x07, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xe6, 0x01, 0x22, 0x21, 0xbb, +0x0f, 0x9e, 0x5e, 0xc4, 0x85, 0xc9, 0x95, 0xb4, +0x89, 0x19, 0x83, 0x20, 0xee, 0x35, 0xf3, 0x61, +0x75, 0x83, 0xea, 0x94, 0x54, 0x56, 0xdc, 0xa9, +0xd1, 0xee, 0x49, 0x39, 0xea, 0x30, 0xcb, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe7, 0x01, 0x22, -0x21, 0x86, 0xee, 0x7b, 0x67, 0xf9, 0x34, 0x65, -0x77, 0x23, 0xf7, 0x48, 0x36, 0xbf, 0xcf, 0x5f, -0x4f, 0x9a, 0xe4, 0x9f, 0xbf, 0x38, 0x18, 0x2a, -0x3f, 0xc2, 0x88, 0x09, 0x2e, 0x6c, 0xa6, 0x40, -0x14, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, -0x01, 0x22, 0x21, 0xef, 0x90, 0x42, 0xc9, 0x93, -0xf3, 0x04, 0x46, 0x16, 0xf5, 0x92, 0x23, 0xe8, -0x5d, 0x3d, 0x33, 0x04, 0xe6, 0xe1, 0x32, 0x82, -0x18, 0x2a, 0x95, 0x1e, 0x10, 0x8d, 0xf9, 0x2d, -0x7f, 0x49, 0xf7, 0x00, 0x03, 0x04, 0x51, 0x02, -0x00, 0xe9, 0x01, 0x22, 0x21, 0xee, 0x55, 0x84, -0x1f, 0x96, 0xc1, 0x10, 0xb4, 0xfc, 0x8f, 0xac, -0xed, 0x88, 0x53, 0xcd, 0xa1, 0x0c, 0x96, 0xe0, -0x82, 0x57, 0xa5, 0xb9, 0x6e, 0xbf, 0x31, 0x40, -0xa9, 0x81, 0xca, 0x20, 0xd9, 0x00, 0x03, 0x04, -0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0x06, -0xa6, 0xf2, 0xe1, 0x53, 0x38, 0x12, 0xec, 0x4d, -0x3e, 0x6d, 0x22, 0x15, 0x7f, 0xad, 0x72, 0x13, -0xb5, 0x0a, 0xbf, 0x13, 0x81, 0x86, 0x22, 0x23, -0x5e, 0xf5, 0x92, 0xc9, 0x36, 0xbd, 0x77, 0x00, +0x21, 0x59, 0xa0, 0x17, 0x15, 0x6c, 0xcb, 0xa7, +0x2e, 0x4a, 0x5c, 0x1b, 0x8b, 0x79, 0x14, 0x21, +0x55, 0x25, 0xb5, 0xa9, 0x76, 0xf0, 0xf2, 0x37, +0x9f, 0xf1, 0x0c, 0x73, 0xbd, 0xd4, 0xf8, 0xb3, +0x3c, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xe8, +0x01, 0x22, 0x21, 0xe3, 0x80, 0xd3, 0xc6, 0x43, +0x80, 0xd8, 0xdc, 0x53, 0x75, 0x18, 0x47, 0x58, +0x5a, 0x23, 0x9e, 0xe5, 0xa7, 0x52, 0x4d, 0x7e, +0x90, 0x7c, 0xff, 0x9f, 0xe4, 0x3d, 0x8e, 0x9e, +0x91, 0xf4, 0x48, 0x00, 0x03, 0x04, 0x51, 0x02, +0x00, 0xe9, 0x01, 0x22, 0x21, 0x51, 0x6e, 0x2d, +0xc9, 0xba, 0x80, 0x22, 0xdb, 0x3b, 0xda, 0xc5, +0x20, 0x1d, 0x84, 0xd2, 0xfb, 0x16, 0xef, 0x69, +0xd3, 0xf6, 0xdf, 0x09, 0xc3, 0x24, 0x5b, 0x5e, +0x1e, 0x9a, 0xc9, 0xdd, 0xe0, 0x00, 0x03, 0x04, +0x51, 0x02, 0x00, 0xea, 0x01, 0x22, 0x21, 0xe9, +0xe4, 0x76, 0x76, 0x28, 0x82, 0x38, 0x2b, 0x22, +0xd5, 0x03, 0xc9, 0xec, 0xef, 0x3c, 0xff, 0xb7, +0xda, 0x90, 0x10, 0xed, 0xfc, 0x86, 0xbc, 0x3e, +0x92, 0x64, 0xce, 0xb6, 0xe3, 0x7a, 0x18, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xeb, 0x01, 0x22, -0x21, 0x2f, 0x85, 0x10, 0xba, 0xd0, 0x0e, 0x93, -0xd0, 0x2d, 0xcc, 0x86, 0x1d, 0x78, 0xe8, 0x6a, -0xb3, 0xf8, 0x27, 0x20, 0x91, 0x5a, 0x1a, 0x86, -0xb0, 0x4f, 0x39, 0x9d, 0xa7, 0xd6, 0xc1, 0xb4, -0x41, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, -0x01, 0x22, 0x21, 0xbf, 0xd9, 0xf9, 0xb2, 0x1c, -0xa8, 0x88, 0x33, 0x28, 0x8e, 0xe6, 0xab, 0x54, -0x28, 0x73, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x1f, 0x0c, -0x07, 0xc9, 0x0a, 0x0c, 0x03, 0x04, 0x51, 0x02, -0x00, 0xed, 0x01, 0x22, 0x21, 0x5e, 0xb5, 0x22, -0xd2, 0x1a, 0xa6, 0x2d, 0x33, 0xb0, 0x32, 0xf3, -0x95, 0x43, 0xc0, 0xb2, 0x7b, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x3b, -0x13, 0x73, 0xa9, 0xca, 0x78, 0xa2, 0x03, 0x04, -0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0xcc, -0x6a, 0xf3, 0x33, 0xc3, 0xf8, 0x50, 0x50, 0x21, -0x47, 0x36, 0x30, 0x74, 0x5d, 0xcc, 0x47, 0x00, +0x21, 0xa6, 0x18, 0xe5, 0xc1, 0x72, 0xbf, 0xe5, +0x17, 0x0e, 0x46, 0x6e, 0xa0, 0xd1, 0x0d, 0x03, +0x9c, 0xa5, 0xcc, 0x4b, 0xa1, 0x47, 0x65, 0x73, +0xb1, 0x0b, 0x9b, 0xc3, 0xb8, 0xb3, 0x05, 0x9a, +0xaa, 0x00, 0x03, 0x04, 0x51, 0x02, 0x00, 0xec, +0x01, 0x22, 0x21, 0x00, 0xd8, 0x01, 0x5c, 0xac, +0xc3, 0x71, 0x25, 0x28, 0x2f, 0x34, 0x16, 0x80, +0x7f, 0x6d, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xba, 0x7f, 0x8d, 0x80, +0x0b, 0x34, 0x17, 0x66, 0x03, 0x04, 0x51, 0x02, +0x00, 0xed, 0x01, 0x22, 0x21, 0xcd, 0xda, 0x63, +0x61, 0x42, 0x68, 0x32, 0x7e, 0xf8, 0x85, 0x1f, +0x25, 0xbd, 0x22, 0x14, 0x6e, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x64, +0xdf, 0x2f, 0x28, 0xad, 0x38, 0xa5, 0x03, 0x04, +0x51, 0x02, 0x00, 0xee, 0x01, 0x22, 0x21, 0x2d, +0x3c, 0x5d, 0x45, 0x02, 0x0b, 0x48, 0x88, 0x90, +0xc5, 0x78, 0xdc, 0x1a, 0xd5, 0xe5, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x3c, 0x0d, 0x00, 0xe0, 0xfa, 0xdc, 0x1e, 0x49, +0x42, 0xe6, 0xea, 0xf8, 0xc3, 0x6f, 0x75, 0x16, 0x03, 0x04, 0x51, 0x02, 0x00, 0xef, 0x00 }; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index e15ae3d66..a57c20ea2 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -224,17 +224,11 @@ enum { #ifdef CONFIG_USB_AUDIO_ENHANCED_DETECT_TIME DVFS_BOOST_HOST_ID = 5, #endif + DVFS_USER_MIN_ID = 6, + DVFS_USER_MAX_ID = 7, DVFS_MAX_ID }; -#define DVFS_TOUCH_ID_MASK (1 << DVFS_TOUCH_ID) -#define DVFS_FINGER_ID_MASK (1 << DVFS_FINGER_ID) -#define DVFS_MULTI_TOUCH_ID_MASK (1 << DVFS_MULTI_TOUCH_ID) -#define DVFS_ARGOS_ID_MASK (1 << DVFS_ARGOS_ID) -#ifdef CONFIG_USB_AUDIO_ENHANCED_DETECT_TIME -#define DVFS_BOOST_HOST_ID_MASK (1 << DVFS_BOOST_HOST_ID) -#endif - int set_freq_limit(unsigned long id, unsigned int freq); #endif diff --git a/include/linux/cpufreq_limit.h b/include/linux/cpufreq_limit.h index ddb1bbb69..551875ffa 100644 --- a/include/linux/cpufreq_limit.h +++ b/include/linux/cpufreq_limit.h @@ -10,27 +10,23 @@ #ifndef __LINUX_CPUFREQ_LIMIT_H__ #define __LINUX_CPUFREQ_LIMIT_H__ -struct cpufreq_limit_handle; +struct cpufreq_limit_handle { + struct list_head node; + unsigned long freq; + u64 start_msecs; + bool requested; + int id; + char *name; +}; -struct cpufreq_limit_handle *cpufreq_limit_get(unsigned long min_freq, - unsigned long max_freq, char *label); +int cpufreq_limit_get(unsigned long freq, struct cpufreq_limit_handle *handle); int cpufreq_limit_put(struct cpufreq_limit_handle *handle); -void cpufreq_limit_corectl(int val); - -static inline -struct cpufreq_limit_handle *cpufreq_limit_min_freq(unsigned long min_freq, - char *label) -{ - return cpufreq_limit_get(min_freq, 0, label); -} - -static inline -struct cpufreq_limit_handle *cpufreq_limit_max_freq(unsigned long max_freq, - char *label) -{ - return cpufreq_limit_get(0, max_freq, label); -} - ssize_t cpufreq_limit_get_table(char *buf); +struct cpufreq_limit_handle *cpufreq_limit_get_handle(int id); +int cpufreq_limit_get_cur_min(void); +int cpufreq_limit_get_cur_max(void); +unsigned int cpufreq_limit_get_over_limit(void); +void cpufreq_limit_set_over_limit(unsigned int val); +void cpufreq_limit_corectl(int val); #endif /* __LINUX_CPUFREQ_LIMIT_H__ */ diff --git a/include/linux/cred.h b/include/linux/cred.h index 42c515498..16cb3a7f2 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -103,6 +103,11 @@ struct ro_rcu_head { void *bp_cred; void *reflected_cred; }; + +struct kdp_usecnt { + atomic_t kdp_use_cnt; + struct ro_rcu_head kdp_rcu_head; +}; #define get_rocred_rcu(cred) ((struct ro_rcu_head *)((atomic_t *)cred->use_cnt + 1)) #define get_usecnt_rcu(use_cnt) ((struct ro_rcu_head *)((atomic_t *)use_cnt + 1)) diff --git a/include/linux/input/qpnp-power-on.h b/include/linux/input/qpnp-power-on.h index f79bea9de..b6f0d9c91 100644 --- a/include/linux/input/qpnp-power-on.h +++ b/include/linux/input/qpnp-power-on.h @@ -57,6 +57,7 @@ enum pon_restart_reason { PON_RESTART_REASON_DMVERITY_CORRUPTED = 0x04, PON_RESTART_REASON_DMVERITY_ENFORCE = 0x05, PON_RESTART_REASON_KEYS_CLEAR = 0x06, + PON_RESTART_REASON_RECOVERY_UPDATE = 0x07, }; #endif diff --git a/include/linux/leds-rt8547.h b/include/linux/leds-rt8547.h index 2d4d60c6a..cf6a8db95 100644 --- a/include/linux/leds-rt8547.h +++ b/include/linux/leds-rt8547.h @@ -41,7 +41,6 @@ #define RT8547_ADDR_FLASH_CURRENT_LEVEL_TIMEOUT_SETTING 0x2 #define RT8547_ADDR_CURRENT_SETTING 0x3 #define RT8547_ADDR_FLASH_TIMEOUT_SETTING 0x4 -#define RT8547_ADDR_HIDDEN_SETTING 0x7 #define RT8547_SLAVE_ADDR 0x99 @@ -49,9 +48,6 @@ #define RT8547_TORCH_SELECT 0x10 #define RT8547_STROBE_SELECT 0x0f -#define RT8547_HIDDEN_DEFAULT 0x67 -#define RT8547_HIDDEN_LVP_DISABLE 0x27 - #define T_SHORT 4 /* us */ #define T_LONG 60 /* us*/ #define T_SOD 10 /* us */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 35a4efecb..910ee8446 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3081,6 +3081,7 @@ static inline void record_memsize_reserved(const char *name, phys_addr_t base, phys_addr_t size, bool nomap, bool reusable) { } #endif +extern bool ion_account_print_usage(void); #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/include/linux/olog.pb.h b/include/linux/olog.pb.h index 177533932..c3422aa56 100644 --- a/include/linux/olog.pb.h +++ b/include/linux/olog.pb.h @@ -44,11 +44,12 @@ enum OlogTestEnum_ID { PERFLOG_IPCSTARVE = 20, PERFLOG_SCREENSHOT = 21, PERFLOG_MUTEX = 22, - PERFLOG_SYSTEMSERVER = 23 + PERFLOG_SYSTEMSERVER = 23, + PERFLOG_PERFETTOLOGGINGENABLED = 24 }; #if defined(KPERFMON_KERNEL) -int OlogTestEnum_ID_maxnum = 24; -char * OlogTestEnum_ID_strings[24] = { +int OlogTestEnum_ID_maxnum = 25; +char * OlogTestEnum_ID_strings[25] = { "UNKNOWN", " ", "LCDV", @@ -72,7 +73,8 @@ char * OlogTestEnum_ID_strings[24] = { "IPCSTARVE", "SCREENSHOT", "MUTEX", - "SYSTEMSERVER" + "SYSTEMSERVER", + "PERFETTOLOGGINGENABLED" }; #endif //KPERFMON_KERNEL diff --git a/include/linux/samsung/debug/sec_debug.h b/include/linux/samsung/debug/sec_debug.h index e21252210..4e8b99d9d 100644 --- a/include/linux/samsung/debug/sec_debug.h +++ b/include/linux/samsung/debug/sec_debug.h @@ -10,8 +10,13 @@ #include +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_IRQ_V2) +#define IRQ_ENTRY_V2 0x76324945 +#define IRQ_EXIT_V2 0x76324958 +#else #define IRQ_ENTRY 0x4945 #define IRQ_EXIT 0x4958 +#endif #define SOFTIRQ_ENTRY 0x5345 #define SOFTIRQ_EXIT 0x5358 @@ -78,7 +83,10 @@ enum sec_debug_upload_cause_t { UPLOAD_CAUSE_QUEST_DDR_TEST_SMD, UPLOAD_CAUSE_SOD_RESULT, UPLOAD_CAUSE_QUEST_ZIP_UNZIP, - UPLOAD_CAUSE_QUEST_END = UPLOAD_CAUSE_QUEST_ZIP_UNZIP, + UPLOAD_CAUSE_DRAM_SCAN, + UPLOAD_CAUSE_QUEST_AOSSTHERMALDIFF, + UPLOAD_CAUSE_QUEST_STRESSAPPTEST, + UPLOAD_CAUSE_QUEST_END = UPLOAD_CAUSE_QUEST_STRESSAPPTEST, /* --Quest : 0xC8_5153_xx -- */ /* -- KP : 0xC8xx_xxxx -- */ /* ++ TP ++ */ @@ -118,6 +126,7 @@ enum sec_restart_reason_t { RESTART_REASON_DMVERITY_ENFORCE = 0x77665509, RESTART_REASON_KEYS_CLEAR = 0x7766550a, RESTART_REASON_SEC_DEBUG_MODE = 0x776655ee, + RESTART_REASON_RECOVERY_UPDATE = 0x776655cc, RESTART_REASON_END = 0xffffffff, }; @@ -270,6 +279,8 @@ enum pon_restart_reason { PON_RESTART_REASON_QUEST_QUEFI_USER_START = 0x51, PON_RESTART_REASON_QUEST_SUEFI_USER_START = 0x52, #endif + PON_RESTART_REASON_RECOVERY_UPDATE = 0x60, + PON_RESTART_REASON_BOTA_COMPLETE = 0x61, PON_RESTART_REASON_MAX = 0x80 #endif }; @@ -382,4 +393,7 @@ extern void sec_debug_check_pwdt(void); static inline void sec_debug_check_pwdt(void) {} #endif +#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP +extern unsigned long sec_delay_check; +#endif #endif /* __INDIRECT__SEC_DEBUG_H__ */ diff --git a/include/linux/samsung/debug/sec_debug_partition_type.h b/include/linux/samsung/debug/sec_debug_partition_type.h index 52799a072..c603bce8e 100644 --- a/include/linux/samsung/debug/sec_debug_partition_type.h +++ b/include/linux/samsung/debug/sec_debug_partition_type.h @@ -27,6 +27,7 @@ enum debug_partition_index { debug_index_reset_history, debug_index_reset_rkplog, debug_index_reset_lpm_klog, + debug_index_onoff_history, debug_index_max, }; @@ -160,6 +161,23 @@ struct lcd_debug_t { struct lcd_debug_fw_up fw_up; }; +#define SEC_DEBUG_ONOFF_HISTORY_MAX_CNT 20 +#define SEC_DEBUG_ONOFF_REASON_STR_SIZE 128 + +typedef struct debug_onoff_reason { + int64_t rtc_offset; + int64_t local_time; + uint32_t boot_cnt; + char reason[SEC_DEBUG_ONOFF_REASON_STR_SIZE]; +} onoff_reason_t; + +typedef struct debug_onoff_history { + uint32_t magic; + uint32_t size; + uint32_t index; + onoff_reason_t history[SEC_DEBUG_ONOFF_HISTORY_MAX_CNT]; +} onoff_history_t; + #define DEBUG_PARTITION_MAGIC 0x41114729 #define PARTITION_RD 0 @@ -197,6 +215,9 @@ struct lcd_debug_t { #define SEC_DEBUG_RESET_HISTORY_MAX_CNT (10) #define SEC_DEBUG_RESET_HISTORY_SIZE (SEC_DEBUG_AUTO_COMMENT_SIZE*SEC_DEBUG_RESET_HISTORY_MAX_CNT) +#define SEC_DEBUG_ONOFF_HISTORY_OFFSET (572*1024) +#define SEC_DEBUG_ONOFF_HISTORY_SIZE (4*1024) + #define SEC_DEBUG_RESET_ETRM_SIZE (0x3c0) #define SEC_DEBUG_RESET_ETRM_OFFSET (SEC_DEBUG_AUTO_COMMENT_OFFSET + ALIGN(SEC_DEBUG_AUTO_COMMENT_SIZE, SECTOR_UNIT_SIZE) - 0x15) /* 5MB + 16KB + 4KB */ diff --git a/include/linux/samsung/debug/sec_debug_sched_log.h b/include/linux/samsung/debug/sec_debug_sched_log.h index 10493f7d1..289812e67 100644 --- a/include/linux/samsung/debug/sec_debug_sched_log.h +++ b/include/linux/samsung/debug/sec_debug_sched_log.h @@ -20,8 +20,10 @@ extern void sec_debug_task_sched_log(int cpu, bool preempt, struct task_struct * /* called @ kernel/irq/chip.c */ /* called @ kernel/irq/handle.c */ +extern void sec_debug_irq_sched_log(unsigned int irq, void *desc_or_fn, void *action_or_name, unsigned int en); + /* called @ kernel/softirq.c */ -extern void sec_debug_irq_sched_log(unsigned int irq, void *fn, char *name, unsigned int en); +extern void sec_debug_softirq_sched_log(unsigned int irq, void *fn, char *name, unsigned int en); /* called @ arch/arm64/kernel/traps.c */ /* called @ drivers/cpuidle/lpm-levels.c */ @@ -44,7 +46,8 @@ static inline int sec_debug_sched_msg(char *fmt, ...) { return 0; } static inline void sec_debug_secure_log(u32 svc_id, u32 cmd_id) {} static inline void sec_debug_task_sched_log(int cpu, bool preempt, struct task_struct *task, struct task_struct *prev) {} static inline void sec_debug_timer_log(unsigned int type, int int_lock, void *fn) {} -static inline void sec_debug_irq_sched_log(unsigned int irq, void *fn, char *name, unsigned int en) {} +static inline void sec_debug_irq_sched_log(unsigned int irq, void *desc_or_fn, void *action_or_name, unsigned int en) {} +static inline void sec_debug_softirq_sched_log(unsigned int irq, void *fn, char *name, unsigned int en) {} #endif /* CONFIG_SEC_DEBUG_SCHED_LOG */ diff --git a/include/linux/samsung/debug/sec_debug_sched_log_type.h b/include/linux/samsung/debug/sec_debug_sched_log_type.h index b0f267dd0..af7de926d 100644 --- a/include/linux/samsung/debug/sec_debug_sched_log_type.h +++ b/include/linux/samsung/debug/sec_debug_sched_log_type.h @@ -12,7 +12,10 @@ struct irq_buf { char *name; int en; int preempt_count; - void *context; + union { + void *context; + irq_hw_number_t hwirq; + }; pid_t pid; unsigned int entry_exit; }; @@ -175,6 +178,27 @@ struct power_log { struct power_buf buf[POWER_LOG_MAX]; } ____cacheline_aligned_in_smp; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +struct sec_debug_log { + struct sched_log sched; + struct irq_log irq; + +#ifdef CONFIG_SEC_DEBUG_MSG_LOG + struct secmsg_log secmsg; +#endif + +#ifdef CONFIG_SEC_DEBUG_POWER_LOG + struct power_log pwr; +#endif +}; + +struct sec_debug_last_pet_ns { + /* zwei variables -- last_pet und last_ns */ + unsigned long long last_pet; + atomic64_t last_ns; +}; + +#else struct sec_debug_log { struct sched_log sched[NR_CPUS]; struct irq_log irq[NR_CPUS]; @@ -207,6 +231,7 @@ struct sec_debug_log { unsigned long long last_pet; atomic64_t last_ns; }; +#endif #endif /* __KERNEL */ diff --git a/include/linux/samsung/debug/sec_debug_summary.h b/include/linux/samsung/debug/sec_debug_summary.h index 694361ff1..64f4e5c62 100644 --- a/include/linux/samsung/debug/sec_debug_summary.h +++ b/include/linux/samsung/debug/sec_debug_summary.h @@ -74,8 +74,4 @@ static inline void sec_modify_restart_level_mdm(int value) { } static inline void sec_set_mdm_summary_info(char *str_buf) { } #endif /* CONFIG_SEC_DEBUG_MDM_FILE_INFO */ -#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP -extern unsigned long sec_delay_check; -#endif - #endif /* __INDIRECT__SEC_DEBUG_SUMMARY_H__ */ diff --git a/include/linux/samsung/debug/sec_debug_summary_type.h b/include/linux/samsung/debug/sec_debug_summary_type.h index a5b69a5ff..b1d5ae2b6 100644 --- a/include/linux/samsung/debug/sec_debug_summary_type.h +++ b/include/linux/samsung/debug/sec_debug_summary_type.h @@ -75,6 +75,25 @@ struct sec_debug_summary_fb { struct rgb_bit_info rgb_bitinfo; }; +#if defined(CONFIG_SEC_DEBUG_SCHED_LOG_PER_CPU) +struct sec_debug_summary_sched_log { + uint64_t sched_idx_vaddr; + uint64_t sched_buf_vaddr; + unsigned int sched_struct_buf_sz; + unsigned int sched_struct_log_sz; + unsigned int sched_array_cnt; + uint64_t irq_idx_vaddr; + uint64_t irq_buf_vaddr; + unsigned int irq_struct_buf_sz; + unsigned int irq_struct_log_sz; + unsigned int irq_array_cnt; + uint64_t msglog_idx_vaddr; + uint64_t msglog_buf_vaddr; + unsigned int msglog_struct_buf_sz; + unsigned int msglog_struct_log_sz; + unsigned int msglog_array_cnt; +}; +#else struct sec_debug_summary_sched_log { uint64_t sched_idx_paddr; uint64_t sched_buf_paddr; @@ -102,6 +121,7 @@ struct sec_debug_summary_sched_log { unsigned int msglog_struct_log_sz; unsigned int msglog_array_cnt; }; +#endif struct __log_struct_info { unsigned int buffer_offset; diff --git a/include/linux/samsung/debug/sec_debug_user_reset_type.h b/include/linux/samsung/debug/sec_debug_user_reset_type.h index d783fe413..283baa751 100644 --- a/include/linux/samsung/debug/sec_debug_user_reset_type.h +++ b/include/linux/samsung/debug/sec_debug_user_reset_type.h @@ -166,12 +166,6 @@ struct debug_reset_header { #define TZ_DIAG_LOG_MAGIC 0x747a6461 /* tzda */ /* copy from drivers/firmware/qcom/tz_log.c */ -#define TZBSP_MAX_CPU_COUNT 0x08 -#define TZBSP_DIAG_NUM_OF_VMID 16 -#define TZBSP_DIAG_VMID_DESC_LEN 7 -#define TZBSP_DIAG_INT_NUM 64 -#define TZBSP_MAX_INT_DESC 16 - #define TZBSP_AES_256_ENCRYPTED_KEY_SIZE 256 #define TZBSP_NONCE_LEN 12 #define TZBSP_TAG_LEN 16 @@ -185,98 +179,6 @@ enum tz_boot_info_cpu_status_type { INVALID_WARM_TERM_ENTRY_EXIT_COUNT, }; -/* - * VMID Table - */ -struct tzdbg_vmid_t { - uint8_t vmid; /* Virtual Machine Identifier */ - uint8_t desc[TZBSP_DIAG_VMID_DESC_LEN]; /* ASCII Text */ -}; - -/* - * Boot Info Table - */ -struct tzdbg_boot_info_t { - uint32_t wb_entry_cnt; /* Warmboot entry CPU Counter */ - uint32_t wb_exit_cnt; /* Warmboot exit CPU Counter */ - uint32_t pc_entry_cnt; /* Power Collapse entry CPU Counter */ - uint32_t pc_exit_cnt; /* Power Collapse exit CPU counter */ - uint32_t warm_jmp_addr; /* Last Warmboot Jump Address */ - uint32_t spare; /* Reserved for future use. */ -}; - -/* - * Boot Info Table for 64-bit - */ -struct tzdbg_boot_info64_t { - uint32_t wb_entry_cnt; /* Warmboot entry CPU Counter */ - uint32_t wb_exit_cnt; /* Warmboot exit CPU Counter */ - uint32_t pc_entry_cnt; /* Power Collapse entry CPU Counter */ - uint32_t pc_exit_cnt; /* Power Collapse exit CPU counter */ - uint32_t psci_entry_cnt;/* PSCI syscall entry CPU Counter */ - uint32_t psci_exit_cnt; /* PSCI syscall exit CPU Counter */ - uint64_t warm_jmp_addr; /* Last Warmboot Jump Address */ - uint32_t warm_jmp_instr; /* Last Warmboot Jump Address Instruction */ -}; - -/* - * Reset Info Table - */ -struct tzdbg_reset_info_t { - uint32_t reset_type; /* Reset Reason */ - uint32_t reset_cnt; /* Number of resets occurred/CPU */ -}; - -/* - * Interrupt Info Table - */ -struct tzdbg_int_t { - /* - * Type of Interrupt/exception - */ - uint16_t int_info; - /* - * Availability of the slot - */ - uint8_t avail; - /* - * Reserved for future use - */ - uint8_t spare; - /* - * Interrupt # for IRQ and FIQ - */ - uint32_t int_num; - /* - * ASCII text describing type of interrupt e.g: - * Secure Timer, EBI XPU. This string is always null terminated, - * supporting at most TZBSP_MAX_INT_DESC characters. - * Any additional characters are truncated. - */ - uint8_t int_desc[TZBSP_MAX_INT_DESC]; - uint32_t int_count[TZBSP_MAX_CPU_COUNT]; /* # of times seen per CPU */ -}; - -/* - * Interrupt Info Table used in tz version >=4.X - */ -struct tzdbg_int_t_tz40 { - uint16_t int_info; - uint8_t avail; - uint8_t spare; - uint32_t int_num; - uint8_t int_desc[TZBSP_MAX_INT_DESC]; - uint32_t int_count[TZBSP_MAX_CPU_COUNT]; /* uint32_t in TZ ver >= 4.x*/ -}; - -/* warm boot reason for cores */ -struct tzbsp_diag_wakeup_info_t { - /* Wake source info : APCS_GICC_HPPIR */ - uint32_t HPPIR; - /* Wake source info : APCS_GICC_AHPPIR */ - uint32_t AHPPIR; -}; - /* * Log ring buffer position */ @@ -307,6 +209,34 @@ struct tzdbg_log_v9_2_t { uint8_t log_buf[]; }; +struct tzbsp_encr_info_for_log_chunk_t { + uint32_t size_to_encr; + uint8_t nonce[TZBSP_NONCE_LEN]; + uint8_t tag[TZBSP_TAG_LEN]; +}; + +/* + * Only `ENTIRE_LOG` will be used unless the + * "OEM_tz_num_of_diag_log_chunks_to_encr" devcfg field >= 2. + * If this is true, the diag log will be encrypted in two + * separate chunks: a smaller chunk containing only error + * fatal logs and a bigger "rest of the log" chunk. In this + * case, `ERR_FATAL_LOG_CHUNK` and `BIG_LOG_CHUNK` will be + * used instead of `ENTIRE_LOG`. + */ +enum tzbsp_encr_info_for_log_chunks_idx_t { + BIG_LOG_CHUNK = 0, + ENTIRE_LOG = 1, + ERR_FATAL_LOG_CHUNK = 1, + MAX_NUM_OF_CHUNKS, +}; + +struct tzbsp_encr_info_t { + uint32_t num_of_chunks; + struct tzbsp_encr_info_for_log_chunk_t chunks[MAX_NUM_OF_CHUNKS]; + uint8_t key[TZBSP_AES_256_ENCRYPTED_KEY_SIZE]; +}; + /* * Diagnostic Table * Note: This is the reference data structure for tz diagnostic table @@ -348,29 +278,34 @@ struct tzdbg_t { /* Offset for Wakeup info */ uint32_t wakeup_info_off; - /* - * VMID to EE Mapping - */ - struct tzdbg_vmid_t vmid_info[TZBSP_DIAG_NUM_OF_VMID]; - /* - * Boot Info - */ - struct tzdbg_boot_info64_t boot_info[TZBSP_MAX_CPU_COUNT]; - /* - * Reset Info - */ - struct tzdbg_reset_info_t reset_info[TZBSP_MAX_CPU_COUNT]; - uint32_t num_interrupts; - struct tzdbg_int_t int_info[TZBSP_DIAG_INT_NUM]; + union { + /* The elements in below structure have to be used for TZ where + * diag version = TZBSP_DIAG_MINOR_VERSION_V2 + */ + struct { + uint8_t reserve[512]; - /* Wake up info */ - struct tzbsp_diag_wakeup_info_t wakeup_info[TZBSP_MAX_CPU_COUNT]; + uint32_t num_interrupts; - uint8_t key[TZBSP_AES_256_ENCRYPTED_KEY_SIZE]; + uint8_t reserve2[3648]; - uint8_t nonce[TZBSP_NONCE_LEN]; + uint8_t key[TZBSP_AES_256_ENCRYPTED_KEY_SIZE]; - uint8_t tag[TZBSP_TAG_LEN]; + uint8_t nonce[TZBSP_NONCE_LEN]; + + uint8_t tag[TZBSP_TAG_LEN]; + } v9_2; + /* The elements in below structure have to be used for TZ where + * diag version = TZBSP_DIAG_MINOR_VERSION_V21 + */ + struct { + uint32_t encr_info_for_log_off; + + uint8_t reserve[4172]; + + struct tzbsp_encr_info_t encr_info_for_log; + } v9_3; + }; /* * We need at least 2K for the ring buffer diff --git a/include/linux/samsung/sec_quest.h b/include/linux/samsung/sec_quest.h index 02150b988..de12ff456 100755 --- a/include/linux/samsung/sec_quest.h +++ b/include/linux/samsung/sec_quest.h @@ -24,12 +24,14 @@ #define MAX_LEN_STR 1024 #define QUEST_BUFF_SIZE 10 #define QUEST_CMD_LIST 3 +#define QUEST_CMD_SIZE 64 #define QUEST_MAIN_CMD_LIST 2 -#define STEP_MAIN_HLOS_TIMEOUT 3000 +#define STEP_MAIN_HLOS_TIMEOUT 5400 #define BUFF_SZ 256 #define MAX_DDR_ERR_ADDR_CNT 64 #define CPR_BPS_SZ_BYTE 256 -#define QUEST_CPR_MODE_CNT 8 +#define QUEST_CPR_MODE_CNT 10 +#define MAIN_QUEST_QUEFI_REPEATS 2 /* @@ -91,6 +93,7 @@ So, let's call proper shell script as concept of STEP_SDMDL #define TEST_QMESACACHE(x) (!strcmp((x), "QMESACACHETEST")) #define TEST_UFS(x) (!strcmp((x), "UFSTEST")) #define TEST_NATURESCENE(x) (!strcmp((x), "NATURESCENE")) +#define TEST_AOSSTHERMALDIFF(x) (!strcmp((x), "AOSSTHERMALDIFF")) #define TEST_SENSOR(x) (!strcmp((x), "SENSORTEST")) #define TEST_SENSORPROBE(x) (!strcmp((x), "SENSORPROBETEST")) #define TEST_DDR_SCAN(x) (!strcmp((x), "DDRSCANTEST")) @@ -118,7 +121,37 @@ So, let's call proper shell script as concept of STEP_SDMDL #define QUEST_CLEAR_ITEM_SUBITEM_RESULT(data, item) \ ((data) = (((data)&(~((uint64_t)0x3<<((item))*2))) | ((uint64_t)0x0 << ((item) *2)))) #define QUEST_SET_BIT_WITH_SHIFT(data, layer, code) \ - ((data) |= ((data) | ((uint64_t)0x1 << (code)<<((layer)*QUEST_MAX_ERR_CODES_AT_ONE_LAYER)))) + ((data) |= ((data) | ((uint64_t)0x1 << (code)<<((layer)*QUEST_MAX_ERR_CODES_AT_ONE_LAYER)))) + + +/* smddl variable */ +#define QUEST_UPDATE_SMDDL_INFO(param_member) \ + if( param_quest_data.num_smd_try == 1 ) \ + param_member##_first = param_member; + +#define QUEST_UPDATE_SMDDL_INFO_WITH_VAL(param_first_member, val) \ + do { \ + if( param_quest_data.num_smd_try == 1 ) {\ + param_first_member = val; \ + }\ + } while(0) + +#define QUEST_UPDATE_SMDDL_INFO_WITH_VAL_AND_RET(param_first_member, val, ret) \ + do { \ + if( param_quest_data.num_smd_try == 1 ) {\ + param_first_member = val; \ + ret = 1; \ + }else \ + ret = 0; \ + } while(0) + +#define QUEST_UPDATE_SMDDL_INFO_WITH_STRING(param_first_member, str, len) \ + do { \ + if( param_quest_data.num_smd_try == 1 ) { \ + strncpy(param_first_member, str, len); \ + } \ + } while(0) + @@ -147,21 +180,30 @@ enum quest_enum_item { enum quest_enum_smd_subitem { SUBITEM_NONE = 0, - SUBITEM_DDRSCANLOADER, + SUBITEM_DDRSCANLOADER = 1, #if defined(CONFIG_SEC_QUEST_EDL) - SUBITEM_QUESTSUEFI_GROUP1, + SUBITEM_QUESTSUEFI_FIRST = 2, + SUBITEM_QUESTSUEFI_GROUP1 = SUBITEM_QUESTSUEFI_FIRST, SUBITEM_QUESTSUEFI_GROUP2, SUBITEM_QUESTSUEFI_GROUP3, SUBITEM_QUESTSUEFI_GROUP4, SUBITEM_QUESTSUEFI_GROUP5, - SUBITEM_QUESTQUEFI_GROUP1, + SUBITEM_QUESTSUEFI_GROUP6, + SUBITEM_QUESTSUEFI_GROUP7, + SUBITEM_QUESTSUEFI_GROUP8, + SUBITEM_QUESTSUEFI_GROUP9, + SUBITEM_QUESTSUEFI_LAST = SUBITEM_QUESTSUEFI_GROUP9, + SUBITEM_QUESTQUEFI_FIRST = 11, + SUBITEM_QUESTQUEFI_GROUP1 = SUBITEM_QUESTQUEFI_FIRST, SUBITEM_QUESTQUEFI_GROUP2, SUBITEM_QUESTQUEFI_GROUP3, SUBITEM_QUESTQUEFI_GROUP4, SUBITEM_QUESTQUEFI_GROUP5, SUBITEM_QUESTQUEFI_GROUP6, SUBITEM_QUESTQUEFI_GROUP7, - SUBITEM_QUESTQUEFI_GROUP8, + SUBITEM_QUESTQUEFI_GROUP8, + SUBITEM_QUESTQUEFI_GROUP9, + SUBITEM_QUESTQUEFI_LAST = SUBITEM_QUESTQUEFI_GROUP9, #else SUBITEM_QUESTQUEFI, SUBITEM_QUESTSUEFILIGHTCRYPTO, @@ -171,6 +213,7 @@ enum quest_enum_smd_subitem { SUBITEM_QUESTHLOSDUMMY, #elif defined(CONFIG_SEC_QUEST_HLOS_NATURESCENE_SMD) SUBITEM_QUESTHLOSNATURESCENE, + SUBITEM_QUESTHLOSAOSSTHERMALDIFF, #else SUBITEM_QUESTHLOSCRYPTO, SUBITEM_QUESTHLOSICACHE, @@ -316,11 +359,20 @@ struct param_quest_t { uint32_t smd_quefi_total_pause_time_first; /* smddl information */ - struct param_quest_cpr_t smd_cx_cpr[8]; - struct param_quest_cpr_t smd_mx_cpr[8]; + uint32_t smd_max_aoss_thermal_diff; + uint32_t smd_max_aoss_thermal_diff_first; + + uint64_t real_smd_register_value; + uint64_t ap_serial; + + uint32_t num_smd_try; + + uint32_t smd_ft_self_cooling_time; + uint32_t smd_ft_thermal_after_self_cooling; + + uint32_t smd_cper; - struct param_quest_cpr_t curr_cx_cpr[8]; - struct param_quest_cpr_t curr_mx_cpr[8]; + uint32_t quest_fv_flashed; }; diff --git a/include/linux/task_integrity.h b/include/linux/task_integrity.h index 0b70d3032..3b1179c76 100644 --- a/include/linux/task_integrity.h +++ b/include/linux/task_integrity.h @@ -112,6 +112,25 @@ struct task_integrity { #ifdef CONFIG_FIVE +#ifdef CONFIG_FIVE_GKI_10 +#define TASK_INTEGRITY(task) \ + ((struct task_integrity *)((task)->android_vendor_data1[2])) + +static inline void task_integrity_assign(struct task_struct *task, + struct task_integrity *tint) +{ + task->android_vendor_data1[2] = (u64)tint; +} +#else +#define TASK_INTEGRITY(task) ((task)->integrity) + +static inline void task_integrity_assign(struct task_struct *task, + struct task_integrity *tint) +{ + task->integrity = tint; +} +#endif + extern void task_integrity_set_reset_reason(struct task_integrity *intg, enum task_integrity_reset_cause cause, struct file *file); @@ -239,6 +258,13 @@ extern int five_process_vm_rw(struct task_struct *task, int write); extern char const * const tint_reset_cause_to_string( enum task_integrity_reset_cause cause); #else +#define TASK_INTEGRITY(task) (NULL) + +static inline void task_integrity_assign(struct task_struct *task, + struct task_integrity *tint) +{ +} + static inline struct task_integrity *task_integrity_alloc(void) { return NULL; diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 09a7ef171..0dfb174f7 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -889,7 +889,6 @@ TRACE_EVENT(ext4_sync_file_enter, __field( ino_t, ino ) __field( ino_t, parent ) __field( int, datasync ) - __array(unsigned char, d_name, EXT4_NAME_LEN) ), TP_fast_assign( @@ -899,14 +898,12 @@ TRACE_EVENT(ext4_sync_file_enter, __entry->ino = d_inode(dentry)->i_ino; __entry->datasync = datasync; __entry->parent = d_inode(dentry->d_parent)->i_ino; - memcpy(__entry->d_name, dentry->d_name.name, EXT4_NAME_LEN); ), - TP_printk("dev %d,%d ino %lu parent %lu datasync %d d_name %s", + TP_printk("dev %d,%d ino %lu parent %lu datasync %d ", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - (unsigned long) __entry->parent, __entry->datasync, - __entry->d_name) + (unsigned long) __entry->parent, __entry->datasync) ); TRACE_EVENT(ext4_sync_file_exit, @@ -1454,7 +1451,6 @@ TRACE_EVENT(ext4_unlink_enter, __field( ino_t, ino ) __field( ino_t, parent ) __field( loff_t, size ) - __array(unsigned char, d_name, EXT4_NAME_LEN) ), TP_fast_assign( @@ -1462,13 +1458,12 @@ TRACE_EVENT(ext4_unlink_enter, __entry->ino = d_inode(dentry)->i_ino; __entry->parent = parent->i_ino; __entry->size = d_inode(dentry)->i_size; - memcpy(__entry->d_name, dentry->d_name.name, EXT4_NAME_LEN); ), - TP_printk("dev %d,%d ino %lu size %lld parent %lu d_name %s", + TP_printk("dev %d,%d ino %lu size %lld parent %lu", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->size, - (unsigned long) __entry->parent, __entry->d_name) + (unsigned long) __entry->parent) ); TRACE_EVENT(ext4_unlink_exit, @@ -1480,20 +1475,18 @@ TRACE_EVENT(ext4_unlink_exit, __field( dev_t, dev ) __field( ino_t, ino ) __field( int, ret ) - __array(unsigned char, d_name, EXT4_NAME_LEN) ), TP_fast_assign( __entry->dev = dentry->d_sb->s_dev; __entry->ino = d_inode(dentry)->i_ino; __entry->ret = ret; - memcpy(__entry->d_name, dentry->d_name.name, EXT4_NAME_LEN); ), - TP_printk("dev %d,%d ino %lu ret %d d_name %s", + TP_printk("dev %d,%d ino %lu ret %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->ret, __entry->d_name) + __entry->ret) ); DECLARE_EVENT_CLASS(ext4__truncate, diff --git a/include/uapi/linux/loop.h b/include/uapi/linux/loop.h index 080a8df13..24a1c45bd 100644 --- a/include/uapi/linux/loop.h +++ b/include/uapi/linux/loop.h @@ -25,6 +25,16 @@ enum { LO_FLAGS_DIRECT_IO = 16, }; +/* LO_FLAGS that can be set using LOOP_SET_STATUS(64) */ +#define LOOP_SET_STATUS_SETTABLE_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN) + +/* LO_FLAGS that can be cleared using LOOP_SET_STATUS(64) */ +#define LOOP_SET_STATUS_CLEARABLE_FLAGS (LO_FLAGS_AUTOCLEAR) + +/* LO_FLAGS that can be set using LOOP_CONFIGURE */ +#define LOOP_CONFIGURE_SETTABLE_FLAGS (LO_FLAGS_READ_ONLY | LO_FLAGS_AUTOCLEAR \ + | LO_FLAGS_PARTSCAN | LO_FLAGS_DIRECT_IO) + #include /* for __kernel_old_dev_t */ #include /* for __u64 */ @@ -37,7 +47,7 @@ struct loop_info { int lo_offset; int lo_encrypt_type; int lo_encrypt_key_size; /* ioctl w/o */ - int lo_flags; /* ioctl r/o */ + int lo_flags; char lo_name[LO_NAME_SIZE]; unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ unsigned long lo_init[2]; @@ -53,13 +63,29 @@ struct loop_info64 { __u32 lo_number; /* ioctl r/o */ __u32 lo_encrypt_type; __u32 lo_encrypt_key_size; /* ioctl w/o */ - __u32 lo_flags; /* ioctl r/o */ + __u32 lo_flags; __u8 lo_file_name[LO_NAME_SIZE]; __u8 lo_crypt_name[LO_NAME_SIZE]; __u8 lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ __u64 lo_init[2]; }; +/** + * struct loop_config - Complete configuration for a loop device. + * @fd: fd of the file to be used as a backing file for the loop device. + * @block_size: block size to use; ignored if 0. + * @info: struct loop_info64 to configure the loop device with. + * + * This structure is used with the LOOP_CONFIGURE ioctl, and can be used to + * atomically setup and configure all loop device parameters at once. + */ +struct loop_config { + __u32 fd; + __u32 block_size; + struct loop_info64 info; + __u64 __reserved[8]; +}; + /* * Loop filter types */ @@ -90,6 +116,7 @@ struct loop_info64 { #define LOOP_SET_CAPACITY 0x4C07 #define LOOP_SET_DIRECT_IO 0x4C08 #define LOOP_SET_BLOCK_SIZE 0x4C09 +#define LOOP_CONFIGURE 0x4C0A /* /dev/loop-control interface */ #define LOOP_CTL_ADD 0x4C80 diff --git a/init/Kconfig b/init/Kconfig index bb9b7cac0..1b1bb286f 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -438,6 +438,13 @@ config SCHED_WALT used to guide task placement as well as task frequency requirements for cpufreq governors. +config WALT_POWER_FEATURE + bool "Power enhance feature in WALT scheduler" + depends on SCHED_WALT + default n + help + This feature save power by adjust start cpu + config SCHED_SEC_TASK_BOOST bool "Enable Task Priority Boost" depends on SCHED_WALT diff --git a/kernel/cred.c b/kernel/cred.c index 2bf934d1a..2726324dc 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -47,7 +47,11 @@ int rkp_cred_enable __kdp_ro = 0; static struct kmem_cache *cred_jar_ro; struct kmem_cache *tsec_jar; struct kmem_cache *usecnt_jar; -atomic_t init_cred_use_cnt = ATOMIC_INIT(4); +struct kdp_usecnt init_cred_use_cnt = { + .kdp_use_cnt = ATOMIC_INIT(4), + .kdp_rcu_head.non_rcu = 0, + .kdp_rcu_head.bp_cred = (void *)0, +}; unsigned int rkp_get_usecount(struct cred *cred) { @@ -113,7 +117,7 @@ struct cred init_cred = { .user_ns = &init_user_ns, .group_info = &init_groups, #ifdef CONFIG_KDP_CRED - .use_cnt = &init_cred_use_cnt, + .use_cnt = (atomic_t *)&init_cred_use_cnt, .bp_task = &init_task, .bp_pgd = (void *) 0, .type = 0, @@ -884,8 +888,8 @@ void revert_creds(const struct cred *old) if (rkp_ro_page((unsigned long)override)){ if(get_rocred_rcu(override)->reflected_cred) put_cred((struct cred *)get_rocred_rcu(override)->reflected_cred); - put_cred(override); -} + put_cred(override); + } } #endif put_cred(override); @@ -930,7 +934,7 @@ void __init cred_init(void) panic("Unable to create RO security cache\n"); } - usecnt_jar = kmem_cache_create("usecnt_jar", sizeof(atomic_t) + sizeof(struct ro_rcu_head), + usecnt_jar = kmem_cache_create("usecnt_jar", sizeof(struct kdp_usecnt), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, usecnt_ctor); if(!usecnt_jar) { panic("Unable to create use count jar\n"); diff --git a/kernel/power/main.c b/kernel/power/main.c index 36a3c9645..15f2bc177 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -794,12 +794,31 @@ power_attr(wake_unlock); #ifdef CONFIG_CPU_FREQ_LIMIT_USERSPACE #define MAX_BUF_SIZE 100 -static int cpufreq_max_limit_val = -1; -static int cpufreq_min_limit_val = -1; -struct cpufreq_limit_handle *cpufreq_max_hd; -struct cpufreq_limit_handle *cpufreq_min_hd; DEFINE_MUTEX(cpufreq_limit_mutex); +int set_freq_limit(unsigned long id, unsigned int freq) +{ + int ret = 0; + struct cpufreq_limit_handle *handle = + cpufreq_limit_get_handle(id); + + pr_debug("%s: id(%d) freq(%d)\n", __func__, (int)id, freq); + + mutex_lock(&cpufreq_limit_mutex); + + if (freq != -1) { + ret = cpufreq_limit_get(freq, handle); + if (ret) + pr_err("%s: cpufreq_limit_get fail %lu, %u, %d\n", + __func__, id, freq, ret); + } else + cpufreq_limit_put(handle); + + mutex_unlock(&cpufreq_limit_mutex); + + return ret; +} + static ssize_t cpufreq_table_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -847,60 +866,66 @@ static ssize_t cpufreq_max_limit_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return snprintf(buf, MAX_BUF_SIZE, "%d\n", cpufreq_max_limit_val); + return snprintf(buf, MAX_BUF_SIZE, "%d\n", cpufreq_limit_get_cur_max()); } static ssize_t cpufreq_max_limit_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { - int val; + int freq; ssize_t ret = -EINVAL; - ret = kstrtoint(buf, 10, &val); + ret = kstrtoint(buf, 10, &freq); if (ret < 0) { pr_err("%s: Invalid cpufreq format\n", __func__); - goto out; + return ret; } - mutex_lock(&cpufreq_limit_mutex); - if (cpufreq_max_hd) { - cpufreq_limit_put(cpufreq_max_hd); - cpufreq_max_hd = NULL; - } + set_freq_limit(DVFS_USER_MAX_ID, freq); + ret = n; - /* big core hotplut in/out regarding max limit clock */ - cpufreq_limit_corectl(val); + return ret; +} - if (val != -1) { - cpufreq_max_hd = cpufreq_limit_max_freq(val, "user lock(max)"); - if (IS_ERR(cpufreq_max_hd)) { - pr_err("%s: fail to get the handle\n", __func__); - cpufreq_max_hd = NULL; - } - } +static ssize_t cpufreq_min_limit_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, MAX_BUF_SIZE, "%d\n", cpufreq_limit_get_cur_min()); +} - cpufreq_max_hd ? - (cpufreq_max_limit_val = val) : (cpufreq_max_limit_val = -1); +static ssize_t cpufreq_min_limit_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + int freq; + ssize_t ret = -EINVAL; - mutex_unlock(&cpufreq_limit_mutex); + ret = kstrtoint(buf, 10, &freq); + if (ret < 0) { + pr_err("%s: Invalid cpufreq format\n", __func__); + return ret; + } + + set_freq_limit(DVFS_USER_MIN_ID, freq); ret = n; -out: + return ret; } -static ssize_t cpufreq_min_limit_show(struct kobject *kobj, +static ssize_t over_limit_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return snprintf(buf, MAX_BUF_SIZE, "%d\n", cpufreq_min_limit_val); + return snprintf(buf, MAX_BUF_SIZE, "%d\n", cpufreq_limit_get_over_limit()); } -static ssize_t cpufreq_min_limit_store(struct kobject *kobj, +static ssize_t over_limit_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { - int val; + unsigned int val; ssize_t ret = -EINVAL; ret = kstrtoint(buf, 10, &val); @@ -910,22 +935,7 @@ static ssize_t cpufreq_min_limit_store(struct kobject *kobj, } mutex_lock(&cpufreq_limit_mutex); - if (cpufreq_min_hd) { - cpufreq_limit_put(cpufreq_min_hd); - cpufreq_min_hd = NULL; - } - - if (val != -1) { - cpufreq_min_hd = cpufreq_limit_min_freq(val, "user lock(min)"); - if (IS_ERR(cpufreq_min_hd)) { - pr_err("%s: fail to get the handle\n", __func__); - cpufreq_min_hd = NULL; - } - } - - cpufreq_min_hd ? - (cpufreq_min_limit_val = val) : (cpufreq_min_limit_val = -1); - + cpufreq_limit_set_over_limit((unsigned int)val); mutex_unlock(&cpufreq_limit_mutex); ret = n; out: @@ -935,79 +945,7 @@ static ssize_t cpufreq_min_limit_store(struct kobject *kobj, power_attr(cpufreq_table); power_attr(cpufreq_max_limit); power_attr(cpufreq_min_limit); - -struct cpufreq_limit_list_t { - char name[20]; - struct cpufreq_limit_handle *handle; - int id_mask; -}; - -struct cpufreq_limit_list_t cpufreq_limit_list[] = { - { - .name = "touch min", - .handle = NULL, - .id_mask = DVFS_TOUCH_ID_MASK - }, - { - .name = "finger min", - .handle = NULL, - .id_mask = DVFS_FINGER_ID_MASK - }, - { - .name = "multi-touch min", - .handle = NULL, - .id_mask = DVFS_MULTI_TOUCH_ID_MASK - }, - { - .name = "argos min", - .handle = NULL, - .id_mask = DVFS_ARGOS_ID_MASK - }, -#ifdef CONFIG_USB_AUDIO_ENHANCED_DETECT_TIME - { - .name = "boost-host min", - .handle = NULL, - .id_mask = DVFS_BOOST_HOST_ID_MASK - }, -#endif -}; - -int set_freq_limit(unsigned long id, unsigned int freq) -{ - ssize_t ret = -EINVAL; - int mask = (1 << id); - size_t i; - struct cpufreq_limit_list_t *list; - - mutex_lock(&cpufreq_limit_mutex); - - pr_debug("%s: id(%d) freq(%d)\n", __func__, (int)id, freq); - - for (i = 0; i < ARRAY_SIZE(cpufreq_limit_list); i++) { - list = &cpufreq_limit_list[i]; - /* min lock */ - if (list->id_mask & mask) { - if (freq != -1) { - list->handle = cpufreq_limit_min_freq(freq, - list->name); - if (IS_ERR(list->handle)) { - pr_err("%s: fail to get the handle\n", - __func__); - list->handle = NULL; - goto out; - } - } else if (list->handle) { - cpufreq_limit_put(list->handle); - list->handle = NULL; - } - } - } - ret = 0; - -out: - mutex_unlock(&cpufreq_limit_mutex); - return ret; -} +power_attr(over_limit); #endif #ifdef CONFIG_PM_TRACE @@ -1178,6 +1116,7 @@ static struct attribute * g[] = { &cpufreq_table_attr.attr, &cpufreq_max_limit_attr.attr, &cpufreq_min_limit_attr.attr, + &over_limit_attr.attr, #endif #ifdef CONFIG_FREEZER &pm_freeze_timeout_attr.attr, diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9da9ccbcf..7b2f82154 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7091,6 +7091,12 @@ static int get_start_cpu(struct task_struct *p) return start_cpu; } #endif /* CONFIG_SCHED_SEC_TASK_BOOST */ + + if (task_boost > TASK_BOOST_ON_MID) { + start_cpu = rd->max_cap_orig_cpu; + return start_cpu; + } + /* * note about min/mid/max_cap_orig_cpu - either all of them will be -ve * or just mid will be -1, there never be any other combinations of -1s @@ -7099,11 +7105,9 @@ static int get_start_cpu(struct task_struct *p) if (task_skip_min || boosted) { start_cpu = rd->mid_cap_orig_cpu == -1 ? rd->max_cap_orig_cpu : rd->mid_cap_orig_cpu; - } - - if (task_boost > TASK_BOOST_ON_MID) { - start_cpu = rd->max_cap_orig_cpu; +#ifdef CONFIG_WALT_POWER_FEATURE return start_cpu; +#endif } if (start_cpu == -1 || start_cpu == rd->max_cap_orig_cpu) diff --git a/mm/Kconfig b/mm/Kconfig index e5d2d3b49..06cf0a224 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -913,7 +913,8 @@ config LARGE_DIRTY_BUFFER config MAX_DIRTY_THRESH_PAGES int "The upper bound of VM dirty_thresh value in number of pages" - default 0 + depends on LARGE_DIRTY_BUFFER + default 25600 help This value is the upper bound of VM dirty-thresh. (0 means no limit.) It is only effective when dirty_ratio is used. diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 2b859f523..e21a86109 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -148,8 +148,15 @@ static ssize_t read_ahead_kb_store(struct device *dev, struct backing_dev_info *bdi = dev_get_drvdata(dev); unsigned long read_ahead_kb; ssize_t ret; + static const char temp[] = "temporary "; + + if (strncmp(buf, temp, sizeof(temp) - 1) != 0) + return count; + + buf += sizeof(temp) - 1; ret = kstrtoul(buf, 10, &read_ahead_kb); + if (ret < 0) return ret; diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 0d03be290..865e0aae3 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -621,6 +621,7 @@ void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask) if (heaviest_rss_sum) pr_info("heaviest_task:%s(%d) rss_pages:%lu\n", heaviest_comm, heaviest_pid, heaviest_rss_sum); + ion_account_print_usage(); } static void dump_header(struct oom_control *oc, struct task_struct *p) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 24e1562c8..b107be294 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -443,7 +443,7 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc) else thresh = (ratio * available_memory) / PAGE_SIZE; -#if defined(CONFIG_MAX_DIRTY_THRESH_PAGES) && CONFIG_MAX_DIRTY_THRESH_PAGES > 0 +#if defined(CONFIG_MAX_DIRTY_THRESH_PAGES) && (CONFIG_MAX_DIRTY_THRESH_PAGES > 0) if (!bytes && thresh > CONFIG_MAX_DIRTY_THRESH_PAGES) { thresh = CONFIG_MAX_DIRTY_THRESH_PAGES; /* reduce available memory not to make bg_thresh too high */ @@ -509,7 +509,7 @@ static unsigned long node_dirty_limit(struct pglist_data *pgdat) else dirty = vm_dirty_ratio * node_memory / 100; -#if defined(CONFIG_MAX_DIRTY_THRESH_PAGES) && CONFIG_MAX_DIRTY_THRESH_PAGES > 0 +#if defined(CONFIG_MAX_DIRTY_THRESH_PAGES) && (CONFIG_MAX_DIRTY_THRESH_PAGES > 0) if (!vm_dirty_bytes && dirty > CONFIG_MAX_DIRTY_THRESH_PAGES) dirty = CONFIG_MAX_DIRTY_THRESH_PAGES; #endif @@ -1890,6 +1890,7 @@ static void balance_dirty_pages(struct bdi_writeback *wb, (unsigned long) nr_dirty_inodes_in_timelist); } + /* IOPP-prevent_infinite_writeback-v1.1.4.4 */ /* Do not sleep if the backing device is removed */ if (unlikely(!bdi->dev)) return; diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 22a709ad0..8cb9c30bf 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -1067,18 +1067,6 @@ static struct sock_tag *get_sock_stat_nl(const struct sock *sk) return sock_tag_tree_search(&sock_tag_tree, sk); } -static struct sock_tag *get_sock_stat(const struct sock *sk) -{ - struct sock_tag *sock_tag_entry; - MT_DEBUG("qtaguid: get_sock_stat(sk=%p)\n", sk); - if (!sk) - return NULL; - spin_lock_bh(&sock_tag_list_lock); - sock_tag_entry = get_sock_stat_nl(sk); - spin_unlock_bh(&sock_tag_list_lock); - return sock_tag_entry; -} - static int ipx_proto(const struct sk_buff *skb, struct xt_action_param *par) { @@ -1313,12 +1301,15 @@ static void if_tag_stat_update(const char *ifname, uid_t uid, * Look for a tagged sock. * It will have an acct_uid. */ - sock_tag_entry = get_sock_stat(sk); + spin_lock_bh(&sock_tag_list_lock); + sock_tag_entry = sk ? get_sock_stat_nl(sk) : NULL; if (sock_tag_entry) { tag = sock_tag_entry->tag; acct_tag = get_atag_from_tag(tag); uid_tag = get_utag_from_tag(tag); - } else { + } + spin_unlock_bh(&sock_tag_list_lock); + if (!sock_tag_entry) { acct_tag = make_atag_from_value(0); tag = combine_atag_with_uid(acct_tag, uid); uid_tag = make_tag_from_uid(uid); diff --git a/security/mstdrv/Kconfig b/security/mstdrv/Kconfig index 00576b73d..f5506c98a 100644 --- a/security/mstdrv/Kconfig +++ b/security/mstdrv/Kconfig @@ -21,7 +21,7 @@ config MST_LDO && !(MACH_C2Q_CHN_OPEN && !(MACH_C2Q_CHN_HK) && !(SEC_FACTORY)) \ && !(MACH_F2Q_CHN_OPEN && !(MACH_F2Q_CHN_HKX) && !(SEC_FACTORY)) \ && !(MACH_BLOOMXQ_CHN_OPEN && !(MACH_BLOOMXQ_CHN_HKX) && !(SEC_FACTORY)) \ - && !(MACH_R8Q_CAN_SINGLE) && !(MACH_R8Q_CHN_HKX) && !(MACH_R8Q_CHN_OPEN) && !(MACH_R8Q_EUR_OPEN) \ + && !(MACH_R8Q_CAN_SINGLE) && !(MACH_R8Q_CHN_HKX) && !(MACH_R8Q_CHN_OPEN) \ && !(SEC_VICTORY_PROJECT) default n help @@ -37,7 +37,7 @@ config MST_V2 && !(MACH_C2Q_CHN_OPEN && !(MACH_C2Q_CHN_HK) && !(SEC_FACTORY)) \ && !(MACH_F2Q_CHN_OPEN && !(MACH_F2Q_CHN_HKX) && !(SEC_FACTORY)) \ && !(MACH_BLOOMXQ_CHN_OPEN && !(MACH_BLOOMXQ_CHN_HKX) && !(SEC_FACTORY)) \ - && !(MACH_R8Q_CAN_SINGLE) && !(MACH_R8Q_CHN_HKX) && !(MACH_R8Q_CHN_OPEN) && !(MACH_R8Q_EUR_OPEN) \ + && !(MACH_R8Q_CAN_SINGLE) && !(MACH_R8Q_CHN_HKX) && !(MACH_R8Q_CHN_OPEN) \ && !(SEC_VICTORY_PROJECT) default n help @@ -77,7 +77,7 @@ config MFC_CHARGER && !(MACH_C2Q_CHN_OPEN && !(MACH_C2Q_CHN_HK) && !(SEC_FACTORY)) \ && !(MACH_F2Q_CHN_OPEN && !(MACH_F2Q_CHN_HKX) && !(SEC_FACTORY)) \ && !(MACH_BLOOMXQ_CHN_OPEN && !(MACH_BLOOMXQ_CHN_HKX) && !(SEC_FACTORY)) \ - && !(MACH_R8Q_CAN_SINGLE) && !(MACH_R8Q_CHN_HKX) && !(MACH_R8Q_CHN_OPEN) && !(MACH_R8Q_EUR_OPEN) \ + && !(MACH_R8Q_CAN_SINGLE) && !(MACH_R8Q_CHN_HKX) && !(MACH_R8Q_CHN_OPEN) \ && !(SEC_VICTORY_PROJECT) default n help @@ -100,4 +100,3 @@ config MST_LPM_CONTROL default n help This enables the MST LPM control code - diff --git a/security/mstdrv/mstdrv.c b/security/mstdrv/mstdrv.c index 8400d217d..7a5c998d1 100644 --- a/security/mstdrv/mstdrv.c +++ b/security/mstdrv/mstdrv.c @@ -861,13 +861,13 @@ static int sec_mst_gpio_init(struct device *dev) static int mfc_get_chip_id() { u8 chip_id = 0; - int retry_cnt = 3; + int retry_cnt = 9; int ret = 0; struct power_supply *psy = NULL; struct mfc_charger_data *charger = NULL; while (retry_cnt-- > 0) { - msleep(30); + msleep(10); psy = get_power_supply_by_name("mfc-charger"); if (psy == NULL) { diff --git a/security/samsung/defex_lsm/Makefile b/security/samsung/defex_lsm/Makefile index 118f3ef8b..658844a47 100755 --- a/security/samsung/defex_lsm/Makefile +++ b/security/samsung/defex_lsm/Makefile @@ -26,15 +26,14 @@ RAMDISK_ENABLE=true # do signing for rules SIGN_ENABLE=true -obj-y := core/defex_common.o -obj-y += core/defex_lsm.o -obj-y += core/defex_main.o -obj-y += core/defex_get_mode.o -obj-y += core/defex_sysfs.o -obj-y += catch_engine/defex_catch_list.o -obj-y += catch_engine/defex_ht.o -obj-y += defex_rules.o -obj-$(CONFIG_COMPAT) += catch_engine/defex_catch_list_compat.o +defex-y := core/defex_common.o +defex-y += core/defex_lsm.o +defex-y += core/defex_main.o +defex-y += core/defex_get_mode.o +defex-y += core/defex_rules_proc.o +defex-y += catch_engine/defex_catch_list.o +defex-y += catch_engine/defex_ht.o +defex-$(CONFIG_COMPAT) += catch_engine/defex_catch_list_compat.o # Immutable Feature is applied with permissive mode first. DEFEX_DEFINES := -DDEFEX_PERMISSIVE_IM @@ -45,6 +44,8 @@ ifeq ($(CONFIG_DEFEX_KERNEL_ONLY), y) $(warning [DEFEX] Kernel_only & Ship) else $(warning [DEFEX] Kernel_only & Noship) + defex-y += debug/defex_debug.o + defex-y += core/defex_sysfs.o DEFEX_DEFINES += -DDEFEX_PERMISSIVE_SP DEFEX_DEFINES += -DDEFEX_PERMISSIVE_IM DEFEX_DEFINES += -DDEFEX_PERMISSIVE_LP @@ -56,19 +57,13 @@ ifeq ($(CONFIG_SEC_FACTORY), y) DEFEX_DEFINES += -DDEFEX_FACTORY_ENABLE endif -ifeq ($(CONFIG_KUNIT), y) - DEFEX_DEFINES += -DDEFEX_KUNIT_ENABLED -else - DEFEX_DEFINES += -D__visible_for_testing=static -endif - ifeq ($(PED_ENABLE), true) - obj-y += feature_privilege_escalation_detection/defex_priv.o + defex-y += feature_privilege_escalation_detection/defex_priv.o DEFEX_DEFINES += -DDEFEX_PED_ENABLE endif ifeq ($(SAFEPLACE_ENABLE), true) - obj-y += feature_safeplace/defex_safeplace.o + defex-y += feature_safeplace/defex_safeplace.o DEFEX_DEFINES += -DDEFEX_SAFEPLACE_ENABLE endif @@ -77,7 +72,7 @@ ifeq ($(INTEGRITY_ENABLE), true) endif ifeq ($(IMMUTABLE_ENABLE), true) - obj-y += feature_immutable/defex_immutable.o + defex-y += feature_immutable/defex_immutable.o DEFEX_DEFINES += -DDEFEX_IMMUTABLE_ENABLE endif @@ -90,7 +85,7 @@ ifeq ($(UMH_RESTRICTION_ENABLE), true) endif ifeq ($(CACHES_ENABLE), true) - obj-y += catch_engine/defex_caches.o + defex-y += catch_engine/defex_caches.o DEFEX_DEFINES += -DDEFEX_CACHES_ENABLE endif @@ -101,25 +96,33 @@ endif ifeq ($(RAMDISK_ENABLE), true) DEFEX_DEFINES += -DDEFEX_RAMDISK_ENABLE ifeq ($(SIGN_ENABLE), true) - obj-y += cert/defex_cert.o - obj-y += cert/defex_sign.o + defex-y += cert/defex_cert.o + defex-y += cert/defex_sign.o DEFEX_DEFINES += -DDEFEX_SIGN_ENABLE endif endif ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT))) - obj-y += debug/defex_debug.o + defex-y += debug/defex_debug.o + defex-y += core/defex_sysfs.o DEFEX_DEFINES += -DDEFEX_PERMISSIVE_SP DEFEX_DEFINES += -DDEFEX_PERMISSIVE_IM DEFEX_DEFINES += -DDEFEX_PERMISSIVE_LP DEFEX_DEFINES += -DDEFEX_DEBUG_ENABLE - DEFEX_DEFINES += -DDEFEX_SYSFS_ENABLE else ifeq ($(CONFIG_SECURITY_DSMS), y) DEFEX_DEFINES += -DDEFEX_DSMS_ENABLE endif endif +# kunit tests options: +ifeq ($(CONFIG_KUNIT), y) + GCOV_PROFILE := y + DEFEX_DEFINES += -DDEFEX_KUNIT_ENABLED +else + DEFEX_DEFINES += -D__visible_for_testing=static +endif + ccflags-y := -Wformat EXTRA_CFLAGS += -I$(srctree)/$(src) @@ -128,7 +131,6 @@ EXTRA_CFLAGS += -I$(srctree)/$(src)/cert EXTRA_AFLAGS += -Isecurity/samsung/defex_lsm/cert ifneq ($(wildcard $(srctree)/$(src)/pack_rules.c),) - DEFEX_DEFINES += -DDEFEX_USE_PACKED_RULES EXTRA_CFLAGS += $(DEFEX_DEFINES) EXTRA_AFLAGS += $(DEFEX_DEFINES) hostprogs-y := pack_rules @@ -145,7 +147,7 @@ ifneq ($(wildcard $(srctree)/$(src)/pack_rules.c),) quiet_cmd_mkey = MAKEKEY $< cmd_mkey = cp -n $< $@ 2>/dev/null || true - $(obj)/core/defex_sysfs.o: $(obj)/pack_rules $(srctree)/$(src)/defex_packed_rules.inc + $(obj)/core/defex_rules_proc.o: $(obj)/pack_rules $(srctree)/$(src)/defex_packed_rules.inc $(obj)/cert/defex_cert.o: $(obj)/cert/pubkey_eng.der $(obj)/cert/pubkey_user.der @@ -178,3 +180,5 @@ else EXTRA_CFLAGS += $(DEFEX_DEFINES) EXTRA_AFLAGS += $(DEFEX_DEFINES) endif + +obj-$(CONFIG_SECURITY_DEFEX) := $(defex-y) diff --git a/security/samsung/defex_lsm/catch_engine/defex_catch_list.c b/security/samsung/defex_lsm/catch_engine/defex_catch_list.c index fcbf13bbe..935374761 100644 --- a/security/samsung/defex_lsm/catch_engine/defex_catch_list.c +++ b/security/samsung/defex_lsm/catch_engine/defex_catch_list.c @@ -6,7 +6,7 @@ * as published by the Free Software Foundation. */ -#include +#include #include #include #include @@ -16,6 +16,12 @@ #include #include "include/defex_catch_list.h" +#ifdef DEFEX_KUNIT_ENABLED +#ifndef __NR_syscalls +#define __NR_syscalls 436 +#endif +#endif + #define DEFEX_CATCH_COUNT __NR_syscalls const int defex_nr_syscalls = DEFEX_CATCH_COUNT; diff --git a/security/samsung/defex_lsm/catch_engine/defex_ht.c b/security/samsung/defex_lsm/catch_engine/defex_ht.c index 34e5675e2..75b7abf1b 100644 --- a/security/samsung/defex_lsm/catch_engine/defex_ht.c +++ b/security/samsung/defex_lsm/catch_engine/defex_ht.c @@ -54,9 +54,9 @@ struct mem_cache_list { #ifdef DEFEX_PED_ENABLE DECLARE_HASHTABLE(creds_hash, 15); -static DEFINE_SPINLOCK(creds_hash_update_lock); +__visible_for_testing DEFINE_SPINLOCK(creds_hash_update_lock); static struct proc_cred_data *creds_fast_hash[MAX_PID_32 + 1]; -static struct mem_cache_list mem_cache[DEFEX_MEM_CACHE_COUNT]; +__visible_for_testing struct mem_cache_list mem_cache[DEFEX_MEM_CACHE_COUNT]; static int creds_fast_hash_ready __ro_after_init; __visible_for_testing void mem_cache_alloc(void); diff --git a/security/samsung/defex_lsm/cert/defex_sign.c b/security/samsung/defex_lsm/cert/defex_sign.c index 7d5c01f7c..0b568f682 100644 --- a/security/samsung/defex_lsm/cert/defex_sign.c +++ b/security/samsung/defex_lsm/cert/defex_sign.c @@ -22,9 +22,7 @@ #include #endif -#define SIGN_SIZE 256 #define SHA256_DIGEST_SIZE 32 -#define MAX_DATA_LEN 300 extern char defex_public_key_start[]; extern char defex_public_key_end[]; @@ -144,46 +142,6 @@ __visible_for_testing int __init defex_public_key_verify_signature(unsigned char } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) */ -#ifdef DEFEX_DEBUG_ENABLE -void __init blob(const char *buffer, const size_t bufLen, const int lineSize) -{ - size_t i = 0, line; - size_t j = 0, len = bufLen; - int offset = 0; - char c, stringToPrint[MAX_DATA_LEN]; - - do { - line = (len > lineSize)?lineSize:len; - offset = 0; - offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "| 0x%0*zx | ", PR_HEX(i)); - - for(j = 0; j < line; j++) - offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "%02X ", (unsigned char)buffer[i + j]); - if (line < lineSize) { - for(j = 0; j < lineSize - line; j++) - offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, " "); - } - offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "| "); - - for(j = 0; j < line; j++) { - c = buffer[i + j]; - c = (c < 0x20)||(c >= 0x7F)?'.':c; - offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "%c", c); - } - if (line < lineSize) { - for(j = 0; j < lineSize - line; j++) - offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, " "); - } - - offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, " |"); - printk(KERN_INFO "%s\n", stringToPrint); - memset(stringToPrint, 0, MAX_DATA_LEN); - i += line; - len -= line; - } while(len); -} -#endif - int __init defex_calc_hash(const char *data, unsigned int size, unsigned char *hash) { struct crypto_shash *handle; diff --git a/security/samsung/defex_lsm/core/defex_common.c b/security/samsung/defex_lsm/core/defex_common.c index 005907671..8e1d24ad4 100644 --- a/security/samsung/defex_lsm/core/defex_common.c +++ b/security/samsung/defex_lsm/core/defex_common.c @@ -94,16 +94,13 @@ void init_defex_context(struct defex_context *dc, int syscall, struct task_struc { const struct cred *cred_ptr; + memset(dc, 0, offsetof(struct defex_context, cred)); + if (!IS_ERR_OR_NULL(f)) { + get_file(f); + dc->target_file = f; + } dc->syscall_no = syscall; dc->task = p; - dc->process_file = NULL; - dc->process_dpath = NULL; - dc->process_name = NULL; - dc->target_file = f; - dc->target_dpath = NULL; - dc->target_name = NULL; - dc->process_name_buff = NULL; - dc->target_name_buff = NULL; if (p == current) cred_ptr = get_current_cred(); else @@ -116,6 +113,8 @@ void release_defex_context(struct defex_context *dc) { kfree(dc->process_name_buff); kfree(dc->target_name_buff); + if (dc->target_file) + fput(dc->target_file); #ifndef DEFEX_CACHES_ENABLE if (dc->process_file) fput(dc->process_file); @@ -172,7 +171,7 @@ const struct path *get_dc_target_dpath(struct defex_context *dc) if (dc->target_dpath) return dc->target_dpath; - if (!IS_ERR_OR_NULL(dc->target_file)) { + if (dc->target_file) { dpath = &(dc->target_file->f_path); if (dpath->dentry && dpath->dentry->d_inode) { dc->target_dpath = dpath; @@ -256,14 +255,20 @@ char *defex_get_filename(struct task_struct *p) char *filename = NULL; exe_file = defex_get_source_file(p); - if (!exe_file) + if (IS_ERR_OR_NULL(exe_file)) goto out_filename; dpath = &exe_file->f_path; + if (!dpath->dentry || !dpath->dentry->d_inode) { + fput(exe_file); + goto out_filename; + } + path_get(dpath); buff = kmalloc(PATH_MAX, GFP_KERNEL); if (buff) path = d_path(dpath, buff, PATH_MAX); + path_put(dpath); #ifndef DEFEX_CACHES_ENABLE fput(exe_file); diff --git a/security/samsung/defex_lsm/core/defex_get_mode.c b/security/samsung/defex_lsm/core/defex_get_mode.c index ca6206750..8b6fb0eae 100644 --- a/security/samsung/defex_lsm/core/defex_get_mode.c +++ b/security/samsung/defex_lsm/core/defex_get_mode.c @@ -15,7 +15,6 @@ #include #include "include/defex_internal.h" - int defex_get_features(void) { int features = 0; @@ -23,9 +22,9 @@ int defex_get_features(void) #if !defined(DEFEX_PERMISSIVE_PED) features |= GLOBAL_PED_STATUS; #else - if (global_privesc_obj->status != 0) + if (global_privesc_status != 0) features |= FEATURE_CHECK_CREDS; - if (global_privesc_obj->status == 2) + if (global_privesc_status == 2) features |= FEATURE_CHECK_CREDS_SOFT; #endif /* DEFEX_PERMISSIVE_PED */ #endif /* DEFEX_PED_ENABLE */ @@ -34,9 +33,9 @@ int defex_get_features(void) #if !defined(DEFEX_PERMISSIVE_SP) features |= GLOBAL_SAFEPLACE_STATUS; #else - if (global_safeplace_obj->status != 0) + if (global_safeplace_status != 0) features |= FEATURE_SAFEPLACE; - if (global_safeplace_obj->status == 2) + if (global_safeplace_status == 2) features |= FEATURE_SAFEPLACE_SOFT; #endif /* DEFEX_PERMISSIVE_SP */ #endif /* DEFEX_SAFEPLACE_ENABLE */ @@ -45,9 +44,9 @@ int defex_get_features(void) #if !defined(DEFEX_PERMISSIVE_IM) features |= GLOBAL_IMMUTABLE_STATUS; #else - if (global_immutable_obj->status != 0) + if (global_immutable_status != 0) features |= FEATURE_IMMUTABLE; - if (global_immutable_obj->status == 2) + if (global_immutable_status == 2) features |= FEATURE_IMMUTABLE_SOFT; #endif /* DEFEX_PERMISSIVE_IM */ #endif /* DEFEX_IMMUTABLE_ENABLE */ diff --git a/security/samsung/defex_lsm/core/defex_lsm.c b/security/samsung/defex_lsm/core/defex_lsm.c index 8a030634f..77187c210 100755 --- a/security/samsung/defex_lsm/core/defex_lsm.c +++ b/security/samsung/defex_lsm/core/defex_lsm.c @@ -6,7 +6,7 @@ * as published by the Free Software Foundation. */ -#include +#include #include #include #include @@ -52,7 +52,9 @@ asmlinkage int defex_syscall_enter(long int syscallno, struct pt_regs *regs) //INIT///////////////////////////////////////////////////////////////////////// __visible_for_testing int __init defex_lsm_init(void) { +#ifdef DEFEX_DEBUG_ENABLE int ret; +#endif /* DEFEX_DEBUG_ENABLE */ #ifdef DEFEX_CACHES_ENABLE defex_file_cache_init(); @@ -62,11 +64,13 @@ __visible_for_testing int __init defex_lsm_init(void) creds_fast_hash_init(); #endif /* DEFEX_PED_ENABLE */ +#ifdef DEFEX_DEBUG_ENABLE ret = defex_init_sysfs(); if (ret) { pr_crit("DEFEX_LSM defex_init_sysfs() failed!"); return ret; } +#endif /* DEFEX_DEBUG_ENABLE */ printk(KERN_INFO "DEFEX_LSM started"); #ifdef DEFEX_LP_ENABLE diff --git a/security/samsung/defex_lsm/core/defex_main.c b/security/samsung/defex_lsm/core/defex_main.c index 882bd6ada..1530c0dda 100644 --- a/security/samsung/defex_lsm/core/defex_main.c +++ b/security/samsung/defex_lsm/core/defex_main.c @@ -43,7 +43,7 @@ #ifdef DEFEX_DEPENDING_ON_OEMUNLOCK bool boot_state_unlocked __ro_after_init; -static int __init verifiedboot_state_setup(char *str) +__visible_for_testing int __init verifiedboot_state_setup(char *str) { static const char unlocked[] = "orange"; @@ -57,8 +57,8 @@ static int __init verifiedboot_state_setup(char *str) __setup("androidboot.verifiedbootstate=", verifiedboot_state_setup); -int warranty_bit __ro_after_init; -static int __init get_warranty_bit(char *str) +static int warranty_bit __ro_after_init; +__visible_for_testing int __init get_warranty_bit(char *str) { get_option(&str, &warranty_bit); @@ -89,7 +89,7 @@ __visible_for_testing struct task_struct *get_parent_task(const struct task_stru # define MESSAGE_BUFFER_SIZE 200 # define STORED_CREDS_SIZE 100 -static void defex_report_violation(const char *violation, uint64_t counter, struct defex_context *dc, +__visible_for_testing void defex_report_violation(const char *violation, uint64_t counter, struct defex_context *dc, uid_t stored_uid, uid_t stored_fsuid, uid_t stored_egid, int case_num) { int usermode_result; @@ -184,7 +184,7 @@ __visible_for_testing int task_defex_is_secured(struct defex_context *dc) return DEFEX_ALLOW; } - is_secured = !rules_lookup2(proc_name, feature_ped_exception, exe_file); + is_secured = !rules_lookup(proc_name, feature_ped_exception, exe_file); return is_secured; } @@ -405,7 +405,7 @@ __visible_for_testing int task_defex_safeplace(struct defex_context *dc) goto out; new_file = get_dc_target_name(dc); - is_violation = rules_lookup2(new_file, feature_safeplace_path, dc->target_file); + is_violation = rules_lookup(new_file, feature_safeplace_path, dc->target_file); #ifdef DEFEX_INTEGRITY_ENABLE if (is_violation != DEFEX_INTEGRITY_FAIL) #endif /* DEFEX_INTEGRITY_ENABLE */ @@ -456,7 +456,7 @@ __visible_for_testing int task_defex_src_exception(struct defex_context *dc) return allow; exe_file = get_dc_process_file(dc); - allow = rules_lookup2(proc_name, feature_immutable_src_exception, exe_file); + allow = rules_lookup(proc_name, feature_immutable_src_exception, exe_file); return allow; } @@ -471,7 +471,7 @@ __visible_for_testing int task_defex_immutable(struct defex_context *dc, int att goto out; new_file = get_dc_target_name(dc); - is_violation = rules_lookup2(new_file, attribute, dc->target_file); + is_violation = rules_lookup(new_file, attribute, dc->target_file); if (is_violation) { /* Check the Source exception and self-access */ @@ -625,7 +625,7 @@ int task_defex_user_exec(const char *new_file) filp_close(fp, NULL); } - is_violation = !rules_lookup2(new_file, feature_umhbin_path, NULL); + is_violation = !rules_lookup(new_file, feature_umhbin_path, NULL); if (is_violation) { printk("[DEFEX] UMH Exec Denied: %s\n", new_file); goto umh_out; diff --git a/security/samsung/defex_lsm/core/defex_rules_proc.c b/security/samsung/defex_lsm/core/defex_rules_proc.c new file mode 100644 index 000000000..9b9039872 --- /dev/null +++ b/security/samsung/defex_lsm/core/defex_rules_proc.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. 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 + * as published by the Free Software Foundation. + */ + +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +#include +#endif /* < KERNEL_VERSION(4, 12, 0) */ + +#include "include/defex_debug.h" +#include "include/defex_internal.h" +#include "include/defex_rules.h" +#include "include/defex_sign.h" + +#define DEFEX_RULES_FILE "/dpolicy" + +/* + * Variant 1: Platform build, use static packed rules array + */ +#include "defex_packed_rules.inc" + +#ifdef DEFEX_RAMDISK_ENABLE +/* + * Variant 2: Platform build, load rules from kernel ramdisk or system partition + */ +#ifdef DEFEX_SIGN_ENABLE +#include "include/defex_sign.h" +#endif +#if (DEFEX_RULES_ARRAY_SIZE < 8) +#undef DEFEX_RULES_ARRAY_SIZE +#define DEFEX_RULES_ARRAY_SIZE sizeof(struct rule_item_struct) +#endif +#ifdef DEFEX_KERNEL_ONLY +#undef DEFEX_RULES_ARRAY_SIZE +#define DEFEX_RULES_ARRAY_SIZE (256 * 1024) +static unsigned char defex_packed_rules[DEFEX_RULES_ARRAY_SIZE] = {0}; +#else +static unsigned char defex_packed_rules[DEFEX_RULES_ARRAY_SIZE] __ro_after_init = {0}; +#endif /* DEFEX_KERNEL_ONLY */ +#endif /* DEFEX_RAMDISK_ENABLE */ + + +#ifdef DEFEX_INTEGRITY_ENABLE + +#include +#include +#include +#include +#include "../../integrity/integrity.h" +#define SHA256_DIGEST_SIZE 32 +#endif /* DEFEX_INTEGRITY_ENABLE */ + +static int is_recovery; + +__visible_for_testing int __init bootmode_setup(char *str) +{ + if (str && *str == '2') { + is_recovery = 1; + pr_alert("[DEFEX] recovery mode setup\n"); + } + return 0; +} +__setup("bootmode=", bootmode_setup); + +int check_rules_ready(void) +{ + struct rule_item_struct *base = (struct rule_item_struct *)defex_packed_rules; + + return (!base || !base->data_size)?0:1; +} + +__visible_for_testing int check_system_mount(void) +{ + static int mount_system_root = -1; + struct file *fp; + + if (mount_system_root < 0) { + fp = local_fopen("/sbin/recovery", O_RDONLY, 0); + if (IS_ERR(fp)) + fp = local_fopen("/system/bin/recovery", O_RDONLY, 0); + + if (!IS_ERR(fp)) { + pr_alert("[DEFEX] recovery mode\n"); + filp_close(fp, NULL); + is_recovery = 1; + } else { + pr_alert("[DEFEX] normal mode\n"); + } + + mount_system_root = 0; + fp = local_fopen("/system_root", O_DIRECTORY | O_PATH, 0); + if (!IS_ERR(fp)) { + filp_close(fp, NULL); + mount_system_root = 1; + pr_alert("[DEFEX] system_root=TRUE\n"); + } else { + pr_alert("[DEFEX] system_root=FALSE\n"); + } + } + return (mount_system_root > 0); +} + +#ifdef DEFEX_INTEGRITY_ENABLE +__visible_for_testing int defex_check_integrity(struct file *f, unsigned char *hash) +{ + struct crypto_shash *handle = NULL; + struct shash_desc *shash = NULL; + static const unsigned char buff_zero[SHA256_DIGEST_SIZE] = {0}; + unsigned char hash_sha256[SHA256_DIGEST_SIZE]; + unsigned char *buff = NULL; + size_t buff_size = PAGE_SIZE; + loff_t file_size = 0; + int ret = 0, err = 0, read_size = 0; + + // A saved hash is zero, skip integrity check + if (!memcmp(buff_zero, hash, SHA256_DIGEST_SIZE)) + return ret; + + if (IS_ERR(f)) + goto hash_error; + + handle = crypto_alloc_shash("sha256", 0, 0); + if (IS_ERR(handle)) { + err = PTR_ERR(handle); + pr_err("[DEFEX] Can't alloc sha256, error : %d", err); + return -1; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + shash = (struct shash_desc *)kvzalloc(sizeof(struct shash_desc) + crypto_shash_descsize(handle), GFP_KERNEL); +#else + shash = kzalloc(sizeof(struct shash_desc) + crypto_shash_descsize(handle), GFP_KERNEL); +#endif /* < KERNEL_VERSION(4, 12, 0) */ + + if (shash == NULL) + goto hash_error; + + shash->tfm = handle; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + buff = kvmalloc(buff_size, GFP_KERNEL); +#else + buff = kmalloc(buff_size, GFP_KERNEL); +#endif /* < KERNEL_VERSION(4, 12, 0) */ + + if (buff == NULL) + goto hash_error; + + err = crypto_shash_init(shash); + if (err < 0) + goto hash_error; + + + while (1) { + read_size = local_fread(f, file_size, (char *)buff, buff_size); + if (read_size < 0) + goto hash_error; + if (read_size == 0) + break; + file_size += read_size; + err = crypto_shash_update(shash, buff, read_size); + if (err < 0) + goto hash_error; + } + + err = crypto_shash_final(shash, hash_sha256); + if (err < 0) + goto hash_error; + + ret = memcmp(hash_sha256, hash, SHA256_DIGEST_SIZE); + + goto hash_exit; + +hash_error: + ret = -1; +hash_exit: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + kvfree(buff); + kvfree(shash); +#else + kfree(buff); + kfree(shash); +#endif /* < KERNEL_VERSION(4, 12, 0) */ + + if (handle) + crypto_free_shash(handle); + return ret; + +} + +__visible_for_testing int defex_integrity_default(const char *file_path) +{ + static const char integrity_default[] = "/system/bin/install-recovery.sh"; + + return strncmp(integrity_default, file_path, sizeof(integrity_default)); +} + +#endif /* DEFEX_INTEGRITY_ENABLE */ + +#if defined(DEFEX_RAMDISK_ENABLE) + +#ifdef DEFEX_KERNEL_ONLY +int load_rules_late(void) +{ + struct file *f; + int data_size, rules_size, res = 0; + unsigned char *data_buff = NULL; + static unsigned long start_time; + static unsigned long last_time; + unsigned long cur_time = get_seconds(); + static DEFINE_SPINLOCK(load_lock); + static atomic_t in_progress = ATOMIC_INIT(0); + + if (!spin_trylock(&load_lock)) + return res; + + if (atomic_read(&in_progress) != 0) { + spin_unlock(&load_lock); + return res; + } + + atomic_set(&in_progress, 1); + spin_unlock(&load_lock); + + /* The first try to load, initialize time values */ + if (!start_time) + start_time = get_seconds(); + /* Skip this try, wait for next second */ + if (cur_time == last_time) + goto do_exit; + /* Load has been attempted for 30 seconds, give up. */ + if ((cur_time - start_time) > 30) { + res = -1; + goto do_exit; + } + last_time = cur_time; + + f = local_fopen(DEFEX_RULES_FILE, O_RDONLY, 0); + if (IS_ERR(f)) { + pr_err("[DEFEX] Failed to open rules file (%ld)\n", (long)PTR_ERR(f)); + goto do_exit; + } + data_size = i_size_read(file_inode(f)); + if (data_size <= 0 || data_size > (sizeof(defex_packed_rules) << 1)) + goto do_clean; + data_buff = vmalloc(data_size); + if (!data_buff) + goto do_clean; + + rules_size = local_fread(f, 0, data_buff, data_size); + if (rules_size <= 0) { + pr_err("[DEFEX] Failed to read rules file (%d)\n", rules_size); + goto do_clean; + } + pr_info("[DEFEX] Late load rules file: %s.\n", DEFEX_RULES_FILE); + pr_info("[DEFEX] Read %d bytes.\n", rules_size); + if (rules_size > sizeof(defex_packed_rules)) + rules_size = sizeof(defex_packed_rules); + memcpy(defex_packed_rules, data_buff, rules_size); + res = (rules_size > 0); +do_clean: + filp_close(f, NULL); + vfree(data_buff); +do_exit: + atomic_set(&in_progress, 0); + return res; +} +#endif /* DEFEX_KERNEL_ONLY */ + +__visible_for_testing int __init do_load_rules(void) +{ + struct file *f; + int res = -1, data_size, rules_size; + unsigned char *data_buff = NULL; + + memset(defex_packed_rules, 0, sizeof(defex_packed_rules)); + pr_info("[DEFEX] Load rules file: %s.\n", DEFEX_RULES_FILE); + f = local_fopen(DEFEX_RULES_FILE, O_RDONLY, 0); + if (IS_ERR(f)) { + pr_err("[DEFEX] Failed to open rules file (%ld)\n", (long)PTR_ERR(f)); +#ifdef DEFEX_KERNEL_ONLY + if (is_recovery) + res = 0; +#endif /* DEFEX_KERNEL_ONLY */ + return res; + } + data_size = i_size_read(file_inode(f)); + if (data_size <= 0 || data_size > (sizeof(defex_packed_rules) << 1)) + goto do_clean; + data_buff = vmalloc(data_size); + if (!data_buff) + goto do_clean; + + rules_size = local_fread(f, 0, data_buff, data_size); + if (rules_size <= 0) { + pr_err("[DEFEX] Failed to read rules file (%d)\n", rules_size); + goto do_clean; + } + pr_info("[DEFEX] Read %d bytes.\n", rules_size); + +#ifdef DEFEX_SIGN_ENABLE + res = defex_rules_signature_check(data_buff, rules_size, &rules_size); + if (!res && rules_size > sizeof(defex_packed_rules)) + res = -1; + + if (!res) + pr_info("[DEFEX] Rules signature verified successfully.\n"); + else + pr_err("[DEFEX] Rules signature incorrect!!!\n"); +#else + res = 0; +#endif + + if (!res) + memcpy(defex_packed_rules, data_buff, rules_size); +do_clean: + filp_close(f, NULL); + vfree(data_buff); + +#ifdef DEFEX_KERNEL_ONLY + if (is_recovery && res != 0) { + res = 0; + pr_info("[DEFEX] Kernel Only & recovery mode, rules loading is passed.\n"); + } +#endif + + return res; +} + +#endif /* DEFEX_RAMDISK_ENABLE */ + +__visible_for_testing struct rule_item_struct *lookup_dir(struct rule_item_struct *base, + const char *name, int l, int for_recovery) +{ + struct rule_item_struct *item = NULL; + unsigned int offset; + + if (!base || !base->next_level) + return item; + item = GET_ITEM_PTR(base->next_level); + do { + if ((!(item->feature_type & feature_is_file) + || (!!(item->feature_type & feature_for_recovery)) == for_recovery) + && item->size == l && !memcmp(name, item->name, l)) + return item; + offset = item->next_file; + item = GET_ITEM_PTR(offset); + } while (offset); + return NULL; +} + +__visible_for_testing int lookup_tree(const char *file_path, int attribute, struct file *f) +{ + const char *ptr, *next_separator; + struct rule_item_struct *base, *cur_item = NULL; + int l; + + if (!file_path || *file_path != '/') + return 0; + +#ifdef DEFEX_KERNEL_ONLY +try_to_load: +#endif + base = (struct rule_item_struct *)defex_packed_rules; + if (!base || !base->data_size) { +#ifdef DEFEX_KERNEL_ONLY + /* allow all requests if rules were not loaded for Recovery mode */ + l = load_rules_late(); + if (l > 0) + goto try_to_load; + if (!l || is_recovery) + return (attribute == feature_ped_exception || attribute == feature_safeplace_path)?1:0; +#endif /* DEFEX_KERNEL_ONLY */ + /* block all requests if rules were not loaded instead */ + return 0; + } + + ptr = file_path + 1; + do { + next_separator = strchr(ptr, '/'); + if (!next_separator) + l = strlen(ptr); + else + l = next_separator - ptr; + if (!l) + return 0; + cur_item = lookup_dir(base, ptr, l, is_recovery); + if (!cur_item) + cur_item = lookup_dir(base, ptr, l, !is_recovery); + if (!cur_item) + break; + if (cur_item->feature_type & attribute) { +#ifdef DEFEX_INTEGRITY_ENABLE + /* Integrity acceptable only for files */ + if ((cur_item->feature_type & feature_is_file) && f) { + if (defex_integrity_default(file_path) + && defex_check_integrity(f, cur_item->integrity)) + return DEFEX_INTEGRITY_FAIL; + } +#endif /* DEFEX_INTEGRITY_ENABLE */ + if (attribute & (feature_immutable_path_open | feature_immutable_path_write) + && !(cur_item->feature_type & feature_is_file)) { + /* Allow open the folder by default */ + if (!next_separator || *(ptr + l + 1) == 0) + return 0; + } + return 1; + } + base = cur_item; + ptr += l; + if (next_separator) + ptr++; + } while (*ptr); + return 0; +} + +int rules_lookup(const char *target_file, int attribute, struct file *f) +{ + int ret = 0; +#if (defined(DEFEX_SAFEPLACE_ENABLE) || defined(DEFEX_IMMUTABLE_ENABLE) || defined(DEFEX_PED_ENABLE)) + static const char system_root_txt[] = "/system_root"; + + if (check_system_mount() && + !strncmp(target_file, system_root_txt, sizeof(system_root_txt) - 1)) + target_file += (sizeof(system_root_txt) - 1); + + ret = lookup_tree(target_file, attribute, f); +#endif + return ret; +} + +void __init defex_load_rules(void) +{ +#if defined(DEFEX_RAMDISK_ENABLE) + if (!boot_state_unlocked && do_load_rules() != 0) { +#if !(defined(DEFEX_DEBUG_ENABLE) || defined(DEFEX_KERNEL_ONLY)) + panic("[DEFEX] Signature mismatch.\n"); +#endif + } +#endif /* DEFEX_RAMDISK_ENABLE */ +} diff --git a/security/samsung/defex_lsm/core/defex_sysfs.c b/security/samsung/defex_lsm/core/defex_sysfs.c index 7460ec000..6e28d8c01 100644 --- a/security/samsung/defex_lsm/core/defex_sysfs.c +++ b/security/samsung/defex_lsm/core/defex_sysfs.c @@ -19,378 +19,15 @@ #include #include #include -#include #include #include #include + #include "include/defex_debug.h" #include "include/defex_internal.h" #include "include/defex_rules.h" -#define DEFEX_RULES_FILE "/dpolicy" - -#ifndef DEFEX_USE_PACKED_RULES -/* - * Variant 1: Use the static, unpacked rules array - */ -#ifdef DEFEX_INTEGRITY_ENABLE -#error "Packed rules required for Integrity feature" -#endif - -#else - -/* - * Variant 2: Platform build, use static packed rules array - */ -#include "defex_packed_rules.inc" - -#ifdef DEFEX_RAMDISK_ENABLE -/* - * Variant 3: Platform build, load rules from kernel ramdisk or system partition - */ -#ifdef DEFEX_SIGN_ENABLE -#include "include/defex_sign.h" -#endif -#if (DEFEX_RULES_ARRAY_SIZE < 8) -#undef DEFEX_RULES_ARRAY_SIZE -#define DEFEX_RULES_ARRAY_SIZE sizeof(struct rule_item_struct) -#endif -#ifdef DEFEX_KERNEL_ONLY -#undef DEFEX_RULES_ARRAY_SIZE -#define DEFEX_RULES_ARRAY_SIZE (256 * 1024) -static unsigned char defex_packed_rules[DEFEX_RULES_ARRAY_SIZE] = {0}; -int load_rules_late(void); -#else -static unsigned char defex_packed_rules[DEFEX_RULES_ARRAY_SIZE] __ro_after_init = {0}; -#endif /* DEFEX_KERNEL_ONLY */ -#endif /* DEFEX_RAMDISK_ENABLE */ - -#endif /* DEFEX_USE_PACKED_RULES */ - -#ifdef DEFEX_INTEGRITY_ENABLE - -#include -#include -#include -#include -#include "../../integrity/integrity.h" -#define SHA256_DIGEST_SIZE 32 -#endif /* DEFEX_INTEGRITY_ENABLE */ - static struct kset *defex_kset; -static int is_recovery = 0; - -__visible_for_testing int __init bootmode_setup(char *str) -{ - if (str && *str == '2') { - is_recovery = 1; - printk(KERN_ALERT "[DEFEX] recovery mode setup\n"); - } - return 0; -} -__setup("bootmode=", bootmode_setup); - -int check_rules_ready(void) -{ - struct rule_item_struct *base = (struct rule_item_struct *)defex_packed_rules; - return (!base || !base->data_size)?0:1; -} - -__visible_for_testing int check_system_mount(void) -{ - static int mount_system_root = -1; - struct file *fp; - - if (mount_system_root < 0) { - fp = local_fopen("/sbin/recovery", O_RDONLY, 0); - if (IS_ERR(fp)) - fp = local_fopen("/system/bin/recovery", O_RDONLY, 0); - - if (!IS_ERR(fp)) { - printk(KERN_ALERT "[DEFEX] recovery mode\n"); - filp_close(fp, NULL); - is_recovery = 1; - } else { - printk(KERN_ALERT "[DEFEX] normal mode\n"); - } - - mount_system_root = 0; - fp = local_fopen("/system_root", O_DIRECTORY | O_PATH, 0); - if (!IS_ERR(fp)) { - filp_close(fp, NULL); - mount_system_root = 1; - printk(KERN_ALERT "[DEFEX] system_root=TRUE\n"); - } else { - printk(KERN_ALERT "[DEFEX] system_root=FALSE\n"); - } - } - return (mount_system_root > 0); -} - -__visible_for_testing void parse_static_rules(const struct static_rule *rules, size_t max_len, int rules_number) -{ - int i; - size_t count; - const char *current_rule; -#if (defined(DEFEX_PERMISSIVE_PED) || defined(DEFEX_PERMISSIVE_SP) || defined(DEFEX_PERMISSIVE_IM)) - static const char permissive[2] = "2"; -#endif /* DEFEX_PERMISSIVE_**/ - - for (i = 0; i < rules_number; i++) { - count = strnlen(rules[i].rule, max_len); - current_rule = rules[i].rule; - switch (rules[i].feature_type) { -#ifdef DEFEX_PED_ENABLE - case feature_ped_status: -#ifdef DEFEX_PERMISSIVE_PED - current_rule = permissive; -#endif /* DEFEX_PERMISSIVE_PED */ - task_defex_privesc_store_status(global_privesc_obj, NULL, current_rule, count); - break; -#endif /* DEFEX_PED_ENABLE */ -#ifdef DEFEX_SAFEPLACE_ENABLE - case feature_safeplace_status: -#ifdef DEFEX_PERMISSIVE_SP - current_rule = permissive; -#endif /* DEFEX_PERMISSIVE_SP */ - safeplace_status_store(global_safeplace_obj, NULL, current_rule, count); - break; -#endif /* DEFEX_SAFEPLACE_ENABLE */ -#ifdef DEFEX_IMMUTABLE_ENABLE - case feature_immutable_status: -#ifdef DEFEX_PERMISSIVE_IM - current_rule = permissive; -#endif /* DEFEX_PERMISSIVE_IM */ - immutable_status_store(global_immutable_obj, NULL, current_rule, count); - break; -#endif /* DEFEX_IMMUTABLE_ENABLE */ - } - } -} - - -#ifdef DEFEX_INTEGRITY_ENABLE -__visible_for_testing int defex_check_integrity(struct file *f, unsigned char *hash) -{ - struct crypto_shash *handle = NULL; - struct shash_desc* shash = NULL; - static const unsigned char buff_zero[SHA256_DIGEST_SIZE] = {0}; - unsigned char hash_sha256[SHA256_DIGEST_SIZE]; - unsigned char *buff = NULL; - size_t buff_size = PAGE_SIZE; - loff_t file_size = 0; - int ret = 0, err = 0, read_size = 0; - - // A saved hash is zero, skip integrity check - if (!memcmp(buff_zero, hash, SHA256_DIGEST_SIZE)) - return ret; - - if (IS_ERR(f)) - goto hash_error; - - handle = crypto_alloc_shash("sha256", 0, 0); - if (IS_ERR(handle)) { - err = PTR_ERR(handle); - pr_err("[DEFEX] Can't alloc sha256, error : %d", err); - return -1; - } - - shash = kzalloc(sizeof(struct shash_desc) + crypto_shash_descsize(handle), GFP_KERNEL); - if (NULL == shash) - goto hash_error; - - shash->tfm = handle; - - buff = kmalloc(buff_size, GFP_KERNEL); - if (NULL == buff) - goto hash_error; - - err = crypto_shash_init(shash); - if (err < 0) - goto hash_error; - - - while(1) { - read_size = local_fread(f, file_size, (char*)buff, buff_size); - if (0 > read_size) - goto hash_error; - if (0 == read_size) - break; - file_size += read_size; - err = crypto_shash_update(shash, buff, read_size); - if (err < 0) - goto hash_error; - } - - err = crypto_shash_final(shash, hash_sha256); - if (err < 0) - goto hash_error; - - ret = memcmp(hash_sha256, hash, SHA256_DIGEST_SIZE); - - goto hash_exit; - - hash_error: - ret = -1; - hash_exit: - if (buff) - kfree(buff); - if (shash) - kfree(shash); - if (handle) - crypto_free_shash(handle); - return ret; - -} - -__visible_for_testing int defex_integrity_default(const char *file_path) -{ - static const char integrity_default[] = "/system/bin/install-recovery.sh"; - return strncmp(integrity_default, file_path, sizeof(integrity_default)); -} - -#endif /* DEFEX_INTEGRITY_ENABLE */ - -#ifdef DEFEX_USE_PACKED_RULES -__visible_for_testing struct rule_item_struct *lookup_dir(struct rule_item_struct *base, const char *name, int l, int for_recovery) -{ - struct rule_item_struct *item = NULL; - unsigned int offset; - - if (!base || !base->next_level) - return item; - item = GET_ITEM_PTR(base->next_level); - do { - if ((!(item->feature_type & feature_is_file) - || (!!(item->feature_type & feature_for_recovery)) == for_recovery) - && item->size == l - && !memcmp(name, item->name, l)) return item; - offset = item->next_file; - item = GET_ITEM_PTR(offset); - } while(offset); - return NULL; -} - -__visible_for_testing int lookup_tree(const char *file_path, int attribute, struct file *f) -{ - const char *ptr, *next_separator; - struct rule_item_struct *base, *cur_item = NULL; - int l; - - if (!file_path || *file_path != '/') - return 0; - -#ifdef DEFEX_KERNEL_ONLY -try_to_load: -#endif - base = (struct rule_item_struct *)defex_packed_rules; - if (!base || !base->data_size) { -#ifdef DEFEX_KERNEL_ONLY - /* allow all requests if rules were not loaded for Recovery mode */ - l = load_rules_late(); - if (l > 0) - goto try_to_load; - if (!l || is_recovery) - return (attribute == feature_ped_exception || attribute == feature_safeplace_path)?1:0; -#endif /* DEFEX_KERNEL_ONLY */ - /* block all requests if rules were not loaded instead */ - return 0; - } - - ptr = file_path + 1; - do { - next_separator = strchr(ptr, '/'); - if (!next_separator) - l = strlen(ptr); - else - l = next_separator - ptr; - if (!l) - return 0; - cur_item = lookup_dir(base, ptr, l, is_recovery); - if (!cur_item) - cur_item = lookup_dir(base, ptr, l, !is_recovery); - - if (!cur_item) - break; - if (cur_item->feature_type & attribute) { -#ifdef DEFEX_INTEGRITY_ENABLE - /* Integrity acceptable only for files */ - if ((cur_item->feature_type & feature_is_file) && f) { - if (defex_integrity_default(file_path) - && defex_check_integrity(f, cur_item->integrity)) - return DEFEX_INTEGRITY_FAIL; - } -#endif /* DEFEX_INTEGRITY_ENABLE */ - if (attribute & (feature_immutable_path_open | feature_immutable_path_write) - && !(cur_item->feature_type & feature_is_file)) { - /* Allow open the folder by default */ - if (!next_separator || *(ptr + l + 1) == 0) - return 0; - } - return 1; - } - base = cur_item; - ptr += l; - if (next_separator) - ptr++; - } while(*ptr); - return 0; -} -#endif /* DEFEX_USE_PACKED_RULES */ - -int rules_lookup2(const char *target_file, int attribute, struct file *f) -{ - int ret = 0; -#if (defined(DEFEX_SAFEPLACE_ENABLE) || defined(DEFEX_IMMUTABLE_ENABLE) || defined(DEFEX_PED_ENABLE)) - static const char system_root_txt[] = "/system_root"; -#ifndef DEFEX_USE_PACKED_RULES - int i, count, end; - const struct static_rule *current_rule; -#endif - if (check_system_mount() && - !strncmp(target_file, system_root_txt, sizeof(system_root_txt) - 1)) - target_file += (sizeof(system_root_txt) - 1); - -#ifdef DEFEX_USE_PACKED_RULES - ret = lookup_tree(target_file, attribute, f); -#else - for (i = 0; i < static_rule_count; i++) { - current_rule = &defex_static_rules[i]; - if (current_rule->feature_type == attribute) { - end = strnlen(current_rule->rule, STATIC_RULES_MAX_STR); - if (current_rule->rule[end - 1] == '/') { - count = end; - } else { - count = strnlen(target_file, STATIC_RULES_MAX_STR); - if (end > count) count = end; - } - if (!strncmp(current_rule->rule, target_file, count)) { - ret = 1; - break; - } - } - } -#endif /* DEFEX_USE_PACKED_RULES */ -#endif - return ret; -} - -int rules_lookup(const struct path *dpath, int attribute, struct file *f) -{ - int ret = 0; - char *target_file, *buff; - - buff = kmalloc(PATH_MAX, GFP_KERNEL); - if (!buff) - return ret; - target_file = d_path(dpath, buff, PATH_MAX); - if (!IS_ERR(target_file)) { - ret = rules_lookup2(target_file, attribute, f); - } - kfree(buff); - return ret; -} - int __init defex_init_sysfs(void) { @@ -398,194 +35,18 @@ int __init defex_init_sysfs(void) if (!defex_kset) return -ENOMEM; -#if defined(DEFEX_DEBUG_ENABLE) && defined(DEFEX_SYSFS_ENABLE) +#if defined(DEFEX_DEBUG_ENABLE) if (defex_create_debug(defex_kset) != DEFEX_OK) goto kset_error; -#endif /* DEFEX_DEBUG_ENABLE && DEFEX_SYSFS_ENABLE */ - -#ifdef DEFEX_PED_ENABLE - global_privesc_obj = task_defex_create_privesc_obj(defex_kset); - if (!global_privesc_obj) - goto privesc_error; -#endif /* DEFEX_PED_ENABLE */ +#endif /* DEFEX_DEBUG_ENABLE */ -#ifdef DEFEX_SAFEPLACE_ENABLE - global_safeplace_obj = task_defex_create_safeplace_obj(defex_kset); - if (!global_safeplace_obj) - goto safeplace_error; -#endif /* DEFEX_SAFEPLACE_ENABLE */ - -#ifdef DEFEX_IMMUTABLE_ENABLE - global_immutable_obj = task_defex_create_immutable_obj(defex_kset); - if (!global_immutable_obj) - goto immutable_error; -#endif /* DEFEX_IMMUTABLE_ENABLE */ - - parse_static_rules(defex_static_rules, STATIC_RULES_MAX_STR, static_rule_count); return 0; -#ifdef DEFEX_IMMUTABLE_ENABLE -immutable_error: -#endif /* DEFEX_IMMUTABLE_ENABLE */ - -#ifdef DEFEX_SAFEPLACE_ENABLE - task_defex_destroy_safeplace_obj(global_safeplace_obj); - safeplace_error: -#endif /* DEFEX_SAFEPLACE_ENABLE */ - -#ifdef DEFEX_PED_ENABLE - task_defex_destroy_privesc_obj(global_privesc_obj); - privesc_error: -#endif /* DEFEX_PED_ENABLE */ - -#if defined(DEFEX_DEBUG_ENABLE) && defined(DEFEX_SYSFS_ENABLE) - kset_error: +kset_error: kset_unregister(defex_kset); defex_kset = NULL; -#endif /* DEFEX_DEBUG_ENABLE && DEFEX_SYSFS_ENABLE */ - return -ENOMEM; -} - - -#if defined(DEFEX_RAMDISK_ENABLE) - -#ifdef DEFEX_KERNEL_ONLY -int load_rules_late(void) -{ - struct file *f; - int data_size, rules_size, res = 0; - unsigned char *data_buff = NULL; - static unsigned long start_time = 0; - static unsigned long last_time = 0; - unsigned long cur_time = get_seconds(); - static DEFINE_SPINLOCK(load_lock); - static atomic_t in_progress = ATOMIC_INIT(0); - - if (!spin_trylock(&load_lock)) - return res; - - if (atomic_read(&in_progress) != 0) { - spin_unlock(&load_lock); - return res; - } - - atomic_set(&in_progress, 1); - spin_unlock(&load_lock); - - /* The first try to load, initialize time values */ - if (!start_time) - start_time = get_seconds(); - /* Skip this try, wait for next second */ - if (cur_time == last_time) - goto do_exit; - /* Load has been attempted for 30 seconds, give up. */ - if ((cur_time - start_time) > 30) { - res = -1; - goto do_exit; - } - last_time = cur_time; - - f = local_fopen(DEFEX_RULES_FILE, O_RDONLY, 0); - if (IS_ERR(f)) { - pr_err("[DEFEX] Failed to open rules file (%ld)\n", (long)PTR_ERR(f)); - goto do_exit; - } - data_size = i_size_read(file_inode(f)); - if (data_size <= 0 || data_size > (sizeof(defex_packed_rules) << 1)) - goto do_clean; - data_buff = kmalloc(data_size, GFP_KERNEL); - if (!data_buff) - goto do_clean; - rules_size = local_fread(f, 0, data_buff, data_size); - if (rules_size <= 0) { - pr_err("[DEFEX] Failed to read rules file (%d)\n", rules_size); - goto do_clean; - } - printk(KERN_INFO "[DEFEX] Late load rules file: %s.\n", DEFEX_RULES_FILE); - printk(KERN_INFO "[DEFEX] Read %d bytes.\n", rules_size); - if (rules_size > sizeof(defex_packed_rules)) - rules_size = sizeof(defex_packed_rules); - memcpy(defex_packed_rules, data_buff, rules_size); - res = (rules_size > 0); -do_clean: - filp_close(f, NULL); - kfree(data_buff); -do_exit: - atomic_set(&in_progress, 0); - return res; -} -#endif /* DEFEX_KERNEL_ONLY */ - -__visible_for_testing int __init do_load_rules(void) -{ - struct file *f; - int res = -1, data_size, rules_size; - unsigned char *data_buff = NULL; - - memset(defex_packed_rules, 0, sizeof(defex_packed_rules)); - printk(KERN_INFO "[DEFEX] Load rules file: %s.\n", DEFEX_RULES_FILE); - f = local_fopen(DEFEX_RULES_FILE, O_RDONLY, 0); - if (IS_ERR(f)) { - pr_err("[DEFEX] Failed to open rules file (%ld)\n", (long)PTR_ERR(f)); -#ifdef DEFEX_KERNEL_ONLY - if (is_recovery) - res = 0; -#endif /* DEFEX_KERNEL_ONLY */ - return res; - } - data_size = i_size_read(file_inode(f)); - if (data_size <= 0 || data_size > (sizeof(defex_packed_rules) << 1)) - goto do_clean; - data_buff = kmalloc(data_size, GFP_KERNEL); - if (!data_buff) - goto do_clean; - - rules_size = local_fread(f, 0, data_buff, data_size); - if (rules_size <= 0) { - pr_err("[DEFEX] Failed to read rules file (%d)\n", rules_size); - goto do_clean; - } - printk(KERN_INFO "[DEFEX] Read %d bytes.\n", rules_size); - -#ifdef DEFEX_SIGN_ENABLE - res = defex_rules_signature_check(data_buff, rules_size, &rules_size); - if (!res && rules_size > sizeof(defex_packed_rules)) - res = -1; - - if (!res) - printk("[DEFEX] Rules signature verified successfully.\n"); - else - pr_err("[DEFEX] Rules signature incorrect!!!\n"); -#else - res = 0; -#endif - - if (!res) - memcpy(defex_packed_rules, data_buff, rules_size); -do_clean: - filp_close(f, NULL); - kfree(data_buff); - -#ifdef DEFEX_KERNEL_ONLY - if (is_recovery && res != 0) { - res = 0; - printk("[DEFEX] Kernel Only & recovery mode, rules loading is passed.\n"); - } -#endif - - return res; + return -ENOMEM; } -#endif /* DEFEX_RAMDISK_ENABLE */ -void __init defex_load_rules(void) -{ -#if defined(DEFEX_RAMDISK_ENABLE) - if ( !boot_state_unlocked && do_load_rules() != 0) { -#if !(defined(DEFEX_DEBUG_ENABLE) || defined(DEFEX_KERNEL_ONLY)) - panic("[DEFEX] Signature mismatch.\n"); -#endif - } -#endif /* DEFEX_RAMDISK_ENABLE */ -} diff --git a/security/samsung/defex_lsm/debug/defex_debug.c b/security/samsung/defex_lsm/debug/defex_debug.c index d18fcfd9f..3a2e2aba2 100644 --- a/security/samsung/defex_lsm/debug/defex_debug.c +++ b/security/samsung/defex_lsm/debug/defex_debug.c @@ -19,6 +19,45 @@ static int last_cmd; +void blob(const char *buffer, const size_t bufLen, const int lineSize) +{ + size_t i = 0, line; + size_t j = 0, len = bufLen; + int offset = 0; + char c, stringToPrint[MAX_DATA_LEN]; + + do { + line = (len > lineSize)?lineSize:len; + offset = 0; + offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "| 0x%08lX | ", i); + + for (j = 0; j < line; j++) + offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "%02X ", + (unsigned char)buffer[i + j]); + if (line < lineSize) { + for (j = 0; j < lineSize - line; j++) + offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, " "); + } + offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "| "); + + for (j = 0; j < line; j++) { + c = buffer[i + j]; + c = (c < 0x20) || (c >= 0x7F)?'.':c; + offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, "%c", c); + } + if (line < lineSize) { + for (j = 0; j < lineSize - line; j++) + offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, " "); + } + + offset += snprintf(stringToPrint + offset, MAX_DATA_LEN - offset, " |"); + pr_info("%s\n", stringToPrint); + memset(stringToPrint, 0, MAX_DATA_LEN); + i += line; + len -= line; + } while (len); +} + __visible_for_testing int set_user(struct cred *new_cred) { struct user_struct *new_user; @@ -95,7 +134,10 @@ __visible_for_testing ssize_t debug_store(struct kobject *kobj, struct kobj_attr static const char *prefix[] = { "uid=", "fsuid=", - "gid=" + "gid=", + "pe_status=", + "im_status=", + "sp_status=" }; if (!buf || !p) @@ -116,6 +158,15 @@ __visible_for_testing ssize_t debug_store(struct kobject *kobj, struct kobj_attr return -EINVAL; ret = set_cred(i, new_val); break; + case DBG_SET_PE_STATUS: + privesc_status_store(buf + l); + break; + case DBG_SET_IM_STATUS: + immutable_status_store(buf + l); + break; + case DBG_SET_SP_STATUS: + safeplace_status_store(buf + l); + break; default: break; } diff --git a/security/samsung/defex_lsm/defex_packed_rules.bin b/security/samsung/defex_lsm/defex_packed_rules.bin index 5e1d50406d8732202c996e8c17917bdea93e307d..a48e85e87644b6b13aab363f605f5906238d3fda 100644 GIT binary patch delta 192 zcmZn-*%HEP&S0X&FxgR1X`_0*46CH3B7@50hx{g+@5?B%Gbw6JzNoCf*-&KzBa@o? zWCd52 z^5k-LXVz#9MF!!?jO+@N@2iWlrUC7M^B7wv>uYE-t_PB;ocU=C3{Nx|nfSnJmupO7 eoHMyV(~#BJh=Jh}kY&osti{O01(rRfX$=6KS~Ac8 delta 179 zcmdlI(i*~Q&cLe0FxgR1X`_0*4C^ZmMFy405BW_t- #include "include/defex_internal.h" -struct defex_immutable *global_immutable_obj; +#ifdef DEFEX_PERMISSIVE_IM +unsigned char global_immutable_status = 2; +#else +unsigned char global_immutable_status = 1; +#endif /* DEFEX_PERMISSIVE_IM */ -#ifdef DEFEX_SYSFS_ENABLE -static struct kobj_type immutable_ktype; - -ssize_t task_defex_immutable_attr_show(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - struct immutable_attribute *attribute; - struct defex_immutable *immutable; - - immutable = to_immutable_obj(kobj); - attribute = to_immutable_attr(attr); - - if (!attribute->show) - return -EIO; - - return attribute->show(immutable, attribute, buf); -} - -ssize_t immutable_status_show(struct defex_immutable *immutable_obj, - struct immutable_attribute *attr, char *buf) -{ - return snprintf(buf, MAX_LEN, "%u\n", immutable_obj->status); -} - - -ssize_t task_defex_immutable_attr_store(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t len) -{ - struct immutable_attribute *attribute; - struct defex_immutable *immutable; - - immutable = to_immutable_obj(kobj); - attribute = to_immutable_attr(attr); - - if (!attribute->store) - return -EIO; - - return attribute->store(immutable, attribute, buf, len); -} - -__visible_for_testing void task_defex_immutable_release(struct kobject *kobj) -{ - struct defex_immutable *immutable_obj; - - immutable_obj = to_immutable_obj(kobj); - kfree(immutable_obj); -} -#endif /* DEFEX_SYSFS_ENABLE */ - -ssize_t immutable_status_store(struct defex_immutable *immutable_obj, - struct immutable_attribute *attr, const char *buf, size_t count) +int immutable_status_store(const char *status_str) { int ret; unsigned int status; - ret = kstrtouint(buf, 10, &status); - if (ret != 0 || status > 2) + if (!status_str) return -EINVAL; - immutable_obj->status = status; - return count; -} - -struct defex_immutable *task_defex_create_immutable_obj(struct kset *defex_kset) -{ - struct defex_immutable *immutable; - - immutable = kzalloc(sizeof(*immutable), GFP_KERNEL); - if (!immutable) - return NULL; - - immutable->kobj.kset = defex_kset; -#ifdef DEFEX_SYSFS_ENABLE - if (kobject_init_and_add(&immutable->kobj, &immutable_ktype, NULL, "%s", "immutable")) { - kobject_put(&immutable->kobj); - return NULL; - } - - kobject_uevent(&immutable->kobj, KOBJ_ADD); -#endif /* DEFEX_SYSFS_ENABLE */ - immutable->status = 0; - return immutable; -} + ret = kstrtouint(status_str, 10, &status); + if (ret != 0 || status > 2) + return -EINVAL; -void task_defex_destroy_immutable_obj(struct defex_immutable *immutable) -{ -#ifdef DEFEX_SYSFS_ENABLE - kobject_put(&immutable->kobj); -#endif /* DEFEX_SYSFS_ENABLE */ + global_immutable_status = status; + return 0; } - -#ifdef DEFEX_SYSFS_ENABLE -static struct immutable_attribute immutable_status_attribute = - __ATTR(status, 0600, immutable_status_show, immutable_status_store); - - -static struct attribute *immutable_default_attrs[] = { - &immutable_status_attribute.attr, - NULL, -}; - -static const struct sysfs_ops immutable_sysfs_ops = { - .show = task_defex_immutable_attr_show, - .store = task_defex_immutable_attr_store, -}; - -static struct kobj_type immutable_ktype = { - .sysfs_ops = &immutable_sysfs_ops, - .release = task_defex_immutable_release, - .default_attrs = immutable_default_attrs, -}; -#endif /* DEFEX_SYSFS_ENABLE */ diff --git a/security/samsung/defex_lsm/feature_privilege_escalation_detection/defex_priv.c b/security/samsung/defex_lsm/feature_privilege_escalation_detection/defex_priv.c index f3213cb0b..dc64b2267 100644 --- a/security/samsung/defex_lsm/feature_privilege_escalation_detection/defex_priv.c +++ b/security/samsung/defex_lsm/feature_privilege_escalation_detection/defex_priv.c @@ -13,117 +13,25 @@ #include #include "include/defex_internal.h" -struct defex_privesc *global_privesc_obj; +#ifdef DEFEX_PERMISSIVE_PED +unsigned char global_privesc_status = 2; +#else +unsigned char global_privesc_status = 1; +#endif /* DEFEX_PERMISSIVE_PED */ -#ifdef DEFEX_SYSFS_ENABLE -static struct kobj_type privesc_ktype; - -ssize_t task_defex_privesc_attr_show(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - struct privesc_attribute *attribute; - struct defex_privesc *privesc; - - attribute = to_privesc_attr(attr); - privesc = to_privesc_obj(kobj); - - if (!attribute->show) - return -EIO; - - return attribute->show(privesc, attribute, buf); -} - -ssize_t task_defex_privesc_show_status(struct defex_privesc *privesc_obj, - struct privesc_attribute *attr, char *buf) -{ - return snprintf(buf, 3, "%u\n", privesc_obj->status); -} - -ssize_t task_defex_privesc_attr_store(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t len) -{ - struct privesc_attribute *attribute; - struct defex_privesc *privesc; - - attribute = to_privesc_attr(attr); - privesc = to_privesc_obj(kobj); - - if (!attribute->store) - return -EIO; - - return attribute->store(privesc, attribute, buf, len); -} - -void task_defex_privesc_release(struct kobject *kobj) -{ - struct defex_privesc *privesc_obj; - - privesc_obj = to_privesc_obj(kobj); - kfree(privesc_obj); -} -#endif /* DEFEX_SYSFS_ENABLE*/ - -ssize_t task_defex_privesc_store_status(struct defex_privesc *privesc_obj, - struct privesc_attribute *attr, const char *buf, size_t count) +int privesc_status_store(const char *status_str) { int ret; unsigned int status; - ret = kstrtouint(buf, 10, &status); - if (ret != 0 || status > 2) + if (!status_str) return -EINVAL; - privesc_obj->status = status; - - return count; -} - -struct defex_privesc *task_defex_create_privesc_obj(struct kset *defex_kset) -{ - struct defex_privesc *privesc; - - privesc = kzalloc(sizeof(*privesc), GFP_KERNEL); - if (!privesc) - return NULL; - - privesc->kobj.kset = defex_kset; -#ifdef DEFEX_SYSFS_ENABLE - if (kobject_init_and_add(&privesc->kobj, &privesc_ktype, NULL, "%s", "privesc")) { - kobject_put(&privesc->kobj); - return NULL; - } - kobject_uevent(&privesc->kobj, KOBJ_ADD); -#endif /* DEFEX_SYSFS_ENABLE */ - - /* Initial state of PED feature (0 - disabled, 1 - enabled) */ - privesc->status = 0; - return privesc; -} + ret = kstrtouint(status_str, 10, &status); + if (ret != 0 || status > 2) + return -EINVAL; + global_privesc_status = status; -void task_defex_destroy_privesc_obj(struct defex_privesc *privesc) -{ -#ifdef DEFEX_SYSFS_ENABLE - kobject_put(&privesc->kobj); -#endif /* DEFEX_SYSFS_ENABLE */ + return 0; } -#ifdef DEFEX_SYSFS_ENABLE -static struct privesc_attribute privesc_status_attribute = - __ATTR(status, 0660, task_defex_privesc_show_status, task_defex_privesc_store_status); - -static struct attribute *privesc_default_attrs[] = { - &privesc_status_attribute.attr, - NULL, -}; - -const struct sysfs_ops privesc_sysfs_ops = { - .show = task_defex_privesc_attr_show, - .store = task_defex_privesc_attr_store, -}; - -static struct kobj_type privesc_ktype = { - .sysfs_ops = &privesc_sysfs_ops, - .release = task_defex_privesc_release, - .default_attrs = privesc_default_attrs, -}; -#endif /* DEFEX_SYSFS_ENABLE */ diff --git a/security/samsung/defex_lsm/feature_safeplace/defex_safeplace.c b/security/samsung/defex_lsm/feature_safeplace/defex_safeplace.c index 3f7a70296..bed0e288a 100644 --- a/security/samsung/defex_lsm/feature_safeplace/defex_safeplace.c +++ b/security/samsung/defex_lsm/feature_safeplace/defex_safeplace.c @@ -13,117 +13,25 @@ #include #include "include/defex_internal.h" -struct defex_safeplace *global_safeplace_obj; +#ifdef DEFEX_PERMISSIVE_SP +unsigned char global_safeplace_status = 2; +#else +unsigned char global_safeplace_status = 1; +#endif /* DEFEX_PERMISSIVE_SP */ -#ifdef DEFEX_SYSFS_ENABLE -static struct kobj_type safeplace_ktype; - -ssize_t task_defex_safeplace_attr_show(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - struct safeplace_attribute *attribute; - struct defex_safeplace *safeplace; - - safeplace = to_safeplace_obj(kobj); - attribute = to_safeplace_attr(attr); - - if (!attribute->show) - return -EIO; - - return attribute->show(safeplace, attribute, buf); -} - -ssize_t safeplace_status_show(struct defex_safeplace *safeplace_obj, - struct safeplace_attribute *attr, char *buf) -{ - return snprintf(buf, MAX_LEN, "%u\n", safeplace_obj->status); -} - - -ssize_t task_defex_safeplace_attr_store(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t len) -{ - struct safeplace_attribute *attribute; - struct defex_safeplace *safeplace; - - safeplace = to_safeplace_obj(kobj); - attribute = to_safeplace_attr(attr); - - if (!attribute->store) - return -EIO; - - return attribute->store(safeplace, attribute, buf, len); -} - -__visible_for_testing void task_defex_safeplace_release(struct kobject *kobj) -{ - struct defex_safeplace *safeplace_obj; - - safeplace_obj = to_safeplace_obj(kobj); - kfree(safeplace_obj); -} -#endif /* DEFEX_SYSFS_ENABLE */ - -ssize_t safeplace_status_store(struct defex_safeplace *safeplace_obj, - struct safeplace_attribute *attr, const char *buf, size_t count) +int safeplace_status_store(const char *status_str) { int ret; unsigned int status; - ret = kstrtouint(buf, 10, &status); - if (ret != 0 || status > 2) + if (!status_str) return -EINVAL; - safeplace_obj->status = status; - return count; -} - -struct defex_safeplace *task_defex_create_safeplace_obj(struct kset *defex_kset) -{ - struct defex_safeplace *safeplace; - - safeplace = kzalloc(sizeof(*safeplace), GFP_KERNEL); - if (!safeplace) - return NULL; - - safeplace->kobj.kset = defex_kset; -#ifdef DEFEX_SYSFS_ENABLE - if (kobject_init_and_add(&safeplace->kobj, &safeplace_ktype, NULL, "%s", "safeplace")) { - kobject_put(&safeplace->kobj); - return NULL; - } + ret = kstrtouint(status_str, 10, &status); + if (ret != 0 || status > 2) + return -EINVAL; - kobject_uevent(&safeplace->kobj, KOBJ_ADD); -#endif /* DEFEX_SYSFS_ENABLE */ - safeplace->status = 0; - return safeplace; -} + global_safeplace_status = status; -void task_defex_destroy_safeplace_obj(struct defex_safeplace *safeplace) -{ -#ifdef DEFEX_SYSFS_ENABLE - kobject_put(&safeplace->kobj); -#endif /* DEFEX_SYSFS_ENABLE */ + return 0; } - -#ifdef DEFEX_SYSFS_ENABLE -static struct safeplace_attribute safeplace_status_attribute = - __ATTR(status, 0600, safeplace_status_show, safeplace_status_store); - - -static struct attribute *safeplace_default_attrs[] = { - &safeplace_status_attribute.attr, - NULL, -}; - -static const struct sysfs_ops safeplace_sysfs_ops = { - .show = task_defex_safeplace_attr_show, - .store = task_defex_safeplace_attr_store, -}; - -static struct kobj_type safeplace_ktype = { - .sysfs_ops = &safeplace_sysfs_ops, - .release = task_defex_safeplace_release, - .default_attrs = safeplace_default_attrs, -}; -#endif /* DEFEX_SYSFS_ENABLE */ diff --git a/security/samsung/defex_lsm/include/defex_debug.h b/security/samsung/defex_lsm/include/defex_debug.h index 957ebd4bf..2c89f7d85 100644 --- a/security/samsung/defex_lsm/include/defex_debug.h +++ b/security/samsung/defex_lsm/include/defex_debug.h @@ -13,6 +13,13 @@ #define DBG_SET_FSUID 1 #define DBG_SETGID 2 +#define DBG_SET_PE_STATUS 3 +#define DBG_SET_IM_STATUS 4 +#define DBG_SET_SP_STATUS 5 + +#define MAX_DATA_LEN 300 + +void blob(const char *buffer, const size_t bufLen, const int lineSize); int defex_create_debug(struct kset *defex_kset); #endif /* __DEFEX_DEBUG_H */ diff --git a/security/samsung/defex_lsm/include/defex_internal.h b/security/samsung/defex_lsm/include/defex_internal.h index 845c3d812..14d2a4f50 100644 --- a/security/samsung/defex_lsm/include/defex_internal.h +++ b/security/samsung/defex_lsm/include/defex_internal.h @@ -102,24 +102,7 @@ (ids_ptr)->egid = egid; \ (cred_data_ptr)->cred_flags |= cred_flags; } while(0) -struct defex_privesc { - struct kobject kobj; - unsigned int status; -}; -#define to_privesc_obj(obj) container_of(obj, struct defex_privesc, kobj) - -struct privesc_attribute { - struct attribute attr; - ssize_t (*show)(struct defex_privesc *privesc, struct privesc_attribute *attr, char *buf); - ssize_t (*store)(struct defex_privesc *foo, struct privesc_attribute *attr, const char *buf, size_t count); -}; -#define to_privesc_attr(obj) container_of(obj, struct privesc_attribute, attr) - -struct defex_privesc *task_defex_create_privesc_obj(struct kset *defex_kset); -void task_defex_destroy_privesc_obj(struct defex_privesc *privesc); -extern struct defex_privesc *global_privesc_obj; -ssize_t task_defex_privesc_store_status(struct defex_privesc *privesc_obj, - struct privesc_attribute *attr, const char *buf, size_t count); +extern unsigned char global_privesc_status; void get_task_creds(struct task_struct *p, unsigned int *uid_ptr, unsigned int *fsuid_ptr, unsigned int *egid_ptr, unsigned short *cred_flags_ptr); int set_task_creds(struct task_struct *p, unsigned int uid, unsigned int fsuid, unsigned int egid, unsigned short cred_flags); @@ -130,47 +113,13 @@ int is_task_creds_ready(void); /* SafePlace feature */ /* -------------------------------------------------------------------------- */ -struct defex_safeplace { - struct kobject kobj; - unsigned int status; -}; -#define to_safeplace_obj(obj) container_of(obj, struct defex_safeplace, kobj) - -struct safeplace_attribute { - struct attribute attr; - ssize_t (*show)(struct defex_safeplace *safeplace, struct safeplace_attribute *attr, char *buf); - ssize_t (*store)(struct defex_safeplace *foo, struct safeplace_attribute *attr, const char *buf, size_t count); -}; -#define to_safeplace_attr(obj) container_of(obj, struct safeplace_attribute, attr) - -struct defex_safeplace *task_defex_create_safeplace_obj(struct kset *defex_kset); -extern void task_defex_destroy_safeplace_obj(struct defex_safeplace *safeplace); -extern struct defex_safeplace *global_safeplace_obj; -ssize_t safeplace_status_store(struct defex_safeplace *safeplace_obj, - struct safeplace_attribute *attr, const char *buf, size_t count); +extern unsigned char global_safeplace_status; /* -------------------------------------------------------------------------- */ /* Immutable feature */ /* -------------------------------------------------------------------------- */ -struct defex_immutable { - struct kobject kobj; - unsigned int status; -}; -#define to_immutable_obj(obj) container_of(obj, struct defex_immutable, kobj) - -struct immutable_attribute { - struct attribute attr; - ssize_t (*show)(struct defex_immutable *immutable, struct immutable_attribute *attr, char *buf); - ssize_t (*store)(struct defex_immutable *foo, struct immutable_attribute *attr, const char *buf, size_t count); -}; -#define to_immutable_attr(obj) container_of(obj, struct immutable_attribute, attr) - -struct defex_immutable *task_defex_create_immutable_obj(struct kset *defex_kset); -extern void task_defex_destroy_immutable_obj(struct defex_immutable *immutable); -extern struct defex_immutable *global_immutable_obj; -ssize_t immutable_status_store(struct defex_immutable *immutable_obj, - struct immutable_attribute *attr, const char *buf, size_t count); +extern unsigned char global_immutable_status; /* -------------------------------------------------------------------------- */ /* Common Helper API */ @@ -180,7 +129,6 @@ struct defex_context { int syscall_no; struct task_struct *task; struct file *process_file; - struct cred cred; struct file *target_file; const struct path *process_dpath; const struct path *target_dpath; @@ -188,6 +136,9 @@ struct defex_context { char *target_name; char *target_name_buff; char *process_name_buff; + + /* NB: cred must be the last field */ + struct cred cred; }; extern const char unknown_file[]; @@ -216,8 +167,7 @@ static inline void safe_str_free(void *ptr) /* Defex lookup API */ /* -------------------------------------------------------------------------- */ -int rules_lookup(const struct path *dpath, int attribute, struct file *f); -int rules_lookup2(const char *target_file, int attribute, struct file *f); +int rules_lookup(const char *target_file, int attribute, struct file *f); /* -------------------------------------------------------------------------- */ /* Defex init API */ @@ -226,6 +176,14 @@ int rules_lookup2(const char *target_file, int attribute, struct file *f); int __init defex_init_sysfs(void); void __init creds_fast_hash_init(void); +/* -------------------------------------------------------------------------- */ +/* Defex debug API */ +/* -------------------------------------------------------------------------- */ + +int immutable_status_store(const char *status_str); +int privesc_status_store(const char *status_str); +int safeplace_status_store(const char *status_str); + #ifdef DEFEX_DEPENDING_ON_OEMUNLOCK extern bool boot_state_unlocked __ro_after_init; #endif /* DEFEX_DEPENDING_ON_OEMUNLOCK */ diff --git a/security/samsung/defex_lsm/include/defex_rules.h b/security/samsung/defex_lsm/include/defex_rules.h index 5f7f07fd3..943208d63 100644 --- a/security/samsung/defex_lsm/include/defex_rules.h +++ b/security/samsung/defex_lsm/include/defex_rules.h @@ -57,9 +57,6 @@ struct rule_item_struct { char name[0]; } __attribute__((packed)); -extern const struct static_rule defex_static_rules[]; -extern const int static_rule_count; - int check_rules_ready(void); #endif /* __DEFEX_RULES_H */ diff --git a/security/samsung/defex_lsm/include/defex_sign.h b/security/samsung/defex_lsm/include/defex_sign.h index b41bfc447..ccfd136a3 100644 --- a/security/samsung/defex_lsm/include/defex_sign.h +++ b/security/samsung/defex_lsm/include/defex_sign.h @@ -9,10 +9,8 @@ #ifndef __DEFEX_SIGN_H #define __DEFEX_SIGN_H -#ifdef DEFEX_DEBUG_ENABLE -#define PR_HEX(X) (int)sizeof(size_t), X -void __init blob(const char *buffer, const size_t bufLen, const int lineSize); -#endif +#define SIGN_SIZE 256 + int __init defex_rules_signature_check(const char *rules_buffer, unsigned int rules_data_size, unsigned int *rules_size); #endif /* __DEFEX_SIGN_H */ diff --git a/security/samsung/defex_lsm/include/defex_test.h b/security/samsung/defex_lsm/include/defex_test.h new file mode 100644 index 000000000..63d0826e3 --- /dev/null +++ b/security/samsung/defex_lsm/include/defex_test.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. 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 + * as published by the Free Software Foundation. + */ + +#ifndef _DEFEX_TEST_H +#define _DEFEX_TEST_H +#ifdef DEFEX_KUNIT_ENABLED +#include + +#include +#include + +/* -------------------------------------------------------------------------- */ +/* defex_debug */ +/* -------------------------------------------------------------------------- */ + +extern struct kobj_attribute debug_attribute; + +extern int set_user(struct cred *new_cred); +extern int set_cred(int target_id, int new_val); +extern ssize_t debug_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +extern ssize_t debug_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); + +/* -------------------------------------------------------------------------- */ +/* defex_immutable */ +/* -------------------------------------------------------------------------- */ + +extern int immutable_status_store(const char *status_str); + +/* -------------------------------------------------------------------------- */ +/* defex_priv */ +/* -------------------------------------------------------------------------- */ + +extern int privesc_status_store(const char *status_str); + +/* -------------------------------------------------------------------------- */ +/* defex_safeplace */ +/* -------------------------------------------------------------------------- */ + +extern int safeplace_status_store(const char *status_str); + +/* -------------------------------------------------------------------------- */ +/* defex_main */ +/* -------------------------------------------------------------------------- */ + +struct defex_context; + +extern struct task_struct *get_parent_task(const struct task_struct *p); + +#ifdef DEFEX_DSMS_ENABLE +extern void defex_report_violation(const char *violation, uint64_t counter, struct defex_context *dc, + uid_t stored_uid, uid_t stored_fsuid, uid_t stored_egid, int case_num); +#endif + +#ifdef DEFEX_SAFEPLACE_ENABLE +extern long kill_process(struct task_struct *p); +#endif + +#ifdef DEFEX_PED_ENABLE +extern long kill_process_group(struct task_struct *p, int tgid, int pid); +extern int task_defex_is_secured(struct defex_context *dc); +extern int at_same_group(unsigned int uid1, unsigned int uid2); +extern int at_same_group_gid(unsigned int gid1, unsigned int gid2); + +#ifdef DEFEX_LP_ENABLE +extern int lower_adb_permission(struct defex_context *dc, unsigned short cred_flags); +#endif /* DEFEX_LP_ENABLE */ +extern int task_defex_check_creds(struct defex_context *dc); +#endif /* DEFEX_PED_ENABLE */ + +#ifdef DEFEX_SAFEPLACE_ENABLE +extern int task_defex_safeplace(struct defex_context *dc); +#endif /* DEFEX_SAFEPLACE_ENABLE */ + +#ifdef DEFEX_IMMUTABLE_ENABLE +extern int task_defex_src_exception(struct defex_context *dc); +extern int task_defex_immutable(struct defex_context *dc, int attribute); +#endif /* DEFEX_IMMUTABLE_ENABLE */ + +#endif /* DEFEX_KUNIT_ENABLED */ +#endif /* _DEFEX_TEST_H */ diff --git a/security/samsung/five/Kconfig b/security/samsung/five/Kconfig index 30b319d97..4bb10c192 100644 --- a/security/samsung/five/Kconfig +++ b/security/samsung/five/Kconfig @@ -17,6 +17,20 @@ config FIVE to change the contents of an important system file being measured, we can tell. +config FIVE_GKI_10 + bool "GKI 1.0 compatible version of FIVE" + depends on FIVE + default n + help + Build GKI 1.0 compatible version of FIVE + +config FIVE_GKI_20 + bool "GKI 2.0 compatible version of FIVE" + depends on FIVE + default n + help + Build GKI 2.0 compatible version of FIVE + config FIVE_DEBUG bool "FIVE Debug mode" depends on FIVE diff --git a/security/samsung/five/Makefile b/security/samsung/five/Makefile index 66f4f0e55..76a04209b 100644 --- a/security/samsung/five/Makefile +++ b/security/samsung/five/Makefile @@ -1,8 +1,6 @@ -obj-$(CONFIG_FIVE) += task_integrity.o obj-$(CONFIG_FIVE) += five.o obj-$(CONFIG_FIVE_PA_FEATURE) += five_pa.o -obj-$(CONFIG_FIVE_TEE_DRIVER) += five_tee_interface.o EXTRA_CFLAGS += -I$(src) asflags-y += -Isecurity/integrity/five @@ -10,7 +8,17 @@ asflags-y += -Isecurity/samsung/five ccflags-y += -I$(srctree) ccflags-y += -Wformat -five-y := five_lv.o five_cert.o five_keyring.o five_init.o five_main.o \ - five_crypto.o five_audit.o five_appraise.o five_state.o \ - five_cert_builtin.o five_hooks.o five_cache.o five_dmverity.o +five-y := five_lv.o five_cert.o five_keyring.o five_init.o \ + five_cert_builtin.o five_cache.o \ + five_dmverity.o five-$(CONFIG_SECURITY_DSMS) += five_dsms.o + +ifdef CONFIG_FIVE_GKI_20 + FILES := five_main.o five_appraise.o five_crypto.o five_audit.o \ + five_hooks.o task_integrity.o five_state.o five_vfs.o \ + five_tint_dev.o five_tee_interface.o + five-y += $(addprefix gki/,$(FILES)) +else + five-y += five_main.o five_appraise.o five_crypto.o five_audit.o \ + five_hooks.o task_integrity.o five_state.o five_tee_interface.o +endif diff --git a/security/samsung/five/five.h b/security/samsung/five/five.h index 42d28c16c..b30815c5d 100644 --- a/security/samsung/five/five.h +++ b/security/samsung/five/five.h @@ -102,7 +102,7 @@ int five_digsig_verify(struct five_cert *cert, const char *digest, int digestlen); int five_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused); -void __init five_load_built_x509(void); +int __init five_load_built_x509(void); int __init five_keyring_init(void); const char *five_get_string_fn(enum five_hooks fn); diff --git a/security/samsung/five/five_appraise.c b/security/samsung/five/five_appraise.c index a604d8268..ddf9213b3 100644 --- a/security/samsung/five/five_appraise.c +++ b/security/samsung/five/five_appraise.c @@ -291,7 +291,7 @@ int five_appraise_measurement(struct task_struct *task, int func, BUG_ON(!task || !iint || !file); - prev_integrity = task_integrity_read(task->integrity); + prev_integrity = task_integrity_read(TASK_INTEGRITY(task)); dentry = file->f_path.dentry; inode = d_backing_inode(dentry); @@ -439,7 +439,7 @@ int five_appraise_measurement(struct task_struct *task, int func, out: if (status == FIVE_FILE_FAIL || status == FIVE_FILE_UNKNOWN) { - task_integrity_set_reset_reason(task->integrity, cause, file); + task_integrity_set_reset_reason(TASK_INTEGRITY(task), cause, file); five_audit_verbose(task, file, five_get_string_fn(func), prev_integrity, prev_integrity, tint_reset_cause_to_string(cause), rc); @@ -513,7 +513,7 @@ static int five_update_xattr(struct task_struct *task, if (rc) goto exit; - if (task_integrity_allow_sign(task->integrity)) { + if (task_integrity_allow_sign(TASK_INTEGRITY(task))) { rc = five_fix_xattr(task, dentry, file, (void **)&raw_cert, &raw_cert_len, iint, label); if (rc) @@ -732,7 +732,7 @@ int five_fcntl_sign(struct file *file, struct integrity_label __user *label) return -EROFS; } - if (task_integrity_allow_sign(current->integrity)) { + if (task_integrity_allow_sign(TASK_INTEGRITY(current))) { rc = copy_label(label, &l); if (rc) { pr_err("FIVE: Can't copy integrity label\n"); @@ -740,7 +740,7 @@ int five_fcntl_sign(struct file *file, struct integrity_label __user *label) } } else { enum task_integrity_value tint = - task_integrity_read(current->integrity); + task_integrity_read(TASK_INTEGRITY(current)); five_audit_err(current, file, "fcntl_sign", tint, tint, "sign:no-perm", -EPERM); @@ -798,7 +798,7 @@ int five_fcntl_edit(struct file *file) if (rc) return rc; - if (!task_integrity_allow_sign(current->integrity)) + if (!task_integrity_allow_sign(TASK_INTEGRITY(current))) return -EPERM; inode_lock(inode); diff --git a/security/samsung/five/five_audit.c b/security/samsung/five/five_audit.c index 7860ad184..dd49bd0bc 100644 --- a/security/samsung/five/five_audit.c +++ b/security/samsung/five/five_audit.c @@ -24,7 +24,6 @@ #include "five_porting.h" #include "five_dsms.h" - static void five_audit_msg(struct task_struct *task, struct file *file, const char *op, enum task_integrity_value prev, enum task_integrity_value tint, const char *cause, int result); @@ -77,8 +76,8 @@ void five_audit_sign_err(struct task_struct *task, struct file *file, { char comm[TASK_COMM_LEN]; struct task_struct *tsk = task ? task : current; - get_task_comm(comm, tsk); + get_task_comm(comm, tsk); five_dsms_sign_err(comm, result); } diff --git a/security/samsung/five/five_hooks.c b/security/samsung/five/five_hooks.c index fdb6fac09..42dca7602 100644 --- a/security/samsung/five/five_hooks.c +++ b/security/samsung/five/five_hooks.c @@ -42,6 +42,7 @@ struct five_hook_heads five_hook_heads = { .integrity_reset2 = LIST_HEAD_INIT(five_hook_heads.integrity_reset2), }; +EXPORT_SYMBOL_GPL(five_hook_heads); enum five_hook_event { FILE_PROCESSED, @@ -208,7 +209,7 @@ void five_hook_file_processed(struct task_struct *task, get_task_struct(task); get_file(file); event.processed.task = task; - event.processed.tint_value = task_integrity_read(task->integrity); + event.processed.tint_value = task_integrity_read(TASK_INTEGRITY(task)); event.processed.file = file; /* * xattr parameters are optional, because FIVE could get results @@ -235,7 +236,7 @@ void five_hook_file_signed(struct task_struct *task, get_task_struct(task); get_file(file); event.processed.task = task; - event.processed.tint_value = task_integrity_read(task->integrity); + event.processed.tint_value = task_integrity_read(TASK_INTEGRITY(task)); event.processed.file = file; /* xattr parameters are optional, so we may ignore kmemdup errors */ if (xattr) { @@ -257,7 +258,7 @@ void five_hook_file_skipped(struct task_struct *task, struct file *file) get_task_struct(task); get_file(file); event.skipped.task = task; - event.skipped.tint_value = task_integrity_read(task->integrity); + event.skipped.tint_value = task_integrity_read(TASK_INTEGRITY(task)); event.skipped.file = file; if (__push_event(&event, GFP_KERNEL) < 0) @@ -273,9 +274,11 @@ void five_hook_task_forked(struct task_struct *parent, get_task_struct(parent); get_task_struct(child); event.forked.parent = parent; - event.forked.parent_tint_value = task_integrity_read(parent->integrity); + event.forked.parent_tint_value = + task_integrity_read(TASK_INTEGRITY(parent)); event.forked.child = child; - event.forked.child_tint_value = task_integrity_read(child->integrity); + event.forked.child_tint_value = + task_integrity_read(TASK_INTEGRITY(child)); if (__push_event(&event, GFP_ATOMIC) < 0) hook_wq_event_destroy(&event); diff --git a/security/samsung/five/five_init.c b/security/samsung/five/five_init.c index 5f36c299b..b46c3c464 100644 --- a/security/samsung/five/five_init.c +++ b/security/samsung/five/five_init.c @@ -30,12 +30,13 @@ int __init five_init(void) { int rc; - five_keyring_init(); - five_load_built_x509(); - - rc = five_init_crypto(); + rc = five_keyring_init(); if (rc) return rc; + rc = five_load_built_x509(); + if (rc) + return rc; + rc = five_init_crypto(); - return 0; + return rc; } diff --git a/security/samsung/five/five_keyring.c b/security/samsung/five/five_keyring.c index cf3362b71..fde552eb8 100644 --- a/security/samsung/five/five_keyring.c +++ b/security/samsung/five/five_keyring.c @@ -151,15 +151,16 @@ static int __init five_load_x509_from_mem(const char *data, size_t size) extern char five_local_ca_start_eng[]; extern char five_local_ca_end_eng[]; -static void __init five_import_eng_key(void) +static int __init five_import_eng_key(void) { size_t size = five_local_ca_end_eng - five_local_ca_start_eng; - five_load_x509_from_mem(five_local_ca_start_eng, size); + return five_load_x509_from_mem(five_local_ca_start_eng, size); } #else -static void __init five_import_eng_key(void) +static int __init five_import_eng_key(void) { + return 0; } #endif @@ -167,22 +168,30 @@ static void __init five_import_eng_key(void) extern char five_local_ca_start_user[]; extern char five_local_ca_end_user[]; -static void __init five_import_user_key(void) +static int __init five_import_user_key(void) { size_t size = five_local_ca_end_user - five_local_ca_start_user; - five_load_x509_from_mem(five_local_ca_start_user, size); + return five_load_x509_from_mem(five_local_ca_start_user, size); } #else -static void __init five_import_user_key(void) +static int __init five_import_user_key(void) { + return 0; } #endif -void __init five_load_built_x509(void) +int __init five_load_built_x509(void) { - five_import_eng_key(); - five_import_user_key(); + int rc; + + rc = five_import_eng_key(); + if (rc) + return rc; + + rc = five_import_user_key(); + + return rc; } int __init five_keyring_init(void) diff --git a/security/samsung/five/five_main.c b/security/samsung/five/five_main.c index f2dc3f6ba..b0d64f4b2 100644 --- a/security/samsung/five/five_main.c +++ b/security/samsung/five/five_main.c @@ -320,16 +320,17 @@ static int push_file_event_bunch(struct task_struct *task, struct file *file, return -ENOMEM; } - spin_lock(&task->integrity->list_lock); + spin_lock(&TASK_INTEGRITY(task)->list_lock); - if (list_empty(&(task->integrity->events.list))) { - task_integrity_get(task->integrity); - task_integrity_processing(task->integrity); + if (list_empty(&(TASK_INTEGRITY(task)->events.list))) { + task_integrity_get(TASK_INTEGRITY(task)); + task_integrity_processing(TASK_INTEGRITY(task)); - context->tint = task->integrity; + context->tint = TASK_INTEGRITY(task); - list_add_tail(&five_file->list, &task->integrity->events.list); - spin_unlock(&task->integrity->list_lock); + list_add_tail(&five_file->list, + &TASK_INTEGRITY(task)->events.list); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); INIT_WORK(&context->data_work, work_handler); rc = queue_work(g_five_workqueue, &context->data_work) ? 0 : 1; } else { @@ -337,12 +338,13 @@ static int push_file_event_bunch(struct task_struct *task, struct file *file, INIT_LIST_HEAD(&dead_list); if ((function == BPRM_CHECK) && - (!list_is_singular(&(task->integrity->events.list)))) { - list_cut_tail(&task->integrity->events.list, + (!list_is_singular(&(TASK_INTEGRITY(task)->events.list)))) { + list_cut_tail(&TASK_INTEGRITY(task)->events.list, &dead_list); } - list_add_tail(&five_file->list, &task->integrity->events.list); - spin_unlock(&task->integrity->list_lock); + list_add_tail(&five_file->list, + &TASK_INTEGRITY(task)->events.list); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); free_files_list(&dead_list); kfree(context); } @@ -360,7 +362,7 @@ static int push_reset_event(struct task_struct *task, return 0; INIT_LIST_HEAD(&dead_list); - current_tint = task->integrity; + current_tint = TASK_INTEGRITY(task); task_integrity_get(current_tint); task_integrity_set_reset_reason(current_tint, cause, file); @@ -441,7 +443,7 @@ void five_file_free(struct file *file) void five_task_free(struct task_struct *task) { - task_integrity_put(task->integrity); + task_integrity_put(TASK_INTEGRITY(task)); } /* Returns string representation of input function */ @@ -563,19 +565,24 @@ static void process_file(struct task_struct *task, xattr_len = five_read_xattr(d_real_comp(file->f_path.dentry), &xattr_value); - if (xattr_value && xattr_len) { - rc = five_cert_fillout(&cert, xattr_value, xattr_len); - if (rc) { - pr_err("FIVE: certificate is incorrect inode=%lu\n", + if (xattr_value) { + if (xattr_len) { + rc = five_cert_fillout(&cert, xattr_value, xattr_len); + if (rc) { + pr_err("FIVE: certificate is incorrect inode=%lu\n", inode->i_ino); - goto out; - } + goto out; + } - pcert = &cert; + pcert = &cert; - if (file->f_flags & O_DIRECT) { - rc = -EACCES; - goto out; + if (file->f_flags & O_DIRECT) { + rc = -EACCES; + goto out; + } + } else { + five_audit_info(task, file, "zero length", 0, 0, + "Found a dummy-cert", rc); } } @@ -604,7 +611,7 @@ static void process_file(struct task_struct *task, static void process_measurement(const struct processing_event_list *params) { struct task_struct *task = params->task; - struct task_integrity *integrity = params->task->integrity; + struct task_integrity *integrity = TASK_INTEGRITY(task); struct file *file = params->file; struct inode *inode = file_inode(file); int function = params->function; @@ -664,7 +671,7 @@ int five_file_mmap(struct file *file, unsigned long prot) { int rc = 0; struct task_struct *task = current; - struct task_integrity *tint = task->integrity; + struct task_integrity *tint = TASK_INTEGRITY(task); if (five_check_params(task, file)) return 0; @@ -704,7 +711,7 @@ int five_bprm_check(struct linux_binprm *bprm) { int rc = 0; struct task_struct *task = current; - struct task_integrity *old_tint = task->integrity; + struct task_integrity *old_tint = TASK_INTEGRITY(task); if (unlikely(task->ptrace)) return rc; @@ -712,8 +719,10 @@ int five_bprm_check(struct linux_binprm *bprm) if (bprm->recursion_depth > 0) { rc = push_file_event_bunch(task, bprm->file, MMAP_CHECK); } else { - task->integrity = task_integrity_alloc(); - if (likely(task->integrity)) { + struct task_integrity *tint = task_integrity_alloc(); + + task_integrity_assign(task, tint); + if (likely(TASK_INTEGRITY(task))) { rc = push_file_event_bunch(task, bprm->file, BPRM_CHECK); } else { @@ -788,7 +797,7 @@ int five_file_open(struct file *file) bool is_signing = false; if (!unlink_on_error) { - five_audit_info(current, file, "five_unlink", 0, 0, + five_audit_verbose(current, file, "five_unlink", 0, 0, "Found a dummy-cert", 0); return 0; } @@ -824,7 +833,7 @@ int five_file_open(struct file *file) int five_file_verify(struct task_struct *task, struct file *file) { int rc = 0; - struct task_integrity *tint = task->integrity; + struct task_integrity *tint = TASK_INTEGRITY(task); if (file && task_integrity_user_read(tint)) rc = push_file_event_bunch(task, file, FILE_CHECK); @@ -904,7 +913,7 @@ static int fcntl_verify(struct file *file) { int rc = 0; struct task_struct *task = current; - struct task_integrity *tint = task->integrity; + struct task_integrity *tint = TASK_INTEGRITY(task); if (task_integrity_user_read(tint)) rc = push_file_event_bunch(task, file, FILE_CHECK); @@ -927,9 +936,9 @@ int five_fork(struct task_struct *task, struct task_struct *child_task) { int rc = 0; - spin_lock(&task->integrity->list_lock); + spin_lock(&TASK_INTEGRITY(task)->list_lock); - if (!list_empty(&task->integrity->events.list)) { + if (!list_empty(&TASK_INTEGRITY(task)->events.list)) { /*copy the list*/ struct list_head *tmp; struct processing_event_list *from_entry; @@ -937,11 +946,11 @@ int five_fork(struct task_struct *task, struct task_struct *child_task) context = kmalloc(sizeof(struct worker_context), GFP_ATOMIC); if (unlikely(!context)) { - spin_unlock(&task->integrity->list_lock); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); return -ENOMEM; } - list_for_each(tmp, &task->integrity->events.list) { + list_for_each(tmp, &TASK_INTEGRITY(task)->events.list) { struct processing_event_list *five_file; from_entry = list_entry(tmp, @@ -955,27 +964,27 @@ int five_fork(struct task_struct *task, struct task_struct *child_task) GFP_ATOMIC); if (unlikely(!five_file)) { kfree(context); - spin_unlock(&task->integrity->list_lock); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); return -ENOMEM; } list_add_tail(&five_file->list, - &child_task->integrity->events.list); + &TASK_INTEGRITY(child_task)->events.list); } - context->tint = child_task->integrity; + context->tint = TASK_INTEGRITY(child_task); - rc = task_integrity_copy(task->integrity, - child_task->integrity); - spin_unlock(&task->integrity->list_lock); + rc = task_integrity_copy(TASK_INTEGRITY(task), + TASK_INTEGRITY(child_task)); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); task_integrity_get(context->tint); - task_integrity_processing(child_task->integrity); + task_integrity_processing(TASK_INTEGRITY(child_task)); INIT_WORK(&context->data_work, work_handler); rc = queue_work(g_five_workqueue, &context->data_work) ? 0 : 1; } else { - rc = task_integrity_copy(task->integrity, - child_task->integrity); - spin_unlock(&task->integrity->list_lock); + rc = task_integrity_copy(TASK_INTEGRITY(task), + TASK_INTEGRITY(child_task)); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); } if (!rc) @@ -1014,7 +1023,7 @@ int five_ptrace(struct task_struct *task, long request) #endif break; default: { - struct task_integrity *tint = task->integrity; + struct task_integrity *tint = TASK_INTEGRITY(task); if (task_integrity_user_read(tint) == INTEGRITY_NONE) break; @@ -1032,7 +1041,7 @@ int five_ptrace(struct task_struct *task, long request) int five_process_vm_rw(struct task_struct *task, int write) { if (write) { - struct task_integrity *tint = task->integrity; + struct task_integrity *tint = TASK_INTEGRITY(task); if (task_integrity_user_read(tint) == INTEGRITY_NONE) goto exit; diff --git a/security/samsung/five/five_pa.c b/security/samsung/five/five_pa.c index 58f10d65a..e7b4abcac 100644 --- a/security/samsung/five/five_pa.c +++ b/security/samsung/five/five_pa.c @@ -26,24 +26,40 @@ #include "five_lv.h" #include "five_porting.h" +#ifdef CONFIG_FIVE_GKI_10 +#define F_SIGNATURE(file) ((void *)((file)->android_vendor_data1)) + +static inline void f_signature_assign(struct file *file, void *f_signature) +{ + file->android_vendor_data1 = (u64)f_signature; +} +#else +#define F_SIGNATURE(file) ((file)->f_signature) + +static inline void f_signature_assign(struct file *file, void *f_signature) +{ + file->f_signature = f_signature; +} +#endif + static void process_file(struct task_struct *task, struct file *file) { char *xattr_value = NULL; - if (file->f_signature) + if (F_SIGNATURE(file)) return; if (five_check_params(task, file)) return; five_read_xattr(d_real_comp(file->f_path.dentry), &xattr_value); - file->f_signature = xattr_value; + f_signature_assign(file, xattr_value); } void fivepa_fsignature_free(struct file *file) { - kfree(file->f_signature); - file->f_signature = NULL; + kfree(F_SIGNATURE(file)); + f_signature_assign(file, NULL); } int proca_fcntl_setxattr(struct file *file, void __user *lv_xattr) @@ -80,7 +96,7 @@ int proca_fcntl_setxattr(struct file *file, void __user *lv_xattr) inode_lock(inode); - if (task_integrity_allow_sign(current->integrity)) { + if (task_integrity_allow_sign(TASK_INTEGRITY(current))) { rc = __vfs_setxattr_noperm(d_real_comp(file->f_path.dentry), XATTR_NAME_PA, x, diff --git a/security/samsung/five/five_tee_api.h b/security/samsung/five/five_tee_api.h index a6a938c75..6312813fd 100644 --- a/security/samsung/five/five_tee_api.h +++ b/security/samsung/five/five_tee_api.h @@ -21,44 +21,11 @@ #include #include -#ifdef CONFIG_FIVE_TEE_DRIVER int verify_hash(enum hash_algo algo, const void *hash, size_t hash_len, const void *label, size_t label_len, const void *signature, size_t signature_len); -int verify_hash_vec(struct tee_iovec *verify_iovec, - const size_t verify_iovcnt); int sign_hash(enum hash_algo algo, const void *hash, size_t hash_len, const void *label, size_t label_len, void *signature, size_t *signature_len); -int sign_hash_vec(struct tee_iovec *sign_iovec, - const size_t sign_iovcnt); -#else -int verify_hash(enum hash_algo algo, const void *hash, size_t hash_len, - const void *label, size_t label_len, - const void *signature, size_t signature_len) -{ - return -ENODEV; -} - -int verify_hash_vec(struct tee_iovec *verify_iovec, - const size_t verify_iovcnt) -{ - return -ENODEV; -} - -int sign_hash(enum hash_algo algo, const void *hash, size_t hash_len, - const void *label, size_t label_len, - void *signature, size_t *signature_len) -{ - return -ENODEV; -} - -int sign_hash_vec(struct tee_iovec *sign_iovec, - const size_t sign_iovcnt) -{ - return -ENODEV; -} - -#endif /* CONFIG_FIVE_TEE_DRIVER */ #endif /* __LINUX_FIVE_TEE_API_H */ diff --git a/security/samsung/five/five_tee_interface.c b/security/samsung/five/five_tee_interface.c index 3857208dd..e7291c06e 100644 --- a/security/samsung/five/five_tee_interface.c +++ b/security/samsung/five/five_tee_interface.c @@ -90,20 +90,6 @@ int verify_hash(enum hash_algo algo, const void *hash, size_t hash_len, return rc; } -int verify_hash_vec(struct tee_iovec *verify_iovec, - const size_t verify_iovcnt) -{ - int rc = -ENODEV; - - down_read(&usage_lock); - if (is_registered) - rc = g_tee_driver_fn->verify_hmac_vec(verify_iovec, - verify_iovcnt); - up_read(&usage_lock); - - return rc; -} - int sign_hash(enum hash_algo algo, const void *hash, size_t hash_len, const void *label, size_t label_len, void *signature, size_t *signature_len) @@ -128,16 +114,3 @@ int sign_hash(enum hash_algo algo, const void *hash, size_t hash_len, return rc; } - -int sign_hash_vec(struct tee_iovec *sign_iovec, - const size_t sign_iovcnt) -{ - int rc = -ENODEV; - - down_read(&usage_lock); - if (is_registered) - rc = g_tee_driver_fn->sign_hmac_vec(sign_iovec, sign_iovcnt); - up_read(&usage_lock); - - return rc; -} diff --git a/security/samsung/five/five_tee_interface.h b/security/samsung/five/five_tee_interface.h index f1143a9e9..6ff986d05 100644 --- a/security/samsung/five/five_tee_interface.h +++ b/security/samsung/five/five_tee_interface.h @@ -37,14 +37,7 @@ struct tee_iovec { struct five_tee_driver_fns { int (*verify_hmac)(const struct tee_iovec *verify_args); - - int (*verify_hmac_vec)(struct tee_iovec *verify_iovec, - const size_t verify_iovcnt); - int (*sign_hmac)(struct tee_iovec *sign_args); - - int (*sign_hmac_vec)(struct tee_iovec *sign_iovec, - const size_t sign_iovcnt); }; int register_five_tee_driver( diff --git a/security/samsung/five/gki/five.h b/security/samsung/five/gki/five.h new file mode 100644 index 000000000..516811e77 --- /dev/null +++ b/security/samsung/five/gki/five.h @@ -0,0 +1,110 @@ +/* + * This code is based on IMA's code + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * + * Egor Uleyskiy, + * Viacheslav Vovchenko + * Yevgen Kopylov + * + * 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 __LINUX_FIVE_H +#define __LINUX_FIVE_H + +#include +#include +#include +#include +#include +#include + +#include "five_cert.h" +#include "five_crypto.h" + +/* set during initialization */ +extern int five_hash_algo; +struct worker_context { + struct work_struct data_work; + struct task_integrity *tint; +}; + +struct f_signature_task { + struct task_integrity *tint; + struct file *file; +}; + +struct f_signature_context { + struct work_struct data_work; + struct f_signature_task payload; +}; + +struct five_stat { + u64 inode_iversion; + u64 cache_iversion; + u32 cache_status; + u32 is_dm_verity; +}; + +/* Internal FIVE function definitions */ +int five_init(void); + +/* FIVE policy related functions */ +enum five_hooks { + FILE_CHECK = 1, + MMAP_CHECK, + BPRM_CHECK, + POST_SETATTR +}; + +struct file_verification_result { + struct task_struct *task; + struct file *file; + struct integrity_iint_cache *iint; + enum five_hooks fn; + int five_result; + void *xattr; + size_t xattr_len; +}; + +static inline void file_verification_result_init( + struct file_verification_result *result) +{ + memset(result, 0, sizeof(*result)); +} + +static inline void file_verification_result_deinit( + struct file_verification_result *result) +{ + kfree(result->xattr); + memset(result, 0, sizeof(*result)); +} + +int five_appraise_measurement(struct task_struct *task, int func, + struct integrity_iint_cache *iint, + struct file *file, + struct five_cert *cert); + +int five_read_xattr(struct dentry *dentry, char **xattr_value); +int five_check_params(struct task_struct *task, struct file *file); +const char *five_d_path(const struct path *path, char **pathbuf, + char *namebuf); + +int five_digsig_verify(struct five_cert *cert, + const char *digest, int digestlen); +int five_reboot_notifier(struct notifier_block *nb, + unsigned long action, void *unused); +int __init five_load_built_x509(void); +int __init five_keyring_init(void); +int __init five_task_integrity_cache_init(void); + +const char *five_get_string_fn(enum five_hooks fn); +#endif diff --git a/security/samsung/five/gki/five_appraise.c b/security/samsung/five/gki/five_appraise.c new file mode 100644 index 000000000..370bf9f04 --- /dev/null +++ b/security/samsung/five/gki/five_appraise.c @@ -0,0 +1,852 @@ +/* + * This code is based on IMA's code + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * + * Egor Uleyskiy, + * Viacheslav Vovchenko + * Yevgen Kopylov + * + * 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 +#include +#include +#include +#include +#include + +#include +#include "five.h" +#include "five_audit.h" +#include "five_hooks.h" +#include "five_tee_api.h" +#include "five_porting.h" +#include "five_cache.h" +#include "five_dmverity.h" +#include "five_vfs.h" + +#define FIVE_RSA_SIGNATURE_MAX_LENGTH (2048/8) +/* Identify extend structure of integrity label */ +#define FIVE_ID_INTEGRITY_LABEL_EX 0xFFFF +#define FIVE_LABEL_VERSION1 1 +/* Maximum length of data integrity label. + * This limit is applied because: + * 1. TEEgris doesn't support signing data longer than 480 bytes; + * 2. The label's length is limited to 3965 byte according to the data + * transmission protocol between five_tee_driver and TA. + */ +#define FIVE_LABEL_MAX_LEN 256 + +/** + * Extend structure of integrity label. + * If field "len" equals 0xffff then it is extend integrity label, + * otherwise simple integrity label. + */ +struct integrity_label_ex { + uint16_t len; + uint8_t version; + uint8_t reserved[2]; + uint8_t hash_algo; + uint8_t hash[64]; + struct integrity_label label; +} __packed; + +#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP +static const bool panic_on_error = true; +#else +static const bool panic_on_error; +#endif + +static DECLARE_RWSEM(sign_fcntl_lock); + +/* + * five_collect_measurement - collect file measurement + * + * Must be called with iint->mutex held. + * + * Return 0 on success, error code otherwise. + */ +static int five_collect_measurement(struct file *file, u8 hash_algo, + u8 *hash, size_t hash_len) +{ + int result = 0; + + BUG_ON(!file || !hash); + + result = five_calc_file_hash(file, hash_algo, hash, &hash_len); + if (result) { + five_audit_err(current, file, "collect_measurement", 0, + 0, "calculate file hash failed", result); + } + return result; +} + +static int get_integrity_label(struct five_cert *cert, + void **label_data, size_t *label_len) +{ + int rc = -ENODATA; + struct five_cert_header *header = + (struct five_cert_header *)cert->body.header->value; + + if (header && header->signature_type == FIVE_XATTR_HMAC) { + *label_data = cert->body.label->value; + *label_len = cert->body.label->length; + rc = 0; + } + return rc; +} + +static int get_signature(struct five_cert *cert, void **sig, + size_t *sig_len) +{ + int rc = -ENODATA; + struct five_cert_header *header = + (struct five_cert_header *)cert->body.header->value; + + if (header && header->signature_type == FIVE_XATTR_HMAC) { + if (cert->signature->length == 0) + return rc; + *sig = cert->signature->value; + *sig_len = cert->signature->length; + + rc = 0; + } + + return rc; +} + +static int update_label(struct integrity_iint_cache *iint, + const void *label_data, size_t label_len) +{ + struct integrity_label *l; + + if (!label_data) + return 0; + + l = kmalloc(sizeof(struct integrity_label) + label_len, GFP_NOFS); + if (l) { + l->len = label_len; + memcpy(l->data, label_data, label_len); + kfree(iint->five_label); + iint->five_label = l; + } else { + return -ENOMEM; + } + + return 0; +} + +static int five_fix_xattr(struct task_struct *task, + struct dentry *dentry, + struct file *file, + void **raw_cert, + size_t *raw_cert_len, + struct integrity_iint_cache *iint, + struct integrity_label_ex *label) +{ + int rc = 0; + u8 hash[FIVE_MAX_DIGEST_SIZE], *hash_file, *sig = NULL; + size_t hash_len = sizeof(hash), hash_file_len, sig_len; + void *file_label = label->label.data; + u16 file_label_len = label->label.len; + struct five_cert_body body_cert = {0}; + struct five_cert_header *header; + + BUG_ON(!task || !dentry || !file || !raw_cert || !(*raw_cert) || !iint); + BUG_ON(!raw_cert_len); + + rc = five_cert_body_fillout(&body_cert, *raw_cert, *raw_cert_len); + if (unlikely(rc)) + return -EINVAL; + + header = (struct five_cert_header *)body_cert.header->value; + hash_file = body_cert.hash->value; + hash_file_len = body_cert.hash->length; + if (unlikely(!header || !hash_file)) + return -EINVAL; + + if (label->version == FIVE_LABEL_VERSION1) { + rc = five_collect_measurement(file, header->hash_algo, + hash_file, hash_file_len); + if (unlikely(rc)) + return rc; + } else { + memcpy(hash_file, label->hash, hash_file_len); + } + + rc = five_cert_calc_hash(&body_cert, hash, &hash_len); + if (unlikely(rc)) + return rc; + + sig_len = (size_t)body_cert.hash->length + file_label_len; + + sig = kzalloc(sig_len, GFP_NOFS); + if (!sig) + return -ENOMEM; + + rc = sign_hash(header->hash_algo, hash, hash_len, + file_label, file_label_len, sig, &sig_len); + + if (!rc) { + rc = five_cert_append_signature(raw_cert, raw_cert_len, + sig, sig_len); + if (!rc) { + int count = 1; + + do { + rc = five_setxattr_noperm(d_real_comp(dentry), + XATTR_NAME_FIVE, + *raw_cert, + *raw_cert_len, + 0); + count--; + } while (count >= 0 && rc != 0); + + if (!rc) { + rc = update_label(iint, + file_label, file_label_len); + } + } + } else if (panic_on_error) { + panic("FIVE failed to sign %s (ret code = %d)", + dentry->d_name.name, rc); + } else { + five_audit_sign_err(current, file, "fix_xattr", 0, + 0, "can't sign the file", rc); + } + + kfree(sig); + + return rc; +} + +int five_read_xattr(struct dentry *dentry, char **xattr_value) +{ + ssize_t ret; + + ret = five_getxattr_alloc(dentry, XATTR_NAME_FIVE, xattr_value, + 0, GFP_NOFS); + if (ret < 0) + ret = 0; + + return ret; +} + +static bool bad_fs(struct inode *inode) +{ + if (inode->i_sb->s_magic == EXT4_SUPER_MAGIC || + inode->i_sb->s_magic == F2FS_SUPER_MAGIC || + inode->i_sb->s_magic == OVERLAYFS_SUPER_MAGIC) + return false; + + return true; +} + +static bool readonly_sb(struct inode *inode) +{ + if (inode->i_sb->s_flags & MS_RDONLY) + return true; + + return false; +} + +/* + * five_is_fsverity_protected - checks if file is protected by FSVERITY + * + * Return true/false + */ +static bool five_is_fsverity_protected(const struct inode *inode) +{ + return IS_VERITY(inode); +} + +/* + * five_appraise_measurement - appraise file measurement + * + * Return 0 on success, error code otherwise + */ +int five_appraise_measurement(struct task_struct *task, int func, + struct integrity_iint_cache *iint, + struct file *file, + struct five_cert *cert) +{ + enum task_integrity_reset_cause cause = CAUSE_UNKNOWN; + struct dentry *dentry = NULL; + struct inode *inode = NULL; + enum five_file_integrity status = FIVE_FILE_UNKNOWN; + enum task_integrity_value prev_integrity; + int rc = 0; + u8 *file_hash; + u8 stored_file_hash[FIVE_MAX_DIGEST_SIZE] = {0}; + size_t file_hash_len = 0; + struct five_cert_header *header = NULL; + + BUG_ON(!task || !iint || !file); + + prev_integrity = task_integrity_read(TASK_INTEGRITY(task)); + dentry = file->f_path.dentry; + inode = d_backing_inode(dentry); + + if (bad_fs(inode)) { + status = FIVE_FILE_FAIL; + cause = CAUSE_BAD_FS; + rc = -ENOTSUPP; + goto out; + } + + if (!cert) { + cause = CAUSE_NO_CERT; + if (five_is_fsverity_protected(inode)) + status = FIVE_FILE_FSVERITY; + else if (five_is_dmverity_protected(file)) + status = FIVE_FILE_DMVERITY; + goto out; + } + + header = (struct five_cert_header *)cert->body.header->value; + file_hash = cert->body.hash->value; + file_hash_len = cert->body.hash->length; + if (file_hash_len > sizeof(stored_file_hash)) { + cause = CAUSE_INVALID_HASH_LENGTH; + rc = -EINVAL; + goto out; + } + + memcpy(stored_file_hash, file_hash, file_hash_len); + + if (unlikely(!header || !file_hash)) { + cause = CAUSE_INVALID_HEADER; + rc = -EINVAL; + goto out; + } + + rc = five_collect_measurement(file, header->hash_algo, file_hash, + file_hash_len); + if (rc) { + cause = CAUSE_CALC_HASH_FAILED; + goto out; + } + + switch (header->signature_type) { + case FIVE_XATTR_HMAC: { + u8 *sig = NULL; + u8 algo = header->hash_algo; + void *file_label_data; + size_t file_label_len, sig_len = 0; + u8 cert_hash[FIVE_MAX_DIGEST_SIZE] = {0}; + size_t cert_hash_len = sizeof(cert_hash); + + status = FIVE_FILE_FAIL; + + rc = get_integrity_label(cert, &file_label_data, + &file_label_len); + if (unlikely(rc)) { + cause = CAUSE_INVALID_LABEL_DATA; + break; + } + + if (unlikely(file_label_len > PAGE_SIZE)) { + cause = CAUSE_INVALID_LABEL_DATA; + break; + } + + rc = get_signature(cert, (void **)&sig, &sig_len); + if (unlikely(rc)) { + cause = CAUSE_INVALID_SIGNATURE_DATA; + break; + } + + rc = five_cert_calc_hash(&cert->body, cert_hash, + &cert_hash_len); + if (unlikely(rc)) { + cause = CAUSE_INVALID_CALC_CERT_HASH; + break; + } + + rc = verify_hash(algo, cert_hash, + cert_hash_len, + file_label_data, file_label_len, + sig, sig_len); + if (unlikely(rc)) { + cause = CAUSE_INVALID_HASH; + if (cert) { + five_audit_hexinfo(file, "stored hash", + stored_file_hash, file_hash_len); + five_audit_hexinfo(file, "calculated hash", + file_hash, file_hash_len); + five_audit_hexinfo(file, "HMAC signature", + sig, sig_len); + } + break; + } + + rc = update_label(iint, file_label_data, file_label_len); + if (unlikely(rc)) { + cause = CAUSE_INVALID_UPDATE_LABEL; + break; + } + + status = FIVE_FILE_HMAC; + + break; + } + case FIVE_XATTR_DIGSIG: { + u8 cert_hash[FIVE_MAX_DIGEST_SIZE] = {0}; + size_t cert_hash_len = sizeof(cert_hash); + + status = FIVE_FILE_FAIL; + + rc = five_cert_calc_hash(&cert->body, cert_hash, + &cert_hash_len); + if (unlikely(rc)) { + cause = CAUSE_INVALID_CALC_CERT_HASH; + break; + } + + rc = five_digsig_verify(cert, cert_hash, cert_hash_len); + + if (rc) { + cause = CAUSE_INVALID_SIGNATURE; + if (cert) { + five_audit_hexinfo(file, "stored hash", + stored_file_hash, file_hash_len); + five_audit_hexinfo(file, "calculated hash", + file_hash, file_hash_len); + five_audit_hexinfo(file, "RSA signature", + cert->signature->value, + cert->signature->length); + } + break; + } + + status = FIVE_FILE_RSA; + + break; + } + default: + status = FIVE_FILE_FAIL; + cause = CAUSE_UKNOWN_FIVE_DATA; + break; + } + +out: + if (status == FIVE_FILE_FAIL || status == FIVE_FILE_UNKNOWN) { + task_integrity_set_reset_reason(TASK_INTEGRITY(task), cause, file); + five_audit_verbose(task, file, five_get_string_fn(func), + prev_integrity, prev_integrity, + tint_reset_cause_to_string(cause), rc); + } + + five_set_cache_status(iint, status); + + return rc; +} + +/* + * five_update_xattr - update 'security.five' hash value + */ +static int five_update_xattr(struct task_struct *task, + struct integrity_iint_cache *iint, struct file *file, + struct integrity_label_ex *label) +{ + struct dentry *dentry; + int rc = 0; + uint8_t *hash; + size_t hash_len; + uint8_t *raw_cert; + size_t raw_cert_len; + struct five_cert_header header = { + .version = FIVE_CERT_VERSION1, + .privilege = FIVE_PRIV_DEFAULT, + .hash_algo = five_hash_algo, + .signature_type = FIVE_XATTR_HMAC }; + + BUG_ON(!task || !iint || !file || !label); + + if (label->version == FIVE_LABEL_VERSION1) { + hash_len = (size_t)hash_digest_size[five_hash_algo]; + } else { + header.hash_algo = label->hash_algo; + if (label->hash_algo >= HASH_ALGO__LAST) + return -EINVAL; + + hash_len = (size_t)hash_digest_size[label->hash_algo]; + if (hash_len > sizeof(label->hash)) + return -EINVAL; + } + + hash = kzalloc(hash_len, GFP_KERNEL); + if (!hash) + return -ENOMEM; + + dentry = file->f_path.dentry; + + /* do not collect and update hash for digital signatures */ + if (five_get_cache_status(iint) == FIVE_FILE_RSA) { + char dummy[512]; + struct inode *inode = file_inode(file); + + rc = __vfs_getxattr(d_real_comp(dentry), inode, XATTR_NAME_FIVE, + dummy, sizeof(dummy), XATTR_NOSECURITY); + + // Check if xattr is exist + if (rc > 0 || rc != -ENODATA) { + kfree(hash); + return -EPERM; + } else { // xattr does not exist. + five_set_cache_status(iint, FIVE_FILE_UNKNOWN); + pr_err("FIVE: ERROR: Cache is unsynchronized"); + } + } + + rc = five_cert_body_alloc(&header, hash, hash_len, + label->label.data, label->label.len, + &raw_cert, &raw_cert_len); + if (rc) + goto exit; + + if (task_integrity_allow_sign(TASK_INTEGRITY(task))) { + rc = five_fix_xattr(task, dentry, file, + (void **)&raw_cert, &raw_cert_len, iint, label); + if (rc) + pr_err("FIVE: Can't sign hash: rc=%d\n", rc); + } else { + rc = -EPERM; + } + + five_hook_file_signed(task, file, raw_cert, raw_cert_len, rc); + + five_cert_free(raw_cert); + +exit: + kfree(hash); + return rc; +} + +static void five_reset_appraise_flags(struct dentry *dentry) +{ + struct inode *inode = d_backing_inode(dentry); + struct integrity_iint_cache *iint; + + if (!S_ISREG(inode->i_mode)) + return; + + iint = integrity_iint_find(inode); + if (iint) + five_set_cache_status(iint, FIVE_FILE_UNKNOWN); +} + +/** + * five_inode_post_setattr - reflect file metadata changes + * @dentry: pointer to the affected dentry + * + * Changes to a dentry's metadata might result in needing to appraise. + * + * This function is called from notify_change(), which expects the caller + * to lock the inode's i_mutex. + */ +void five_inode_post_setattr(struct task_struct *task, struct dentry *dentry) +{ + five_reset_appraise_flags(dentry); +} + +/* + * five_protect_xattr - protect 'security.five' + * + * Ensure that not just anyone can modify or remove 'security.five'. + */ +static int five_protect_xattr(struct dentry *dentry, const char *xattr_name, + const void *xattr_value, size_t xattr_value_len) +{ + if (strcmp(xattr_name, XATTR_NAME_FIVE) == 0) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + return 1; + } + return 0; +} + +int five_inode_setxattr(struct dentry *dentry, const char *xattr_name, + const void *xattr_value, size_t xattr_value_len) +{ + int result = five_protect_xattr(dentry, xattr_name, xattr_value, + xattr_value_len); + + if (result == 1 && xattr_value_len == 0) { + five_reset_appraise_flags(dentry); + return 0; + } + + if (result == 1) { + bool digsig; + struct five_cert_header *header; + struct five_cert cert = { {0} }; + + result = five_cert_fillout(&cert, xattr_value, xattr_value_len); + if (result) + return result; + + header = (struct five_cert_header *)cert.body.header->value; + + if (!xattr_value_len || !header || + (header->signature_type >= FIVE_XATTR_END)) + return -EINVAL; + + digsig = (header->signature_type == FIVE_XATTR_DIGSIG); + if (!digsig) + return -EPERM; + + five_reset_appraise_flags(dentry); + result = 0; + } + + return result; +} + +int five_inode_removexattr(struct dentry *dentry, const char *xattr_name) +{ + int result; + + result = five_protect_xattr(dentry, xattr_name, NULL, 0); + if (result == 1) { + five_reset_appraise_flags(dentry); + result = 0; + } + return result; +} + +int five_reboot_notifier(struct notifier_block *nb, + unsigned long action, void *unused) +{ + down_write(&sign_fcntl_lock); + /* Need to wait for five_fcntl_sign finish */ + up_write(&sign_fcntl_lock); + + return NOTIFY_DONE; +} + +static int copy_label(const struct integrity_label __user *ulabel, + struct integrity_label_ex **out_label) +{ + u16 len; + size_t label_len; + int rc = 0; + struct integrity_label_ex header = {0}; + struct integrity_label_ex *label = NULL; + + if (unlikely(!ulabel || !out_label)) { + rc = -EINVAL; + goto error; + } + + if (unlikely(copy_from_user(&len, ulabel, sizeof(len)))) { + rc = -EFAULT; + goto error; + } + + if (len == FIVE_ID_INTEGRITY_LABEL_EX) { + if (unlikely(copy_from_user(&header, ulabel, sizeof(header)))) { + rc = -EFAULT; + goto error; + } + + if (len != header.len || + header.label.len > FIVE_LABEL_MAX_LEN || + header.version <= FIVE_LABEL_VERSION1) { + rc = -EINVAL; + goto error; + } + + label_len = sizeof(header) + header.label.len; + + label = kzalloc(label_len, GFP_NOFS); + if (unlikely(!label)) { + rc = -ENOMEM; + goto error; + } + + memcpy(label, &header, sizeof(header)); + if (unlikely(copy_from_user(&label->label.data[0], + (const u8 __user *)ulabel + sizeof(header), + label_len - sizeof(header)))) { + rc = -EFAULT; + goto error; + } + } else { + if (len > FIVE_LABEL_MAX_LEN) { + rc = -EINVAL; + goto error; + } + + label_len = sizeof(header) + len; + + label = kzalloc(label_len, GFP_NOFS); + if (unlikely(!label)) { + rc = -ENOMEM; + goto error; + } + + if (unlikely(copy_from_user(&label->label, ulabel, + sizeof(len) + len))) { + rc = -EFAULT; + goto error; + } + + if (len != label->label.len) { + rc = -EINVAL; + goto error; + } + + label->version = FIVE_LABEL_VERSION1; + } + + *out_label = label; +error: + if (rc) + kfree(label); + + return rc; +} + +/* Called from do_fcntl */ +int five_fcntl_sign(struct file *file, struct integrity_label __user *label) +{ + struct integrity_iint_cache *iint; + struct inode *inode = file_inode(file); + struct integrity_label_ex *l = NULL; + int rc = 0; + + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + if (readonly_sb(inode)) { + pr_err("FIVE: Can't sign a file on RO FS\n"); + return -EROFS; + } + + if (task_integrity_allow_sign(TASK_INTEGRITY(current))) { + rc = copy_label(label, &l); + if (rc) { + pr_err("FIVE: Can't copy integrity label\n"); + return rc; + } + } else { + enum task_integrity_value tint = + task_integrity_read(TASK_INTEGRITY(current)); + + five_audit_err(current, file, "fcntl_sign", tint, tint, + "sign:no-perm", -EPERM); + return -EPERM; + } + + iint = integrity_inode_get(inode); + if (!iint) { + kfree(l); + return -ENOMEM; + } + + if (file->f_op && file->f_op->flush) { + if (file->f_op->flush(file, current->files)) { + kfree(l); + return -EOPNOTSUPP; + } + } + + down_read(&sign_fcntl_lock); + inode_lock(inode); + rc = five_update_xattr(current, iint, file, l); + iint->five_signing = false; + inode_unlock(inode); + up_read(&sign_fcntl_lock); + + kfree(l); + + return rc; +} + +static int check_input_inode(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + if (readonly_sb(inode)) { + pr_err("FIVE: Can't sign a file on RO FS\n"); + return -EROFS; + } + + return 0; +} + +int five_fcntl_edit(struct file *file) +{ + int rc; + struct dentry *dentry; + uint8_t *raw_cert = NULL; + size_t raw_cert_len = 0; + struct integrity_iint_cache *iint; + struct inode *inode = file_inode(file); + + rc = check_input_inode(inode); + if (rc) + return rc; + + if (!task_integrity_allow_sign(TASK_INTEGRITY(current))) + return -EPERM; + + inode_lock(inode); + dentry = file->f_path.dentry; + rc = five_setxattr_noperm(d_real_comp(dentry), + XATTR_NAME_FIVE, + raw_cert, + raw_cert_len, + 0); + iint = integrity_inode_get(inode); + if (iint) + iint->five_signing = true; + inode_unlock(inode); + + return rc; +} + +int five_fcntl_close(struct file *file) +{ + int rc; + ssize_t xattr_len; + struct dentry *dentry; + struct integrity_iint_cache *iint; + struct inode *inode = file_inode(file); + + rc = check_input_inode(inode); + if (rc) + return rc; + + inode_lock(inode); + iint = integrity_inode_get(inode); + if (!iint) { + inode_unlock(inode); + return -ENOMEM; + } + + if (iint->five_signing) { + dentry = file->f_path.dentry; + xattr_len = __vfs_getxattr(d_real_comp(dentry), inode, + XATTR_NAME_FIVE, NULL, 0, XATTR_NOSECURITY); + if (xattr_len == 0) + rc = __vfs_removexattr(d_real_comp(dentry), + XATTR_NAME_FIVE); + + iint->five_signing = false; + } + inode_unlock(inode); + + return rc; +} diff --git a/security/samsung/five/gki/five_audit.c b/security/samsung/five/gki/five_audit.c new file mode 100644 index 000000000..dd49bd0bc --- /dev/null +++ b/security/samsung/five/gki/five_audit.c @@ -0,0 +1,216 @@ +/* + * Audit calls for FIVE audit subsystem. + * + * Copyright (C) 2017 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 +#include +#include +#include +#include "five.h" +#include "five_audit.h" +#include "five_cache.h" +#include "five_porting.h" +#include "five_dsms.h" + +static void five_audit_msg(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result); + +#ifdef CONFIG_FIVE_AUDIT_VERBOSE +void five_audit_verbose(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result) +{ + five_audit_msg(task, file, op, prev, tint, cause, result); +} +#else +void five_audit_verbose(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result) +{ +} +#endif + +void five_audit_info(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result) +{ + five_audit_msg(task, file, op, prev, tint, cause, result); +} + +/** + * There are two kind of event that can come to the function: error + * and tampering attempt. 'result' is for identification of error type + * and it should be non-zero in case of error but is always zero in + * case of tampering. + */ +void five_audit_err(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result) +{ + five_audit_msg(task, file, op, prev, tint, cause, result); + + if (!result) { + char comm[TASK_COMM_LEN]; + struct task_struct *tsk = task ? task : current; + + five_dsms_reset_integrity(get_task_comm(comm, tsk), 0, op); + } +} + +void five_audit_sign_err(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result) +{ + char comm[TASK_COMM_LEN]; + struct task_struct *tsk = task ? task : current; + + get_task_comm(comm, tsk); + five_dsms_sign_err(comm, result); +} + +static void five_audit_msg(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result) +{ + struct audit_buffer *ab; + struct inode *inode = NULL; + const char *fname = NULL; + char *pathbuf = NULL; + char filename[NAME_MAX]; + char comm[TASK_COMM_LEN]; + const char *name = ""; + struct task_struct *tsk = task ? task : current; + struct integrity_iint_cache *iint = NULL; + + if (file) { + inode = file_inode(file); + fname = five_d_path(&file->f_path, &pathbuf, filename); + } + + ab = audit_log_start(current->audit_context, GFP_KERNEL, + AUDIT_INTEGRITY_DATA); + if (unlikely(!ab)) { + pr_err("Can't get a context of audit logs\n"); + goto exit; + } + + audit_log_format(ab, " pid=%d", task_pid_nr(tsk)); + audit_log_format(ab, " tgid=%d", task_tgid_nr(tsk)); + audit_log_task_context(ab); + audit_log_format(ab, " op="); + audit_log_string(ab, op); + audit_log_format(ab, " cint=0x%x", tint); + audit_log_format(ab, " pint=0x%x", prev); + audit_log_format(ab, " cause="); + audit_log_string(ab, cause); + audit_log_format(ab, " comm="); + audit_log_untrustedstring(ab, get_task_comm(comm, tsk)); + if (fname) { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, fname); + name = fname; + } + if (inode) { + audit_log_format(ab, " dev="); + audit_log_untrustedstring(ab, inode->i_sb->s_id); + audit_log_format(ab, " ino=%lu", inode->i_ino); + audit_log_format(ab, " i_version=%llu ", + inode_query_iversion(inode)); + iint = integrity_inode_get(inode); + if (iint) { + audit_log_format(ab, " five_status=%d ", + five_get_cache_status(iint)); + audit_log_format(ab, " version=%llu ", + (unsigned long long)iint->version); + } + } + audit_log_format(ab, " res=%d", result); + audit_log_end(ab); + +exit: + if (pathbuf) + __putname(pathbuf); +} + +void five_audit_tee_msg(const char *func, const char *cause, int rc, + uint32_t origin) +{ + struct audit_buffer *ab; + + ab = audit_log_start(current->audit_context, GFP_KERNEL, + AUDIT_INTEGRITY_DATA); + if (unlikely(!ab)) { + pr_err("Can't get a context of audit logs\n"); + return; + } + + audit_log_format(ab, " func="); + audit_log_string(ab, func); + audit_log_format(ab, " cause="); + audit_log_string(ab, cause); + audit_log_format(ab, " rc=0x%x, ", rc); + audit_log_format(ab, " origin=0x%x", origin); + audit_log_end(ab); +} + +void five_audit_hexinfo(struct file *file, const char *msg, char *data, + size_t data_length) +{ + struct audit_buffer *ab; + struct inode *inode = NULL; + const unsigned char *fname = NULL; + char filename[NAME_MAX]; + char *pathbuf = NULL; + struct integrity_iint_cache *iint = NULL; + + if (file) { + fname = five_d_path(&file->f_path, &pathbuf, filename); + inode = file_inode(file); + } + + ab = audit_log_start(current->audit_context, GFP_KERNEL, + AUDIT_INTEGRITY_DATA); + if (unlikely(!ab)) { + pr_err("Can't get a context of audit logs\n"); + goto exit; + } + + if (fname) { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, fname); + } + if (inode) { + audit_log_format(ab, " i_version=%llu ", + inode_query_iversion(inode)); + + iint = integrity_inode_get(inode); + if (iint) { + audit_log_format(ab, " cache_value=%lu ", + iint->five_flags); + audit_log_format(ab, " five_status=%d ", + five_get_cache_status(iint)); + audit_log_format(ab, " version=%llu ", + (unsigned long long)iint->version); + } + } + + audit_log_string(ab, msg); + audit_log_n_hex(ab, data, data_length); + audit_log_end(ab); +exit: + if (pathbuf) + __putname(pathbuf); +} diff --git a/security/samsung/five/gki/five_audit.h b/security/samsung/five/gki/five_audit.h new file mode 100644 index 000000000..e0838399a --- /dev/null +++ b/security/samsung/five/gki/five_audit.h @@ -0,0 +1,40 @@ +/* + * Audit calls for FIVE audit subsystem. + * + * Copyright (C) 2017 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 __LINUX_FIVE_AUDIT_H +#define __LINUX_FIVE_AUDIT_H + +#include + +void five_audit_verbose(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result); +void five_audit_info(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result); +void five_audit_err(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result); +void five_audit_sign_err(struct task_struct *task, struct file *file, + const char *op, enum task_integrity_value prev, + enum task_integrity_value tint, const char *cause, int result); +void five_audit_tee_msg(const char *func, const char *cause, int rc, + uint32_t origin); + +void five_audit_hexinfo(struct file *file, + const char *msg, char *data, size_t data_length); + +#endif diff --git a/security/samsung/five/gki/five_cache.c b/security/samsung/five/gki/five_cache.c new file mode 100644 index 000000000..c23f6028c --- /dev/null +++ b/security/samsung/five/gki/five_cache.c @@ -0,0 +1,44 @@ +/* + * FIVE cache functions + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * + * Egor Uleyskiy, + * Viacheslav Vovchenko + * Yevgen Kopylov + * + * 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 "five_cache.h" +#include "five_porting.h" + +enum five_file_integrity five_get_cache_status( + const struct integrity_iint_cache *iint) +{ + if (unlikely(!iint)) + return FIVE_FILE_UNKNOWN; + + if (!inode_eq_iversion(iint->inode, iint->version)) + return FIVE_FILE_UNKNOWN; + + return iint->five_status; +} + +void five_set_cache_status(struct integrity_iint_cache *iint, + enum five_file_integrity status) +{ + if (unlikely(!iint)) + return; + + iint->version = inode_query_iversion(iint->inode); + iint->five_status = status; +} + diff --git a/security/samsung/five/gki/five_cache.h b/security/samsung/five/gki/five_cache.h new file mode 100644 index 000000000..a40bfa019 --- /dev/null +++ b/security/samsung/five/gki/five_cache.h @@ -0,0 +1,30 @@ +/* + * FIVE cache functions + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * + * Egor Uleyskiy, + * Viacheslav Vovchenko + * Yevgen Kopylov + * + * 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 __LINUX_FIVE_CACHE_H +#define __LINUX_FIVE_CACHE_H + +#include "security/integrity/integrity.h" + +enum five_file_integrity five_get_cache_status( + const struct integrity_iint_cache *iint); +void five_set_cache_status(struct integrity_iint_cache *iint, + enum five_file_integrity status); + +#endif // __LINUX_FIVE_CACHE_H diff --git a/security/samsung/five/gki/five_crypto.c b/security/samsung/five/gki/five_crypto.c new file mode 100644 index 000000000..08c9399fd --- /dev/null +++ b/security/samsung/five/gki/five_crypto.c @@ -0,0 +1,537 @@ +/* + * This code is based on IMA's code + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * + * Egor Uleyskiy, + * Viacheslav Vovchenko + * Yevgen Kopylov + * + * 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. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "five.h" +#include "five_porting.h" +#include "five_vfs.h" + +struct ahash_completion { + struct completion completion; + int err; +}; + +/* minimum file size for ahash use */ +static unsigned long five_ahash_minsize; +module_param_named(ahash_minsize, five_ahash_minsize, ulong, 0644); +MODULE_PARM_DESC(ahash_minsize, "Minimum file size for ahash use"); + +/* default is 0 - 1 page. */ +static int five_maxorder; +static unsigned long five_bufsize = PAGE_SIZE; + +static int param_set_bufsize(const char *val, const struct kernel_param *kp) +{ + unsigned long long size; + int order; + + size = memparse(val, NULL); + order = get_order(size); + if (order >= MAX_ORDER) + return -EINVAL; + five_maxorder = order; + five_bufsize = PAGE_SIZE << order; + return 0; +} + +static const struct kernel_param_ops param_ops_bufsize = { + .set = param_set_bufsize, + .get = param_get_uint, +}; + +#define param_check_bufsize(name, p) __param_check(name, p, unsigned int) + +module_param_named(ahash_bufsize, five_bufsize, ulong, 0644); +MODULE_PARM_DESC(ahash_bufsize, "Maximum ahash buffer size"); + +static struct crypto_shash *five_shash_tfm; +static struct crypto_ahash *five_ahash_tfm; + +int __init five_init_crypto(void) +{ + long rc; + + five_shash_tfm = crypto_alloc_shash( + hash_algo_name[five_hash_algo], 0, 0); + if (IS_ERR(five_shash_tfm)) { + rc = PTR_ERR(five_shash_tfm); + pr_err("Can not allocate %s (reason: %ld)\n", + hash_algo_name[five_hash_algo], rc); + return rc; + } + return 0; +} + +static struct crypto_shash *five_alloc_tfm(enum hash_algo algo) +{ + struct crypto_shash *tfm = five_shash_tfm; + int rc; + + if (algo < 0 || algo >= HASH_ALGO__LAST) + algo = five_hash_algo; + + if (algo != five_hash_algo) { + tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0); + if (IS_ERR(tfm)) { + rc = PTR_ERR(tfm); + pr_err("Can not allocate %s (reason: %d)\n", + hash_algo_name[algo], rc); + } + } + return tfm; +} + +static void five_free_tfm(struct crypto_shash *tfm) +{ + if (tfm != five_shash_tfm) + crypto_free_shash(tfm); +} + +/** + * five_alloc_pages() - Allocate contiguous pages. + * @max_size: Maximum amount of memory to allocate. + * @allocated_size: Returned size of actual allocation. + * @last_warn: Should the min_size allocation warn or not. + * + * Tries to do opportunistic allocation for memory first trying to allocate + * max_size amount of memory and then splitting that until zero order is + * reached. Allocation is tried without generating allocation warnings unless + * last_warn is set. Last_warn set affects only last allocation of zero order. + * + * By default, five_maxorder is 0 and it is equivalent to kmalloc(GFP_KERNEL) + * + * Return pointer to allocated memory, or NULL on failure. + */ +static void *five_alloc_pages(loff_t max_size, size_t *allocated_size, + int last_warn) +{ + void *ptr; + int order = five_maxorder; + gfp_t gfp_mask = __GFP_RECLAIM | __GFP_NOWARN | __GFP_NORETRY; + + if (order) + order = min(get_order(max_size), order); + + for (; order; order--) { + ptr = (void *)__get_free_pages(gfp_mask, order); + if (ptr) { + *allocated_size = PAGE_SIZE << order; + return ptr; + } + } + + /* order is zero - one page */ + + gfp_mask = GFP_KERNEL; + + if (!last_warn) + gfp_mask |= __GFP_NOWARN; + + ptr = (void *)__get_free_pages(gfp_mask, 0); + if (ptr) { + *allocated_size = PAGE_SIZE; + return ptr; + } + + *allocated_size = 0; + return NULL; +} + +/** + * five_free_pages() - Free pages allocated by five_alloc_pages(). + * @ptr: Pointer to allocated pages. + * @size: Size of allocated buffer. + */ +static void five_free_pages(void *ptr, size_t size) +{ + if (!ptr) + return; + free_pages((unsigned long)ptr, get_order(size)); +} + +static struct crypto_ahash *five_alloc_atfm(enum hash_algo algo) +{ + struct crypto_ahash *tfm = five_ahash_tfm; + int rc; + + if (algo < 0 || algo >= HASH_ALGO__LAST) + algo = five_hash_algo; + + if (algo != five_hash_algo || !tfm) { + tfm = crypto_alloc_ahash(hash_algo_name[algo], 0, 0); + if (!IS_ERR(tfm)) { + if (algo == five_hash_algo) + five_ahash_tfm = tfm; + } else { + rc = PTR_ERR(tfm); + pr_err("Can not allocate %s (reason: %d)\n", + hash_algo_name[algo], rc); + } + } + return tfm; +} + +static void five_free_atfm(struct crypto_ahash *tfm) +{ + if (tfm != five_ahash_tfm) + crypto_free_ahash(tfm); +} + +static void ahash_complete(struct crypto_async_request *req, int err) +{ + struct ahash_completion *res = req->data; + + if (err == -EINPROGRESS) + return; + res->err = err; + complete(&res->completion); +} + +static int ahash_wait(int err, struct ahash_completion *res) +{ + try_to_freeze(); + + switch (err) { + case 0: + break; + case -EINPROGRESS: + case -EBUSY: + wait_for_completion(&res->completion); + reinit_completion(&res->completion); + err = res->err; + /* fall through */ + default: + pr_crit_ratelimited("ahash calculation failed: err: %d\n", err); + } + + return err; +} + +static int five_calc_file_hash_atfm(struct file *file, + u8 *hash, size_t *hash_len, + struct crypto_ahash *tfm) +{ + const size_t len = crypto_ahash_digestsize(tfm); + loff_t i_size, offset; + char *rbuf[2] = { NULL, }; + int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0; + struct ahash_request *req; + struct scatterlist sg[1]; + struct ahash_completion res; + size_t rbuf_size[2]; + + if (*hash_len < len) + return -EINVAL; + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) + return -ENOMEM; + + init_completion(&res.completion); + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP, + ahash_complete, &res); + + rc = ahash_wait(crypto_ahash_init(req), &res); + if (rc) + goto out1; + + i_size = i_size_read(file_inode(file)); + + if (i_size == 0) + goto out2; + + /* + * Try to allocate maximum size of memory. + * Fail if even a single page cannot be allocated. + */ + rbuf[0] = five_alloc_pages(i_size, &rbuf_size[0], 1); + if (!rbuf[0]) { + rc = -ENOMEM; + goto out1; + } + + /* Only allocate one buffer if that is enough. */ + if (i_size > rbuf_size[0]) { + /* + * Try to allocate secondary buffer. If that fails fallback to + * using single buffering. Use previous memory allocation size + * as baseline for possible allocation size. + */ + rbuf[1] = five_alloc_pages(i_size - rbuf_size[0], + &rbuf_size[1], 0); + } + + if (!(file->f_mode & FMODE_READ)) { + file->f_mode |= FMODE_READ; + read = 1; + } + + for (offset = 0; offset < i_size; offset += rbuf_len) { + if (!rbuf[1] && offset) { + /* Not using two buffers, and it is not the first + * read/request, wait for the completion of the + * previous ahash_update() request. + */ + rc = ahash_wait(ahash_rc, &res); + if (rc) + goto out3; + } + /* read buffer */ + rbuf_len = min_t(loff_t, i_size - offset, rbuf_size[active]); + rc = five_kernel_read(file, offset, rbuf[active], + rbuf_len); + if (rc != rbuf_len) + goto out3; + + if (rbuf[1] && offset) { + /* Using two buffers, and it is not the first + * read/request, wait for the completion of the + * previous ahash_update() request. + */ + rc = ahash_wait(ahash_rc, &res); + if (rc) + goto out3; + } + + sg_init_one(&sg[0], rbuf[active], rbuf_len); + ahash_request_set_crypt(req, sg, NULL, rbuf_len); + + ahash_rc = crypto_ahash_update(req); + + if (rbuf[1]) + active = !active; /* swap buffers, if we use two */ + } + /* wait for the last update request to complete */ + rc = ahash_wait(ahash_rc, &res); +out3: + if (read) + file->f_mode &= ~FMODE_READ; + five_free_pages(rbuf[0], rbuf_size[0]); + five_free_pages(rbuf[1], rbuf_size[1]); +out2: + if (!rc) { + ahash_request_set_crypt(req, NULL, hash, 0); + rc = ahash_wait(crypto_ahash_final(req), &res); + if (!rc) + *hash_len = len; + } +out1: + ahash_request_free(req); + return rc; +} + +static int five_calc_file_ahash(struct file *file, + u8 hash_algo, u8 *hash, + size_t *hash_len) +{ + struct crypto_ahash *tfm; + int rc; + + tfm = five_alloc_atfm(hash_algo); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + rc = five_calc_file_hash_atfm(file, hash, hash_len, tfm); + + five_free_atfm(tfm); + + return rc; +} + +static int five_calc_file_hash_tfm(struct file *file, + u8 *hash, size_t *hash_len, + struct crypto_shash *tfm) +{ + SHASH_DESC_ON_STACK(shash, tfm); + const size_t len = crypto_shash_digestsize(tfm); + loff_t i_size, offset = 0; + char *rbuf; + int rc, read = 0; + + if (*hash_len < len) + return -EINVAL; + + shash->tfm = tfm; + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) + shash->flags = 0; + #endif + + rc = crypto_shash_init(shash); + if (rc != 0) + return rc; + + i_size = i_size_read(file_inode(file)); + + if (i_size == 0) + goto out; + + rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!rbuf) + return -ENOMEM; + + if (!(file->f_mode & FMODE_READ)) { + file->f_mode |= FMODE_READ; + read = 1; + } + + while (offset < i_size) { + int rbuf_len; + + rbuf_len = five_kernel_read(file, offset, rbuf, PAGE_SIZE); + if (rbuf_len < 0) { + rc = rbuf_len; + break; + } + if (rbuf_len == 0) + break; + offset += rbuf_len; + + try_to_freeze(); + + rc = crypto_shash_update(shash, rbuf, rbuf_len); + if (rc) + break; + } + if (read) + file->f_mode &= ~FMODE_READ; + kfree(rbuf); +out: + if (!rc) + rc = crypto_shash_final(shash, hash); + + if (!rc) + *hash_len = len; + + return rc; +} + +static int five_calc_hash_tfm(const u8 *data, size_t data_len, + u8 *hash, size_t *hash_len, struct crypto_shash *tfm) +{ + SHASH_DESC_ON_STACK(shash, tfm); + const size_t len = crypto_shash_digestsize(tfm); + int rc; + + if (*hash_len < len || data_len == 0) + return -EINVAL; + + shash->tfm = tfm; + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) + shash->flags = 0; + #endif + + rc = crypto_shash_init(shash); + if (rc != 0) + return rc; + + rc = crypto_shash_update(shash, data, data_len); + if (!rc) { + rc = crypto_shash_final(shash, hash); + + if (!rc) + *hash_len = len; + } + + return rc; +} + +static int five_calc_file_shash(struct file *file, + u8 hash_algo, + u8 *hash, + size_t *hash_len) +{ + struct crypto_shash *tfm; + int rc; + + tfm = five_alloc_tfm(hash_algo); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + rc = five_calc_file_hash_tfm(file, hash, hash_len, tfm); + + five_free_tfm(tfm); + + return rc; +} + +static int five_calc_data_shash(const u8 *data, size_t data_len, u8 hash_algo, + u8 *hash, size_t *hash_len) +{ + struct crypto_shash *tfm; + int rc; + + tfm = five_alloc_tfm(hash_algo); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + rc = five_calc_hash_tfm(data, data_len, hash, hash_len, tfm); + + five_free_tfm(tfm); + + return rc; +} + +/* + * five_calc_file_hash - calculate file hash + * + * Asynchronous hash (ahash) allows using HW acceleration for calculating + * a hash. ahash performance varies for different data sizes on different + * crypto accelerators. shash performance might be better for smaller files. + * The 'five.ahash_minsize' module parameter allows specifying the best + * minimum file size for using ahash on the system. + * + * If the five.ahash_minsize parameter is not specified, this function uses + * shash for the hash calculation. If ahash fails, it falls back to using + * shash. + */ +int five_calc_file_hash(struct file *file, u8 hash_algo, u8 *hash, + size_t *hash_len) +{ + loff_t i_size; + int rc; + + i_size = i_size_read(file_inode(file)); + + if (five_ahash_minsize && i_size >= five_ahash_minsize) { + rc = five_calc_file_ahash(file, hash_algo, hash, hash_len); + if (!rc) + return 0; + } + + return five_calc_file_shash(file, hash_algo, hash, hash_len); +} + +int five_calc_data_hash(const uint8_t *data, size_t data_len, + uint8_t hash_algo, uint8_t *hash, size_t *hash_len) +{ + return five_calc_data_shash(data, data_len, hash_algo, hash, hash_len); +} diff --git a/security/samsung/five/gki/five_hooks.c b/security/samsung/five/gki/five_hooks.c new file mode 100644 index 000000000..1ca934a6e --- /dev/null +++ b/security/samsung/five/gki/five_hooks.c @@ -0,0 +1,313 @@ +/* + * Five Event interface + * + * Copyright (C) 2018 Samsung Electronics, Inc. + * Ivan Vorobiov, + * + * 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 "five_hooks.h" +#include "five_porting.h" + +#include +#include + +#define call_void_hook(FUNC, ...) \ + do { \ + struct five_hook_list *P; \ + \ + list_for_each_entry(P, &five_hook_heads.FUNC, list) \ + P->hook.FUNC(__VA_ARGS__); \ + } while (0) + +struct five_hook_heads five_hook_heads = { + .file_processed = + LIST_HEAD_INIT(five_hook_heads.file_processed), + .file_skipped = + LIST_HEAD_INIT(five_hook_heads.file_skipped), + .file_signed = + LIST_HEAD_INIT(five_hook_heads.file_signed), + .task_forked = + LIST_HEAD_INIT(five_hook_heads.task_forked), + .integrity_reset = + LIST_HEAD_INIT(five_hook_heads.integrity_reset), + .integrity_reset2 = + LIST_HEAD_INIT(five_hook_heads.integrity_reset2), +}; + +enum five_hook_event { + FILE_PROCESSED, + FILE_SKIPPED, + FILE_SIGNED, + TASK_FORKED, + INTEGRITY_RESET +}; + +struct hook_wq_event { + enum five_hook_event event; + union { + struct { + struct task_struct *task; + enum task_integrity_value tint_value; + struct file *file; + void *xattr; + size_t xattr_size; + int result; + } processed; + struct { + struct task_struct *task; + enum task_integrity_value tint_value; + struct file *file; + } skipped; + struct { + struct task_struct *parent; + enum task_integrity_value parent_tint_value; + struct task_struct *child; + enum task_integrity_value child_tint_value; + } forked; + struct { + struct task_struct *task; + struct file *file; + enum task_integrity_reset_cause cause; + } reset; + }; +}; + +static void hook_wq_event_destroy(struct hook_wq_event *event) +{ + switch (event->event) { + case FILE_PROCESSED: { + fput(event->processed.file); + put_task_struct(event->processed.task); + kfree(event->processed.xattr); + break; + } + case FILE_SKIPPED: { + fput(event->skipped.file); + put_task_struct(event->skipped.task); + break; + } + case FILE_SIGNED: { + fput(event->processed.file); + put_task_struct(event->processed.task); + kfree(event->processed.xattr); + break; + } + case TASK_FORKED: { + put_task_struct(event->forked.parent); + put_task_struct(event->forked.child); + break; + } + case INTEGRITY_RESET: { + if (event->reset.file) + fput(event->reset.file); + put_task_struct(event->reset.task); + break; + } + } +} + +struct hook_wq_context { + struct work_struct data_work; + struct hook_wq_event payload; +}; + +static struct workqueue_struct *g_hook_workqueue; + +static void hook_handler(struct work_struct *in_data) +{ + struct hook_wq_event *event; + struct hook_wq_context *context = container_of(in_data, + struct hook_wq_context, data_work); + + if (unlikely(!context)) + return; + event = &context->payload; + + switch (event->event) { + case FILE_PROCESSED: { + call_void_hook(file_processed, + event->processed.task, + event->processed.tint_value, + event->processed.file, + event->processed.xattr, + event->processed.xattr_size, + event->processed.result); + break; + } + case FILE_SKIPPED: { + call_void_hook(file_skipped, + event->skipped.task, + event->skipped.tint_value, + event->skipped.file); + break; + } + case FILE_SIGNED: { + call_void_hook(file_signed, + event->processed.task, + event->processed.tint_value, + event->processed.file, + event->processed.xattr, + event->processed.xattr_size, + event->processed.result); + break; + } + case TASK_FORKED: { + call_void_hook(task_forked, + event->forked.parent, + event->forked.parent_tint_value, + event->forked.child, + event->forked.child_tint_value); + break; + } + case INTEGRITY_RESET: { + call_void_hook(integrity_reset, + event->reset.task); + call_void_hook(integrity_reset2, event->reset.task, + event->reset.file, event->reset.cause); + break; + } + } + + hook_wq_event_destroy(event); + kfree(context); +} + +static int __push_event(struct hook_wq_event *event, gfp_t flags) +{ + struct hook_wq_context *context; + + if (!g_hook_workqueue) + return -ENAVAIL; + + context = kmalloc(sizeof(struct hook_wq_context), flags); + if (unlikely(!context)) + return -ENOMEM; + + context->payload = *event; + + INIT_WORK(&context->data_work, hook_handler); + return queue_work(g_hook_workqueue, &context->data_work) ? 0 : 1; +} + +void five_hook_file_processed(struct task_struct *task, + struct file *file, void *xattr, + size_t xattr_size, int result) +{ + struct hook_wq_event event = {0}; + + event.event = FILE_PROCESSED; + get_task_struct(task); + get_file(file); + event.processed.task = task; + event.processed.tint_value = task_integrity_read(TASK_INTEGRITY(task)); + event.processed.file = file; + /* + * xattr parameters are optional, because FIVE could get results + * from cache where xattr absents, so we may ignore kmemdup errors + */ + if (xattr) { + event.processed.xattr = kmemdup(xattr, xattr_size, GFP_KERNEL); + if (event.processed.xattr) + event.processed.xattr_size = xattr_size; + } + event.processed.result = result; + + if (__push_event(&event, GFP_KERNEL) < 0) + hook_wq_event_destroy(&event); +} + +void five_hook_file_signed(struct task_struct *task, + struct file *file, void *xattr, + size_t xattr_size, int result) +{ + struct hook_wq_event event = {0}; + + event.event = FILE_SIGNED; + get_task_struct(task); + get_file(file); + event.processed.task = task; + event.processed.tint_value = task_integrity_read(TASK_INTEGRITY(task)); + event.processed.file = file; + /* xattr parameters are optional, so we may ignore kmemdup errors */ + if (xattr) { + event.processed.xattr = kmemdup(xattr, xattr_size, GFP_KERNEL); + if (event.processed.xattr) + event.processed.xattr_size = xattr_size; + } + event.processed.result = result; + + if (__push_event(&event, GFP_KERNEL) < 0) + hook_wq_event_destroy(&event); +} + +void five_hook_file_skipped(struct task_struct *task, struct file *file) +{ + struct hook_wq_event event = {0}; + + event.event = FILE_SKIPPED; + get_task_struct(task); + get_file(file); + event.skipped.task = task; + event.skipped.tint_value = task_integrity_read(TASK_INTEGRITY(task)); + event.skipped.file = file; + + if (__push_event(&event, GFP_KERNEL) < 0) + hook_wq_event_destroy(&event); +} + +void five_hook_task_forked(struct task_struct *parent, + struct task_struct *child) +{ + struct hook_wq_event event = {0}; + + event.event = TASK_FORKED; + get_task_struct(parent); + get_task_struct(child); + event.forked.parent = parent; + event.forked.parent_tint_value = task_integrity_read(TASK_INTEGRITY(parent)); + event.forked.child = child; + event.forked.child_tint_value = task_integrity_read(TASK_INTEGRITY(child)); + + if (__push_event(&event, GFP_ATOMIC) < 0) + hook_wq_event_destroy(&event); +} + +int five_hook_wq_init(void) +{ + g_hook_workqueue = alloc_ordered_workqueue("%s", + WQ_MEM_RECLAIM | WQ_FREEZABLE, "five_hook_wq"); + if (!g_hook_workqueue) + return -ENOMEM; + + return 0; +} + +void five_hook_integrity_reset(struct task_struct *task, + struct file *file, + enum task_integrity_reset_cause cause) +{ + struct hook_wq_event event = {0}; + + if (task == NULL) + return; + + event.event = INTEGRITY_RESET; + get_task_struct(task); + if (file) + get_file(file); + event.reset.task = task; + event.reset.file = file; + event.reset.cause = cause; + + if (__push_event(&event, GFP_KERNEL) < 0) + hook_wq_event_destroy(&event); +} diff --git a/security/samsung/five/gki/five_hooks.h b/security/samsung/five/gki/five_hooks.h new file mode 100644 index 000000000..78b6dfb49 --- /dev/null +++ b/security/samsung/five/gki/five_hooks.h @@ -0,0 +1,111 @@ +/* + * Five Event interface + * + * Copyright (C) 2018 Samsung Electronics, Inc. + * Ivan Vorobiov, + * + * 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 _FIVE_HOOKS_H +#define _FIVE_HOOKS_H + +#include +#include +#include +#include + +void five_hook_file_processed(struct task_struct *task, + struct file *file, void *xattr, + size_t xattr_size, int result); + +void five_hook_task_forked(struct task_struct *parent, + struct task_struct *child); + +void five_hook_file_skipped(struct task_struct *task, + struct file *file); + +void five_hook_file_signed(struct task_struct *task, + struct file *file, void *xattr, + size_t xattr_size, int result); + +void five_hook_integrity_reset(struct task_struct *task, + struct file *file, + enum task_integrity_reset_cause cause); + +union five_list_options { + void (*file_processed)(struct task_struct *task, + enum task_integrity_value tint_value, + struct file *file, + void *xattr, + size_t xattr_size, + int result); + + void (*file_skipped)(struct task_struct *task, + enum task_integrity_value tint_value, + struct file *file); + + void (*task_forked)(struct task_struct *parent, + enum task_integrity_value parent_tint_value, + struct task_struct *child, + enum task_integrity_value child_tint_value); + + void (*file_signed)(struct task_struct *task, + enum task_integrity_value tint_value, + struct file *file, void *xattr, + size_t xattr_size, int result); + void (*integrity_reset)(struct task_struct *task); + void (*integrity_reset2)(struct task_struct *task, + struct file *file, + enum task_integrity_reset_cause cause); +}; + +struct five_hook_heads { + struct list_head file_processed; + struct list_head file_skipped; + struct list_head file_signed; + struct list_head task_forked; + struct list_head integrity_reset; + struct list_head integrity_reset2; +}; + +/* + * FIVE module hook list structure. + * For use with generic list macros for common operations. + */ +struct five_hook_list { + struct list_head list; + struct list_head *head; + union five_list_options hook; +}; + +/* + * Initializing a five_hook_list structure takes + * up a lot of space in a source file. This macro takes + * care of the common case and reduces the amount of + * text involved. + */ +#define FIVE_HOOK_INIT(HEAD, HOOK) \ + { .head = &five_hook_heads.HEAD, .hook = { .HEAD = HOOK } } + +extern struct five_hook_heads five_hook_heads; + +static inline void five_add_hooks(struct five_hook_list *hooks, + int count) +{ + int i; + + for (i = 0; i < count; i++) + list_add_tail_rcu(&hooks[i].list, hooks[i].head); +} + +int five_hook_wq_init(void); + +#endif /* _FIVE_HOOKS_H */ diff --git a/security/samsung/five/gki/five_iint.c b/security/samsung/five/gki/five_iint.c new file mode 100644 index 000000000..36e6c0824 --- /dev/null +++ b/security/samsung/five/gki/five_iint.c @@ -0,0 +1,258 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2008 IBM Corporation + * + * Authors: + * Mimi Zohar + * + * File: integrity_iint.c + * - implements the integrity hooks: integrity_inode_alloc, + * integrity_inode_free + * - cache integrity information associated with an inode + * using a rbtree tree. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_FIVE +#include +#endif +#include "integrity.h" + +static struct rb_root integrity_iint_tree = RB_ROOT; +static DEFINE_RWLOCK(integrity_iint_lock); +static struct kmem_cache *iint_cache __read_mostly; + +struct dentry *integrity_dir; + +/* + * __integrity_iint_find - return the iint associated with an inode + */ +static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode) +{ + struct integrity_iint_cache *iint; + struct rb_node *n = integrity_iint_tree.rb_node; + + while (n) { + iint = rb_entry(n, struct integrity_iint_cache, rb_node); + + if (inode < iint->inode) + n = n->rb_left; + else if (inode > iint->inode) + n = n->rb_right; + else + break; + } + if (!n) + return NULL; + + return iint; +} + +/* + * integrity_iint_find - return the iint associated with an inode + */ +struct integrity_iint_cache *integrity_iint_find(struct inode *inode) +{ + struct integrity_iint_cache *iint; + + if (!IS_IMA(inode)) + return NULL; + + read_lock(&integrity_iint_lock); + iint = __integrity_iint_find(inode); + read_unlock(&integrity_iint_lock); + + return iint; +} + +static void iint_free(struct integrity_iint_cache *iint) +{ +#ifdef CONFIG_FIVE + kfree(iint->five_label); + iint->five_label = NULL; + iint->five_flags = 0UL; + iint->five_status = FIVE_FILE_UNKNOWN; + iint->five_signing = false; +#endif + kfree(iint->ima_hash); + iint->ima_hash = NULL; + iint->version = 0; + iint->flags = 0UL; + iint->atomic_flags = 0UL; + iint->ima_file_status = INTEGRITY_UNKNOWN; + iint->ima_mmap_status = INTEGRITY_UNKNOWN; + iint->ima_bprm_status = INTEGRITY_UNKNOWN; + iint->ima_read_status = INTEGRITY_UNKNOWN; + iint->ima_creds_status = INTEGRITY_UNKNOWN; + iint->evm_status = INTEGRITY_UNKNOWN; + iint->measured_pcrs = 0; + kmem_cache_free(iint_cache, iint); +} + +/** + * integrity_inode_get - find or allocate an iint associated with an inode + * @inode: pointer to the inode + * @return: allocated iint + * + * Caller must lock i_mutex + */ +struct integrity_iint_cache *integrity_inode_get(struct inode *inode) +{ + struct rb_node **p; + struct rb_node *node, *parent = NULL; + struct integrity_iint_cache *iint, *test_iint; + + iint = integrity_iint_find(inode); + if (iint) + return iint; + + iint = kmem_cache_alloc(iint_cache, GFP_NOFS); + if (!iint) + return NULL; + + write_lock(&integrity_iint_lock); + + p = &integrity_iint_tree.rb_node; + while (*p) { + parent = *p; + test_iint = rb_entry(parent, struct integrity_iint_cache, + rb_node); + if (inode < test_iint->inode) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + iint->inode = inode; + node = &iint->rb_node; + inode->i_flags |= S_IMA; + rb_link_node(node, parent, p); + rb_insert_color(node, &integrity_iint_tree); + + write_unlock(&integrity_iint_lock); + return iint; +} + +/** + * integrity_inode_free - called on security_inode_free + * @inode: pointer to the inode + * + * Free the integrity information(iint) associated with an inode. + */ +void integrity_inode_free(struct inode *inode) +{ + struct integrity_iint_cache *iint; + + if (!IS_IMA(inode)) + return; + + write_lock(&integrity_iint_lock); + iint = __integrity_iint_find(inode); + rb_erase(&iint->rb_node, &integrity_iint_tree); + write_unlock(&integrity_iint_lock); + + iint_free(iint); +} + +static void init_once(void *foo) +{ + struct integrity_iint_cache *iint = foo; + + memset(iint, 0, sizeof(*iint)); +#ifdef CONFIG_FIVE + iint->five_flags = 0UL; + iint->five_status = FIVE_FILE_UNKNOWN; + iint->five_signing = false; +#endif + iint->ima_file_status = INTEGRITY_UNKNOWN; + iint->ima_mmap_status = INTEGRITY_UNKNOWN; + iint->ima_bprm_status = INTEGRITY_UNKNOWN; + iint->ima_read_status = INTEGRITY_UNKNOWN; + iint->ima_creds_status = INTEGRITY_UNKNOWN; + iint->evm_status = INTEGRITY_UNKNOWN; + mutex_init(&iint->mutex); +} + +static int __init integrity_iintcache_init(void) +{ + iint_cache = + kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache), + 0, SLAB_PANIC, init_once); + return 0; +} + +DEFINE_LSM(integrity) = { + .name = "integrity", + .init = integrity_iintcache_init, +}; + +/* + * integrity_kernel_read - read data from the file + * + * This is a function for reading file content instead of kernel_read(). + * It does not perform locking checks to ensure it cannot be blocked. + * It does not perform security checks because it is irrelevant for IMA. + * + */ +int integrity_kernel_read(struct file *file, loff_t offset, + void *addr, unsigned long count) +{ + mm_segment_t old_fs; + char __user *buf = (char __user *)addr; + ssize_t ret; +#ifdef CONFIG_FIVE + struct inode *inode = file_inode(file); +#endif + + if (!(file->f_mode & FMODE_READ)) + return -EBADF; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + +#ifdef CONFIG_FIVE + if (inode->i_sb->s_magic == OVERLAYFS_SUPER_MAGIC && file->private_data) + file = (struct file *)file->private_data; +#endif + + ret = __vfs_read(file, buf, count, &offset); + set_fs(old_fs); + + return ret; +} + +/* + * integrity_load_keys - load integrity keys hook + * + * Hooks is called from init/main.c:kernel_init_freeable() + * when rootfs is ready + */ +void __init integrity_load_keys(void) +{ + ima_load_x509(); + evm_load_x509(); +} + +static int __init integrity_fs_init(void) +{ + integrity_dir = securityfs_create_dir("integrity", NULL); + if (IS_ERR(integrity_dir)) { + int ret = PTR_ERR(integrity_dir); + + if (ret != -ENODEV) + pr_err("Unable to create integrity sysfs dir: %d\n", + ret); + integrity_dir = NULL; + return ret; + } + + return 0; +} + +late_initcall(integrity_fs_init) diff --git a/security/samsung/five/gki/five_iint.h b/security/samsung/five/gki/five_iint.h new file mode 100644 index 000000000..03413eca1 --- /dev/null +++ b/security/samsung/five/gki/five_iint.h @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2009-2010 IBM Corporation + * + * Authors: + * Mimi Zohar + */ + +#include +#include +#include +#include +#include + +struct integrity_label; + +enum five_file_integrity { + FIVE_FILE_UNKNOWN, + FIVE_FILE_FAIL, + FIVE_FILE_RSA, + FIVE_FILE_DMVERITY, + FIVE_FILE_FSVERITY, + FIVE_FILE_HMAC +}; + +/* iint action cache flags */ +#define IMA_MEASURE 0x00000001 +#define IMA_MEASURED 0x00000002 +#define IMA_APPRAISE 0x00000004 +#define IMA_APPRAISED 0x00000008 +/*#define IMA_COLLECT 0x00000010 do not use this flag */ +#define IMA_COLLECTED 0x00000020 +#define IMA_AUDIT 0x00000040 +#define IMA_AUDITED 0x00000080 +#define IMA_HASH 0x00000100 +#define IMA_HASHED 0x00000200 + +/* iint cache flags */ +#define IMA_ACTION_FLAGS 0xff000000 +#define IMA_DIGSIG_REQUIRED 0x01000000 +#define IMA_PERMIT_DIRECTIO 0x02000000 +#define IMA_NEW_FILE 0x04000000 +#define EVM_IMMUTABLE_DIGSIG 0x08000000 +#define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000 +#define IMA_MODSIG_ALLOWED 0x20000000 + +#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ + IMA_HASH | IMA_APPRAISE_SUBMASK) +#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED | \ + IMA_HASHED | IMA_COLLECTED | \ + IMA_APPRAISED_SUBMASK) + +/* iint subaction appraise cache flags */ +#define IMA_FILE_APPRAISE 0x00001000 +#define IMA_FILE_APPRAISED 0x00002000 +#define IMA_MMAP_APPRAISE 0x00004000 +#define IMA_MMAP_APPRAISED 0x00008000 +#define IMA_BPRM_APPRAISE 0x00010000 +#define IMA_BPRM_APPRAISED 0x00020000 +#define IMA_READ_APPRAISE 0x00040000 +#define IMA_READ_APPRAISED 0x00080000 +#define IMA_CREDS_APPRAISE 0x00100000 +#define IMA_CREDS_APPRAISED 0x00200000 + +#define FIVE_DMVERITY_PROTECTED 0x00040000 +#define FIVE_TRUSTED_FILE 0x00080000 + +#define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ + IMA_BPRM_APPRAISE | IMA_READ_APPRAISE | \ + IMA_CREDS_APPRAISE) +#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ + IMA_BPRM_APPRAISED | IMA_READ_APPRAISED | \ + IMA_CREDS_APPRAISED) + +/* iint cache atomic_flags */ +#define IMA_CHANGE_XATTR 0 +#define IMA_UPDATE_XATTR 1 +#define IMA_CHANGE_ATTR 2 +#define IMA_DIGSIG 3 +#define IMA_MUST_MEASURE 4 + +enum evm_ima_xattr_type { + IMA_XATTR_DIGEST = 0x01, + EVM_XATTR_HMAC, + EVM_IMA_XATTR_DIGSIG, + IMA_XATTR_DIGEST_NG, + EVM_XATTR_PORTABLE_DIGSIG, + IMA_XATTR_LAST +}; + +struct evm_ima_xattr_data { + u8 type; + u8 data[]; +} __packed; + +/* Only used in the EVM HMAC code. */ +struct evm_xattr { + struct evm_ima_xattr_data data; + u8 digest[SHA1_DIGEST_SIZE]; +} __packed; + +#define IMA_MAX_DIGEST_SIZE 64 + +struct ima_digest_data { + u8 algo; + u8 length; + union { + struct { + u8 unused; + u8 type; + } sha1; + struct { + u8 type; + u8 algo; + } ng; + u8 data[2]; + } xattr; + u8 digest[0]; +} __packed; + +/* + * signature format v2 - for using with asymmetric keys + */ +struct signature_v2_hdr { + uint8_t type; /* xattr type */ + uint8_t version; /* signature format version */ + uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */ + __be32 keyid; /* IMA key identifier - not X509/PGP specific */ + __be16 sig_size; /* signature size */ + uint8_t sig[0]; /* signature payload */ +} __packed; + +/* integrity data associated with an inode */ +struct integrity_iint_cache { + struct rb_node rb_node; /* rooted in integrity_iint_tree */ + struct mutex mutex; /* protects: version, flags, digest */ + struct inode *inode; /* back pointer to inode in question */ + u64 version; /* track inode changes */ + unsigned long flags; + unsigned long measured_pcrs; + unsigned long atomic_flags; + enum integrity_status ima_file_status:4; + enum integrity_status ima_mmap_status:4; + enum integrity_status ima_bprm_status:4; + enum integrity_status ima_read_status:4; + enum integrity_status ima_creds_status:4; + enum integrity_status evm_status:4; + struct ima_digest_data *ima_hash; +#ifdef CONFIG_FIVE + unsigned long five_flags; + enum five_file_integrity five_status; + struct integrity_label *five_label; + bool five_signing; +#endif +}; + +/* rbtree tree calls to lookup, insert, delete + * integrity data associated with an inode. + */ +struct integrity_iint_cache *integrity_iint_find(struct inode *inode); + +int integrity_kernel_read(struct file *file, loff_t offset, + void *addr, unsigned long count); + +#define INTEGRITY_KEYRING_EVM 0 +#define INTEGRITY_KEYRING_IMA 1 +#define INTEGRITY_KEYRING_PLATFORM 2 +#define INTEGRITY_KEYRING_MAX 3 + +extern struct dentry *integrity_dir; + +struct modsig; + +#ifdef CONFIG_INTEGRITY_SIGNATURE + +int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, + const char *digest, int digestlen); +int integrity_modsig_verify(unsigned int id, const struct modsig *modsig); + +int __init integrity_init_keyring(const unsigned int id); +int __init integrity_load_x509(const unsigned int id, const char *path); +int __init integrity_load_cert(const unsigned int id, const char *source, + const void *data, size_t len, key_perm_t perm); +#else + +static inline int integrity_digsig_verify(const unsigned int id, + const char *sig, int siglen, + const char *digest, int digestlen) +{ + return -EOPNOTSUPP; +} + +static inline int integrity_modsig_verify(unsigned int id, + const struct modsig *modsig) +{ + return -EOPNOTSUPP; +} + +static inline int integrity_init_keyring(const unsigned int id) +{ + return 0; +} + +static inline int __init integrity_load_cert(const unsigned int id, + const char *source, + const void *data, size_t len, + key_perm_t perm) +{ + return 0; +} +#endif /* CONFIG_INTEGRITY_SIGNATURE */ + +#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS +int asymmetric_verify(struct key *keyring, const char *sig, + int siglen, const char *data, int datalen); +#else +static inline int asymmetric_verify(struct key *keyring, const char *sig, + int siglen, const char *data, int datalen) +{ + return -EOPNOTSUPP; +} +#endif + +#ifdef CONFIG_IMA_APPRAISE_MODSIG +int ima_modsig_verify(struct key *keyring, const struct modsig *modsig); +#else +static inline int ima_modsig_verify(struct key *keyring, + const struct modsig *modsig) +{ + return -EOPNOTSUPP; +} +#endif + +#ifdef CONFIG_IMA_LOAD_X509 +void __init ima_load_x509(void); +#else +static inline void ima_load_x509(void) +{ +} +#endif + +#ifdef CONFIG_EVM_LOAD_X509 +void __init evm_load_x509(void); +#else +static inline void evm_load_x509(void) +{ +} +#endif + +#ifdef CONFIG_INTEGRITY_AUDIT +/* declarations */ +void integrity_audit_msg(int audit_msgno, struct inode *inode, + const unsigned char *fname, const char *op, + const char *cause, int result, int info); + +static inline struct audit_buffer * +integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) +{ + return audit_log_start(ctx, gfp_mask, type); +} + +#else +static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, + const unsigned char *fname, + const char *op, const char *cause, + int result, int info) +{ +} + +static inline struct audit_buffer * +integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) +{ + return NULL; +} + +#endif + +#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING +void __init add_to_platform_keyring(const char *source, const void *data, + size_t len); +#else +static inline void __init add_to_platform_keyring(const char *source, + const void *data, size_t len) +{ +} +#endif diff --git a/security/samsung/five/gki/five_init.c b/security/samsung/five/gki/five_init.c new file mode 100644 index 000000000..0c6598226 --- /dev/null +++ b/security/samsung/five/gki/five_init.c @@ -0,0 +1,45 @@ +/* + * This code is based on IMA's code + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * + * Egor Uleyskiy, + * Viacheslav Vovchenko + * Yevgen Kopylov + * + * 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. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include "five.h" + +int __init five_init(void) +{ + int rc; + + rc = five_keyring_init(); + if (rc) + return rc; + rc = five_load_built_x509(); + if (rc) + return rc; + rc = five_task_integrity_cache_init(); + if (rc) + return rc; + rc = five_init_crypto(); + + return rc; +} diff --git a/security/samsung/five/gki/five_main.c b/security/samsung/five/gki/five_main.c new file mode 100644 index 000000000..e401a3045 --- /dev/null +++ b/security/samsung/five/gki/five_main.c @@ -0,0 +1,1139 @@ +/* + * This code is based on IMA's code + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * + * Egor Uleyskiy, + * Viacheslav Vovchenko + * Yevgen Kopylov + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "five.h" +#include "five_audit.h" +#include "five_hooks.h" +#include "five_state.h" +#include "five_pa.h" +#include "five_porting.h" +#include "five_cache.h" +#include "five_dmverity.h" +#include "five_dsms.h" +#include "five_tint_dev.h" + +static const bool unlink_on_error; // false + +static const bool check_dex2oat_binary = true; +static const bool check_memfd_file = true; + +static struct file *memfd_file __ro_after_init; + +static struct workqueue_struct *g_five_workqueue; + +static inline void task_integrity_processing(struct task_integrity *tint); +static inline void task_integrity_done(struct task_integrity *tint); +static void process_measurement(const struct processing_event_list *params); +static inline struct processing_event_list *five_event_create( + enum five_event event, struct task_struct *task, + struct file *file, int function, gfp_t flags); +static inline void five_event_destroy( + const struct processing_event_list *file); + +#ifdef CONFIG_FIVE_DEBUG +static int five_enabled = 1; + +static ssize_t five_enabled_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + char command; + + if (get_user(command, buf)) + return -EFAULT; + + switch (command) { + case '0': + five_enabled = 0; + break; + case '1': + five_enabled = 1; + break; + default: + pr_err("FIVE: %s: unknown cmd: %hhx\n", __func__, command); + return -EINVAL; + } + + pr_info("FIVE debug: FIVE %s\n", five_enabled ? "enabled" : "disabled"); + return count; +} + +static ssize_t five_enabled_read(struct file *file, char __user *user_buf, + size_t count, loff_t *pos) +{ + char buf[2]; + + buf[0] = five_enabled ? '1' : '0'; + buf[1] = '\n'; + + return simple_read_from_buffer(user_buf, count, pos, buf, sizeof(buf)); +} + +static const struct file_operations five_enabled_fops = { + .owner = THIS_MODULE, + .read = five_enabled_read, + .write = five_enabled_write +}; + +static int __init init_fs(void) +{ + struct dentry *debug_file = NULL; + umode_t umode = (S_IRUGO | S_IWUSR | S_IWGRP); + + debug_file = debugfs_create_file( + "five_enabled", umode, NULL, NULL, &five_enabled_fops); + if (IS_ERR_OR_NULL(debug_file)) + goto error; + + return 0; +error: + if (debug_file) + return -PTR_ERR(debug_file); + + return -EEXIST; +} + +static inline int is_five_enabled(void) +{ + return five_enabled; +} + +int five_fcntl_debug(struct file *file, void __user *argp) +{ + struct inode *inode; + struct five_stat stat = {0}; + struct integrity_iint_cache *iint; + + if (unlikely(!file || !argp)) + return -EINVAL; + + inode = file_inode(file); + + inode_lock(inode); + iint = integrity_inode_get(inode); + if (unlikely(!iint)) { + inode_unlock(inode); + return -ENOMEM; + } + + stat.cache_status = five_get_cache_status(iint); + stat.cache_iversion = inode_query_iversion(iint->inode); + stat.inode_iversion = inode_query_iversion(inode); + + inode_unlock(inode); + + if (unlikely(copy_to_user(argp, &stat, sizeof(stat)))) + return -EFAULT; + + return 0; +} +#else +static int __init init_fs(void) +{ + return 0; +} + +static inline int is_five_enabled(void) +{ + return 1; +} +#endif + +static void work_handler(struct work_struct *in_data) +{ + struct worker_context *context = container_of(in_data, + struct worker_context, data_work); + struct task_integrity *intg; + + if (unlikely(!context)) + return; + + intg = context->tint; + + spin_lock(&intg->list_lock); + while (!list_empty(&(intg->events.list))) { + struct processing_event_list *five_file; + + five_file = list_entry(intg->events.list.next, + struct processing_event_list, list); + spin_unlock(&intg->list_lock); + switch (five_file->event) { + case FIVE_VERIFY_BUNCH_FILES: { + process_measurement(five_file); + break; + } + case FIVE_RESET_INTEGRITY: { + task_integrity_reset(intg); + five_hook_integrity_reset(five_file->task, + NULL, CAUSE_UNKNOWN); + break; + } + default: + break; + } + spin_lock(&intg->list_lock); + list_del(&five_file->list); + five_event_destroy(five_file); + } + + task_integrity_done(intg); + spin_unlock(&intg->list_lock); + task_integrity_put(intg); + + kfree(context); +} + +static void fix_dpath(const struct path *path, char *pathbuf, char *pathname) +{ + /* `d_path' appends " (deleted)" string if a file is unlinked. Below + * code removes it. + * `d_path' fills the buffer from the end of it therefore we can easily + * calculate the length of the pathname. + */ + const long pathname_size = pathbuf + PATH_MAX - pathname; + const char str_deleted[] = " (deleted)"; + const int deleted_size = sizeof(str_deleted); + + if (pathname_size > deleted_size && d_unlinked(path->dentry)) { + char *start_deleted = pathbuf + PATH_MAX - deleted_size; + + if (!strncmp(str_deleted, start_deleted, deleted_size)) + *start_deleted = '\0'; + } +} + +const char *five_d_path(const struct path *path, char **pathbuf, char *namebuf) +{ + char *pathname = NULL; + + *pathbuf = __getname(); + if (*pathbuf) { + pathname = d_path(path, *pathbuf, PATH_MAX); + if (IS_ERR(pathname)) { + __putname(*pathbuf); + *pathbuf = NULL; + pathname = NULL; + } + fix_dpath(path, *pathbuf, pathname); + } + + if (!pathname) { + strlcpy(namebuf, path->dentry->d_name.name, NAME_MAX); + pathname = namebuf; + } + + return pathname; +} + +int five_check_params(struct task_struct *task, struct file *file) +{ + struct inode *inode; + + if (unlikely(!file)) + return 1; + + inode = file_inode(file); + if (!S_ISREG(inode->i_mode)) + return 1; + + return 0; +} + +/* cut a list into two + * @cur_list: a list with entries + * @new_list: a new list to add all removed entries. Should be an empty list + * + * Use it under spin_lock + * + * The function moves second entry and following entries to new list. + * First entry is left in cur_list. + * + * Initial state: + * [cur_list]<=>[first]<=>[second]<=>[third]<=>...<=>[last] [new_list] + * ^=================================================^ ^====^ + * Result: + * [cur_list]<=>[first] + * ^==========^ + * [new_list]<=>[second]<=>[third]<=>...<=>[last] + * ^=====================================^ + * + * the function is similar to kernel list_cut_position, but there are few + * differences: + * - cut position is second entry + * - original list is left with only first entry + * - moving entries are from second entry to last entry + */ +static void list_cut_tail(struct list_head *cur_list, + struct list_head *new_list) +{ + if ((!list_empty(cur_list)) && + (!list_is_singular(cur_list))) { + new_list->next = cur_list->next->next; + cur_list->next->next->prev = new_list; + cur_list->next->next = cur_list; + new_list->prev = cur_list->prev; + cur_list->prev->next = new_list; + cur_list->prev = cur_list->next; + } +} + +static void free_files_list(struct list_head *list) +{ + struct list_head *tmp, *list_entry; + struct processing_event_list *file_entry; + + list_for_each_safe(list_entry, tmp, list) { + file_entry = list_entry(list_entry, + struct processing_event_list, list); + list_del(&file_entry->list); + five_event_destroy(file_entry); + } +} + +static int push_file_event_bunch(struct task_struct *task, struct file *file, + int function) +{ + int rc = 0; + struct worker_context *context; + struct processing_event_list *five_file; + + if (unlikely(!is_five_enabled()) || five_check_params(task, file)) + return 0; + + context = kmalloc(sizeof(struct worker_context), GFP_KERNEL); + if (unlikely(!context)) + return -ENOMEM; + + five_file = five_event_create(FIVE_VERIFY_BUNCH_FILES, task, file, + function, GFP_KERNEL); + if (unlikely(!five_file)) { + kfree(context); + return -ENOMEM; + } + + spin_lock(&TASK_INTEGRITY(task)->list_lock); + + if (list_empty(&(TASK_INTEGRITY(task)->events.list))) { + task_integrity_get(TASK_INTEGRITY(task)); + task_integrity_processing(TASK_INTEGRITY(task)); + + context->tint = TASK_INTEGRITY(task); + + list_add_tail(&five_file->list, &TASK_INTEGRITY(task)->events.list); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); + INIT_WORK(&context->data_work, work_handler); + rc = queue_work(g_five_workqueue, &context->data_work) ? 0 : 1; + } else { + struct list_head dead_list; + + INIT_LIST_HEAD(&dead_list); + if ((function == BPRM_CHECK) && + (!list_is_singular(&(TASK_INTEGRITY(task)->events.list)))) { + list_cut_tail(&TASK_INTEGRITY(task)->events.list, + &dead_list); + } + list_add_tail(&five_file->list, &TASK_INTEGRITY(task)->events.list); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); + free_files_list(&dead_list); + kfree(context); + } + return rc; +} + +static int push_reset_event(struct task_struct *task, + enum task_integrity_reset_cause cause, struct file *file) +{ + struct list_head dead_list; + struct task_integrity *current_tint; + struct processing_event_list *five_reset; + + if (unlikely(!is_five_enabled())) + return 0; + + INIT_LIST_HEAD(&dead_list); + current_tint = TASK_INTEGRITY(task); + task_integrity_get(current_tint); + + task_integrity_set_reset_reason(current_tint, cause, file); + + five_reset = five_event_create(FIVE_RESET_INTEGRITY, task, NULL, 0, + GFP_KERNEL); + if (unlikely(!five_reset)) { + task_integrity_reset_both(current_tint); + five_hook_integrity_reset(task, file, cause); + task_integrity_put(current_tint); + return -ENOMEM; + } + + task_integrity_reset_both(current_tint); + five_hook_integrity_reset(task, file, cause); + spin_lock(¤t_tint->list_lock); + if (!list_empty(¤t_tint->events.list)) { + list_cut_tail(¤t_tint->events.list, &dead_list); + five_reset->event = FIVE_RESET_INTEGRITY; + list_add_tail(&five_reset->list, ¤t_tint->events.list); + spin_unlock(¤t_tint->list_lock); + } else { + spin_unlock(¤t_tint->list_lock); + five_event_destroy(five_reset); + } + + task_integrity_put(current_tint); + /* remove dead_list */ + free_files_list(&dead_list); + return 0; +} + +void task_integrity_delayed_reset(struct task_struct *task, + enum task_integrity_reset_cause cause, struct file *file) +{ + push_reset_event(task, cause, file); +} + +static void five_check_last_writer(struct integrity_iint_cache *iint, + struct inode *inode, struct file *file) +{ + fmode_t mode = file->f_mode; + + if (!(mode & FMODE_WRITE)) + return; + + inode_lock(inode); + if (atomic_read(&inode->i_writecount) == 1) { + if (!inode_eq_iversion(inode, iint->version)) + five_set_cache_status(iint, FIVE_FILE_UNKNOWN); + } + iint->five_signing = false; + inode_unlock(inode); +} + +/** + * five_file_free - called on __fput() + * @file: pointer to file structure being freed + * + * Flag files that changed, based on i_version + */ +void five_file_free(struct file *file) +{ + struct inode *inode = file_inode(file); + struct integrity_iint_cache *iint; + + if (!S_ISREG(inode->i_mode)) + return; + + fivepa_fsignature_free(file); + + iint = integrity_iint_find(inode); + if (!iint) + return; + + five_check_last_writer(iint, inode, file); +} + +void five_task_free(struct task_struct *task) +{ + task_integrity_put(TASK_INTEGRITY(task)); +} + +/* Returns string representation of input function */ +const char *five_get_string_fn(enum five_hooks fn) +{ + switch (fn) { + case FILE_CHECK: + return "file-check"; + case MMAP_CHECK: + return "mmap-check"; + case BPRM_CHECK: + return "bprm-check"; + case POST_SETATTR: + return "post-setattr"; + } + return "unknown-function"; +} + +static inline bool is_dex2oat_binary(const struct file *file) +{ + const char *pathname = NULL; + char *pathbuf = NULL; + const char * const dex2oat_full_path[] = { + /* R OS */ + "/apex/com.android.art/bin/dex2oat", + "/apex/com.android.art/bin/dex2oat32", + "/apex/com.android.art/bin/dex2oat64", + /* Q OS */ + "/apex/com.android.runtime/bin/dex2oat" + }; + char filename[NAME_MAX]; + bool res = false; + size_t i; + + if (!file || !file->f_path.dentry) + return false; + + if (strncmp(file->f_path.dentry->d_iname, "dex2oat", + sizeof("dex2oat")) && + strncmp(file->f_path.dentry->d_iname, "dex2oat32", + sizeof("dex2oat32")) && + strncmp(file->f_path.dentry->d_iname, "dex2oat64", + sizeof("dex2oat64"))) + return false; + + pathname = five_d_path(&file->f_path, &pathbuf, filename); + + for (i = 0; i < ARRAY_SIZE(dex2oat_full_path); ++i) { + if (!strncmp(pathname, dex2oat_full_path[i], + strlen(dex2oat_full_path[i]) + 1)) { + res = true; + break; + } + } + + if (pathbuf) + __putname(pathbuf); + + return res; +} + +static inline bool match_trusted_executable(const struct five_cert *cert, + const struct integrity_iint_cache *iint, + const struct file *file) +{ + const struct five_cert_header *hdr = NULL; + + if (!cert) + return check_dex2oat_binary && is_dex2oat_binary(file); + + if (five_get_cache_status(iint) != FIVE_FILE_RSA) + return false; + + hdr = (const struct five_cert_header *)cert->body.header->value; + + if (hdr->privilege == FIVE_PRIV_ALLOW_SIGN) + return true; + + return false; +} + +static inline void task_integrity_processing(struct task_integrity *tint) +{ + tint->user_value = INTEGRITY_PROCESSING; +} + +static inline void task_integrity_done(struct task_integrity *tint) +{ + tint->user_value = task_integrity_read(tint); +} + +static void process_file(struct task_struct *task, + struct file *file, + int function, + struct file_verification_result *result) +{ + struct inode *inode = d_real_inode(file_dentry(file)); + struct integrity_iint_cache *iint = NULL; + struct five_cert cert = { {0} }; + struct five_cert *pcert = NULL; + int rc = -ENOMEM; + char *xattr_value = NULL; + int xattr_len = 0; + + if (!S_ISREG(inode->i_mode)) { + rc = 0; + goto out; + } + + iint = integrity_inode_get(inode); + if (!iint) + goto out; + + /* Nothing to do, just return existing appraised status */ + if (five_get_cache_status(iint) != FIVE_FILE_UNKNOWN) { + rc = 0; + goto out; + } + + xattr_len = five_read_xattr(d_real_comp(file->f_path.dentry), + &xattr_value); + if (xattr_value && xattr_len) { + rc = five_cert_fillout(&cert, xattr_value, xattr_len); + if (rc) { + pr_err("FIVE: certificate is incorrect inode=%lu\n", + inode->i_ino); + goto out; + } + + pcert = &cert; + + if (file->f_flags & O_DIRECT) { + rc = -EACCES; + goto out; + } + } + + rc = five_appraise_measurement(task, function, iint, file, pcert); + if (!rc && match_trusted_executable(pcert, iint, file)) + iint->five_flags |= FIVE_TRUSTED_FILE; + +out: + if (rc && iint) + iint->five_flags &= ~FIVE_TRUSTED_FILE; + + result->file = file; + result->task = task; + result->iint = iint; + result->fn = function; + result->xattr = xattr_value; + result->xattr_len = (size_t)xattr_len; + + if (!iint || five_get_cache_status(iint) == FIVE_FILE_UNKNOWN + || five_get_cache_status(iint) == FIVE_FILE_FAIL) + result->five_result = 1; + else + result->five_result = 0; +} + +static void process_measurement(const struct processing_event_list *params) +{ + struct task_struct *task = params->task; + struct task_integrity *integrity = TASK_INTEGRITY(task); + struct file *file = params->file; + struct inode *inode = file_inode(file); + int function = params->function; + struct file_verification_result file_result; + + if (function != BPRM_CHECK) { + if (task_integrity_read(integrity) == INTEGRITY_NONE) + return; + } + + file_verification_result_init(&file_result); + inode_lock(inode); + + process_file(task, file, function, &file_result); + + five_hook_file_processed(task, file, + file_result.xattr, file_result.xattr_len, + file_result.five_result); + + five_state_proceed(integrity, &file_result); + + inode_unlock(inode); + file_verification_result_deinit(&file_result); +} + +#define MFD_NAME_PREFIX "memfd:" +#define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1) + +static bool is_memfd_file(struct file *file) +{ + struct inode *inode; + struct inode *memfd_inode; + + if (!file) + return false; + + memfd_inode = file_inode(memfd_file); + inode = file_inode(file); + if (inode && memfd_inode && inode->i_sb == memfd_inode->i_sb) + if (file->f_path.dentry && + !strncmp(file->f_path.dentry->d_iname, MFD_NAME_PREFIX, + MFD_NAME_PREFIX_LEN)) + return true; + + return false; +} + +/** + * five_file_mmap - measure files being mapped executable based on + * the process_measurement() policy decision. + * @file: pointer to the file to be measured (May be NULL) + * @prot: contains the protection that will be applied by the kernel. + * + * On success return 0. + */ +int five_file_mmap(struct file *file, unsigned long prot) +{ + int rc = 0; + struct task_struct *task = current; + struct task_integrity *tint = TASK_INTEGRITY(task); + + if (five_check_params(task, file)) + return 0; + + if (check_memfd_file && is_memfd_file(file)) + return 0; + + if (file && task_integrity_user_read(tint)) { + if (prot & PROT_EXEC) { + rc = push_file_event_bunch(task, file, MMAP_CHECK); + if (rc) + return rc; + } else { + five_hook_file_skipped(task, file); + } + } + + return rc; +} + +/** + * five_bprm_check - Measure executable being launched based on + * the process_measurement() policy decision. + * @bprm: contains the linux_binprm structure + * + * Notes: + * bprm_check could be called few times for one process when few binary loaders + * are used. Example: execution of shell script. + * In this case we should process first file (e.g. shell script) as main and + * use BPRM_CHECK. The second file (interpetator ) will be processed as general + * mapping (MMAP_CHECK). + * To implement this option variable bprm->recursion_depth is used. + * + * On success return 0. + */ +int five_bprm_check(struct linux_binprm *bprm) +{ + int rc = 0; + struct task_struct *task = current; + struct task_integrity *old_tint = TASK_INTEGRITY(task); + + if (unlikely(task->ptrace)) + return rc; + + if (bprm->recursion_depth > 0) { + rc = push_file_event_bunch(task, bprm->file, MMAP_CHECK); + } else { + struct task_integrity *tint = task_integrity_alloc(); + + task_integrity_assign(task, tint); + if (likely(TASK_INTEGRITY(task))) { + rc = push_file_event_bunch(task, + bprm->file, BPRM_CHECK); + } else { + rc = -ENOMEM; + } + task_integrity_put(old_tint); + } + + return rc; +} + +/* Does `unlink' of the `file'. + * This function breaks delegation (drops file's leases. See + * man 2 fcntl "Leases"). do_unlinkat function in fs/namei.c was used + * as an example. + */ +static int five_unlink(struct file *file) +{ + int rc; + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = d_backing_inode(dentry->d_parent); + struct inode *delegated_inode = NULL; + bool retry; + + do { + delegated_inode = NULL; + retry = false; + inode_lock_nested(inode, I_MUTEX_PARENT); + ihold(inode); + rc = vfs_unlink(inode, dentry, &delegated_inode); + inode_unlock(inode); + iput(inode); + if (rc == -EWOULDBLOCK && delegated_inode) { + rc = break_deleg_wait(&delegated_inode); + if (!rc) + retry = true; + } + } while (retry); + + five_audit_info(current, file, "five_unlink", 0, 0, + "Unlink a file", rc); + + return rc; +} + +/** + * This function handles two situations: + * 1. Device had been rebooted before five_sign finished. + * Then xattr_len will be zero and iint->five_signing will be false. + * 2. The file is being signing when another process tries to open it. + * Then xattr_len will be zero and iint->five_signing will be true. + * + * - five_fcntl_edit stores the xattr with zero length and set + * iint->five_signing to true + * - five_fcntl_sign stores correct certificates and set + * iint->five_signing to false + * + * On success returns 0 + */ +int five_file_open(struct file *file) +{ + ssize_t xattr_len; + struct inode *inode = file_inode(file); + + if (!S_ISREG(inode->i_mode)) + return 0; + + xattr_len = vfs_getxattr(file->f_path.dentry, XATTR_NAME_FIVE, + NULL, 0); + if (xattr_len == 0) { + struct integrity_iint_cache *iint; + bool is_signing = false; + + if (!unlink_on_error) { + five_audit_info(current, file, "five_unlink", 0, 0, + "Found a dummy-cert", 0); + return 0; + } + + inode_lock(inode); + iint = integrity_iint_find(inode); + if (iint) + is_signing = iint->five_signing; + inode_unlock(inode); + + if (!is_signing) { + int rc; + + rc = five_unlink(file); + rc = rc ?: -ENOENT; + + return rc; + } + return -EPERM; + } + + return 0; +} + +/** + * five_file_verify - force five integrity measurements for file + * the process_measurement() policy decision. This check affects + * task integrity. + * @file: pointer to the file to be measured (May be NULL) + * + * On success return 0. + */ +int five_file_verify(struct task_struct *task, struct file *file) +{ + int rc = 0; + struct task_integrity *tint = TASK_INTEGRITY(task); + + if (file && task_integrity_user_read(tint)) + rc = push_file_event_bunch(task, file, FILE_CHECK); + + return rc; +} + +static struct notifier_block five_reboot_nb = { + .notifier_call = five_reboot_notifier, + .priority = INT_MAX, +}; + +int five_hash_algo __ro_after_init = HASH_ALGO_SHA1; + +static int __init hash_setup(const char *str) +{ + int i; + + for (i = 0; i < HASH_ALGO__LAST; i++) { + if (strcmp(str, hash_algo_name[i]) == 0) { + five_hash_algo = i; + break; + } + } + + return 1; +} + +static int __init init_five(void) +{ + int error; + + g_five_workqueue = alloc_workqueue("%s", WQ_FREEZABLE | WQ_MEM_RECLAIM, + 0, "five_wq"); + if (!g_five_workqueue) + return -ENOMEM; + + hash_setup(CONFIG_FIVE_DEFAULT_HASH); + error = five_init(); + if (error) + return error; + + error = five_hook_wq_init(); + if (error) + return error; + + error = register_reboot_notifier(&five_reboot_nb); + if (error) + return error; + +/** + * This empty file is needed in is_memfd_file() function. + * The only way to check whether the file was created using memfd_create() + * syscall is to compare its superblock address with address of another memfd + * file. + * + * Below code is copied from shmem_kernel_file_setup(). The difference between + * shmem_file_setup() isshmem_kernel_file_setup() calls __shmem_file_setup() + * with S_PRIVATE flag but shmem_file_setup() calls it without one. After that + * __shmem_file_setup() sets S_PRIVATE flag in inode->i_flags: + inode->i_flags |= i_flags; + */ + memfd_file = shmem_file_setup( + "five_memfd_check", 0, VM_NORESERVE); + if (IS_ERR(memfd_file)) { + error = PTR_ERR(memfd_file); + memfd_file = NULL; + return error; + } + file_inode(memfd_file)->i_flags |= S_PRIVATE; + + error = init_fs(); + if (error) + return error; + + five_dsms_init("1", 0); + + error = five_init_dmverity(); + if (error) + return error; + + error = five_tint_init_dev(); + + return error; +} + +static int fcntl_verify(struct file *file) +{ + int rc = 0; + struct task_struct *task = current; + struct task_integrity *tint = TASK_INTEGRITY(task); + + if (task_integrity_user_read(tint)) + rc = push_file_event_bunch(task, file, FILE_CHECK); + return rc; +} + +/* Called from do_fcntl */ +int five_fcntl_verify_async(struct file *file) +{ + return fcntl_verify(file); +} + +/* Called from do_fcntl */ +int five_fcntl_verify_sync(struct file *file) +{ + return -EINVAL; +} + +int five_fork(struct task_struct *task, struct task_struct *child_task) +{ + int rc = 0; + + spin_lock(&TASK_INTEGRITY(task)->list_lock); + + if (!list_empty(&TASK_INTEGRITY(task)->events.list)) { + /*copy the list*/ + struct list_head *tmp; + struct processing_event_list *from_entry; + struct worker_context *context; + + context = kmalloc(sizeof(struct worker_context), GFP_ATOMIC); + if (unlikely(!context)) { + spin_unlock(&TASK_INTEGRITY(task)->list_lock); + return -ENOMEM; + } + + list_for_each(tmp, &TASK_INTEGRITY(task)->events.list) { + struct processing_event_list *five_file; + + from_entry = list_entry(tmp, + struct processing_event_list, list); + + five_file = five_event_create( + from_entry->event, + child_task, + from_entry->file, + from_entry->function, + GFP_ATOMIC); + if (unlikely(!five_file)) { + kfree(context); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); + return -ENOMEM; + } + + list_add_tail(&five_file->list, + &TASK_INTEGRITY(child_task)->events.list); + } + + context->tint = TASK_INTEGRITY(child_task); + + rc = task_integrity_copy(TASK_INTEGRITY(task), + TASK_INTEGRITY(child_task)); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); + task_integrity_get(context->tint); + task_integrity_processing(TASK_INTEGRITY(child_task)); + INIT_WORK(&context->data_work, work_handler); + rc = queue_work(g_five_workqueue, &context->data_work) ? 0 : 1; + } else { + rc = task_integrity_copy(TASK_INTEGRITY(task), + TASK_INTEGRITY(child_task)); + spin_unlock(&TASK_INTEGRITY(task)->list_lock); + } + + if (!rc) + five_hook_task_forked(task, child_task); + + return rc; +} + +int five_ptrace(struct task_struct *task, long request) +{ + switch (request) { + case PTRACE_TRACEME: + case PTRACE_ATTACH: + case PTRACE_SEIZE: + case PTRACE_INTERRUPT: + case PTRACE_CONT: + case PTRACE_DETACH: + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: + case PTRACE_PEEKUSR: + case PTRACE_GETREGSET: + case PTRACE_GETSIGINFO: + case PTRACE_PEEKSIGINFO: + case PTRACE_GETSIGMASK: + case PTRACE_GETEVENTMSG: +#ifdef CONFIG_ARM64 + case COMPAT_PTRACE_GETREGS: + case COMPAT_PTRACE_GET_THREAD_AREA: + case COMPAT_PTRACE_GETVFPREGS: + case COMPAT_PTRACE_GETHBPREGS: +#else + case PTRACE_GETREGS: + case PTRACE_GET_THREAD_AREA: + case PTRACE_GETVFPREGS: + case PTRACE_GETHBPREGS: +#endif + break; + default: { + struct task_integrity *tint = TASK_INTEGRITY(task); + + if (task_integrity_user_read(tint) == INTEGRITY_NONE) + break; + + task_integrity_delayed_reset(task, CAUSE_PTRACE, NULL); + five_audit_err(task, NULL, "ptrace", task_integrity_read(tint), + INTEGRITY_NONE, "reset-integrity", 0); + break; + } + } + + return 0; +} + +int five_process_vm_rw(struct task_struct *task, int write) +{ + if (write) { + struct task_integrity *tint = TASK_INTEGRITY(task); + + if (task_integrity_user_read(tint) == INTEGRITY_NONE) + goto exit; + + task_integrity_delayed_reset(task, CAUSE_VMRW, NULL); + five_audit_err(task, NULL, "process_vm_rw", + task_integrity_read(tint), INTEGRITY_NONE, + "reset-integrity", 0); + } + +exit: + return 0; +} + +static inline struct processing_event_list *five_event_create( + enum five_event event, struct task_struct *task, + struct file *file, int function, gfp_t flags) +{ + struct processing_event_list *five_file; + + five_file = kzalloc(sizeof(struct processing_event_list), flags); + if (unlikely(!five_file)) + return NULL; + + five_file->event = event; + + switch (five_file->event) { + case FIVE_VERIFY_BUNCH_FILES: { + get_task_struct(task); + get_file(file); + five_file->task = task; + five_file->file = file; + five_file->function = function; + break; + } + case FIVE_RESET_INTEGRITY: { + get_task_struct(task); + five_file->task = task; + break; + } + default: + break; + } + + return five_file; +} + +static inline void five_event_destroy( + const struct processing_event_list *file) +{ + switch (file->event) { + case FIVE_VERIFY_BUNCH_FILES: { + fput(file->file); + put_task_struct(file->task); + break; + } + case FIVE_RESET_INTEGRITY: { + put_task_struct(file->task); + break; + } + default: + break; + } + kfree(file); +} + +late_initcall(init_five); + +MODULE_DESCRIPTION("File-based process Integrity Verifier"); +MODULE_LICENSE("GPL"); diff --git a/security/samsung/five/gki/five_pa.c b/security/samsung/five/gki/five_pa.c new file mode 100644 index 000000000..56d27ca1c --- /dev/null +++ b/security/samsung/five/gki/five_pa.c @@ -0,0 +1,144 @@ +/* + * Process Authentificator helpers + * + * Copyright (C) 2017 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 +#include +#include +#include +#include + +#include "five.h" +#include "five_pa.h" +#include "five_hooks.h" +#include "five_lv.h" +#include "five_porting.h" + +#define F_SIGNATURE(file) ((void *)((file)->android_vendor_data1)) + +static inline void f_signature_assign(struct file *file, void *f_signature) +{ + file->android_vendor_data1 = (u64)f_signature; +} + +static void process_file(struct task_struct *task, struct file *file) +{ + char *xattr_value = NULL; + + if (F_SIGNATURE(file)) + return; + + if (five_check_params(task, file)) + return; + + five_read_xattr(d_real_comp(file->f_path.dentry), &xattr_value); + f_signature_assign(file, xattr_value); +} + +void fivepa_fsignature_free(struct file *file) +{ + kfree(F_SIGNATURE(file)); + f_signature_assign(file, NULL); +} + +int proca_fcntl_setxattr(struct file *file, void __user *lv_xattr) +{ + struct inode *inode = file_inode(file); + struct lv lv_hdr = {0}; + int rc = -EPERM; + void *x = NULL; + + if (unlikely(!file || !lv_xattr)) + return -EINVAL; + + if (unlikely(copy_from_user(&lv_hdr, lv_xattr, sizeof(lv_hdr)))) + return -EFAULT; + + if (unlikely(lv_hdr.length > PAGE_SIZE)) + return -EINVAL; + + x = kmalloc(lv_hdr.length, GFP_NOFS); + if (unlikely(!x)) + return -ENOMEM; + + if (unlikely(copy_from_user(x, lv_xattr + sizeof(lv_hdr), + lv_hdr.length))) { + rc = -EFAULT; + goto out; + } + + if (file->f_op && file->f_op->flush) + if (file->f_op->flush(file, current->files)) { + rc = -EOPNOTSUPP; + goto out; + } + + inode_lock(inode); + + if (task_integrity_allow_sign(TASK_INTEGRITY(current))) { + rc = __vfs_setxattr_noperm(d_real_comp(file->f_path.dentry), + XATTR_NAME_PA, + x, + lv_hdr.length, + 0); + } + inode_unlock(inode); + +out: + kfree(x); + + return rc; +} + +static void proca_hook_file_processed(struct task_struct *task, + enum task_integrity_value tint_value, + struct file *file, void *xattr, + size_t xattr_size, int result); + +static void proca_hook_file_skipped(struct task_struct *task, + enum task_integrity_value tint_value, + struct file *file); + +static struct five_hook_list five_ops[] = { + FIVE_HOOK_INIT(file_processed, proca_hook_file_processed), + FIVE_HOOK_INIT(file_skipped, proca_hook_file_skipped), +}; + +static void proca_hook_file_processed(struct task_struct *task, + enum task_integrity_value tint_value, + struct file *file, void *xattr, + size_t xattr_size, int result) +{ + process_file(task, file); +} + +static void proca_hook_file_skipped(struct task_struct *task, + enum task_integrity_value tint_value, + struct file *file) +{ + process_file(task, file); +} + +static __init int proca_module_init(void) +{ + five_add_hooks(five_ops, ARRAY_SIZE(five_ops)); + pr_info("PROCA was initialized\n"); + + return 0; +} +late_initcall(proca_module_init); + +MODULE_DESCRIPTION("PROCA module"); +MODULE_LICENSE("GPL"); diff --git a/security/samsung/five/gki/five_state.c b/security/samsung/five/gki/five_state.c new file mode 100644 index 000000000..a8c03ce46 --- /dev/null +++ b/security/samsung/five/gki/five_state.c @@ -0,0 +1,387 @@ +/* + * FIVE State machine + * + * Copyright (C) 2017 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 +#include "five_audit.h" +#include "five_state.h" +#include "five_hooks.h" +#include "five_cache.h" +#include "five_dsms.h" + +enum task_integrity_state_cause { + STATE_CAUSE_UNKNOWN, + STATE_CAUSE_DIGSIG, + STATE_CAUSE_DMV_PROTECTED, + STATE_CAUSE_TRUSTED, + STATE_CAUSE_HMAC, + STATE_CAUSE_SYSTEM_LABEL, + STATE_CAUSE_NOCERT, + STATE_CAUSE_TAMPERED, + STATE_CAUSE_MISMATCH_LABEL, + STATE_CAUSE_FSV_PROTECTED +}; + +struct task_verification_result { + enum task_integrity_value new_tint; + enum task_integrity_value prev_tint; + enum task_integrity_state_cause cause; +}; + +static const char *task_integrity_state_str( + enum task_integrity_state_cause cause) +{ + const char *str = "unknown"; + + switch (cause) { + case STATE_CAUSE_DIGSIG: + str = "digsig"; + break; + case STATE_CAUSE_DMV_PROTECTED: + str = "dmv_protected"; + break; + case STATE_CAUSE_FSV_PROTECTED: + str = "fsv_protected"; + break; + case STATE_CAUSE_TRUSTED: + str = "trusted"; + break; + case STATE_CAUSE_HMAC: + str = "hmac"; + break; + case STATE_CAUSE_SYSTEM_LABEL: + str = "system_label"; + break; + case STATE_CAUSE_NOCERT: + str = "nocert"; + break; + case STATE_CAUSE_MISMATCH_LABEL: + str = "mismatch_label"; + break; + case STATE_CAUSE_TAMPERED: + str = "tampered"; + break; + case STATE_CAUSE_UNKNOWN: + str = "unknown"; + break; + } + + return str; +} + +static enum task_integrity_reset_cause state_to_reason_cause( + enum task_integrity_state_cause cause) +{ + enum task_integrity_reset_cause reset_cause; + + switch (cause) { + case STATE_CAUSE_UNKNOWN: + reset_cause = CAUSE_UNKNOWN; + break; + case STATE_CAUSE_TAMPERED: + reset_cause = CAUSE_TAMPERED; + break; + case STATE_CAUSE_NOCERT: + reset_cause = CAUSE_NO_CERT; + break; + case STATE_CAUSE_MISMATCH_LABEL: + reset_cause = CAUSE_MISMATCH_LABEL; + break; + default: + /* Integrity is not NONE. */ + reset_cause = CAUSE_UNSET; + break; + } + + return reset_cause; +} + +static int is_system_label(struct integrity_label *label) +{ + if (label && label->len == 0) + return 1; /* system label */ + + return 0; +} + +static inline int integrity_label_cmp(struct integrity_label *l1, + struct integrity_label *l2) +{ + return 0; +} + +static int verify_or_update_label(struct task_integrity *intg, + struct integrity_iint_cache *iint) +{ + struct integrity_label *l; + struct integrity_label *file_label = iint->five_label; + int rc = 0; + + if (!file_label) /* digsig doesn't have label */ + return 0; + + if (is_system_label(file_label)) + return 0; + + spin_lock(&intg->value_lock); + l = intg->label; + + if (l) { + if (integrity_label_cmp(file_label, l)) { + rc = -EPERM; + goto out; + } + } else { + struct integrity_label *new_label; + + new_label = kmalloc(sizeof(file_label->len) + file_label->len, + GFP_ATOMIC); + if (!new_label) { + rc = -ENOMEM; + goto out; + } + + new_label->len = file_label->len; + memcpy(new_label->data, file_label->data, new_label->len); + intg->label = new_label; + } + +out: + spin_unlock(&intg->value_lock); + + return rc; +} + +static bool set_first_state(struct integrity_iint_cache *iint, + struct task_integrity *integrity, + struct task_verification_result *result) +{ + enum task_integrity_value tint = INTEGRITY_NONE; + enum five_file_integrity status = five_get_cache_status(iint); + bool trusted_file = iint->five_flags & FIVE_TRUSTED_FILE; + enum task_integrity_state_cause cause = STATE_CAUSE_UNKNOWN; + + result->new_tint = result->prev_tint = task_integrity_read(integrity); + task_integrity_clear(integrity); + + switch (status) { + case FIVE_FILE_RSA: + if (trusted_file) { + cause = STATE_CAUSE_TRUSTED; + tint = INTEGRITY_PRELOAD_ALLOW_SIGN; + } else { + cause = STATE_CAUSE_DIGSIG; + tint = INTEGRITY_PRELOAD; + } + break; + case FIVE_FILE_FSVERITY: + case FIVE_FILE_DMVERITY: + if (trusted_file) { + cause = STATE_CAUSE_TRUSTED; + tint = INTEGRITY_DMVERITY_ALLOW_SIGN; + } else { + cause = (status == FIVE_FILE_FSVERITY) + ? STATE_CAUSE_FSV_PROTECTED + : STATE_CAUSE_DMV_PROTECTED; + tint = INTEGRITY_DMVERITY; + } + break; + case FIVE_FILE_HMAC: + cause = STATE_CAUSE_HMAC; + tint = INTEGRITY_MIXED; + break; + case FIVE_FILE_FAIL: + cause = STATE_CAUSE_TAMPERED; + tint = INTEGRITY_NONE; + break; + case FIVE_FILE_UNKNOWN: + cause = STATE_CAUSE_NOCERT; + tint = INTEGRITY_NONE; + break; + default: + cause = STATE_CAUSE_NOCERT; + tint = INTEGRITY_NONE; + break; + } + + task_integrity_set(integrity, tint); + result->new_tint = tint; + result->cause = cause; + + return true; +} + +static bool set_next_state(struct integrity_iint_cache *iint, + struct task_integrity *integrity, + struct task_verification_result *result) +{ + bool is_newstate = false; + enum five_file_integrity status = five_get_cache_status(iint); + bool has_digsig = (status == FIVE_FILE_RSA); + bool dmv_protected = (status == FIVE_FILE_DMVERITY); + bool fsv_protected = (status == FIVE_FILE_FSVERITY); + bool xv_protected = dmv_protected || fsv_protected; + struct integrity_label *label = iint->five_label; + enum task_integrity_state_cause cause = STATE_CAUSE_UNKNOWN; + enum task_integrity_value state_tint = INTEGRITY_NONE; + + result->new_tint = result->prev_tint = task_integrity_read(integrity); + + if (has_digsig) + return is_newstate; + + if (status == FIVE_FILE_UNKNOWN || status == FIVE_FILE_FAIL) { + spin_lock(&integrity->value_lock); + + if (status == FIVE_FILE_UNKNOWN) + cause = STATE_CAUSE_NOCERT; + else + cause = STATE_CAUSE_TAMPERED; + + state_tint = INTEGRITY_NONE; + is_newstate = true; + goto out; + } + + if (verify_or_update_label(integrity, iint)) { + spin_lock(&integrity->value_lock); + cause = STATE_CAUSE_MISMATCH_LABEL; + state_tint = INTEGRITY_NONE; + is_newstate = true; + goto out; + } + + spin_lock(&integrity->value_lock); + switch (integrity->value) { + case INTEGRITY_PRELOAD_ALLOW_SIGN: + if (xv_protected) { + cause = fsv_protected ? STATE_CAUSE_FSV_PROTECTED + : STATE_CAUSE_DMV_PROTECTED; + state_tint = INTEGRITY_DMVERITY_ALLOW_SIGN; + } else if (is_system_label(label)) { + cause = STATE_CAUSE_SYSTEM_LABEL; + state_tint = INTEGRITY_MIXED_ALLOW_SIGN; + } else { + cause = STATE_CAUSE_HMAC; + state_tint = INTEGRITY_MIXED; + } + is_newstate = true; + break; + case INTEGRITY_PRELOAD: + if (xv_protected) { + cause = fsv_protected ? STATE_CAUSE_FSV_PROTECTED + : STATE_CAUSE_DMV_PROTECTED; + state_tint = INTEGRITY_DMVERITY; + } else { + cause = STATE_CAUSE_HMAC; + state_tint = INTEGRITY_MIXED; + } + is_newstate = true; + break; + case INTEGRITY_MIXED_ALLOW_SIGN: + if (!xv_protected && !is_system_label(label)) { + cause = STATE_CAUSE_HMAC; + state_tint = INTEGRITY_MIXED; + is_newstate = true; + } + break; + case INTEGRITY_DMVERITY: + if (!xv_protected) { + cause = STATE_CAUSE_HMAC; + state_tint = INTEGRITY_MIXED; + is_newstate = true; + } + break; + case INTEGRITY_DMVERITY_ALLOW_SIGN: + if (!xv_protected) { + if (is_system_label(label)) { + cause = STATE_CAUSE_SYSTEM_LABEL; + state_tint = INTEGRITY_MIXED_ALLOW_SIGN; + } else { + cause = STATE_CAUSE_HMAC; + state_tint = INTEGRITY_MIXED; + } + is_newstate = true; + } + break; + case INTEGRITY_MIXED: + break; + case INTEGRITY_NONE: + break; + default: + // Unknown state + cause = STATE_CAUSE_UNKNOWN; + state_tint = INTEGRITY_NONE; + is_newstate = true; + } + +out: + + if (is_newstate) { + __task_integrity_set(integrity, state_tint); + result->new_tint = state_tint; + result->cause = cause; + } + spin_unlock(&integrity->value_lock); + + return is_newstate; +} + +void five_state_proceed(struct task_integrity *integrity, + struct file_verification_result *file_result) +{ + struct integrity_iint_cache *iint = file_result->iint; + enum five_hooks fn = file_result->fn; + struct task_struct *task = file_result->task; + struct file *file = file_result->file; + bool is_newstate; + struct task_verification_result task_result = {}; + + if (!iint) + return; + + if (fn == BPRM_CHECK) + is_newstate = set_first_state(iint, integrity, &task_result); + else + is_newstate = set_next_state(iint, integrity, &task_result); + + if (is_newstate) { + if (task_result.new_tint == INTEGRITY_NONE) { + task_integrity_set_reset_reason(integrity, + state_to_reason_cause(task_result.cause), file); + five_hook_integrity_reset(task, file, + state_to_reason_cause(task_result.cause)); + + if (fn != BPRM_CHECK) { + char comm[TASK_COMM_LEN]; + char filename[NAME_MAX]; + char *pathbuf = NULL; + + five_dsms_reset_integrity( + get_task_comm(comm, task), + task_result.cause, + five_d_path(&file->f_path, &pathbuf, + filename)); + if (pathbuf) + __putname(pathbuf); + } + } + five_audit_verbose(task, file, five_get_string_fn(fn), + task_result.prev_tint, task_result.new_tint, + task_integrity_state_str(task_result.cause), + file_result->five_result); + } +} + diff --git a/security/samsung/five/gki/five_tee_interface.c b/security/samsung/five/gki/five_tee_interface.c new file mode 100644 index 000000000..e7291c06e --- /dev/null +++ b/security/samsung/five/gki/five_tee_interface.c @@ -0,0 +1,116 @@ +/* + * Interface for TEE Driver + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 +#include +#include +#include "five_tee_interface.h" +#include "five_tee_api.h" + +static struct five_tee_driver_fns *g_tee_driver_fn; +static char is_registered; +static DECLARE_RWSEM(usage_lock); + +int register_five_tee_driver( + struct five_tee_driver_fns *tee_driver_fns) +{ + int rc = 0; + + if (!tee_driver_fns) + return -EINVAL; + + down_write(&usage_lock); + if (is_registered) { + rc = -EACCES; + goto exit; + } + + g_tee_driver_fn = kmalloc(sizeof(*g_tee_driver_fn), GFP_KERNEL); + if (!g_tee_driver_fn) { + rc = -ENOMEM; + goto exit; + } + + g_tee_driver_fn->verify_hmac = tee_driver_fns->verify_hmac; + g_tee_driver_fn->sign_hmac = tee_driver_fns->sign_hmac; + is_registered = 1; + +exit: + up_write(&usage_lock); + + return rc; +} +EXPORT_SYMBOL_GPL(register_five_tee_driver); + +void unregister_five_tee_driver(void) +{ + down_write(&usage_lock); + if (is_registered) { + kfree(g_tee_driver_fn); + g_tee_driver_fn = NULL; + is_registered = 0; + } + up_write(&usage_lock); +} +EXPORT_SYMBOL_GPL(unregister_five_tee_driver); + +int verify_hash(enum hash_algo algo, const void *hash, size_t hash_len, + const void *label, size_t label_len, + const void *signature, size_t signature_len) +{ + int rc = -ENODEV; + struct tee_iovec args = { + .algo = algo, + .hash = hash, + .hash_len = hash_len, + .label = label, + .label_len = label_len, + .signature = (void *)signature, + .signature_len = signature_len + }; + + down_read(&usage_lock); + if (is_registered) + rc = g_tee_driver_fn->verify_hmac(&args); + up_read(&usage_lock); + + return rc; +} + +int sign_hash(enum hash_algo algo, const void *hash, size_t hash_len, + const void *label, size_t label_len, + void *signature, size_t *signature_len) +{ + int rc = -ENODEV; + struct tee_iovec args = { + .algo = algo, + .hash = hash, + .hash_len = hash_len, + .label = label, + .label_len = label_len, + .signature = signature, + .signature_len = *signature_len + }; + + down_read(&usage_lock); + if (is_registered) + rc = g_tee_driver_fn->sign_hmac(&args); + up_read(&usage_lock); + + *signature_len = args.signature_len; + + return rc; +} diff --git a/security/samsung/five/gki/five_tee_interface.h b/security/samsung/five/gki/five_tee_interface.h new file mode 100644 index 000000000..6ff986d05 --- /dev/null +++ b/security/samsung/five/gki/five_tee_interface.h @@ -0,0 +1,47 @@ +/* + * Interface for TEE Driver + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 INTEGRITY_TEE_DRIVER_H +#define INTEGRITY_TEE_DRIVER_H + +#include +#include + +struct tee_iovec { + enum hash_algo algo; + + const void *hash; + size_t hash_len; + + const void *label; + size_t label_len; + + void *signature; + size_t signature_len; + + int rc; +}; + +struct five_tee_driver_fns { + int (*verify_hmac)(const struct tee_iovec *verify_args); + int (*sign_hmac)(struct tee_iovec *sign_args); +}; + +int register_five_tee_driver( + struct five_tee_driver_fns *tee_driver_fns); +void unregister_five_tee_driver(void); + +#endif diff --git a/security/samsung/five/gki/five_tint_dev.c b/security/samsung/five/gki/five_tint_dev.c new file mode 100644 index 000000000..6172b5bcd --- /dev/null +++ b/security/samsung/five/gki/five_tint_dev.c @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * FIVE task integrity + * + * Copyright (C) 2020 Samsung Electronics, Inc. + * Egor Uleyskiy, + * Viacheslav Vovchenko + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "task_integrity.h" +#include "five_tint_dev.h" + +struct tint_message { + uint32_t version; + uint32_t param; + uint64_t reserved; + union __packed { + enum task_integrity_value value; + struct __packed { + uint64_t value_ptr; + uint16_t len_buf; + } label; + struct __packed { + uint64_t i_ino; + enum task_integrity_reset_cause cause; + struct __packed { + uint64_t pathname_ptr; + uint16_t len_buf; + } path; + } reset_file; + struct __packed { + uint64_t label_ptr; + } sign; + } data; +} __packed; + +#define TINT_VERSION 1 +#define TINT_DEV "task_integrity" +#define TINT_IOC_MAGIC 'f' +#define TINT_IOCTL_GET_VALUE \ + _IOWR(TINT_IOC_MAGIC, 1, struct tint_message) +#define TINT_IOCTL_GET_LABEL \ + _IOWR(TINT_IOC_MAGIC, 2, struct tint_message) +#define TINT_IOCTL_GET_RESET_FILE \ + _IOWR(TINT_IOC_MAGIC, 3, struct tint_message) +#define TINT_IOCTL_SIGN_FILE \ + _IOWR(TINT_IOC_MAGIC, 4, struct tint_message) +#define TINT_IOCTL_EDIT_FILE \ + _IOWR(TINT_IOC_MAGIC, 5, struct tint_message) +#define TINT_IOCTL_CLOSE_FILE \ + _IOWR(TINT_IOC_MAGIC, 6, struct tint_message) +#define TINT_IOCTL_VERIFY_SYNC_FILE \ + _IOWR(TINT_IOC_MAGIC, 7, struct tint_message) +#define TINT_IOCTL_VERIFY_ASYNC_FILE \ + _IOWR(TINT_IOC_MAGIC, 8, struct tint_message) + +static struct tint_control { + struct device *pdev; + struct class *driver_class; + dev_t device_no; + struct cdev cdev; +} dev_ctrl; + +static struct task_struct *get_task_by_pid(pid_t pid) +{ + struct task_struct *task = NULL; + struct pid *pid_data; + + pid_data = find_get_pid(pid); + if (unlikely(!pid_data)) { + pr_err("FIVE: Can't find PID: %u\n", pid); + return NULL; + } + + task = get_pid_task(pid_data, PIDTYPE_PID); + if (unlikely(!task)) + pr_err("FIVE: Can't find task by PID: %u\n", pid); + + put_pid(pid_data); + + return task; +} + +static struct task_struct *get_tint_and_task(pid_t pid) +{ + struct task_struct *task = get_task_by_pid(pid); + + if (!task) + return NULL; + + task_integrity_get(TASK_INTEGRITY(task)); + + return task; +} + +static void put_tint_and_task(struct task_struct *task) +{ + if (!task) + return; + + task_integrity_put(TASK_INTEGRITY(task)); + put_task_struct(task); +} + +static int do_command_file(unsigned int cmd, unsigned int fd, + struct integrity_label __user *label) +{ + int ret = 0; + struct file *file; + + file = fget(fd); + if (!file) { + pr_err("FIVE: Can't get file struct: %u\n", cmd); + return -EFAULT; + } + + switch (cmd) { + case TINT_IOCTL_SIGN_FILE: { + ret = five_fcntl_sign(file, label); + break; + } + case TINT_IOCTL_EDIT_FILE: { + ret = five_fcntl_edit(file); + break; + } + case TINT_IOCTL_CLOSE_FILE: { + ret = five_fcntl_close(file); + break; + } + case TINT_IOCTL_VERIFY_SYNC_FILE: { + ret = five_fcntl_verify_sync(file); + break; + } + case TINT_IOCTL_VERIFY_ASYNC_FILE: { + ret = five_fcntl_verify_async(file); + break; + } + default: { + pr_err("FIVE: Invalid IOCTL command: %u\n", cmd); + ret = -ENOIOCTLCMD; + } + } + + if (ret) + pr_err("FIVE: Command failed: %u %d\n", cmd, ret); + + fput(file); + + return ret; +} + +static long tint_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + struct tint_message __user *argp = (void __user *) arg; + struct task_struct *task; + struct tint_message msg = {0}; + + if (_IOC_TYPE(cmd) != TINT_IOC_MAGIC) { + pr_err("FIVE: IOCTL type is wrong\n"); + return -ENOTTY; + } + + ret = copy_from_user(&msg, argp, sizeof(msg)); + if (ret) { + pr_err("FIVE: copy_from_user failed ret: %ld\n", ret); + return -EFAULT; + } + + if (msg.version != TINT_VERSION) { + pr_err("FIVE: Unsupported protocol version: %u\n", msg.version); + return -EINVAL; + } + + switch (cmd) { + case TINT_IOCTL_GET_VALUE: { + task = get_tint_and_task(msg.param); + if (!task) { + ret = -ESRCH; + break; + } + + msg.data.value = task_integrity_user_read(TASK_INTEGRITY(task)); + + ret = copy_to_user( + (void __user *) &argp->data.value, &msg.data.value, + sizeof(msg.data.value)); + if (unlikely(ret)) { + pr_err("FIVE: copy_to_user failed: %u %ld\n", + cmd, ret); + ret = -EFAULT; + } + + put_tint_and_task(task); + break; + } + case TINT_IOCTL_GET_LABEL: { + const struct integrity_label *label; + + task = get_tint_and_task(msg.param); + if (!task) { + ret = -ESRCH; + break; + } + + spin_lock(&TASK_INTEGRITY(task)->value_lock); + label = TASK_INTEGRITY(task)->label; + spin_unlock(&TASK_INTEGRITY(task)->value_lock); + + if (!label) { + ret = -ENOENT; + put_tint_and_task(task); + break; + } + + if (msg.data.label.len_buf < sizeof(label->len) + label->len) { + pr_err("FIVE: User buffer is small for label: %u %u", + cmd, msg.data.label.len_buf); + ret = -EINVAL; + put_tint_and_task(task); + break; + } + + ret = copy_to_user( + (void __user *) msg.data.label.value_ptr, label, + sizeof(label->len) + label->len); + if (unlikely(ret)) { + pr_err("FIVE: copy_to_user failed len: %u %ld\n", + cmd, ret); + ret = -EFAULT; + } + + put_tint_and_task(task); + break; + } + case TINT_IOCTL_GET_RESET_FILE: { + const struct file *reset_file; + const struct inode *inode; + uint16_t len_buf; + char *buf, *pathname; + + task = get_tint_and_task(msg.param); + if (!task) { + ret = -ESRCH; + break; + } + + reset_file = TASK_INTEGRITY(task)->reset_file; + if (!reset_file) { + ret = -ENOENT; + put_tint_and_task(task); + break; + } + + inode = file_inode(reset_file); + msg.data.reset_file.i_ino = inode->i_ino; + msg.data.reset_file.cause = TASK_INTEGRITY(task)->reset_cause; + len_buf = msg.data.reset_file.path.len_buf; + + if (!len_buf || len_buf > PAGE_SIZE) { + pr_err("FIVE: Bad size of user buffer: %u %u", + cmd, len_buf); + ret = -EINVAL; + put_tint_and_task(task); + break; + } + + buf = kmalloc(len_buf, GFP_KERNEL); + if (unlikely(!buf)) { + pr_err("FIVE: Can't allocate memory: %u %u", + cmd, len_buf); + ret = -ENOMEM; + put_tint_and_task(task); + break; + } + + pathname = d_path(&reset_file->f_path, buf, len_buf); + if (IS_ERR(pathname)) { + pr_err("FIVE: Can't obtain path: %u", len_buf); + ret = -ENOMEM; + kfree(buf); + put_tint_and_task(task); + break; + } + + len_buf = strnlen(pathname, len_buf) + 1; + + ret = copy_to_user( + (void __user *) msg.data.reset_file.path.pathname_ptr, + pathname, len_buf); + if (unlikely(ret)) { + pr_err("FIVE: copy_to_user failed path: %u %ld\n", + cmd, ret); + ret = -EFAULT; + kfree(buf); + put_tint_and_task(task); + break; + } + + ret = copy_to_user((void __user *) &argp->data.reset_file, + &msg.data.reset_file, + sizeof(msg.data.reset_file)); + + if (unlikely(ret)) { + pr_err("FIVE: copy_to_user failed: %u %ld\n", + cmd, ret); + ret = -EFAULT; + } + + kfree(buf); + put_tint_and_task(task); + break; + } + case TINT_IOCTL_SIGN_FILE: + case TINT_IOCTL_EDIT_FILE: + case TINT_IOCTL_CLOSE_FILE: + case TINT_IOCTL_VERIFY_SYNC_FILE: + case TINT_IOCTL_VERIFY_ASYNC_FILE: { + ret = do_command_file(cmd, msg.param, + (struct integrity_label __user *) msg.data.sign.label_ptr); + break; + } + default: { + pr_err("FIVE: Invalid IOCTL command: %u\n", cmd); + ret = -ENOIOCTLCMD; + } + } + + return ret; +} + +#ifdef CONFIG_COMPAT +static long tint_compact_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return tint_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); +} +#endif + +static const struct file_operations tint_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = tint_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tint_compact_ioctl, +#endif +}; + +int __init five_tint_init_dev(void) +{ + int rc = 0; + + rc = alloc_chrdev_region(&dev_ctrl.device_no, 0, 1, TINT_DEV); + if (unlikely(rc < 0)) { + pr_err("FIVE: alloc_chrdev_region failed %d\n", rc); + return rc; + } + + dev_ctrl.driver_class = class_create(THIS_MODULE, TINT_DEV); + if (IS_ERR(dev_ctrl.driver_class)) { + rc = PTR_ERR(dev_ctrl.driver_class); + pr_err("FIVE: class_create failed %d\n", rc); + goto exit_unreg_chrdev_region; + } + + dev_ctrl.pdev = device_create(dev_ctrl.driver_class, NULL, + dev_ctrl.device_no, NULL, TINT_DEV); + if (IS_ERR(dev_ctrl.pdev)) { + rc = PTR_ERR(dev_ctrl.pdev); + pr_err("FIVE: class_device_create failed %d\n", rc); + goto exit_destroy_class; + } + + cdev_init(&dev_ctrl.cdev, &tint_fops); + dev_ctrl.cdev.owner = THIS_MODULE; + + rc = cdev_add(&dev_ctrl.cdev, + MKDEV(MAJOR(dev_ctrl.device_no), 0), 1); + if (unlikely(rc < 0)) { + pr_err("FIVE: cdev_add failed %d\n", rc); + goto exit_destroy_device; + } + + return 0; + +exit_destroy_device: + device_destroy(dev_ctrl.driver_class, dev_ctrl.device_no); +exit_destroy_class: + class_destroy(dev_ctrl.driver_class); +exit_unreg_chrdev_region: + unregister_chrdev_region(dev_ctrl.device_no, 1); + + return rc; +} + +void __exit five_tint_deinit_dev(void) +{ + cdev_del(&dev_ctrl.cdev); + device_destroy(dev_ctrl.driver_class, dev_ctrl.device_no); + class_destroy(dev_ctrl.driver_class); + unregister_chrdev_region(dev_ctrl.device_no, 1); +} diff --git a/security/samsung/five/gki/five_tint_dev.h b/security/samsung/five/gki/five_tint_dev.h new file mode 100644 index 000000000..18014364b --- /dev/null +++ b/security/samsung/five/gki/five_tint_dev.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * FIVE task integrity + * + * Copyright (C) 2020 Samsung Electronics, Inc. + * Egor Uleyskiy, + * Viacheslav Vovchenko + * + * 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 __LINUX_FIVE_GKI_FIVE_TINT_DEV_H +#define __LINUX_FIVE_GKI_FIVE_TINT_DEV_H + +int __init five_tint_init_dev(void); +void __exit five_tint_deinit_dev(void); + +#endif diff --git a/security/samsung/five/gki/five_vfs.c b/security/samsung/five/gki/five_vfs.c new file mode 100644 index 000000000..40f476160 --- /dev/null +++ b/security/samsung/five/gki/five_vfs.c @@ -0,0 +1,130 @@ +/* + * FIVE vfs functions + * + * Copyright (C) 2020 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 +#include +#include +#include "five_vfs.h" + +/* This function is an alternative implementation of vfs_getxattr_alloc() */ +ssize_t five_getxattr_alloc(struct dentry *dentry, const char *name, + char **xattr_value, size_t xattr_size, gfp_t flags) +{ + struct inode *inode = dentry->d_inode; + char *value = *xattr_value; + int error; + + error = __vfs_getxattr(dentry, inode, name, NULL, 0, XATTR_NOSECURITY); + if (error < 0) + return error; + + if (!value || (error > xattr_size)) { + value = krealloc(*xattr_value, error + 1, flags); + if (!value) + return -ENOMEM; + memset(value, 0, error + 1); + } + + error = __vfs_getxattr(dentry, inode, name, value, error, + XATTR_NOSECURITY); + *xattr_value = value; + return error; +} + +/* This function is copied from new_sync_read() */ +static ssize_t new_sync_read(struct file *filp, char __user *buf, + size_t len, loff_t *ppos) +{ + struct iovec iov = { .iov_base = buf, .iov_len = len }; + struct kiocb kiocb; + struct iov_iter iter; + ssize_t ret; + + init_sync_kiocb(&kiocb, filp); + kiocb.ki_pos = (ppos ? *ppos : 0); + iov_iter_init(&iter, READ, &iov, 1, len); + + ret = call_read_iter(filp, &kiocb, &iter); + BUG_ON(ret == -EIOCBQUEUED); + if (ppos) + *ppos = kiocb.ki_pos; + return ret; +} + +/* This function is copied from __vfs_read() */ +ssize_t five_vfs_read(struct file *file, char __user *buf, size_t count, + loff_t *pos) +{ + if (file->f_op->read) + return file->f_op->read(file, buf, count, pos); + else if (file->f_op->read_iter) + return new_sync_read(file, buf, count, pos); + else + return -EINVAL; +} + +/* This function is copied from __vfs_setxattr_noperm() */ +int five_setxattr_noperm(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + struct inode *inode = dentry->d_inode; + int error = -EAGAIN; + int issec = !strncmp(name, XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN); + + if (issec) + inode->i_flags &= ~S_NOSEC; + if (inode->i_opflags & IOP_XATTR) { + error = __vfs_setxattr(dentry, inode, name, value, size, flags); + } else { + if (unlikely(is_bad_inode(inode))) + return -EIO; + } + + return error; +} + +/* + * five_kernel_read - read data from the file + * + * This is a function for reading file content instead of kernel_read(). + * It does not perform locking checks to ensure it cannot be blocked. + * It does not perform security checks because it is irrelevant for IMA. + * + * This function is copied from integrity_kernel_read() + */ +int five_kernel_read(struct file *file, loff_t offset, + void *addr, unsigned long count) +{ + mm_segment_t old_fs; + char __user *buf = (char __user *)addr; + ssize_t ret; + struct inode *inode = file_inode(file); + + if (!(file->f_mode & FMODE_READ)) + return -EBADF; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + if (inode->i_sb->s_magic == OVERLAYFS_SUPER_MAGIC && file->private_data) + file = (struct file *)file->private_data; + + ret = five_vfs_read(file, buf, count, &offset); + set_fs(old_fs); + + return ret; +} diff --git a/security/samsung/five/gki/five_vfs.h b/security/samsung/five/gki/five_vfs.h new file mode 100644 index 000000000..980ad105b --- /dev/null +++ b/security/samsung/five/gki/five_vfs.h @@ -0,0 +1,24 @@ +/* + * FIVE vfs functions + * + * Copyright (C) 2020 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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. + */ + +ssize_t five_getxattr_alloc(struct dentry *dentry, const char *name, + char **xattr_value, size_t xattr_size, gfp_t flags); +ssize_t five_vfs_read(struct file *file, char __user *buf, + size_t count, loff_t *pos); +int five_kernel_read(struct file *file, loff_t offset, + void *addr, unsigned long count); +int five_setxattr_noperm(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags); diff --git a/security/samsung/five/gki/task_integrity.c b/security/samsung/five/gki/task_integrity.c new file mode 100644 index 000000000..449409814 --- /dev/null +++ b/security/samsung/five/gki/task_integrity.c @@ -0,0 +1,196 @@ +/* + * Task Integrity Verifier + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 +#include +#include +#include +#include "five_porting.h" + +static struct kmem_cache *task_integrity_cache; + +static void init_once(void *foo) +{ + struct task_integrity *tint = foo; + + memset(tint, 0, sizeof(*tint)); + spin_lock_init(&tint->value_lock); + spin_lock_init(&tint->list_lock); +} + +int __init five_task_integrity_cache_init(void) +{ + task_integrity_cache = kmem_cache_create("task_integrity_cache", + sizeof(struct task_integrity), 0, + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, init_once); + + if (!task_integrity_cache) + return -ENOMEM; + + return 0; +} + +struct task_integrity *task_integrity_alloc(void) +{ + struct task_integrity *tint; + + tint = kmem_cache_alloc(task_integrity_cache, GFP_KERNEL); + if (tint) { + atomic_set(&tint->usage_count, 1); + INIT_LIST_HEAD(&tint->events.list); + } + + return tint; +} + +void task_integrity_free(struct task_integrity *tint) +{ + if (tint) { + /* These values should be changed under "value_lock" spinlock. + But then lockdep prints warning because this function can be called + from sw-irq (from function free_task). + Actually deadlock never happens because this function is called + only if usage_count is 0 (no reference to this struct), + so changing these values without spinlock is safe. + */ + kfree(tint->label); + tint->label = NULL; + tint->user_value = INTEGRITY_NONE; + tint->value = INTEGRITY_NONE; + atomic_set(&tint->usage_count, 0); + + tint->reset_cause = CAUSE_UNSET; + if (tint->reset_file) { + fput(tint->reset_file); + tint->reset_file = NULL; + } + + kmem_cache_free(task_integrity_cache, tint); + } +} + +void task_integrity_clear(struct task_integrity *tint) +{ + task_integrity_set(tint, INTEGRITY_NONE); + spin_lock(&tint->value_lock); + kfree(tint->label); + tint->label = NULL; + spin_unlock(&tint->value_lock); + + tint->reset_cause = CAUSE_UNSET; + if (tint->reset_file) { + fput(tint->reset_file); + tint->reset_file = NULL; + } +} + +static int copy_label(struct task_integrity *from, struct task_integrity *to) +{ + int ret = 0; + struct integrity_label *l = NULL; + + if (task_integrity_read(from) && from->label) + l = from->label; + + if (l) { + struct integrity_label *label; + + label = kmalloc(sizeof(*label) + l->len, GFP_ATOMIC); + if (!label) { + ret = -ENOMEM; + goto exit; + } + + label->len = l->len; + memcpy(label->data, l->data, label->len); + to->label = label; + } + +exit: + return ret; +} + +int task_integrity_copy(struct task_integrity *from, struct task_integrity *to) +{ + int rc = -EPERM; + enum task_integrity_value value = task_integrity_read(from); + + task_integrity_set(to, value); + + if (list_empty(&from->events.list)) + to->user_value = value; + + rc = copy_label(from, to); + + to->reset_cause = from->reset_cause; + if (from->reset_file) { + get_file(from->reset_file); + to->reset_file = from->reset_file; + } + + return rc; +} + +char const * const tint_reset_cause_to_string( + enum task_integrity_reset_cause cause) +{ + static const char * const tint_cause2str[] = { + [CAUSE_UNSET] = "unset", + [CAUSE_UNKNOWN] = "unknown", + [CAUSE_MISMATCH_LABEL] = "mismatch-label", + [CAUSE_BAD_FS] = "bad-fs", + [CAUSE_NO_CERT] = "no-cert", + [CAUSE_INVALID_HASH_LENGTH] = "invalid-hash-length", + [CAUSE_INVALID_HEADER] = "invalid-header", + [CAUSE_CALC_HASH_FAILED] = "calc-hash-failed", + [CAUSE_INVALID_LABEL_DATA] = "invalid-label-data", + [CAUSE_INVALID_SIGNATURE_DATA] = "invalid-signature-data", + [CAUSE_INVALID_HASH] = "invalid-hash", + [CAUSE_INVALID_CALC_CERT_HASH] = "invalid-calc-cert-hash", + [CAUSE_INVALID_UPDATE_LABEL] = "invalid-update-label", + [CAUSE_INVALID_SIGNATURE] = "invalid-signature", + [CAUSE_UKNOWN_FIVE_DATA] = "unknown-five-data", + [CAUSE_PTRACE] = "ptrace", + [CAUSE_VMRW] = "vmrw", + [CAUSE_EXEC] = "exec", + [CAUSE_TAMPERED] = "tampered", + [CAUSE_MAX] = "incorrect-cause", + }; + + if (cause > CAUSE_MAX) + cause = CAUSE_MAX; + + return tint_cause2str[cause]; +} + +/* + * task_integrity_set_reset_reason + * + * Only first call of this function per task will have effect, because first + * reason will be root cause. + */ +void task_integrity_set_reset_reason(struct task_integrity *tint, + enum task_integrity_reset_cause cause, struct file *file) +{ + if (tint->reset_cause != CAUSE_UNSET) + return; + + tint->reset_cause = cause; + if (file) { + get_file(file); + tint->reset_file = file; + } +} diff --git a/security/samsung/five/gki/task_integrity.h b/security/samsung/five/gki/task_integrity.h new file mode 100644 index 000000000..fb940c76a --- /dev/null +++ b/security/samsung/five/gki/task_integrity.h @@ -0,0 +1,426 @@ +/* + * Task Integrity Verifier + * + * Copyright (C) 2016 Samsung Electronics, Inc. + * Egor Uleyskiy, + * + * 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 _LINUX_TASK_INTEGRITY_H +#define _LINUX_TASK_INTEGRITY_H + +#include +#include +#include +#include +#include + +struct linux_binprm; +struct task_integrity; + +struct integrity_label { + uint16_t len; + uint8_t data[0]; +} __packed; + +enum five_event { + FIVE_RESET_INTEGRITY, + FIVE_VERIFY_BUNCH_FILES, +}; + +/* + * This is list of numbers which Hamming distance is 16 + * + * 0x00000000 <-- used + * 0x0f0f0f0f, + * 0xf0f0f0f0, + * 0x0000ffff, + * 0xffff0000, + * 0xff00ff00, + * 0x00ff00ff, + * 0x33333333,<-- used + * 0xcccccccc,<-- used + * 0x55555555,<-- used + * 0x5a5a5a5a,<-- used + * 0xa5a5a5a5, + * 0xaaaaaaaa,<-- used + * 0x3c3c3c3c,<-- used + * 0xc3c3c3c3, + * 0xffffffff <-- used + */ +enum task_integrity_value { + INTEGRITY_NONE = 0x00000000, + INTEGRITY_PRELOAD = 0x33333333, + INTEGRITY_PRELOAD_ALLOW_SIGN = 0xcccccccc, + INTEGRITY_MIXED = 0x55555555, + INTEGRITY_MIXED_ALLOW_SIGN = 0x5a5a5a5a, + INTEGRITY_DMVERITY = 0xaaaaaaaa, + INTEGRITY_DMVERITY_ALLOW_SIGN = 0x3c3c3c3c, + INTEGRITY_PROCESSING = 0xffffffff +}; + +struct processing_event_list { + enum five_event event; + struct task_struct *task; + struct file *file; + int function; + struct list_head list; +}; + +enum task_integrity_reset_cause { + CAUSE_UNSET, + CAUSE_UNKNOWN, + CAUSE_MISMATCH_LABEL, + CAUSE_BAD_FS, + CAUSE_NO_CERT, + CAUSE_INVALID_HASH_LENGTH, + CAUSE_INVALID_HEADER, + CAUSE_CALC_HASH_FAILED, + CAUSE_INVALID_LABEL_DATA, + CAUSE_INVALID_SIGNATURE_DATA, + CAUSE_INVALID_HASH, + CAUSE_INVALID_CALC_CERT_HASH, + CAUSE_INVALID_UPDATE_LABEL, + CAUSE_INVALID_SIGNATURE, + CAUSE_UKNOWN_FIVE_DATA, + CAUSE_PTRACE, + CAUSE_VMRW, + CAUSE_EXEC, + CAUSE_TAMPERED, + CAUSE_MAX, +}; + +struct task_integrity { + enum task_integrity_value user_value; + enum task_integrity_value value; + atomic_t usage_count; + spinlock_t value_lock; + spinlock_t list_lock; + struct integrity_label *label; + struct processing_event_list events; + enum task_integrity_reset_cause reset_cause; + struct file *reset_file; +}; + +#ifdef CONFIG_FIVE + +#define TASK_INTEGRITY(task) \ + ((struct task_integrity *)((task)->android_vendor_data1[2])) + +static inline void task_integrity_assign(struct task_struct *task, + struct task_integrity *tint) +{ + task->android_vendor_data1[2] = (u64)tint; +} + +extern void task_integrity_set_reset_reason(struct task_integrity *tint, + enum task_integrity_reset_cause cause, struct file *file); + +struct task_integrity *task_integrity_alloc(void); +void task_integrity_free(struct task_integrity *tint); +void task_integrity_clear(struct task_integrity *tint); + +static inline void task_integrity_get(struct task_integrity *tint) +{ + BUG_ON(!atomic_read(&tint->usage_count)); + atomic_inc(&tint->usage_count); +} + +static inline void task_integrity_put(struct task_integrity *tint) +{ + BUG_ON(!atomic_read(&tint->usage_count)); + if (atomic_dec_and_test(&tint->usage_count)) + task_integrity_free(tint); +} + +static inline void __task_integrity_set(struct task_integrity *tint, + enum task_integrity_value value) +{ + tint->value = value; +} + +static inline void task_integrity_set(struct task_integrity *tint, + enum task_integrity_value value) +{ + spin_lock(&tint->value_lock); + tint->value = value; + spin_unlock(&tint->value_lock); +} + +static inline void task_integrity_reset(struct task_integrity *tint) +{ + task_integrity_set(tint, INTEGRITY_NONE); + // If cause is already set, this function will be skipped + task_integrity_set_reset_reason(tint, CAUSE_UNKNOWN, NULL); +} + +extern void task_integrity_delayed_reset(struct task_struct *task, + enum task_integrity_reset_cause cause, struct file *file); + +static inline enum task_integrity_value task_integrity_read( + struct task_integrity *tint) +{ + enum task_integrity_value value; + + spin_lock(&tint->value_lock); + value = tint->value; + spin_unlock(&tint->value_lock); + + return value; +} + +static inline bool task_integrity_value_allow_sign( + enum task_integrity_value value) +{ + if (value == INTEGRITY_PRELOAD_ALLOW_SIGN + || value == INTEGRITY_MIXED_ALLOW_SIGN + || value == INTEGRITY_DMVERITY_ALLOW_SIGN) { + return true; + } + + return false; +} + +/** + * task_integrity_allow_sign - check whether application is allowed to sign + * @tint: pointer to the corresponding integrity struct (Should not be NULL) + * + * On success return true. + */ +static inline bool task_integrity_allow_sign(struct task_integrity *tint) +{ + enum task_integrity_value value = task_integrity_read(tint); + + return task_integrity_value_allow_sign(value); +} + +static inline enum task_integrity_value task_integrity_user_read( + struct task_integrity *tint) +{ + return tint->user_value; +} + +static inline void task_integrity_user_set(struct task_integrity *tint, + enum task_integrity_value value) +{ + tint->user_value = value; +} + +static inline void task_integrity_reset_both(struct task_integrity *tint) +{ + task_integrity_reset(tint); + tint->user_value = INTEGRITY_NONE; +} + +extern int task_integrity_copy(struct task_integrity *from, + struct task_integrity *to); +extern int five_bprm_check(struct linux_binprm *bprm); +extern void five_file_free(struct file *file); +extern int five_file_mmap(struct file *file, unsigned long prot); +extern int five_file_open(struct file *file); +extern int five_file_verify(struct task_struct *task, struct file *file); +extern void five_task_free(struct task_struct *task); + +extern void five_inode_post_setattr(struct task_struct *tsk, + struct dentry *dentry); +extern int five_inode_setxattr(struct dentry *dentry, const char *xattr_name, + const void *xattr_value, size_t xattr_value_len); +extern int five_inode_removexattr(struct dentry *dentry, + const char *xattr_name); +extern int five_fcntl_sign(struct file *file, + struct integrity_label __user *label); +extern int five_fcntl_verify_async(struct file *file); +extern int five_fcntl_verify_sync(struct file *file); +extern int five_fcntl_edit(struct file *file); +extern int five_fcntl_close(struct file *file); +extern int five_fcntl_debug(struct file *file, void __user *arg); +extern int five_fork(struct task_struct *task, struct task_struct *child_task); +extern int five_ptrace(struct task_struct *task, long request); +extern int five_process_vm_rw(struct task_struct *task, int write); +extern char const * const tint_reset_cause_to_string( + enum task_integrity_reset_cause cause); +#else +#define TASK_INTEGRITY(task) (NULL) + +static inline void task_integrity_assign(struct task_struct *task, + struct task_integrity *tint) +{ +} + +static inline struct task_integrity *task_integrity_alloc(void) +{ + return NULL; +} + +static inline void task_integrity_free(struct task_integrity *tint) +{ +} + +static inline void task_integrity_clear(struct task_integrity *tint) +{ +} + +static inline void task_integrity_set(struct task_integrity *tint, + enum task_integrity_value value) +{ +} + +static inline void task_integrity_reset(struct task_integrity *tint) +{ +} + +static inline enum task_integrity_value task_integrity_read( + struct task_integrity *tint) +{ + return INTEGRITY_NONE; +} + +static inline void task_integrity_user_set(struct task_integrity *tint, + enum task_integrity_value value) +{ +} + +static inline enum task_integrity_value task_integrity_user_read( + struct task_integrity *tint) +{ + return INTEGRITY_NONE; +} + +static inline void task_integrity_delayed_reset(struct task_struct *task, + enum task_integrity_reset_cause cause, struct file *file) +{ +} + +static inline void task_integrity_reset_both(struct task_integrity *tint) +{ +} + +static inline void task_integrity_add_file(struct task_integrity *tint) +{ +} + +static inline void task_integrity_report_file(struct task_integrity *tint) +{ +} + +static inline int five_bprm_check(struct linux_binprm *bprm) +{ + return 0; +} + +static inline void five_file_free(struct file *file) +{ +} + +static inline int five_file_mmap(struct file *file, unsigned long prot) +{ + return 0; +} + +static inline int five_file_open(struct file *file) +{ + return 0; +} + +static inline int five_file_verify(struct task_struct *task, struct file *file) +{ + return 0; +} + +static inline void five_task_free(struct task_struct *task) +{ +} + +static inline void five_inode_post_setattr(struct task_struct *tsk, + struct dentry *dentry) +{ +} + +static inline int five_inode_setxattr(struct dentry *dentry, + const char *xattr_name, + const void *xattr_value, + size_t xattr_value_len) +{ + return 0; +} + +static inline int five_inode_removexattr(struct dentry *dentry, + const char *xattr_name) +{ + return 0; +} + +static inline int five_fcntl_sign(struct file *file, + struct integrity_label __user *label) +{ + return 0; +} + +static inline int five_fcntl_verify_async(struct file *file) +{ + return 0; +} + +static inline int five_fcntl_verify_sync(struct file *file) +{ + return 0; +} + +static inline int five_fcntl_edit(struct file *file) +{ + return 0; +} + +static inline int five_fcntl_close(struct file *file) +{ + return 0; +} + +static inline int five_fcntl_debug(struct file *file, void __user *arg) +{ + return 0; +} + +static inline int five_fork(struct task_struct *task, + struct task_struct *child_task) +{ + return 0; +} + +static inline int five_ptrace(struct task_struct *task, long request) +{ + return 0; +} + +static inline int five_process_vm_rw(struct task_struct *task, int write) +{ + return 0; +} + +static inline int task_integrity_copy(struct task_integrity *from, + struct task_integrity *to) +{ + return 0; +} + +static inline char const * const tint_reset_cause_to_string( + enum task_integrity_reset_cause cause) +{ + return NULL; +} + +static inline void task_integrity_set_reset_reason(struct task_integrity *tint, + enum task_integrity_reset_cause cause, struct file *file) +{ +} +#endif + +#endif /* _LINUX_TASK_INTEGRITY_H */ diff --git a/techpack/audio/asoc/kona.c b/techpack/audio/asoc/kona.c index 3f689194d..56b676d9a 100644 --- a/techpack/audio/asoc/kona.c +++ b/techpack/audio/asoc/kona.c @@ -9142,7 +9142,7 @@ static void msm_update_dai_link(struct platform_device *pdev, return; } - if (soc_find_component(component_of_node, NULL) != NULL) { + if (soc_find_component_locked(component_of_node, NULL) != NULL) { dev_dbg(&pdev->dev, "%s: component devs are connected\n", __func__); diff --git a/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_core.c b/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_core.c index 5671cf9c0..6efa77a8d 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_core.c @@ -7,8 +7,6 @@ #include "cam_cci_core.h" #include "cam_cci_dev.h" -#define DUMP_CCI_REGISTERS - static int32_t cam_cci_convert_type_to_num_bytes( enum camera_sensor_i2c_type type) { @@ -190,11 +188,12 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) { uint32_t read_val = 0; - uint32_t i = 0, count = 0; + uint32_t i = 0; uint32_t reg_offset = 0; void __iomem *base = cci_dev->soc_info.reg_map[0].mem_base; - CAM_INFO(CAM_CCI, "**** CCI:%d register dump ****",cci_dev->soc_info.index); + CAM_INFO(CAM_CCI, "**** CCI:%d register dump ****", + cci_dev->soc_info->index); /* CCI Top Registers */ CAM_INFO(CAM_CCI, "****CCI TOP Registers ****"); @@ -203,10 +202,6 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev, read_val = cam_io_r_mb(base + reg_offset); CAM_INFO(CAM_CCI, "offset = 0x%X value = 0x%X", reg_offset, read_val); - CAM_INFO(CAM_CCI, "before reset offset = 0x%X value = 0x%X", - cci_dev->cci_dump[count].reg_addr, - cci_dev->cci_dump[count].reg_data); - count++; } /* CCI Master registers */ @@ -215,14 +210,11 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev, for (i = 0; i < DEBUG_MASTER_REG_COUNT; i++) { if ((i * 4) == 0x18) continue; + reg_offset = DEBUG_MASTER_REG_START + master*0x100 + i * 4; read_val = cam_io_r_mb(base + reg_offset); CAM_INFO(CAM_CCI, "offset = 0x%X value = 0x%X", reg_offset, read_val); - CAM_INFO(CAM_CCI, "before reset offset = 0x%X value = 0x%X", - cci_dev->cci_dump[count].reg_addr, - cci_dev->cci_dump[count].reg_data); - count++; } /* CCI Master Queue registers */ @@ -234,10 +226,6 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev, read_val = cam_io_r_mb(base + reg_offset); CAM_INFO(CAM_CCI, "offset = 0x%X value = 0x%X", reg_offset, read_val); - CAM_INFO(CAM_CCI, "before reset offset = 0x%X value = 0x%X", - cci_dev->cci_dump[count].reg_addr, - cci_dev->cci_dump[count].reg_data); - count++; } /* CCI Interrupt registers */ @@ -247,10 +235,6 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev, read_val = cam_io_r_mb(base + reg_offset); CAM_INFO(CAM_CCI, "offset = 0x%X value = 0x%X", reg_offset, read_val); - CAM_INFO(CAM_CCI, "before reset offset = 0x%X value = 0x%X", - cci_dev->cci_dump[count].reg_addr, - cci_dev->cci_dump[count].reg_data); - count++; } } #endif diff --git a/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c b/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c index 9c249f794..c949608d1 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -58,51 +58,6 @@ static long cam_cci_subdev_compat_ioctl(struct v4l2_subdev *sd, } #endif -#ifdef DUMP_CCI_REGISTERS -static void cam_cci_irq_dump_registers(struct cci_device *cci_dev, - enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) -{ - uint32_t read_val = 0; - uint32_t i = 0, count = 0; - uint32_t reg_offset = 0; - void __iomem *base = cci_dev->soc_info.reg_map[0].mem_base; - - /* CCI Top Registers */ - for (i = 0; i < DEBUG_TOP_REG_COUNT; i++) { - reg_offset = DEBUG_TOP_REG_START + i * 4; - read_val = cam_io_r_mb(base + reg_offset); - cci_dev->cci_dump[count].reg_addr=reg_offset; - cci_dev->cci_dump[count++].reg_data= read_val; - } - - /* CCI Master registers */ - for (i = 0; i < DEBUG_MASTER_REG_COUNT; i++) { - reg_offset = DEBUG_MASTER_REG_START + master*0x100 + i * 4; - read_val = cam_io_r_mb(base + reg_offset); - cci_dev->cci_dump[count].reg_addr=reg_offset; - cci_dev->cci_dump[count++].reg_data= read_val; - } - - /* CCI Master Queue registers */ - for (i = 0; i < DEBUG_MASTER_QUEUE_REG_COUNT; i++) { - reg_offset = DEBUG_MASTER_QUEUE_REG_START + master*0x200 + - queue*0x100 + i * 4; - read_val = cam_io_r_mb(base + reg_offset); - cci_dev->cci_dump[count].reg_addr=reg_offset; - cci_dev->cci_dump[count++].reg_data= read_val; - } - - /* CCI Interrupt registers */ - for (i = 0; i < DEBUG_INTR_REG_COUNT; i++) { - reg_offset = DEBUG_INTR_REG_START + i * 4; - read_val = cam_io_r_mb(base + reg_offset); - cci_dev->cci_dump[count].reg_addr=reg_offset; - cci_dev->cci_dump[count++].reg_data= read_val; - } -} -#endif - - irqreturn_t cam_cci_irq(int irq_num, void *data) { uint32_t irq_status0, irq_status1, reg_bmsk; @@ -262,19 +217,11 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_0].reset_pending = true; - CAM_INFO(CAM_CCI, "got HALT_ACK for M0"); -#ifdef DUMP_CCI_REGISTERS - cam_cci_irq_dump_registers(cci_dev,MASTER_0,QUEUE_0); -#endif cam_io_w_mb(CCI_M0_RESET_RMSK, base + CCI_RESET_CMD_ADDR); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_1].reset_pending = true; -#ifdef DUMP_CCI_REGISTERS - CAM_INFO(CAM_CCI, "got HALT_ACK for M1"); - cam_cci_irq_dump_registers(cci_dev,MASTER_1,QUEUE_0); -#endif cam_io_w_mb(CCI_M1_RESET_RMSK, base + CCI_RESET_CMD_ADDR); } diff --git a/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.h b/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.h index 99b999e47..caa9be1a3 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.h +++ b/techpack/camera/drivers/cam_sensor_module/cam_cci/cam_cci_dev.h @@ -39,9 +39,6 @@ #define CCI_TIMEOUT msecs_to_jiffies(1500) -#define DUMP_CCI_REGISTERS -#define CCI_REG_MAX_SIZE 50 - #define NUM_MASTERS 2 #define NUM_QUEUES 2 @@ -228,9 +225,6 @@ struct cci_device { bool is_burst_read; uint32_t irqs_disabled; struct mutex init_mutex; -#ifdef DUMP_CCI_REGISTERS - struct cam_sensor_i2c_reg_array cci_dump[CCI_REG_MAX_SIZE]; -#endif }; enum cam_cci_i2c_cmd_type { diff --git a/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_rumba_s4.c b/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_rumba_s4.c index 5494db8df..7be6a8a0f 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_rumba_s4.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_rumba_s4.c @@ -1923,4 +1923,4 @@ void cam_ois_reset(void *ctrl) } CAM_INFO(CAM_OIS, "X"); -} \ No newline at end of file +} diff --git a/techpack/display/msm/dp/dp_display.c b/techpack/display/msm/dp/dp_display.c index b0b0f8a30..89241d475 100644 --- a/techpack/display/msm/dp/dp_display.c +++ b/techpack/display/msm/dp/dp_display.c @@ -507,11 +507,64 @@ void secdp_clear_branch_info(struct dp_display_private *dp) return; } +/** + * get max dex resolution of current dongle/cable. + * it's decided by secdp_check_adapter_type() at connection moment. + */ +enum dex_support_res_t secdp_get_dex_res(void) +{ + struct dp_display_private *dp = g_secdp_priv; + enum dex_support_res_t res = dp->sec.dex.res; + + if (dp->sec.dex.adapter_check_skip) + res = DEX_RES_MAX; + + return res; +} + +/** + * check if dex is running + */ +bool secdp_check_dex_mode(void) +{ + struct dp_display_private *dp = g_secdp_priv; + bool mode = false; + + if (secdp_get_dex_res() == DEX_RES_NOT_SUPPORT) + goto end; + + if (dp->sec.dex.setting_ui == DEX_DISABLED && + dp->sec.dex.curr == DEX_DISABLED) + goto end; + + mode = true; +end: + return mode; +} + +bool secdp_dex_adapter_skip_show(void) +{ + struct dp_display_private *dp = g_secdp_priv; + bool skip = dp->sec.dex.adapter_check_skip; + + DP_DEBUG("skip: %d\n", skip); + + return skip; +} + +void secdp_dex_adapter_skip_store(bool skip) +{ + struct dp_display_private *dp = g_secdp_priv; + + dp->sec.dex.adapter_check_skip = skip; + DP_INFO("skip: %d\n", dp->sec.dex.adapter_check_skip); +} + /** * check connected dongle type with given vid and pid. Based upon this info, * we can decide maximum dex resolution for that cable/adapter. */ -static enum dex_support_res_t secdp_check_adapter_type(CC_NOTI_TYPEDEF *noti) +static enum dex_support_res_t secdp_dex_adapter_check(CC_NOTI_TYPEDEF *noti) { struct dp_display_private *dp = g_secdp_priv; enum dex_support_res_t type = DEX_RES_DFT; /* default resolution */ @@ -532,18 +585,8 @@ static enum dex_support_res_t secdp_check_adapter_type(CC_NOTI_TYPEDEF *noti) if (ven_id == SAMSUNG_VENDOR_ID) { switch (prod_id) { - case 0xa029: /* PAD */ - case 0xa020: /* Station */ - case 0xa02a: - case 0xa02b: - case 0xa02c: - case 0xa02d: - case 0xa02e: - case 0xa02f: - case 0xa030: - case 0xa031: - case 0xa032: - case 0xa033: + case DEXDOCK_PRODUCT_ID: + case DEXPAD_PRODUCT_ID: type = DEX_RES_MAX; break; default: @@ -636,7 +679,7 @@ int secdp_show_hmd_dev(char *buf) end: return rc; } -#endif +#endif/*CONFIG_SEC_DISPLAYPORT_ENG*/ int secdp_store_hmd_dev(char *str, size_t len, int num_hmd) { @@ -831,7 +874,22 @@ void secdp_debug_prefer_ratio_store(int ratio) dp->sec.prefer_ratio = ratio; DP_DEBUG("ratio: %d\n", dp->sec.prefer_ratio); } -#endif + +int secdp_show_link_param(char *buf) +{ + struct dp_display_private *dp = g_secdp_priv; + int rc = 0; + + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + "v_level: %u, p_level: %u\nlane_cnt: %u\nbw_code: 0x%x\n", + dp->link->phy_params.v_level, + dp->link->phy_params.p_level, + dp->link->link_params.lane_count, + dp->link->link_params.bw_code); + + return rc; +} +#endif/*CONFIG_SEC_DISPLAYPORT_ENG*/ static inline bool dp_display_is_hdcp_enabled(struct dp_display_private *dp) { @@ -1988,32 +2046,6 @@ void secdp_dex_do_reconnecting(void) dp->sec.dex.reconnecting = false; mutex_unlock(&dp->attention_lock); } - -/** check if dex is running now */ -bool secdp_check_dex_mode(void) -{ - struct dp_display_private *dp = g_secdp_priv; - bool mode = false; - - if (dp->sec.dex.res == DEX_RES_NOT_SUPPORT) - goto end; - - if (dp->sec.dex.setting_ui == DEX_DISABLED && - dp->sec.dex.curr == DEX_DISABLED) - goto end; - - mode = true; -end: - return mode; -} - -/** get dex resolution. it depends on which dongle/adapter is connected */ -enum dex_support_res_t secdp_get_dex_res(void) -{ - struct dp_display_private *dp = g_secdp_priv; - - return dp->sec.dex.res; -} #endif static int dp_display_usbpd_configure_cb(struct device *dev) @@ -2753,7 +2785,7 @@ static void secdp_ccic_connect_init(struct dp_display_private *dp, * resource clear will be made later at "secdp_process_attention" */ dp->sec.dex.res = connect ? - secdp_check_adapter_type(noti) : DEX_RES_NOT_SUPPORT; + secdp_dex_adapter_check(noti) : DEX_RES_NOT_SUPPORT; dp->sec.dex.prev = dp->sec.dex.curr = dp->sec.dex.status = DEX_DISABLED; dp->sec.dex.reconnecting = 0; diff --git a/techpack/display/msm/dp/secdp.h b/techpack/display/msm/dp/secdp.h index 9956f2085..23f8312b7 100644 --- a/techpack/display/msm/dp/secdp.h +++ b/techpack/display/msm/dp/secdp.h @@ -131,7 +131,6 @@ enum dex_support_res_t { DEX_RES_2560X1440, /* QHD */ DEX_RES_2560X1600, /* WQXGA */ DEX_RES_3440X1440, /* UW-QHD */ - DEX_RES_MAX, }; #define DEX_RES_DFT DEX_RES_1920X1080 /* DeX default resolution */ #define DEX_RES_MAX DEX_RES_3440X1440 /* DeX max resolution */ @@ -143,6 +142,8 @@ static inline char *secdp_dex_res_to_string(int res) switch (res) { case DEX_RES_NOT_SUPPORT: return DP_ENUM_STR(DEX_RES_NOT_SUPPORT); + case DEX_RES_1600X900: + return DP_ENUM_STR(DEX_RES_1600X900); case DEX_RES_1920X1080: return DP_ENUM_STR(DEX_RES_1920X1080); case DEX_RES_1920X1200: @@ -188,6 +189,9 @@ struct secdp_dex { enum DEX_STATUS prev; /*previously known as "dex_now"*/ enum DEX_STATUS curr; /*previously known as "dex_en"*/ int setting_ui; /*"dex_set", true if setting has Dex mode*/ + + bool adapter_check_skip; + /* * 2 if resolution is changed during dex mode change. * And once dex framework reads the dex_node_stauts using dex node, @@ -357,6 +361,8 @@ enum dex_support_res_t secdp_get_dex_res(void); void secdp_clear_link_status_update_cnt(struct dp_link *dp_link); void secdp_reset_link_status(struct dp_link *dp_link); bool secdp_check_link_stable(struct dp_link *dp_link); +bool secdp_dex_adapter_skip_show(void); +void secdp_dex_adapter_skip_store(bool skip); bool secdp_panel_hdr_supported(void); @@ -419,7 +425,6 @@ static inline char *secdp_phy_type_to_string(int param) } int secdp_show_hmd_dev(char *buf); -int secdp_show_phy_param(char *buf); /* preshoot adjustment */ int secdp_catalog_preshoot_show(char *buf); @@ -430,6 +435,7 @@ int secdp_parse_vxpx_show(enum secdp_hw_ver_t hw, enum secdp_phy_param_t vxpx, char *buf); int secdp_parse_vxpx_store(enum secdp_hw_ver_t hw, enum secdp_phy_param_t vxpx, char *buf); +int secdp_show_phy_param(char *buf); /* AUX configuration */ int secdp_aux_cfg_show(char *buf); @@ -440,6 +446,7 @@ int secdp_debug_prefer_skip_show(void); void secdp_debug_prefer_skip_store(bool skip); int secdp_debug_prefer_ratio_show(void); void secdp_debug_prefer_ratio_store(int ratio); -#endif +int secdp_show_link_param(char *buf); +#endif/*CONFIG_SEC_DISPLAYPORT_ENG*/ #endif/*__SECDP_H*/ diff --git a/techpack/display/msm/dp/secdp_sysfs.c b/techpack/display/msm/dp/secdp_sysfs.c index d08bf35bb..722be4062 100644 --- a/techpack/display/msm/dp/secdp_sysfs.c +++ b/techpack/display/msm/dp/secdp_sysfs.c @@ -101,6 +101,8 @@ static ssize_t dp_sbu_sw_sel_store(struct class *dev, static CLASS_ATTR_WO(dp_sbu_sw_sel); #endif +#define SECDP_DEX_ADAPTER_SKIP "SkipAdapterCheck" + static ssize_t dex_show(struct class *class, struct class_attribute *attr, char *buf) { @@ -114,8 +116,9 @@ static ssize_t dex_show(struct class *class, dex->prev = dex->curr = dex->status = DEX_DISABLED; } - DP_INFO("prev: %d, curr: %d, status: %d\n", - dex->prev, dex->curr, dex->status); + DP_INFO("prev:%d, curr:%d, status:%d, %s:%d\n", + dex->prev, dex->curr, dex->status, + SECDP_DEX_ADAPTER_SKIP, secdp_dex_adapter_skip_show()); rc = scnprintf(buf, PAGE_SIZE, "%d\n", dex->status); if (dex->status == DEX_DURING_MODE_CHANGE) @@ -165,27 +168,13 @@ static ssize_t dex_store(struct class *class, DP_DEBUG("tok: %s, len: %d\n", tok, len); if (!strncmp(DEX_TAG_HMD, tok, len)) { - /* called by HmtManager to inform list of supported HMD devices - * - * Format : - * HMD,NUM,NAME01,VID01,PID01,NAME02,VID02,PID02,... - * - * HMD : tag - * NUM : num of HMD dev ..... max 2 bytes to decimal (max 32) - * NAME : name of HMD ...... max 14 bytes, char string - * VID : vendor id ....... 4 bytes to hexadecimal - * PID : product id ....... 4 bytes to hexadecimal - * - * ex) HMD,2,PicoVR,2d40,0000,Nreal light,0486,573c - * - * call hmd store function with tag(HMD),NUM removed - */ int num_hmd = 0, sz = 0, ret; tok = strsep(&p, ","); sz = strlen(tok); ret = kstrtouint(tok, 10, &num_hmd); - DP_DEBUG("HMD num: %d, sz:%d, ret:%d\n", num_hmd, sz, ret); + DP_DEBUG("[%s] num:%d,sz:%d,ret:%d\n", DEX_TAG_HMD, + num_hmd, sz, ret); if (!ret) { ret = secdp_store_hmd_dev(str + (len + sz + 2), size - (len + sz + 2), num_hmd); @@ -198,6 +187,24 @@ static ssize_t dex_store(struct class *class, } mutex_unlock(&sec->hmd_lock); + if (!strncmp(SECDP_DEX_ADAPTER_SKIP, tok, len)) { + int param = 0, sz = 0, ret; + + tok = strsep(&p, ","); + sz = strlen(tok); + ret = kstrtouint(tok, 2, ¶m); + if (ret) { + DP_ERR("error:%d\n", ret); + goto exit; + } + + DP_DEBUG("[%s] param:%d,sz:%d,ret:%d\n", SECDP_DEX_ADAPTER_SKIP, + param, sz, ret); + + secdp_dex_adapter_skip_store((!param) ? false : true); + goto exit; + } + get_options(buf, ARRAY_SIZE(val), val); DP_INFO("%d(0x%02x)\n", val[1], val[1]); setting_ui = (val[1] & 0xf0) >> 4; @@ -262,7 +269,7 @@ static ssize_t dex_store(struct class *class, secdp_bigdata_save_item(BD_DP_MODE, "MIRROR"); #endif - if (sec->dex.res == DEX_RES_NOT_SUPPORT) { + if (secdp_get_dex_res() == DEX_RES_NOT_SUPPORT) { DP_DEBUG("this dongle does not support dex\n"); goto exit; } @@ -679,17 +686,21 @@ static ssize_t dp_forced_resolution_show(struct class *class, rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< HMD >\n%s\n", tmp); memset(tmp, 0, ARRAY_SIZE(tmp)); - secdp_show_phy_param(tmp); rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< DP-PHY >\n%s\n", tmp); + memset(tmp, 0, ARRAY_SIZE(tmp)); + secdp_show_link_param(tmp); + rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< link params >\n%s\n", tmp); + return rc; } static ssize_t dp_forced_resolution_store(struct class *dev, struct class_attribute *attr, const char *buf, size_t size) { - int val[10] = {0, }; + char str[MAX_DEX_STORE_LEN] = {0,}, *p, *tok; + int len, val[10] = {0, }; if (secdp_check_store_args(buf, size)) { DP_ERR("args error!\n"); @@ -698,11 +709,16 @@ static ssize_t dp_forced_resolution_store(struct class *dev, get_options(buf, ARRAY_SIZE(val), val); + memcpy(str, buf, size); + p = str; + tok = strsep(&p, ","); + len = strlen(tok); + DP_DEBUG("tok:%s, len:%d\n", tok, len); + if (val[1] <= 0) forced_resolution = 0; else forced_resolution = val[1]; - exit: return size; } diff --git a/techpack/display/msm/dsi/dsi_defs.h b/techpack/display/msm/dsi/dsi_defs.h index af93dcf6a..f63d0d5c6 100644 --- a/techpack/display/msm/dsi/dsi_defs.h +++ b/techpack/display/msm/dsi/dsi_defs.h @@ -449,7 +449,8 @@ enum dsi_cmd_set_type { TX_IRC_SUBDIVISION, TX_PAC_IRC_SUBDIVISION, TX_IRC_OFF, - + TX_SMOOTH_DIMMING_ON, + TX_SMOOTH_DIMMING_OFF, TX_NORMAL_BRIGHTNESS_ETC, TX_MICRO_SHORT_TEST_ON, diff --git a/techpack/display/msm/dsi/dsi_panel.c b/techpack/display/msm/dsi/dsi_panel.c index bd9d6ad65..b0240cfc7 100644 --- a/techpack/display/msm/dsi/dsi_panel.c +++ b/techpack/display/msm/dsi/dsi_panel.c @@ -2110,7 +2110,8 @@ char *cmd_set_prop_map[SS_DSI_CMD_SET_MAX] = { "samsung,irc_subdivision_tx_cmds_revA", "samsung,pac_irc_subdivision_tx_cmds_revA", "samsung,irc_off_tx_cmds_revA", - + "samsung,smooth_dimming_on_tx_cmds_revA", + "samsung,smooth_dimming_off_tx_cmds_revA", "samsung,normal_brightness_etc_tx_cmds_revA", "samsung,micro_short_test_on_tx_cmds_revA", diff --git a/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_mdnie_EA8079B_AMS646YB01.h b/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_mdnie_EA8079B_AMS646YB01.h index 85d8b7ab2..517204fa2 100644 --- a/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_mdnie_EA8079B_AMS646YB01.h +++ b/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_mdnie_EA8079B_AMS646YB01.h @@ -92,17 +92,199 @@ static char night_mode_data[] = { 0xff, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x62, 0x00, 0xb9, 0x62, 0xff, 0x00, 0x62, 0xff, 0xb9, 0x00, 0xff, 0xb9, 0x62, 0xff, 0x00, 0x00, /* 3700K */ 0xff, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x42, 0x00, 0xa4, 0x42, 0xff, 0x00, 0x42, 0xff, 0xa4, 0x00, 0xff, 0xa4, 0x42, 0xff, 0x00, 0x00, /* 3100K */ 0xff, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x78, 0x1a, 0xff, 0x00, 0x1a, 0xff, 0x78, 0x00, 0xff, 0x78, 0x1a, 0xff, 0x00, 0x00, /* 2300K */ - 0xac, 0x02, 0x04, 0x28, 0xf8, 0x11, 0x05, 0x06, 0xb3, 0x4a, 0xe4, 0xcf, 0xc1, 0x07, 0xbd, 0xe7, 0xd8, 0x18, 0xff, 0xf9, 0xee, 0xff, 0x00, 0x00, /* 6500K */ - 0xac, 0x02, 0x04, 0x28, 0xf6, 0x10, 0x05, 0x06, 0xad, 0x4a, 0xe3, 0xc8, 0xc1, 0x07, 0xb7, 0xe7, 0xd6, 0x17, 0xff, 0xf7, 0xe6, 0xff, 0x00, 0x00, /* 6300K */ - 0xac, 0x02, 0x03, 0x28, 0xf2, 0x10, 0x05, 0x06, 0xa7, 0x4a, 0xdf, 0xc1, 0xc1, 0x07, 0xb1, 0xe7, 0xd3, 0x17, 0xff, 0xf3, 0xde, 0xff, 0x00, 0x00, /* 6100K */ - 0xac, 0x02, 0x03, 0x28, 0xee, 0x0f, 0x05, 0x06, 0xa1, 0x4a, 0xdb, 0xba, 0xc1, 0x07, 0xaa, 0xe7, 0xcf, 0x16, 0xff, 0xef, 0xd6, 0xff, 0x00, 0x00, /* 5900K */ - 0xac, 0x02, 0x03, 0x28, 0xeb, 0x0e, 0x05, 0x06, 0x9a, 0x4a, 0xd9, 0xb2, 0xc1, 0x06, 0xa3, 0xe7, 0xcd, 0x15, 0xff, 0xec, 0xcd, 0xff, 0x00, 0x00, /* 5700K */ - 0xac, 0x02, 0x03, 0x28, 0xe7, 0x0e, 0x05, 0x05, 0x94, 0x4a, 0xd5, 0xac, 0xc1, 0x06, 0x9d, 0xe7, 0xc9, 0x14, 0xff, 0xe8, 0xc5, 0xff, 0x00, 0x00, /* 5500K */ - 0xac, 0x02, 0x03, 0x28, 0xdc, 0x0c, 0x05, 0x05, 0x80, 0x4a, 0xcb, 0x94, 0xc1, 0x06, 0x87, 0xe7, 0xc0, 0x11, 0xff, 0xdd, 0xaa, 0xff, 0x00, 0x00, /* 4900K */ - 0xac, 0x02, 0x02, 0x28, 0xcc, 0x0a, 0x05, 0x05, 0x66, 0x4a, 0xbc, 0x76, 0xc1, 0x06, 0x6b, 0xe7, 0xb2, 0x0e, 0xff, 0xcd, 0x87, 0xff, 0x00, 0x00, /* 4300K */ - 0xac, 0x01, 0x02, 0x28, 0xb8, 0x07, 0x05, 0x04, 0x4a, 0x4a, 0xaa, 0x55, 0xc1, 0x05, 0x4e, 0xe7, 0xa0, 0x0a, 0xff, 0xb9, 0x62, 0xff, 0x00, 0x00, /* 3700K */ - 0xac, 0x01, 0x01, 0x28, 0xa3, 0x05, 0x05, 0x04, 0x32, 0x4a, 0x96, 0x39, 0xc1, 0x05, 0x35, 0xe7, 0x8e, 0x07, 0xff, 0xa4, 0x42, 0xff, 0x00, 0x00, /* 3100K */ - 0xac, 0x01, 0x00, 0x28, 0x78, 0x02, 0x05, 0x03, 0x14, 0x4a, 0x6e, 0x17, 0xc1, 0x03, 0x15, 0xe7, 0x68, 0x03, 0xff, 0x78, 0x1a, 0xff, 0x00, 0x00, /* 2300K */ + 0xff, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xda, 0x00, 0xf1, 0xda, 0xff, 0x00, 0xda, 0xff, 0xf1, 0x00, 0xff, 0xf1, 0xda, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xd8, 0x00, 0xf0, 0xd8, 0xff, 0x00, 0xd8, 0xff, 0xf0, 0x00, 0xff, 0xf0, 0xd8, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0xd5, 0x00, 0xef, 0xd5, 0xff, 0x00, 0xd5, 0xff, 0xef, 0x00, 0xff, 0xef, 0xd5, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xd3, 0x00, 0xee, 0xd3, 0xff, 0x00, 0xd3, 0xff, 0xee, 0x00, 0xff, 0xee, 0xd3, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0xd0, 0x00, 0xed, 0xd0, 0xff, 0x00, 0xd0, 0xff, 0xed, 0x00, 0xff, 0xed, 0xd0, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0xce, 0x00, 0xec, 0xce, 0xff, 0x00, 0xce, 0xff, 0xec, 0x00, 0xff, 0xec, 0xce, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xcb, 0x00, 0xeb, 0xcb, 0xff, 0x00, 0xcb, 0xff, 0xeb, 0x00, 0xff, 0xeb, 0xcb, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xc9, 0x00, 0xea, 0xc9, 0xff, 0x00, 0xc9, 0xff, 0xea, 0x00, 0xff, 0xea, 0xc9, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0xc7, 0x00, 0xe9, 0xc7, 0xff, 0x00, 0xc7, 0xff, 0xe9, 0x00, 0xff, 0xe9, 0xc7, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xc4, 0x00, 0xe8, 0xc4, 0xff, 0x00, 0xc4, 0xff, 0xe8, 0x00, 0xff, 0xe8, 0xc4, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xc2, 0x00, 0xe7, 0xc2, 0xff, 0x00, 0xc2, 0xff, 0xe7, 0x00, 0xff, 0xe7, 0xc2, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0xbf, 0x00, 0xe6, 0xbf, 0xff, 0x00, 0xbf, 0xff, 0xe6, 0x00, 0xff, 0xe6, 0xbf, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xbd, 0x00, 0xe5, 0xbd, 0xff, 0x00, 0xbd, 0xff, 0xe5, 0x00, 0xff, 0xe5, 0xbd, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0xba, 0x00, 0xe4, 0xba, 0xff, 0x00, 0xba, 0xff, 0xe4, 0x00, 0xff, 0xe4, 0xba, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xb8, 0x00, 0xe3, 0xb8, 0xff, 0x00, 0xb8, 0xff, 0xe3, 0x00, 0xff, 0xe3, 0xb8, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0xb5, 0x00, 0xe2, 0xb5, 0xff, 0x00, 0xb5, 0xff, 0xe2, 0x00, 0xff, 0xe2, 0xb5, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xb2, 0x00, 0xe0, 0xb2, 0xff, 0x00, 0xb2, 0xff, 0xe0, 0x00, 0xff, 0xe0, 0xb2, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xaf, 0x00, 0xdf, 0xaf, 0xff, 0x00, 0xaf, 0xff, 0xdf, 0x00, 0xff, 0xdf, 0xaf, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0xad, 0x00, 0xde, 0xad, 0xff, 0x00, 0xad, 0xff, 0xde, 0x00, 0xff, 0xde, 0xad, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xaa, 0x00, 0xdd, 0xaa, 0xff, 0x00, 0xaa, 0xff, 0xdd, 0x00, 0xff, 0xdd, 0xaa, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xa7, 0x00, 0xdb, 0xa7, 0xff, 0x00, 0xa7, 0xff, 0xdb, 0x00, 0xff, 0xdb, 0xa7, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xda, 0xa4, 0xff, 0x00, 0xa4, 0xff, 0xda, 0x00, 0xff, 0xda, 0xa4, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xa1, 0x00, 0xd9, 0xa1, 0xff, 0x00, 0xa1, 0xff, 0xd9, 0x00, 0xff, 0xd9, 0xa1, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x9d, 0x00, 0xd7, 0x9d, 0xff, 0x00, 0x9d, 0xff, 0xd7, 0x00, 0xff, 0xd7, 0x9d, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x9a, 0x00, 0xd6, 0x9a, 0xff, 0x00, 0x9a, 0xff, 0xd6, 0x00, 0xff, 0xd6, 0x9a, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x97, 0x00, 0xd4, 0x97, 0xff, 0x00, 0x97, 0xff, 0xd4, 0x00, 0xff, 0xd4, 0x97, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x94, 0x00, 0xd3, 0x94, 0xff, 0x00, 0x94, 0xff, 0xd3, 0x00, 0xff, 0xd3, 0x94, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x90, 0x00, 0xd1, 0x90, 0xff, 0x00, 0x90, 0xff, 0xd1, 0x00, 0xff, 0xd1, 0x90, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x8d, 0x00, 0xd0, 0x8d, 0xff, 0x00, 0x8d, 0xff, 0xd0, 0x00, 0xff, 0xd0, 0x8d, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0x8a, 0x00, 0xce, 0x8a, 0xff, 0x00, 0x8a, 0xff, 0xce, 0x00, 0xff, 0xce, 0x8a, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x86, 0x00, 0xcc, 0x86, 0xff, 0x00, 0x86, 0xff, 0xcc, 0x00, 0xff, 0xcc, 0x86, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x83, 0x00, 0xca, 0x83, 0xff, 0x00, 0x83, 0xff, 0xca, 0x00, 0xff, 0xca, 0x83, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xc9, 0x7f, 0xff, 0x00, 0x7f, 0xff, 0xc9, 0x00, 0xff, 0xc9, 0x7f, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xc7, 0x7c, 0xff, 0x00, 0x7c, 0xff, 0xc7, 0x00, 0xff, 0xc7, 0x7c, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x78, 0x00, 0xc5, 0x78, 0xff, 0x00, 0x78, 0xff, 0xc5, 0x00, 0xff, 0xc5, 0x78, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, /* 3700K */ + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x75, 0x00, 0xc3, 0x75, 0xff, 0x00, 0x75, 0xff, 0xc3, 0x00, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xf9, 0x02, 0x06, 0x05, 0xbd, 0x20, 0xea, 0xd1, 0xda, 0x00, 0xc8, 0xda, 0xd1, 0x05, 0xff, 0xf9, 0xee, 0xff, 0x00, 0x00, /* 6500K */ + 0xc6, 0x00, 0x00, 0x1f, 0xf7, 0x02, 0x06, 0x05, 0xb6, 0x20, 0xe8, 0xca, 0xda, 0x00, 0xc1, 0xda, 0xcf, 0x05, 0xff, 0xf7, 0xe6, 0xff, 0x00, 0x00, /* 6300K */ + 0xc6, 0x00, 0x00, 0x1f, 0xf3, 0x02, 0x06, 0x05, 0xb0, 0x20, 0xe5, 0xc3, 0xda, 0x00, 0xba, 0xda, 0xcc, 0x05, 0xff, 0xf3, 0xde, 0xff, 0x00, 0x00, /* 6100K */ + 0xc6, 0x00, 0x00, 0x1f, 0xef, 0x02, 0x06, 0x05, 0xaa, 0x20, 0xe1, 0xbc, 0xda, 0x00, 0xb4, 0xda, 0xc9, 0x05, 0xff, 0xef, 0xd6, 0xff, 0x00, 0x00, /* 5900K */ + 0xc6, 0x00, 0x00, 0x1f, 0xec, 0x02, 0x06, 0x05, 0x92, 0x20, 0xde, 0xb4, 0xda, 0x00, 0xac, 0xda, 0xc6, 0x05, 0xff, 0xec, 0xcd, 0xff, 0x00, 0x00, /* 5700K */ + 0xc6, 0x00, 0x00, 0x1f, 0xe8, 0x02, 0x06, 0x05, 0x9c, 0x20, 0xda, 0xad, 0xda, 0x00, 0xa5, 0xda, 0xc3, 0x05, 0xff, 0xe8, 0xc5, 0xff, 0x00, 0x00, /* 5500K */ + 0xc6, 0x00, 0x00, 0x1f, 0xdd, 0x02, 0x06, 0x04, 0x87, 0x20, 0xd0, 0x95, 0xda, 0x00, 0x8f, 0xda, 0xb9, 0x04, 0xff, 0xdd, 0xaa, 0xff, 0x00, 0x00, /* 4900K */ + 0xc6, 0x00, 0x00, 0x1f, 0xcd, 0x02, 0x06, 0x04, 0x6b, 0x20, 0xc1, 0x77, 0xda, 0x00, 0x71, 0xda, 0xac, 0x04, 0xff, 0xcd, 0x87, 0xff, 0x00, 0x00, /* 4300K */ + 0xc6, 0x00, 0x00, 0x1f, 0xb9, 0x02, 0x06, 0x04, 0x4e, 0x20, 0x9e, 0x56, 0xda, 0x00, 0x52, 0xda, 0x9b, 0x04, 0xff, 0xb9, 0x62, 0xff, 0x00, 0x00, /* 3700K */ + 0xc6, 0x00, 0x00, 0x1f, 0xa4, 0x02, 0x06, 0x03, 0x34, 0x20, 0x9a, 0x3a, 0xda, 0x00, 0x37, 0xda, 0x8a, 0x03, 0xff, 0xa4, 0x42, 0xff, 0x00, 0x00, /* 3100K */ + 0xc6, 0x00, 0x00, 0x1f, 0x78, 0x02, 0x06, 0x02, 0x15, 0x20, 0x71, 0x17, 0xda, 0x00, 0x16, 0xda, 0x65, 0x02, 0xff, 0x78, 0x1a, 0xff, 0x00, 0x00, /* 2300K */ + 0xc6, 0x00, 0x00, 0x1f, 0xf1, 0x01, 0x07, 0x06, 0xac, 0x20, 0xe2, 0xbf, 0xda, 0x00, 0xb6, 0xda, 0xca, 0x04, 0xff, 0xf1, 0xda, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xf0, 0x01, 0x07, 0x06, 0xab, 0x20, 0xe1, 0xbd, 0xda, 0x00, 0xb5, 0xda, 0xc9, 0x04, 0xff, 0xf0, 0xd8, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xef, 0x01, 0x07, 0x06, 0xa8, 0x20, 0xe0, 0xbb, 0xda, 0x00, 0xb2, 0xda, 0xc8, 0x04, 0xff, 0xef, 0xd5, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xee, 0x01, 0x07, 0x06, 0xa7, 0x20, 0xe0, 0xb9, 0xda, 0x00, 0xb1, 0xda, 0xc7, 0x04, 0xff, 0xee, 0xd3, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xed, 0x01, 0x07, 0x06, 0xa4, 0x20, 0xdf, 0xb6, 0xda, 0x00, 0xae, 0xda, 0xc6, 0x04, 0xff, 0xed, 0xd0, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xec, 0x01, 0x07, 0x06, 0xa3, 0x20, 0xde, 0xb4, 0xda, 0x00, 0xac, 0xda, 0xc6, 0x04, 0xff, 0xec, 0xce, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xeb, 0x01, 0x07, 0x06, 0xa0, 0x20, 0xdd, 0xb2, 0xda, 0x00, 0xaa, 0xda, 0xc5, 0x04, 0xff, 0xeb, 0xcb, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xea, 0x01, 0x07, 0x06, 0x9f, 0x20, 0xdc, 0xb0, 0xda, 0x00, 0xa8, 0xda, 0xc4, 0x04, 0xff, 0xea, 0xc9, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe9, 0x01, 0x07, 0x06, 0x9d, 0x20, 0xdb, 0xae, 0xda, 0x00, 0xa7, 0xda, 0xc3, 0x04, 0xff, 0xe9, 0xc7, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe8, 0x01, 0x07, 0x06, 0x9b, 0x20, 0xda, 0xac, 0xda, 0x00, 0xa4, 0xda, 0xc2, 0x04, 0xff, 0xe8, 0xc4, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe7, 0x01, 0x07, 0x06, 0x99, 0x20, 0xd9, 0xaa, 0xda, 0x00, 0xa2, 0xda, 0xc1, 0x04, 0xff, 0xe7, 0xc2, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe6, 0x01, 0x07, 0x06, 0x97, 0x20, 0xd8, 0xa7, 0xda, 0x00, 0xa0, 0xda, 0xc1, 0x04, 0xff, 0xe6, 0xbf, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe5, 0x01, 0x07, 0x06, 0x95, 0x20, 0xd7, 0xa6, 0xda, 0x00, 0x9e, 0xda, 0xc0, 0x04, 0xff, 0xe5, 0xbd, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe4, 0x01, 0x07, 0x06, 0x93, 0x20, 0xd6, 0xa3, 0xda, 0x00, 0x9c, 0xda, 0xbf, 0x04, 0xff, 0xe4, 0xba, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe3, 0x01, 0x07, 0x06, 0x91, 0x20, 0xd5, 0xa1, 0xda, 0x00, 0x9a, 0xda, 0xbe, 0x04, 0xff, 0xe3, 0xb8, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe2, 0x01, 0x07, 0x06, 0x8f, 0x20, 0xd4, 0x9e, 0xda, 0x00, 0x97, 0xda, 0xbd, 0x04, 0xff, 0xe2, 0xb5, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xe0, 0x01, 0x07, 0x06, 0x8d, 0x20, 0xd2, 0x9c, 0xda, 0x00, 0x95, 0xda, 0xbb, 0x04, 0xff, 0xe0, 0xb2, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xdf, 0x01, 0x07, 0x06, 0x8a, 0x20, 0xd1, 0x99, 0xda, 0x00, 0x92, 0xda, 0xbb, 0x04, 0xff, 0xdf, 0xaf, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xde, 0x01, 0x07, 0x06, 0x89, 0x20, 0xd0, 0x97, 0xda, 0x00, 0x91, 0xda, 0xba, 0x04, 0xff, 0xde, 0xad, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xdd, 0x01, 0x07, 0x06, 0x86, 0x20, 0xd0, 0x95, 0xda, 0x00, 0x8e, 0xda, 0xb9, 0x04, 0xff, 0xdd, 0xaa, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xdb, 0x01, 0x07, 0x05, 0x84, 0x20, 0xce, 0x92, 0xda, 0x00, 0x8c, 0xda, 0xb7, 0x04, 0xff, 0xdb, 0xa7, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xda, 0x01, 0x07, 0x05, 0x81, 0x20, 0xcd, 0x90, 0xda, 0x00, 0x89, 0xda, 0xb6, 0x04, 0xff, 0xda, 0xa4, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xd9, 0x01, 0x07, 0x05, 0x7f, 0x20, 0xcc, 0x8d, 0xda, 0x00, 0x87, 0xda, 0xb6, 0x04, 0xff, 0xd9, 0xa1, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xd7, 0x01, 0x07, 0x05, 0x7c, 0x20, 0xca, 0x89, 0xda, 0x00, 0x83, 0xda, 0xb4, 0x04, 0xff, 0xd7, 0x9d, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xd6, 0x01, 0x07, 0x05, 0x79, 0x20, 0xc9, 0x87, 0xda, 0x00, 0x81, 0xda, 0xb3, 0x04, 0xff, 0xd6, 0x9a, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xd4, 0x01, 0x07, 0x05, 0x77, 0x20, 0xc7, 0x84, 0xda, 0x00, 0x7e, 0xda, 0xb1, 0x04, 0xff, 0xd4, 0x97, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xd3, 0x01, 0x07, 0x05, 0x75, 0x20, 0xc6, 0x82, 0xda, 0x00, 0x7c, 0xda, 0xb1, 0x04, 0xff, 0xd3, 0x94, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xd1, 0x01, 0x07, 0x05, 0x72, 0x20, 0xc4, 0x7e, 0xda, 0x00, 0x78, 0xda, 0xaf, 0x04, 0xff, 0xd1, 0x90, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xd0, 0x01, 0x07, 0x05, 0x6f, 0x20, 0xc3, 0x7b, 0xda, 0x00, 0x76, 0xda, 0xae, 0x04, 0xff, 0xd0, 0x8d, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xce, 0x01, 0x07, 0x05, 0x6d, 0x20, 0xc1, 0x79, 0xda, 0x00, 0x73, 0xda, 0xac, 0x04, 0xff, 0xce, 0x8a, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xcc, 0x01, 0x07, 0x05, 0x6a, 0x20, 0xc0, 0x75, 0xda, 0x00, 0x70, 0xda, 0xab, 0x04, 0xff, 0xcc, 0x86, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xca, 0x01, 0x07, 0x05, 0x67, 0x20, 0xbe, 0x73, 0xda, 0x00, 0x6d, 0xda, 0xa9, 0x03, 0xff, 0xca, 0x83, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc9, 0x00, 0x07, 0x05, 0x64, 0x20, 0xbd, 0x6f, 0xda, 0x00, 0x6a, 0xda, 0xa8, 0x03, 0xff, 0xc9, 0x7f, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc7, 0x00, 0x07, 0x05, 0x62, 0x20, 0xbb, 0x6c, 0xda, 0x00, 0x68, 0xda, 0xa7, 0x03, 0xff, 0xc7, 0x7c, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc5, 0x00, 0x07, 0x05, 0x5f, 0x20, 0xb9, 0x69, 0xda, 0x00, 0x64, 0xda, 0xa5, 0x03, 0xff, 0xc5, 0x78, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, /* 37 step */ + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x1f, 0xc3, 0x00, 0x07, 0x05, 0x5c, 0x20, 0xb7, 0x66, 0xda, 0x00, 0x62, 0xda, 0xa3, 0x03, 0xff, 0xc3, 0x75, 0xff, 0x00, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_panel_EA8079B_AMS646YB01.c b/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_panel_EA8079B_AMS646YB01.c index 81d7714e1..d31995911 100644 --- a/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_panel_EA8079B_AMS646YB01.c +++ b/techpack/display/msm/samsung/EA8079B_AMS646YB01/ss_dsi_panel_EA8079B_AMS646YB01.c @@ -983,7 +983,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/Kconfig b/techpack/display/msm/samsung/Kconfig index dde45bc62..19fbab5d0 100644 --- a/techpack/display/msm/samsung/Kconfig +++ b/techpack/display/msm/samsung/Kconfig @@ -302,3 +302,10 @@ config PANEL_EA8079B_AMS646YB01_FHD default n ---help--- MAGNA EA8079B LDI 1080_2400 R8_Rev01 + +config PANEL_S6E3FC3_AMS646YD01_FHD + depends on DISPLAY_SAMSUNG + bool "SEC S6E3FC3 LDI" + default n + ---help--- + SEC S6E3FC3 LDI 1080_2400 A52XQ and R8_Rev07 diff --git a/techpack/display/msm/samsung/MAFPC/ss_dsi_mafpc_XA1.c b/techpack/display/msm/samsung/MAFPC/ss_dsi_mafpc_XA1.c index 2e245cad4..b8f2408b6 100755 --- a/techpack/display/msm/samsung/MAFPC/ss_dsi_mafpc_XA1.c +++ b/techpack/display/msm/samsung/MAFPC/ss_dsi_mafpc_XA1.c @@ -529,11 +529,13 @@ static long ss_mafpc_ioctl(struct file *file, unsigned int cmd, unsigned long ar vdd->mafpc.en = true; break; case IOCTL_MAFPC_ON_INSTANT: + vdd->mafpc.en = true; if (!ss_is_ready_to_send_cmd(vdd)) { - LCD_ERR("Panel is not ready. Panel State(%d)\n", vdd->panel_state); - return -ENODEV; + LCD_INFO("Panel is not ready(%d), will apply next display on\n", + vdd->panel_state); + break; } - vdd->mafpc.en = true; + ss_mafpc_img_write(vdd, true); ss_mafpc_enable(vdd, true); break; diff --git a/techpack/display/msm/samsung/Makefile b/techpack/display/msm/samsung/Makefile index de88479c0..e2ca8edfa 100644 --- a/techpack/display/msm/samsung/Makefile +++ b/techpack/display/msm/samsung/Makefile @@ -127,3 +127,6 @@ obj-$(CONFIG_PANEL_EA8076A_AMS646UJ10_FHD) += EA8076A_AMS646UJ10/ # R8_Rev01 panel obj-$(CONFIG_PANEL_EA8079B_AMS646YB01_FHD) += EA8079B_AMS646YB01/ + +# A52 & R8_Rev07 panel +obj-$(CONFIG_PANEL_S6E3FC3_AMS646YD01_FHD) += S6E3FC3_AMS646YD01/ diff --git a/techpack/display/msm/samsung/S6E36W3_AMB114EU09/dsi_panel_S6E36W3_AMB114EU09_octa_cmd.dtsi b/techpack/display/msm/samsung/S6E36W3_AMB114EU09/dsi_panel_S6E36W3_AMB114EU09_octa_cmd.dtsi index 2689a2cd0..2659540e1 100755 --- a/techpack/display/msm/samsung/S6E36W3_AMB114EU09/dsi_panel_S6E36W3_AMB114EU09_octa_cmd.dtsi +++ b/techpack/display/msm/samsung/S6E36W3_AMB114EU09/dsi_panel_S6E36W3_AMB114EU09_octa_cmd.dtsi @@ -25,8 +25,8 @@ qcom,mdss-dsi-sec-bl-pmic-control-type = "bl_ctrl_dcs"; qcom,mdss-dsi-bl-min-level = <1>; - qcom,mdss-dsi-bl-max-level = <36500>; - qcom,mdss-brightness-max-level = <36500>; + qcom,mdss-dsi-bl-max-level = <50000>; + qcom,mdss-brightness-max-level = <50000>; qcom,mdss-brightness-default-level = <25500>; qcom,mdss-dsi-interleave-mode = <0>; @@ -589,7 +589,7 @@ >; samsung,hbm_candela_map_table_revA = < 0 9600 11999 670 5 - 1 12000 25501 1000 6 + 1 12000 50000 1000 6 >; /* WHITE uses table_revK 32/119/207/282/440/666 */ @@ -603,7 +603,7 @@ samsung,hbm_candela_map_table_revK = < 0 9600 11999 440 5 /* BLOOMX_TODO : need to modify proper just cd value for WHITE */ - 1 12000 25501 666 6 + 1 12000 50000 666 6 >; /* diff --git a/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_mdnie_S6E36W3_AMB114EU09.h b/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_mdnie_S6E36W3_AMB114EU09.h index 5440f1788..81783d9b4 100755 --- a/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_mdnie_S6E36W3_AMB114EU09.h +++ b/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_mdnie_S6E36W3_AMB114EU09.h @@ -92,7 +92,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe0, 0x00, 0xa4, 0x00, 0xff, 0x00, 0x00, 0xe0, 0xa4, 0x00, 0xff, 0x00, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe0, 0x00, 0xa4, 0x00, /* 3700K */ 0x00, 0xff, 0xd3, 0x00, 0x86, 0x00, 0xff, 0x00, 0x00, 0xd3, 0x86, 0x00, 0xff, 0x00, 0xd3, 0x00, 0x00, 0x86, 0xff, 0x00, 0xd3, 0x00, 0x86, 0x00, /* 3100K */ 0x00, 0xff, 0xb8, 0x00, 0x58, 0x00, 0xff, 0x00, 0x00, 0xb8, 0x58, 0x00, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x58, 0xff, 0x00, 0xb8, 0x00, 0x58, 0x00, /* 2300K */ - 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, /* GAME_MODE */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x00, 0xff, 0xfc, 0x00, 0xf6, 0x00, 0xff, 0x00, 0x00, 0xfc, 0xf6, 0x00, 0xff, 0x00, 0xfc, 0x00, 0x00, 0xf6, 0xff, 0x00, 0xfc, 0x00, 0xf6, 0x00, /* 6500K */ 0x00, 0xff, 0xfb, 0x00, 0xf3, 0x00, 0xff, 0x00, 0x00, 0xfb, 0xf3, 0x00, 0xff, 0x00, 0xfb, 0x00, 0x00, 0xf3, 0xff, 0x00, 0xfb, 0x00, 0xf3, 0x00, /* 6300K */ 0x00, 0xff, 0xfa, 0x00, 0xef, 0x00, 0xff, 0x00, 0x00, 0xfa, 0xef, 0x00, 0xff, 0x00, 0xfa, 0x00, 0x00, 0xef, 0xff, 0x00, 0xfa, 0x00, 0xef, 0x00, /* 6100K */ @@ -104,7 +194,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe0, 0x00, 0xa4, 0x00, 0xff, 0x00, 0x00, 0xe0, 0xa4, 0x00, 0xff, 0x00, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe0, 0x00, 0xa4, 0x00, /* 3700K */ 0x00, 0xff, 0xd3, 0x00, 0x86, 0x00, 0xff, 0x00, 0x00, 0xd3, 0x86, 0x00, 0xff, 0x00, 0xd3, 0x00, 0x00, 0x86, 0xff, 0x00, 0xd3, 0x00, 0x86, 0x00, /* 3100K */ 0x00, 0xff, 0xb8, 0x00, 0x58, 0x00, 0xff, 0x00, 0x00, 0xb8, 0x58, 0x00, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x58, 0xff, 0x00, 0xb8, 0x00, 0x58, 0x00, /* 2300K */ - 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, /* GAME_MODE */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_panel_S6E36W3_AMB114EU09.c b/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_panel_S6E36W3_AMB114EU09.c index 5727196a8..ffcfa731b 100755 --- a/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_panel_S6E36W3_AMB114EU09.c +++ b/techpack/display/msm/samsung/S6E36W3_AMB114EU09/ss_dsi_panel_S6E36W3_AMB114EU09.c @@ -732,7 +732,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 12; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_mdnie_S6E3FA7_AMB623VH01.h b/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_mdnie_S6E3FA7_AMB623VH01.h index d62edac4a..f7123201c 100755 --- a/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_mdnie_S6E3FA7_AMB623VH01.h +++ b/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_mdnie_S6E3FA7_AMB623VH01.h @@ -92,6 +92,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xde, 0x00, 0xa1, 0x00, 0xff, 0x00, 0x00, 0xde, 0xa1, 0x00, 0xff, 0x00, 0xde, 0x00, 0x00, 0xa1, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x00, 0xff, 0xd1, 0x00, 0x83, 0x00, 0xff, 0x00, 0x00, 0xd1, 0x83, 0x00, 0xff, 0x00, 0xd1, 0x00, 0x00, 0x83, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x30, 0xf1, 0xfc, 0x0a, 0xf4, 0x00, 0xf1, 0x1d, 0x00, 0xf8, 0xed, 0x00, 0xf8, 0x14, 0xf9, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xfc, 0x00, 0xf5, 0x00, /* 6500K */ 0x30, 0xf1, 0xfb, 0x0a, 0xf0, 0x00, 0xf1, 0x1d, 0x00, 0xf7, 0xe9, 0x00, 0xf8, 0x14, 0xf8, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xfb, 0x00, 0xf1, 0x00, /* 6300K */ 0x30, 0xf1, 0xfa, 0x0a, 0xec, 0x00, 0xf1, 0x1d, 0x00, 0xf6, 0xe6, 0x00, 0xf8, 0x14, 0xf7, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xfa, 0x00, 0xed, 0x00, /* 6100K */ @@ -103,6 +194,97 @@ static char night_mode_data[] = { 0x30, 0xf1, 0xde, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xdb, 0x9c, 0x00, 0xf8, 0x14, 0xdb, 0x00, 0x00, 0x99, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x30, 0xf1, 0xd1, 0x08, 0x82, 0x00, 0xf1, 0x1d, 0x00, 0xce, 0x7f, 0x00, 0xf8, 0x14, 0xcf, 0x00, 0x00, 0x7d, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x30, 0xf1, 0xba, 0x07, 0x5d, 0x00, 0xf1, 0x1d, 0x00, 0xb7, 0x5a, 0x00, 0xf8, 0x14, 0xb8, 0x00, 0x00, 0x59, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xda, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd3, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd2, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd5, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xcf, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd0, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xca, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcb, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc1, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc5, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbf, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc4, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbe, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc2, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbc, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc0, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xba, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xbf, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xb9, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbd, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbc, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb7, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xba, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb5, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xb9, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb4, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb1, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb8, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb3, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xb0, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb7, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb2, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xaf, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb5, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xb0, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xad, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb4, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xaf, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xac, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb3, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xae, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb2, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xad, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xaa, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xac, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xae, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa9, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xad, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa8, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xac, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa7, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xab, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa6, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_panel_S6E3FA7_AMB623VH01.c b/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_panel_S6E3FA7_AMB623VH01.c index e1983fcd5..863461143 100755 --- a/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_panel_S6E3FA7_AMB623VH01.c +++ b/techpack/display/msm/samsung/S6E3FA7_AMB623VH01/ss_dsi_panel_S6E3FA7_AMB623VH01.c @@ -496,7 +496,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_mdnie_S6E3FA9_AMB667UM01.h b/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_mdnie_S6E3FA9_AMB667UM01.h index 1bbdc6f22..ac875c6ab 100755 --- a/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_mdnie_S6E3FA9_AMB667UM01.h +++ b/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_mdnie_S6E3FA9_AMB667UM01.h @@ -90,6 +90,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe0, 0x00, 0xa4, 0x00, 0xff, 0x00, 0x00, 0xe0, 0xa4, 0x00, 0xff, 0x00, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe0, 0x00, 0xa4, 0x00, /* 3700K */ 0x00, 0xff, 0xd3, 0x00, 0x86, 0x00, 0xff, 0x00, 0x00, 0xd3, 0x86, 0x00, 0xff, 0x00, 0xd3, 0x00, 0x00, 0x86, 0xff, 0x00, 0xd3, 0x00, 0x86, 0x00, /* 3100K */ 0x00, 0xff, 0xb8, 0x00, 0x58, 0x00, 0xff, 0x00, 0x00, 0xb8, 0x58, 0x00, 0xff, 0x00, 0xb8, 0x00, 0x00, 0x58, 0xff, 0x00, 0xb8, 0x00, 0x58, 0x00, /* 2300K */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x28, 0xe3, 0xf0, 0x0b, 0xe8, 0x00, 0xef, 0x0b, 0x08, 0xdd, 0xe6, 0x00, 0xeb, 0x11, 0xec, 0x03, 0x00, 0xe0, 0xff, 0x00, 0xfc, 0x00, 0xf6, 0x00, /* 6500K */ 0x28, 0xe3, 0xef, 0x0b, 0xe5, 0x00, 0xef, 0x0b, 0x08, 0xdc, 0xe3, 0x00, 0xeb, 0x11, 0xeb, 0x03, 0x00, 0xdd, 0xff, 0x00, 0xfb, 0x00, 0xf3, 0x00, /* 6300K */ 0x28, 0xe3, 0xee, 0x0b, 0xe1, 0x00, 0xef, 0x0b, 0x08, 0xdc, 0xdf, 0x00, 0xeb, 0x11, 0xea, 0x03, 0x00, 0xd9, 0xff, 0x00, 0xfa, 0x00, 0xef, 0x00, /* 6100K */ @@ -101,6 +192,97 @@ static char night_mode_data[] = { 0x28, 0xe3, 0xd5, 0x0a, 0x9a, 0x00, 0xef, 0x0b, 0x07, 0xc5, 0x99, 0x00, 0xeb, 0x11, 0xd2, 0x03, 0x00, 0x95, 0xff, 0x00, 0xe0, 0x00, 0xa4, 0x00, /* 3700K */ 0x28, 0xe3, 0xc9, 0x09, 0x7e, 0x00, 0xef, 0x0b, 0x07, 0xb9, 0x7d, 0x00, 0xeb, 0x11, 0xc6, 0x02, 0x00, 0x7a, 0xff, 0x00, 0xd3, 0x00, 0x86, 0x00, /* 3100K */ 0x28, 0xe3, 0xaf, 0x08, 0x53, 0x00, 0xef, 0x0b, 0x06, 0xa2, 0x52, 0x00, 0xeb, 0x11, 0xac, 0x02, 0x00, 0x50, 0xff, 0x00, 0xb8, 0x00, 0x58, 0x00, /* 2300K */ + 0x28, 0xe3, 0xea, 0x0a, 0xd7, 0x00, 0xef, 0x0b, 0x07, 0xd7, 0xd5, 0x00, 0xeb, 0x11, 0xe6, 0x02, 0x00, 0xd0, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x28, 0xe3, 0xea, 0x0a, 0xd7, 0x00, 0xef, 0x0b, 0x07, 0xd7, 0xd5, 0x00, 0xeb, 0x11, 0xe6, 0x02, 0x00, 0xd0, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x28, 0xe3, 0xea, 0x0a, 0xd6, 0x00, 0xef, 0x0b, 0x07, 0xd7, 0xd4, 0x00, 0xeb, 0x11, 0xe6, 0x02, 0x00, 0xcf, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x28, 0xe3, 0xea, 0x0a, 0xd6, 0x00, 0xef, 0x0b, 0x07, 0xd7, 0xd4, 0x00, 0xeb, 0x11, 0xe6, 0x02, 0x00, 0xcf, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x28, 0xe3, 0xe9, 0x0a, 0xd5, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd3, 0x00, 0xeb, 0x11, 0xe5, 0x02, 0x00, 0xce, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x28, 0xe3, 0xe9, 0x0a, 0xd5, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd3, 0x00, 0xeb, 0x11, 0xe5, 0x02, 0x00, 0xce, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x28, 0xe3, 0xe9, 0x0a, 0xd4, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd3, 0x00, 0xeb, 0x11, 0xe5, 0x02, 0x00, 0xcd, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x28, 0xe3, 0xe9, 0x0a, 0xd4, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd3, 0x00, 0xeb, 0x11, 0xe5, 0x02, 0x00, 0xcd, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x28, 0xe3, 0xe9, 0x0a, 0xd3, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd2, 0x00, 0xeb, 0x11, 0xe5, 0x02, 0x00, 0xcc, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x28, 0xe3, 0xe9, 0x0a, 0xd3, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd2, 0x00, 0xeb, 0x11, 0xe5, 0x02, 0x00, 0xcc, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x28, 0xe3, 0xe8, 0x0a, 0xd3, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd1, 0x00, 0xeb, 0x11, 0xe4, 0x02, 0x00, 0xcb, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x28, 0xe3, 0xe8, 0x0a, 0xd3, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd1, 0x00, 0xeb, 0x11, 0xe4, 0x02, 0x00, 0xcb, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x28, 0xe3, 0xe8, 0x0a, 0xd2, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd0, 0x00, 0xeb, 0x11, 0xe4, 0x02, 0x00, 0xca, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x28, 0xe3, 0xe8, 0x0a, 0xd2, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xd0, 0x00, 0xeb, 0x11, 0xe4, 0x02, 0x00, 0xca, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x28, 0xe3, 0xe8, 0x0a, 0xd1, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xcf, 0x00, 0xeb, 0x11, 0xe4, 0x02, 0x00, 0xca, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x28, 0xe3, 0xe8, 0x0a, 0xd1, 0x00, 0xef, 0x0b, 0x07, 0xd6, 0xcf, 0x00, 0xeb, 0x11, 0xe4, 0x02, 0x00, 0xca, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x28, 0xe3, 0xe7, 0x0a, 0xd0, 0x00, 0xef, 0x0b, 0x07, 0xd5, 0xce, 0x00, 0xeb, 0x11, 0xe3, 0x02, 0x00, 0xc9, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x28, 0xe3, 0xe7, 0x0a, 0xd0, 0x00, 0xef, 0x0b, 0x07, 0xd5, 0xce, 0x00, 0xeb, 0x11, 0xe3, 0x02, 0x00, 0xc9, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x28, 0xe3, 0xe7, 0x0a, 0xcf, 0x00, 0xef, 0x0b, 0x07, 0xd5, 0xcd, 0x00, 0xeb, 0x11, 0xe3, 0x02, 0x00, 0xc8, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x28, 0xe3, 0xe7, 0x0a, 0xce, 0x00, 0xef, 0x0b, 0x07, 0xd5, 0xcc, 0x00, 0xeb, 0x11, 0xe3, 0x02, 0x00, 0xc7, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x28, 0xe3, 0xe7, 0x0a, 0xce, 0x00, 0xef, 0x0b, 0x07, 0xd5, 0xcc, 0x00, 0xeb, 0x11, 0xe3, 0x02, 0x00, 0xc7, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x28, 0xe3, 0xe7, 0x0a, 0xcd, 0x00, 0xef, 0x0b, 0x07, 0xd5, 0xcb, 0x00, 0xeb, 0x11, 0xe3, 0x02, 0x00, 0xc6, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x28, 0xe3, 0xe6, 0x0a, 0xcd, 0x00, 0xef, 0x0b, 0x07, 0xd4, 0xcb, 0x00, 0xeb, 0x11, 0xe2, 0x02, 0x00, 0xc6, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x28, 0xe3, 0xe6, 0x0a, 0xcc, 0x00, 0xef, 0x0b, 0x07, 0xd4, 0xca, 0x00, 0xeb, 0x11, 0xe2, 0x02, 0x00, 0xc5, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x28, 0xe3, 0xe6, 0x0a, 0xcc, 0x00, 0xef, 0x0b, 0x07, 0xd4, 0xca, 0x00, 0xeb, 0x11, 0xe2, 0x02, 0x00, 0xc5, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x28, 0xe3, 0xe6, 0x0a, 0xcb, 0x00, 0xef, 0x0b, 0x07, 0xd4, 0xca, 0x00, 0xeb, 0x11, 0xe2, 0x02, 0x00, 0xc4, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x28, 0xe3, 0xe6, 0x0a, 0xcb, 0x00, 0xef, 0x0b, 0x07, 0xd4, 0xca, 0x00, 0xeb, 0x11, 0xe2, 0x02, 0x00, 0xc4, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x28, 0xe3, 0xe6, 0x0a, 0xca, 0x00, 0xef, 0x0b, 0x07, 0xd4, 0xc9, 0x00, 0xeb, 0x11, 0xe2, 0x02, 0x00, 0xc3, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x28, 0xe3, 0xe5, 0x0a, 0xc9, 0x00, 0xef, 0x0b, 0x07, 0xd3, 0xc8, 0x00, 0xeb, 0x11, 0xe1, 0x02, 0x00, 0xc3, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x28, 0xe3, 0xe5, 0x0a, 0xc9, 0x00, 0xef, 0x0b, 0x07, 0xd3, 0xc8, 0x00, 0xeb, 0x11, 0xe1, 0x02, 0x00, 0xc3, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x28, 0xe3, 0xe5, 0x0a, 0xc9, 0x00, 0xef, 0x0b, 0x07, 0xd3, 0xc7, 0x00, 0xeb, 0x11, 0xe1, 0x02, 0x00, 0xc2, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x28, 0xe3, 0xe5, 0x0a, 0xc9, 0x00, 0xef, 0x0b, 0x07, 0xd3, 0xc7, 0x00, 0xeb, 0x11, 0xe1, 0x02, 0x00, 0xc2, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x28, 0xe3, 0xe5, 0x0a, 0xc8, 0x00, 0xef, 0x0b, 0x07, 0xd3, 0xc6, 0x00, 0xeb, 0x11, 0xe1, 0x02, 0x00, 0xc1, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x28, 0xe3, 0xe5, 0x09, 0xc8, 0x00, 0xef, 0x0b, 0x07, 0xd3, 0xc6, 0x00, 0xeb, 0x11, 0xe1, 0x02, 0x00, 0xc1, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x28, 0xe3, 0xe4, 0x09, 0xc7, 0x00, 0xef, 0x0b, 0x07, 0xd2, 0xc5, 0x00, 0xeb, 0x11, 0xe0, 0x02, 0x00, 0xc0, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x28, 0xe3, 0xe4, 0x09, 0xc7, 0x00, 0xef, 0x0b, 0x07, 0xd2, 0xc5, 0x00, 0xeb, 0x11, 0xe0, 0x02, 0x00, 0xc0, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x28, 0xe3, 0xe4, 0x09, 0xc6, 0x00, 0xef, 0x0b, 0x07, 0xd2, 0xc4, 0x00, 0xeb, 0x11, 0xe0, 0x02, 0x00, 0xbf, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x28, 0xe3, 0xe4, 0x09, 0xc5, 0x00, 0xef, 0x0b, 0x07, 0xd2, 0xc3, 0x00, 0xeb, 0x11, 0xe0, 0x02, 0x00, 0xbe, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x28, 0xe3, 0xe4, 0x09, 0xc5, 0x00, 0xef, 0x0b, 0x07, 0xd2, 0xc3, 0x00, 0xeb, 0x11, 0xe0, 0x02, 0x00, 0xbe, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x28, 0xe3, 0xe3, 0x09, 0xc4, 0x00, 0xef, 0x0b, 0x07, 0xd1, 0xc2, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xbd, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x28, 0xe3, 0xe3, 0x09, 0xc4, 0x00, 0xef, 0x0b, 0x07, 0xd1, 0xc2, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xbd, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x28, 0xe3, 0xe3, 0x09, 0xc3, 0x00, 0xef, 0x0b, 0x07, 0xd1, 0xc1, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xbc, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x28, 0xe3, 0xe3, 0x09, 0xc3, 0x00, 0xef, 0x0b, 0x07, 0xd1, 0xc1, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xbc, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x28, 0xe3, 0xe2, 0x09, 0xc2, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xc1, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xbb, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x28, 0xe3, 0xe2, 0x09, 0xc2, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xc1, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xbb, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x28, 0xe3, 0xe2, 0x09, 0xc1, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xc0, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xbb, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x28, 0xe3, 0xe2, 0x09, 0xc0, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xbf, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xba, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x28, 0xe3, 0xe2, 0x09, 0xc0, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xbf, 0x00, 0xeb, 0x11, 0xdf, 0x02, 0x00, 0xba, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x28, 0xe3, 0xe1, 0x09, 0xbf, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xbe, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xb9, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x28, 0xe3, 0xe1, 0x09, 0xbf, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xbe, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xb9, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x28, 0xe3, 0xe1, 0x09, 0xbf, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xbd, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xb8, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x28, 0xe3, 0xe1, 0x09, 0xbf, 0x00, 0xef, 0x0b, 0x07, 0xd0, 0xbd, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xb8, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xbe, 0x00, 0xef, 0x0b, 0x07, 0xcf, 0xbc, 0x00, 0xeb, 0x11, 0xdd, 0x02, 0x00, 0xb7, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xbe, 0x00, 0xef, 0x0b, 0x07, 0xcf, 0xbc, 0x00, 0xeb, 0x11, 0xdd, 0x02, 0x00, 0xb7, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xbd, 0x00, 0xef, 0x0b, 0x07, 0xcf, 0xbb, 0x00, 0xeb, 0x11, 0xdd, 0x02, 0x00, 0xb6, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xbc, 0x00, 0xef, 0x0b, 0x07, 0xcf, 0xba, 0x00, 0xeb, 0x11, 0xdd, 0x02, 0x00, 0xb5, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xbc, 0x00, 0xef, 0x0b, 0x07, 0xcf, 0xba, 0x00, 0xeb, 0x11, 0xdd, 0x02, 0x00, 0xb5, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xbb, 0x00, 0xef, 0x0b, 0x07, 0xce, 0xb9, 0x00, 0xeb, 0x11, 0xdc, 0x02, 0x00, 0xb4, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xba, 0x00, 0xef, 0x0b, 0x07, 0xce, 0xb8, 0x00, 0xeb, 0x11, 0xdc, 0x02, 0x00, 0xb4, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xb9, 0x00, 0xef, 0x0b, 0x07, 0xce, 0xb8, 0x00, 0xeb, 0x11, 0xdc, 0x02, 0x00, 0xb3, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x28, 0xe3, 0xe0, 0x09, 0xb9, 0x00, 0xef, 0x0b, 0x07, 0xce, 0xb8, 0x00, 0xeb, 0x11, 0xdc, 0x02, 0x00, 0xb3, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x28, 0xe3, 0xdf, 0x09, 0xb8, 0x00, 0xef, 0x0b, 0x07, 0xcd, 0xb7, 0x00, 0xeb, 0x11, 0xdb, 0x02, 0x00, 0xb2, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x28, 0xe3, 0xdf, 0x09, 0xb7, 0x00, 0xef, 0x0b, 0x07, 0xcd, 0xb6, 0x00, 0xeb, 0x11, 0xdb, 0x02, 0x00, 0xb1, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x28, 0xe3, 0xdf, 0x09, 0xb7, 0x00, 0xef, 0x0b, 0x07, 0xcd, 0xb6, 0x00, 0xeb, 0x11, 0xdb, 0x02, 0x00, 0xb1, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x28, 0xe3, 0xdf, 0x09, 0xb6, 0x00, 0xef, 0x0b, 0x07, 0xcd, 0xb5, 0x00, 0xeb, 0x11, 0xdb, 0x02, 0x00, 0xb0, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x28, 0xe3, 0xdf, 0x09, 0xb5, 0x00, 0xef, 0x0b, 0x07, 0xcd, 0xb4, 0x00, 0xeb, 0x11, 0xdb, 0x02, 0x00, 0xaf, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x28, 0xe3, 0xde, 0x09, 0xb5, 0x00, 0xef, 0x0b, 0x07, 0xcc, 0xb3, 0x00, 0xeb, 0x11, 0xda, 0x02, 0x00, 0xae, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x28, 0xe3, 0xde, 0x09, 0xb5, 0x00, 0xef, 0x0b, 0x07, 0xcc, 0xb3, 0x00, 0xeb, 0x11, 0xda, 0x02, 0x00, 0xae, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x28, 0xe3, 0xde, 0x09, 0xb4, 0x00, 0xef, 0x0b, 0x07, 0xcc, 0xb2, 0x00, 0xeb, 0x11, 0xda, 0x02, 0x00, 0xad, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x28, 0xe3, 0xde, 0x09, 0xb3, 0x00, 0xef, 0x0b, 0x07, 0xcc, 0xb1, 0x00, 0xeb, 0x11, 0xda, 0x02, 0x00, 0xad, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x28, 0xe3, 0xdd, 0x09, 0xb2, 0x00, 0xef, 0x0b, 0x07, 0xcb, 0xb0, 0x00, 0xeb, 0x11, 0xd9, 0x02, 0x00, 0xac, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x28, 0xe3, 0xdd, 0x09, 0xb2, 0x00, 0xef, 0x0b, 0x07, 0xcb, 0xb0, 0x00, 0xeb, 0x11, 0xd9, 0x02, 0x00, 0xac, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x28, 0xe3, 0xdd, 0x09, 0xb1, 0x00, 0xef, 0x0b, 0x07, 0xcb, 0xaf, 0x00, 0xeb, 0x11, 0xd9, 0x02, 0x00, 0xab, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x28, 0xe3, 0xdd, 0x09, 0xb0, 0x00, 0xef, 0x0b, 0x07, 0xcb, 0xae, 0x00, 0xeb, 0x11, 0xd9, 0x02, 0x00, 0xaa, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x28, 0xe3, 0xdc, 0x09, 0xaf, 0x00, 0xef, 0x0b, 0x07, 0xca, 0xae, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xa9, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x28, 0xe3, 0xdc, 0x09, 0xae, 0x00, 0xef, 0x0b, 0x07, 0xca, 0xad, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xa8, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x28, 0xe3, 0xdc, 0x09, 0xad, 0x00, 0xef, 0x0b, 0x07, 0xca, 0xac, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xa7, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x28, 0xe3, 0xdc, 0x09, 0xad, 0x00, 0xef, 0x0b, 0x07, 0xca, 0xac, 0x00, 0xeb, 0x11, 0xd8, 0x02, 0x00, 0xa7, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x28, 0xe3, 0xdb, 0x09, 0xac, 0x00, 0xef, 0x0b, 0x07, 0xc9, 0xab, 0x00, 0xeb, 0x11, 0xd7, 0x02, 0x00, 0xa6, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x28, 0xe3, 0xdb, 0x09, 0xab, 0x00, 0xef, 0x0b, 0x07, 0xc9, 0xaa, 0x00, 0xeb, 0x11, 0xd7, 0x02, 0x00, 0xa6, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x28, 0xe3, 0xdb, 0x09, 0xab, 0x00, 0xef, 0x0b, 0x07, 0xc9, 0xa9, 0x00, 0xeb, 0x11, 0xd7, 0x02, 0x00, 0xa5, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x28, 0xe3, 0xdb, 0x09, 0xaa, 0x00, 0xef, 0x0b, 0x07, 0xc9, 0xa8, 0x00, 0xeb, 0x11, 0xd7, 0x02, 0x00, 0xa4, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x28, 0xe3, 0xda, 0x09, 0xa9, 0x00, 0xef, 0x0b, 0x07, 0xc9, 0xa7, 0x00, 0xeb, 0x11, 0xd6, 0x02, 0x00, 0xa3, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x28, 0xe3, 0xda, 0x09, 0xa8, 0x00, 0xef, 0x0b, 0x07, 0xc9, 0xa6, 0x00, 0xeb, 0x11, 0xd6, 0x02, 0x00, 0xa2, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x28, 0xe3, 0xda, 0x09, 0xa7, 0x00, 0xef, 0x0b, 0x07, 0xc7, 0xa5, 0x00, 0xeb, 0x11, 0xd6, 0x02, 0x00, 0xa1, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x28, 0xe3, 0xd9, 0x09, 0xa6, 0x00, 0xef, 0x0b, 0x07, 0xc8, 0xa5, 0x00, 0xeb, 0x11, 0xd5, 0x02, 0x00, 0xa0, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x28, 0xe3, 0xd9, 0x09, 0xa6, 0x00, 0xef, 0x0b, 0x07, 0xc8, 0xa5, 0x00, 0xeb, 0x11, 0xd5, 0x02, 0x00, 0xa0, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x28, 0xe3, 0xd9, 0x09, 0xa5, 0x00, 0xef, 0x0b, 0x07, 0xc8, 0xa4, 0x00, 0xeb, 0x11, 0xd5, 0x02, 0x00, 0x9f, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x28, 0xe3, 0xd9, 0x09, 0xa4, 0x00, 0xef, 0x0b, 0x07, 0xc8, 0xa3, 0x00, 0xeb, 0x11, 0xd5, 0x02, 0x00, 0x9e, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x28, 0xe3, 0xd8, 0x09, 0xa3, 0x00, 0xef, 0x0b, 0x07, 0xc7, 0xa2, 0x00, 0xeb, 0x11, 0xd4, 0x02, 0x00, 0x9e, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x28, 0xe3, 0xd8, 0x09, 0xa2, 0x00, 0xef, 0x0b, 0x07, 0xc7, 0xa1, 0x00, 0xeb, 0x11, 0xd4, 0x02, 0x00, 0x9d, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_panel_S6E3FA9_AMB667UM01.c b/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_panel_S6E3FA9_AMB667UM01.c index e0404cffc..017695b22 100755 --- a/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_panel_S6E3FA9_AMB667UM01.c +++ b/techpack/display/msm/samsung/S6E3FA9_AMB667UM01/ss_dsi_panel_S6E3FA9_AMB667UM01.c @@ -567,7 +567,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/Makefile b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/Makefile new file mode 100644 index 000000000..1d1ce722e --- /dev/null +++ b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/Makefile @@ -0,0 +1,12 @@ +# +# panel object +# namd : ss_dsi_panel_"DDI NAME"_"PANEL NAME".c +# + +ccflags-y := -I$(srctree)/include/drm +ccflags-y += -I$(srctree)/techpack/display/msm +ccflags-y += -I$(srctree)/techpack/display/msm/dsi +ccflags-y += -I$(srctree)/techpack/display/msm/sde +ccflags-y += -I$(srctree)/techpack/display/msm/samsung + +obj-y += ss_dsi_panel_S6E3FC3_AMS646YD01.o diff --git a/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/dsi_panel_S6E3FC3_AMS646YD01_fhd_octa_cmd.dtsi b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/dsi_panel_S6E3FC3_AMS646YD01_fhd_octa_cmd.dtsi new file mode 100644 index 000000000..2653d44be --- /dev/null +++ b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/dsi_panel_S6E3FC3_AMS646YD01_fhd_octa_cmd.dtsi @@ -0,0 +1,1568 @@ +/* Copyright (c) 2012, Samsung Electronics Corporation. 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 { + ss_dsi_panel_S6E3FC3_AMS646YD01_FHD: ss_dsi_panel_S6E3FC3_AMS646YD01_FHD { + qcom,mdss-dsi-panel-name = "ss_dsi_panel_S6E3FC3_AMS646YD01_FHD"; + label = "ss_dsi_panel_S6E3FC3_AMS646YD01_FHD"; + + qcom,mdss-dsi-bpp = <24>; + + qcom,mdss-dsi-underflow-color = <0xFF>; + qcom,mdss-dsi-border-color = <0>; + + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <486>; + qcom,mdss-brightness-max-level = <486>; + qcom,mdss-brightness-default-level = <255>; + + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + + qcom,mdss-dsi-te-pin-select = <1>; + + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2C>; + qcom,mdss-dsi-wr-mem-continue = <0x3C>; + + qcom,mdss-dsi-pixel-packing = "loose"; + + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + 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-lane-map = "lane_map_0123"; + + qcom,mdss-dsi-t-clk-pre = <0x3E>; + qcom,mdss-dsi-t-clk-post = <0x10>; + + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + + qcom,mdss-pan-physical-width-dimension = <67>; /* 67.284 round-off */ + qcom,mdss-pan-physical-height-dimension = <150>; /* 149.520 round-off */ + + qcom,mdss-dsi-reset-sequence = <0 10>, <1 10>; + + qcom,mdss-dsi-lp11-init; + /*qcom,mdss-dsi-init-delay-us = <1000>;*/ + + qcom,mdss-dsi-rx-eot-ignore; + qcom,mdss-dsi-tx-eot-append; + + /* HDR Setting */ + /*qcom,mdss-dsi-panel-hdr-enabled;*/ + /*qcom,mdss-dsi-panel-hdr-color-primaries = <15635 16450 34000 16000 13250 34500 7500 3000>;*/ + /*qcom,mdss-dsi-panel-peak-brightness = <5400000>;*/ + /*qcom,mdss-dsi-panel-average-brightness = <2000000>;*/ + /*qcom,mdss-dsi-panel-blackness-level = <2000>;*/ + + qcom,ulps-enabled; + + /* qcom,suspend-ulps-enabled; */ + qcom,esd-check-enabled; + qcom,mdss-dsi-panel-status-check-mode ="irq_check"; + qcom,mdss-dsi-panel-status-irq-trigger1 = "falling"; + /*qcom,mdss-dsi-panel-status-read-length;*/ + /*qcom,mdss-dsi-panel-status-value;*/ + /*qcom,mdss-dsi-panel-status-irq-trigger1 = "rising";*/ + + /* ************************************************************* + * Below parameters are samsung dependent thigs + * ************************************************************* + */ + samsung,panel-vendor = "SDC"; + samsung,disp-model = "AMS646YD01"; + samsung,panel-lpm-enable; + samsung,support_gamma_mode2; + samsung,skip_read_on_pre; + samsung,elvss_interpolation_temperature = <(-16)>; + samsung,support_lpm; + samsung,rsc_4_frame_idle; + samsung,support_factory_panel_swap; + samsung,support-optical-fingerprint; + + samsung,support_vrr_based_bl; /* VRR Variable Refresh Rate */ + + //samsung,esd-irq-trigger1 = "falling"; /* FG_ERR */ + + /* ************************************************************* + * SELF DISPLAY + * ************************************************************* + */ + //ss,self_display = <&self_display_FC3_dtsi>; + + /* ************************************************************* + * Tx + * ************************************************************* + */ + samsung,level0_key_enable_tx_cmds_revA = [29 01 00 00 00 00 03 9F A5 A5]; /* PASSWD0 */ + samsung,level0_key_disable_tx_cmds_revA = [29 01 00 00 00 00 03 9F 5A 5A]; /* PASSWD0 */ + samsung,level1_key_enable_tx_cmds_revA = [29 01 00 00 00 00 03 F0 5A 5A]; /* PASSWD1 */ + samsung,level1_key_disable_tx_cmds_revA = [29 01 00 00 00 00 03 F0 A5 A5]; /* PASSWD1 */ + samsung,level2_key_enable_tx_cmds_revA = [29 01 00 00 00 00 03 FC 5A 5A]; + samsung,level2_key_disable_tx_cmds_revA = [29 01 00 00 00 00 03 FC A5 A5]; + + /* BRIGHTNESS_MAX_PACKET = 50 */ + samsung,brightness_tx_cmds_revA = [ + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + 39 01 00 00 00 00 01 00 + ]; + + samsung,display_on_tx_cmds_revA = [ + /* DSC PPS cmd unlock & lock LEVEL0 KEY */ + 29 00 00 00 00 00 03 9F A5 A5 + 05 00 00 00 00 00 02 29 00 + 29 01 00 00 00 00 03 9F 5A 5A + ]; + + samsung,display_off_tx_cmds_revA = [05 01 00 00 00 00 02 28 00]; + + samsung,reg_read_pos_tx_cmds_revA = [29 00 00 00 00 00 04 B0 00 00 00]; + + samsung,mtp_write_sysfs_tx_cmds_revA = [ + 29 00 00 00 00 00 3D 00 + 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 + ]; + + samsung,smooth_dimming_off_tx_cmds_revA = [ + 29 00 00 00 00 00 03 F0 5A 5A + 29 01 00 00 21 00 02 53 20 + 29 01 00 00 00 00 03 F0 A5 A5 + ]; + + samsung,gamma_mode2_normal_tx_cmds_revI=[ + 29 00 00 00 00 00 04 B0 00 91 63 + 29 00 00 00 00 00 02 63 60 /* hbm setting 1 */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f1 07 /* hbm setting 2 */ + + 29 00 00 00 00 00 02 53 20 /* dimming speed setting */ + 29 00 00 00 00 00 03 51 03 FF /* WRDISBV */ + 29 00 00 00 00 00 02 B5 14 /* temperature */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f0 00 /* hbm setting 2 */ + + 29 00 00 00 00 00 04 B0 00 76 63 + 29 00 00 00 00 00 04 63 00 00 00 /* AOR */ + ]; + + samsung,gamma_mode2_normal_tx_cmds_revG=[ + 29 00 00 00 00 00 03 91 02 01 /* normal brightness */ + 29 00 00 00 00 00 02 53 20 /* dimming speed setting */ + 29 00 00 00 00 00 03 51 03 FF /* WRDISBV */ + 29 00 00 00 00 00 02 B5 14 /* temperature */ + 29 00 00 00 00 00 04 B0 00 76 63 + 29 00 00 00 00 00 04 63 00 00 00 /* AOR */ + ]; + + samsung,gamma_mode2_normal_tx_cmds_revA=[ + 29 00 00 00 00 00 04 B0 00 91 63 + 29 00 00 00 00 00 02 63 60 /* hbm setting 1 */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f1 07 /* hbm setting 2 */ + + 29 00 00 00 00 00 02 53 20 /* dimming speed setting */ + 29 00 00 00 00 00 03 51 03 FF /* WRDISBV */ + 29 00 00 00 00 00 02 B5 14 /* temperature */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f0 00 /* hbm setting 2 */ + ]; + + samsung,gamma_mode2_hbm_tx_cmds_revI=[ + 29 00 00 00 00 00 04 B0 00 91 63 + 29 00 00 00 00 00 02 63 20 /* hbm setting 1 */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f1 00 /* hbm setting 2 */ + + 29 00 00 00 00 00 02 53 E0 /* dimming speed setting */ + 29 00 00 00 00 00 03 51 03 FF /* WRDISBV */ + 29 00 00 00 00 00 02 B5 14 /* temperature */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f0 07 /* hbm setting 2 */ + + 29 00 00 00 00 00 04 B0 00 76 63 + 29 00 00 00 00 00 04 63 00 00 00 /* AOR */ + ]; + + samsung,gamma_mode2_hbm_tx_cmds_revG=[ + 29 00 00 00 00 00 03 91 02 00 /* hbm brightness */ + 29 00 00 00 00 00 02 53 E0 /* dimming speed setting */ + 29 00 00 00 00 00 03 51 03 FF /* WRDISBV */ + 29 00 00 00 00 00 02 B5 14 /* temperature */ + 29 00 00 00 00 00 04 B0 00 76 63 + 29 00 00 00 00 00 04 63 00 00 00 /* AOR */ + ]; + + samsung,gamma_mode2_hbm_tx_cmds_revA=[ + 29 00 00 00 00 00 04 B0 00 91 63 + 29 00 00 00 00 00 02 63 20 /* hbm setting 1 */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f1 00 /* hbm setting 2 */ + + 29 00 00 00 00 00 02 53 E0 /* dimming speed setting */ + 29 00 00 00 00 00 03 51 03 FF /* WRDISBV */ + 29 00 00 00 00 00 02 B5 14 /* temperature */ + + 29 00 00 00 00 00 04 B0 02 03 63 + 29 00 00 00 00 00 03 63 f0 07 /* hbm setting 2 */ + ]; + + samsung,vrr_tx_cmds_revA = [ + 29 00 00 00 00 00 03 60 00 00 + 29 00 00 00 00 00 02 F7 0F + ]; + + samsung,acl_on_tx_cmds_revA = [ + 29 00 00 00 00 00 04 B0 03 B3 65 + 29 00 00 00 00 00 14 65 + 55 00 B0 51 66 98 15 55 55 55 /* 32 Frame Avg & ACL start step 50% */ + 08 F1 C6 48 40 00 20 10 09 /* ACL Dimming : 32 frame */ + 29 00 00 00 00 00 02 55 03 /* normal ACL 15% & HBM ACL 8% */ + ]; + + samsung,acl_off_tx_cmds_revA = [ + 29 01 00 00 00 00 02 55 00 /* ACL OFF */ + ]; + + /* ************************************************************* + * Rx (Module Information READ) + * ************************************************************* + */ + samsung,manufacture_id0_rx_cmds_revA = [06 01 00 00 00 00 01 da 01 00]; + samsung,manufacture_id1_rx_cmds_revA = [06 01 00 00 00 00 01 db 01 00]; + samsung,manufacture_id2_rx_cmds_revA = [06 01 00 00 00 00 01 dc 01 00]; + + samsung,module_info_rx_cmds_revA = [06 01 00 00 00 00 01 A1 0B 00]; + samsung,octa_id_rx_cmds_revA = [06 01 00 00 00 00 01 A1 04 0B]; /* OCTA ID : read A1 12th ~ 15th + Cell ID */ + samsung,cell_id_rx_cmds_revA = [06 01 00 00 00 00 01 92 10 02]; /* CELL ID : read 92 3rd~18th bytes*/ + samsung,ddi_id_rx_cmds_revA = [06 01 00 00 00 00 01 D6 05 00]; + + samsung,mtp_read_sysfs_rx_cmds_revA = [06 01 00 00 00 00 01 00 00 00]; + + /* ************************************************************* + * candela to index mappings + * ************************************************************** + */ + samsung,candela_map_table_revA = < /* THIS TABLE USED FOR DIMMING */ + /* */ + 0 0 0 2 2 + 1 1 1 2 2 + 2 2 2 5 3 + 3 3 3 5 3 + 4 4 4 8 4 + 5 5 5 8 4 + 6 6 6 11 6 + 7 7 7 11 6 + 8 8 8 14 7 + 9 9 9 14 7 + 10 10 10 17 8 + 11 11 11 20 9 + 12 12 12 24 11 + 13 13 13 24 11 + 14 14 14 27 12 + 15 15 15 29 13 + 16 16 16 31 14 + 17 17 17 34 15 + 18 18 18 36 16 + 19 19 19 39 17 + 20 20 20 41 18 + 21 21 21 44 19 + 22 22 22 46 20 + 23 23 23 49 21 + 24 24 24 52 22 + 25 25 25 54 23 + 26 26 26 57 24 + 27 27 27 60 25 + 28 28 28 63 26 + 29 29 29 66 27 + 30 30 30 68 28 + 31 31 31 71 29 + 32 32 32 74 31 + 33 33 33 77 32 + 34 34 34 80 33 + 35 35 35 83 34 + 36 36 36 86 35 + 37 37 37 89 37 + 38 38 38 92 38 + 39 39 39 95 39 + 40 40 40 98 40 + 41 41 41 102 42 + 42 42 42 105 43 + 43 43 43 108 44 + 44 44 44 111 45 + 45 45 45 114 47 + 46 46 46 118 48 + 47 47 47 121 49 + 48 48 48 124 51 + 49 49 49 128 52 + 50 50 50 131 53 + 51 51 51 134 55 + 52 52 52 138 56 + 53 53 53 141 57 + 54 54 54 145 59 + 55 55 55 148 60 + 56 56 56 151 61 + 57 57 57 155 63 + 58 58 58 158 64 + 59 59 59 162 65 + 60 60 60 165 67 + 61 61 61 169 68 + 62 62 62 173 70 + 63 63 63 176 71 + 64 64 64 180 73 + 65 65 65 183 74 + 66 66 66 187 75 + 67 67 67 191 77 + 68 68 68 194 78 + 69 69 69 198 80 + 70 70 70 202 81 + 71 71 71 205 83 + 72 72 72 209 84 + 73 73 73 213 86 + 74 74 74 217 87 + 75 75 75 220 89 + 76 76 76 224 90 + 77 77 77 228 92 + 78 78 78 232 93 + 79 79 79 236 95 + 80 80 80 240 96 + 81 81 81 243 98 + 82 82 82 247 99 + 83 83 83 251 101 + 84 84 84 255 102 + 85 85 85 259 104 + 86 86 86 263 106 + 87 87 87 267 107 + 88 88 88 271 109 + 89 89 89 275 110 + 90 90 90 279 112 + 91 91 91 283 113 + 92 92 92 287 115 + 93 93 93 291 117 + 94 94 94 295 118 + 95 95 95 299 120 + 96 96 96 303 122 + 97 97 97 307 123 + 98 98 98 311 125 + 99 99 99 315 126 + 100 100 100 319 128 + 101 101 101 324 130 + 102 102 102 328 131 + 103 103 103 332 133 + 104 104 104 336 135 + 105 105 105 340 136 + 106 106 106 344 138 + 107 107 107 349 140 + 108 108 108 353 141 + 109 109 109 357 143 + 110 110 110 361 145 + 111 111 111 366 146 + 112 112 112 370 148 + 113 113 113 374 150 + 114 114 114 378 151 + 115 115 115 383 153 + 116 116 116 387 155 + 117 117 117 391 157 + 118 118 118 396 158 + 119 119 119 400 160 + 120 120 120 404 162 + 121 121 121 409 163 + 122 122 122 413 165 + 123 123 123 418 167 + 124 124 124 422 169 + 125 125 125 426 170 + 126 126 126 431 172 + 127 127 127 435 174 + 128 128 128 440 176 + 129 129 129 444 177 + 130 130 130 449 179 + 131 131 131 453 181 + 132 132 132 457 183 + 133 133 133 462 185 + 134 134 134 466 186 + 135 135 135 470 188 + 136 136 136 475 190 + 137 137 137 479 192 + 138 138 138 483 194 + 139 139 139 487 195 + 140 140 140 492 197 + 141 141 141 496 199 + 142 142 142 500 201 + 143 143 143 505 203 + 144 144 144 509 204 + 145 145 145 513 206 + 146 146 146 518 208 + 147 147 147 522 210 + 148 148 148 527 212 + 149 149 149 531 214 + 150 150 150 535 215 + 151 151 151 540 217 + 152 152 152 544 219 + 153 153 153 549 221 + 154 154 154 553 223 + 155 155 155 558 225 + 156 156 156 562 227 + 157 157 157 566 229 + 158 158 158 571 230 + 159 159 159 575 232 + 160 160 160 580 234 + 161 161 161 584 236 + 162 162 162 589 238 + 163 163 163 593 240 + 164 164 164 598 242 + 165 165 165 603 244 + 166 166 166 607 246 + 167 167 167 612 247 + 168 168 168 616 249 + 169 169 169 621 251 + 170 170 170 625 253 + 171 171 171 630 255 + 172 172 172 635 257 + 173 173 173 639 259 + 174 174 174 644 261 + 175 175 175 648 263 + 176 176 176 653 265 + 177 177 177 658 267 + 178 178 178 662 269 + 179 179 179 667 271 + 180 180 180 672 273 + 181 181 181 676 275 + 182 182 182 681 276 + 183 183 183 686 278 + 184 184 184 690 280 + 185 185 185 695 282 + 186 186 186 700 284 + 187 187 187 704 286 + 188 188 188 709 288 + 189 189 189 714 290 + 190 190 190 718 292 + 191 191 191 723 294 + 192 192 192 728 296 + 193 193 193 733 298 + 194 194 194 737 300 + 195 195 195 742 302 + 196 196 196 747 304 + 197 197 197 752 306 + 198 198 198 757 308 + 199 199 199 761 310 + 200 200 200 766 312 + 201 201 201 771 314 + 202 202 202 776 316 + 203 203 203 781 318 + 204 204 204 786 320 + 205 205 205 790 322 + 206 206 206 795 324 + 207 207 207 800 326 + 208 208 208 805 329 + 209 209 209 810 331 + 210 210 210 815 333 + 211 211 211 820 335 + 212 212 212 824 337 + 213 213 213 829 339 + 214 214 214 834 341 + 215 215 215 839 343 + 216 216 216 844 345 + 217 217 217 847 346 + 218 218 218 852 348 + 219 219 219 856 350 + 220 220 220 860 352 + 221 221 221 864 354 + 222 222 222 869 355 + 223 223 223 873 357 + 224 224 224 878 359 + 225 225 225 882 361 + 226 226 226 887 363 + 227 227 227 892 365 + 228 228 228 897 367 + 229 229 229 903 370 + 230 230 230 909 372 + 231 231 231 913 374 + 232 232 232 918 376 + 233 233 233 923 378 + 234 234 234 928 380 + 235 235 235 932 382 + 236 236 236 936 384 + 237 237 237 940 385 + 238 238 238 944 387 + 239 239 239 949 389 + 240 240 240 954 391 + 241 241 241 959 393 + 242 242 242 963 395 + 243 243 243 968 397 + 244 244 244 973 399 + 245 245 245 978 401 + 246 246 246 982 403 + 247 247 247 988 405 + 248 248 248 993 408 + 249 249 249 999 410 + 250 250 250 1004 412 + 251 251 251 1008 414 + 252 252 252 1012 415 + 253 253 253 1015 417 + 254 254 254 1019 418 + 255 255 255 1023 420 + >; + + samsung,hbm_candela_map_table_revI = < + /* */ + 0 256 256 2 427 0 + 1 257 257 4 429 0 + 2 258 258 6 430 0 + 3 259 259 9 432 0 + 4 260 260 12 434 0 + 5 261 261 14 435 0 + 6 262 262 17 437 0 + 7 263 263 19 439 0 + 8 264 264 21 440 0 + 9 265 265 24 442 0 + 10 266 266 27 443 0 + 11 267 267 29 445 0 + 12 268 268 32 446 0 + 13 269 269 34 448 0 + 14 270 270 36 450 0 + 15 271 271 39 451 0 + 16 272 272 42 453 0 + 17 273 273 44 454 0 + 18 274 274 47 456 0 + 19 275 275 49 458 0 + 20 276 276 51 459 0 + 21 277 277 54 461 0 + 22 278 278 57 463 0 + 23 279 279 59 464 0 + 24 280 280 62 466 0 + 25 281 281 64 468 0 + 26 282 282 66 469 0 + 27 283 283 69 471 0 + 28 284 284 72 473 0 + 29 285 285 74 474 0 + 30 286 286 77 476 0 + 31 287 287 79 478 0 + 32 288 288 81 479 0 + 33 289 289 84 481 0 + 34 290 290 87 482 0 + 35 291 291 89 484 0 + 36 292 292 92 485 0 + 37 293 293 94 487 0 + 38 294 294 96 488 0 + 39 295 295 99 490 0 + 40 296 296 102 492 0 + 41 297 297 104 493 0 + 42 298 298 106 495 0 + 43 299 299 109 497 0 + 44 300 300 111 498 0 + 45 301 301 114 500 0 + 46 302 302 117 502 0 + 47 303 303 119 503 0 + 48 304 304 121 505 0 + 49 305 305 124 507 0 + 50 306 306 126 508 0 + 51 307 307 129 510 0 + 52 308 308 132 512 0 + 53 309 309 134 513 0 + 54 310 310 136 515 0 + 55 311 311 139 516 0 + 56 312 312 141 518 0 + 57 313 313 144 519 0 + 58 314 314 147 521 0 + 59 315 315 149 523 0 + 60 316 316 151 524 0 + 61 317 317 154 526 0 + 62 318 318 156 527 0 + 63 319 319 159 529 0 + 64 320 320 162 531 0 + 65 321 321 164 532 0 + 66 322 322 166 534 0 + 67 323 323 169 536 0 + 68 324 324 171 537 0 + 69 325 325 174 539 0 + 70 326 326 177 541 0 + 71 327 327 179 542 0 + 72 328 328 181 544 0 + 73 329 329 184 546 0 + 74 330 330 186 547 0 + 75 331 331 189 549 0 + 76 332 332 192 551 0 + 77 333 333 194 552 0 + 78 334 334 196 554 0 + 79 335 335 199 555 0 + 80 336 336 201 557 0 + 81 337 337 204 558 0 + 82 338 338 207 560 0 + 83 339 339 209 561 0 + 84 340 340 211 563 0 + 85 341 341 214 565 0 + 86 342 342 216 566 0 + 87 343 343 219 568 0 + 88 344 344 222 570 0 + 89 345 345 224 571 0 + 90 346 346 226 573 0 + 91 347 347 229 575 0 + 92 348 348 231 576 0 + 93 349 349 234 578 0 + 94 350 350 237 580 0 + 95 351 351 239 581 0 + 96 352 352 241 583 0 + 97 353 353 244 585 0 + 98 354 354 246 586 0 + 99 355 355 249 588 0 + 100 356 356 252 589 0 + 101 357 357 254 591 0 + 102 358 358 256 593 0 + 103 359 359 259 594 0 + 104 360 360 261 596 0 + 105 361 361 264 597 0 + 106 362 362 267 599 0 + 107 363 363 269 600 0 + 108 364 364 271 602 0 + 109 365 365 274 604 0 + 110 366 366 276 605 0 + 111 367 367 279 607 0 + 112 368 368 281 608 0 + 113 369 369 284 610 0 + 114 370 370 286 612 0 + 115 371 371 288 613 0 + 116 372 372 291 615 0 + 117 373 373 294 617 0 + 118 374 374 296 618 0 + 119 375 375 299 620 0 + 120 376 376 301 622 0 + 121 377 377 303 623 0 + 122 378 378 306 625 0 + 123 379 379 309 627 0 + 124 380 380 311 628 0 + 125 381 381 314 630 0 + 126 382 382 316 631 0 + 127 383 383 318 633 0 + 128 384 384 321 634 0 + 129 385 385 324 636 0 + 130 386 386 326 638 0 + 131 387 387 329 639 0 + 132 388 388 331 641 0 + 133 389 389 333 642 0 + 134 390 390 336 644 0 + 135 391 391 339 646 0 + 136 392 392 341 647 0 + 137 393 393 344 649 0 + 138 394 394 346 651 0 + 139 395 395 348 652 0 + 140 396 396 351 654 0 + 141 397 397 354 656 0 + 142 398 398 356 657 0 + 143 399 399 359 659 0 + 144 400 400 361 661 0 + 145 401 401 363 662 0 + 146 402 402 366 664 0 + 147 403 403 369 666 0 + 148 404 404 371 667 0 + 149 405 405 374 669 0 + 150 406 406 376 670 0 + 151 407 407 378 672 0 + 152 408 408 381 673 0 + 153 409 409 384 675 0 + 154 410 410 386 676 0 + 155 411 411 389 678 0 + 156 412 412 391 680 0 + 157 413 413 393 681 0 + 158 414 414 396 683 0 + 159 415 415 399 685 0 + 160 416 416 401 686 0 + 161 417 417 404 688 0 + 162 418 418 406 690 0 + 163 419 419 408 691 0 + 164 420 420 411 693 0 + 165 421 421 414 695 0 + 166 422 422 416 696 0 + 167 423 423 419 698 0 + 168 424 424 421 700 0 + 169 425 425 423 701 0 + 170 426 426 426 703 0 + 171 427 427 429 704 0 + 172 428 428 431 706 0 + 173 429 429 434 708 0 + 174 430 430 436 709 0 + 175 431 431 438 711 0 + 176 432 432 441 712 0 + 177 433 433 444 714 0 + 178 434 434 446 715 0 + 179 435 435 449 717 0 + 180 436 436 451 719 0 + 181 437 437 453 720 0 + 182 438 438 456 722 0 + 183 439 439 459 724 0 + 184 440 440 461 725 0 + 185 441 441 464 727 0 + 186 442 442 466 729 0 + 187 443 443 468 730 0 + 188 444 444 471 732 0 + 189 445 445 474 734 0 + 190 446 446 476 735 0 + 191 447 447 479 737 0 + 192 448 448 481 739 0 + 193 449 449 483 740 0 + 194 450 450 486 742 0 + 195 451 451 489 743 0 + 196 452 452 491 745 0 + 197 453 453 494 746 0 + 198 454 454 496 748 0 + 199 455 455 498 749 0 + 200 456 456 501 751 0 + 201 457 457 504 753 0 + 202 458 458 506 754 0 + 203 459 459 509 756 0 + 204 460 460 511 758 0 + 205 461 461 513 759 0 + 206 462 462 516 761 0 + 207 463 463 519 763 0 + 208 464 464 521 764 0 + 209 465 465 524 766 0 + 210 466 466 526 768 0 + 211 467 467 528 769 0 + 212 468 468 531 771 0 + 213 469 469 534 773 0 + 214 470 470 536 774 0 + 215 471 471 539 776 0 + 216 472 472 541 777 0 + 217 473 473 543 779 0 + 218 474 474 546 781 0 + 219 475 475 549 782 0 + 220 476 476 551 784 0 + 221 477 477 554 785 0 + 222 478 478 556 787 0 + 223 479 479 558 788 0 + 224 480 480 561 790 0 + 225 481 481 564 792 0 + 226 482 482 566 793 0 + 227 483 483 569 795 0 + 228 484 484 571 797 0 + 229 485 485 573 798 0 + 230 486 486 576 800 0 + >; + + samsung,hbm_candela_map_table_revA = < + /* */ + 0 256 256 2 427 0 + 1 257 257 4 429 0 + 2 258 258 6 430 0 + 3 259 259 9 432 0 + 4 260 260 12 434 0 + 5 261 261 14 435 0 + 6 262 262 17 437 0 + 7 263 263 19 439 0 + 8 264 264 21 440 0 + 9 265 265 24 442 0 + 10 266 266 27 443 0 + 11 267 267 29 445 0 + 12 268 268 32 446 0 + 13 269 269 34 448 0 + 14 270 270 36 450 0 + 15 271 271 39 451 0 + 16 272 272 42 453 0 + 17 273 273 44 454 0 + 18 274 274 47 456 0 + 19 275 275 49 458 0 + 20 276 276 51 459 0 + 21 277 277 54 461 0 + 22 278 278 57 463 0 + 23 279 279 59 464 0 + 24 280 280 62 466 0 + 25 281 281 64 468 0 + 26 282 282 66 469 0 + 27 283 283 69 471 0 + 28 284 284 72 473 0 + 29 285 285 74 474 0 + 30 286 286 77 476 0 + 31 287 287 79 478 0 + 32 288 288 81 479 0 + 33 289 289 84 481 0 + 34 290 290 87 482 0 + 35 291 291 89 484 0 + 36 292 292 92 485 0 + 37 293 293 94 487 0 + 38 294 294 96 488 0 + 39 295 295 99 490 0 + 40 296 296 102 492 0 + 41 297 297 104 493 0 + 42 298 298 106 495 0 + 43 299 299 109 497 0 + 44 300 300 111 498 0 + 45 301 301 114 500 0 + 46 302 302 117 502 0 + 47 303 303 119 503 0 + 48 304 304 121 505 0 + 49 305 305 124 507 0 + 50 306 306 126 508 0 + 51 307 307 129 510 0 + 52 308 308 132 512 0 + 53 309 309 134 513 0 + 54 310 310 136 515 0 + 55 311 311 139 516 0 + 56 312 312 141 518 0 + 57 313 313 144 519 0 + 58 314 314 147 521 0 + 59 315 315 149 523 0 + 60 316 316 151 524 0 + 61 317 317 154 526 0 + 62 318 318 156 527 0 + 63 319 319 159 529 0 + 64 320 320 162 531 0 + 65 321 321 164 532 0 + 66 322 322 166 534 0 + 67 323 323 169 536 0 + 68 324 324 171 537 0 + 69 325 325 174 539 0 + 70 326 326 177 541 0 + 71 327 327 179 542 0 + 72 328 328 181 544 0 + 73 329 329 184 546 0 + 74 330 330 186 547 0 + 75 331 331 189 549 0 + 76 332 332 192 551 0 + 77 333 333 194 552 0 + 78 334 334 196 554 0 + 79 335 335 199 555 0 + 80 336 336 201 557 0 + 81 337 337 204 558 0 + 82 338 338 207 560 0 + 83 339 339 209 561 0 + 84 340 340 211 563 0 + 85 341 341 214 565 0 + 86 342 342 216 566 0 + 87 343 343 219 568 0 + 88 344 344 222 570 0 + 89 345 345 224 571 0 + 90 346 346 226 573 0 + 91 347 347 229 575 0 + 92 348 348 231 576 0 + 93 349 349 234 578 0 + 94 350 350 237 580 0 + 95 351 351 239 581 0 + 96 352 352 241 583 0 + 97 353 353 244 585 0 + 98 354 354 246 586 0 + 99 355 355 249 588 0 + 100 356 356 252 589 0 + 101 357 357 254 591 0 + 102 358 358 256 593 0 + 103 359 359 259 594 0 + 104 360 360 261 596 0 + 105 361 361 264 597 0 + 106 362 362 267 599 0 + 107 363 363 269 600 0 + 108 364 364 271 602 0 + 109 365 365 274 604 0 + 110 366 366 276 605 0 + 111 367 367 279 607 0 + 112 368 368 281 608 0 + 113 369 369 284 610 0 + 114 370 370 286 612 0 + 115 371 371 288 613 0 + 116 372 372 291 615 0 + 117 373 373 294 617 0 + 118 374 374 296 618 0 + 119 375 375 299 620 0 + 120 376 376 301 622 0 + 121 377 377 303 623 0 + 122 378 378 306 625 0 + 123 379 379 309 627 0 + 124 380 380 311 628 0 + 125 381 381 314 630 0 + 126 382 382 316 631 0 + 127 383 383 318 633 0 + 128 384 384 321 634 0 + 129 385 385 324 636 0 + 130 386 386 326 638 0 + 131 387 387 329 639 0 + 132 388 388 331 641 0 + 133 389 389 333 642 0 + 134 390 390 336 644 0 + 135 391 391 339 646 0 + 136 392 392 341 647 0 + 137 393 393 344 649 0 + 138 394 394 346 651 0 + 139 395 395 348 652 0 + 140 396 396 351 654 0 + 141 397 397 354 656 0 + 142 398 398 356 657 0 + 143 399 399 359 659 0 + 144 400 400 361 661 0 + 145 401 401 363 662 0 + 146 402 402 366 664 0 + 147 403 403 369 666 0 + 148 404 404 371 667 0 + 149 405 405 374 669 0 + 150 406 406 376 670 0 + 151 407 407 378 672 0 + 152 408 408 381 673 0 + 153 409 409 384 675 0 + 154 410 410 386 676 0 + 155 411 411 389 678 0 + 156 412 412 391 680 0 + 157 413 413 393 681 0 + 158 414 414 396 683 0 + 159 415 415 399 685 0 + 160 416 416 401 686 0 + 161 417 417 404 688 0 + 162 418 418 406 690 0 + 163 419 419 408 691 0 + 164 420 420 411 693 0 + 165 421 421 414 695 0 + 166 422 422 416 696 0 + 167 423 423 419 698 0 + 168 424 424 421 700 0 + 169 425 425 423 701 0 + 170 426 426 426 703 0 + 171 427 427 429 704 0 + 172 428 428 431 706 0 + 173 429 429 434 708 0 + 174 430 430 436 709 0 + 175 431 431 438 711 0 + 176 432 432 441 712 0 + 177 433 433 444 714 0 + 178 434 434 446 715 0 + 179 435 435 449 717 0 + 180 436 436 451 719 0 + 181 437 437 453 720 0 + 182 438 438 456 722 0 + 183 439 439 459 724 0 + 184 440 440 461 725 0 + 185 441 441 464 727 0 + 186 442 442 466 729 0 + 187 443 443 468 730 0 + 188 444 444 471 732 0 + 189 445 445 474 734 0 + 190 446 446 476 735 0 + 191 447 447 479 737 0 + 192 448 448 481 739 0 + 193 449 449 483 740 0 + 194 450 450 486 742 0 + 195 451 451 489 743 0 + 196 452 452 491 745 0 + 197 453 453 494 746 0 + 198 454 454 496 748 0 + 199 455 455 498 749 0 + 200 456 456 501 751 0 + 201 457 457 504 753 0 + 202 458 458 506 754 0 + 203 459 459 509 756 0 + 204 460 460 511 758 0 + 205 461 461 513 759 0 + 206 462 462 516 761 0 + 207 463 463 519 763 0 + 208 464 464 521 764 0 + 209 465 465 524 766 0 + 210 466 466 526 768 0 + 211 467 467 528 769 0 + 212 468 468 531 771 0 + 213 469 469 534 773 0 + 214 470 470 536 774 0 + 215 471 471 539 776 0 + 216 472 472 541 777 0 + 217 473 473 543 779 0 + 218 474 474 546 781 0 + 219 475 475 549 782 0 + 220 476 476 551 784 0 + 221 477 477 554 785 0 + 222 478 478 556 787 0 + 223 479 479 558 788 0 + 224 480 480 561 790 0 + 225 481 481 564 792 0 + 226 482 482 566 793 0 + 227 483 483 569 795 0 + 228 484 484 571 797 0 + 229 485 485 573 798 0 + 230 486 486 576 800 0 + >; + + samsung,aod_candela_map_table_revA = < + /* */ + 0 0 12 27 2 + 1 13 31 26 10 + 2 32 54 25 30 + 3 55 255 24 60 + >; + + /* ************************************************************* + * Dynamic MIPI Clock + * ************************************************************** + */ + samsung,support_dynamic_mipi_clk; + + samsung,ffc_tx_cmds_revA = [ + 29 00 00 00 00 00 03 F0 5A 5A + 29 00 00 00 00 00 03 FC 5A 5A + + /* 0. Default 1110 Mbps */ + 29 00 00 00 00 00 04 B0 00 2A C5 + 29 00 00 00 00 00 05 C5 0D 10 80 45 + 29 00 00 00 00 00 04 B0 00 2E C5 + 29 00 00 00 00 00 03 C5 53 A0 + + 29 00 00 00 00 00 02 F7 0F + 29 00 00 00 00 00 03 FC A5 A5 + 29 00 00 00 00 00 03 F0 A5 A5 + ]; + + samsung,dyn_mipi_clk_ffc_cmds_revA = [ + /* 0. Default 1110 Mbps */ + 29 00 00 00 00 00 04 B0 00 2A C5 + 29 00 00 00 00 00 05 C5 0D 10 80 45 + 29 00 00 00 00 00 04 B0 00 2E C5 + 29 00 00 00 00 00 03 C5 53 A0 + + /* 1. Default 1114 Mbps */ + 29 00 00 00 00 00 04 B0 00 2A C5 + 29 00 00 00 00 00 05 C5 0D 10 80 45 + 29 00 00 00 00 00 04 B0 00 2E C5 + 29 00 00 00 00 00 03 C5 53 54 + + /* 2. Default 1124 Mbps */ + 29 00 00 00 00 00 04 B0 00 2A C5 + 29 00 00 00 00 00 05 C5 0D 10 80 45 + 29 00 00 00 00 00 04 B0 00 2E C5 + 29 00 00 00 00 00 03 C5 52 96 + ]; + + samsung,dynamic_mipi_clk_timing_table = < + /*<>*/ + 1110000000 /* clk id 0 default */ + 1114000000 /* clk id 1 */ + 1124000000 /* clk id 2 */ + >; + + samsung,dynamic_mipi_clk_sel_table = < + /**/ + 1 1 0 0 0 + 1 2 0 0 0 + 1 3 0 0 2 + 1 4 0 0 1 + 2 11 10562 10838 0 + 2 12 9662 9677 0 + 2 12 9678 9712 1 + 2 12 9713 9747 2 + 2 12 9748 9938 0 + 2 13 1162 1178 2 + 2 13 1179 1513 0 + 2 14 1537 1738 0 + 2 15 4357 4458 0 + 2 17 2237 2271 0 + 2 17 2272 2318 1 + 2 17 2319 2341 2 + 2 17 2342 2563 0 + 2 18 2937 3088 0 + 3 91 0 599 0 + 3 92 600 654 0 + 3 92 655 724 1 + 3 92 725 794 2 + 3 92 795 1199 0 + 3 93 1200 1257 2 + 3 93 1258 1949 0 + 3 94 1950 2399 0 + 3 95 2400 2649 0 + 3 97 2750 2842 0 + 3 97 2843 2937 1 + 3 97 2938 2982 2 + 3 97 2983 3449 0 + 3 98 3450 3799 0 + 3 102 5010 5179 0 + 3 103 5180 5279 0 + 3 104 5280 5379 0 + 3 107 5730 5849 0 + 3 108 5850 5999 0 + 3 109 6000 6149 0 + 3 110 6150 6449 0 + 3 111 6450 6599 0 + 3 115 8040 8094 0 + 3 115 8095 8164 1 + 3 115 8165 8234 2 + 3 115 8235 8689 0 + 3 116 8690 9039 0 + 3 118 9210 9659 0 + 3 119 9660 9769 0 + 3 120 9770 9787 0 + 3 120 9788 9869 1 + 3 122 9920 10359 0 + 3 124 36200 36349 0 + 3 128 37750 38249 0 + 3 129 38250 38649 0 + 3 130 38650 39167 0 + 3 130 39168 39252 1 + 3 130 39253 39307 2 + 3 130 39308 39649 0 + 3 131 39650 39684 1 + 3 131 39685 39734 2 + 3 131 39735 40982 0 + 3 131 40983 41077 1 + 3 131 41078 41122 2 + 3 131 41123 41589 0 + 3 132 41590 42207 0 + 3 132 42208 42332 1 + 3 132 42333 42347 2 + 3 132 42348 43589 0 + 3 138 55240 55745 0 + 3 138 55746 55875 1 + 3 138 55876 55885 2 + 3 138 55886 56739 0 + 3 156 66436 67335 0 + 3 161 68586 68935 0 + 4 51 0 0 0 + 4 52 0 0 0 + 4 53 0 0 0 + 4 54 0 0 0 + 4 55 0 0 2 + 4 56 0 0 0 + 5 61 0 0 0 + 5 62 0 0 0 + 5 71 0 0 0 + 7 260 173800 178780 0 + 7 263 185000 191840 0 + 7 263 191841 191980 1 + 7 283 151600 160580 0 + 7 326 123400 130380 0 + >; + + /* + * ************************************************************************************************************************ + * FD Settings + * ************************************************************************************************************************ + */ + + samsung,fd_on_tx_cmds_revA = [ + /* Display PMIC FD On */ + 29 00 00 00 00 00 03 F0 5A 5A /* TEST KEY Enable */ + 29 00 00 00 00 00 04 B0 00 0A B5 + 29 00 00 00 00 00 03 B5 40 40 /* Setting */ + 29 01 00 00 00 00 03 F0 A5 A5 /* TEST KEY Disable */ + ]; + + samsung,fd_off_tx_cmds_revA = [ + /* Display PMIC FD Off */ + 29 00 00 00 00 00 03 F0 5A 5A /* TEST KEY Enable */ + 29 00 00 00 00 00 04 B0 00 0A B5 + 29 00 00 00 00 00 03 B5 80 40 /* Setting */ + 29 01 00 00 00 00 03 F0 A5 A5 /* TEST KEY Disable */ + ]; + + /* ************************************************************* + * APLPM + * ************************************************************* + */ + samsung,self_grid_on_revA = [ + /* TIG Enable */ + 29 00 00 00 00 00 03 F0 5A 5A + 29 00 00 00 00 00 03 BF 01 00 + 29 01 00 00 11 00 03 F0 A5 A5 /* wait 16.7ms */ + ]; + + samsung,self_grid_off_revA = [ + /* TIG Disable */ + 29 01 00 00 11 00 03 F0 5A 5A /* wait 16.7ms */ + 29 00 00 00 00 00 03 BF 00 00 + 29 01 00 00 00 00 03 F0 A5 A5 + ]; + + samsung,lpm_on_tx_cmds_revI = [ + 29 00 00 00 00 00 03 F0 5A 5A + 29 00 00 00 00 00 03 91 01 01 /* AOD Setting */ + 29 00 00 00 00 00 02 53 27 + 29 00 00 00 00 00 04 B0 01 88 CB + 29 00 00 00 00 00 08 CB 40 0A 00 00 00 00 40 /* HFP Setting */ + 29 00 00 00 00 00 04 B0 01 C0 CB + 29 00 00 00 00 00 08 CB 38 00 00 00 18 03 38 /* HFP Setting */ + 29 00 00 00 00 00 04 B0 00 10 F2 + 29 00 00 00 00 00 03 F2 24 A4 /* HFP Setting */ + 29 01 00 00 00 00 02 F7 0F /* 10ns dealy */ + 29 01 00 00 11 00 03 F0 A5 A5 /* wait 16.7ms */ + ]; + + samsung,lpm_on_tx_cmds_revA = [ + 29 00 00 00 00 00 03 F0 5A 5A + 29 00 00 00 00 00 03 91 01 01 /* AOD Setting */ + 29 00 00 00 00 00 02 53 27 + 29 00 00 00 00 00 04 B0 01 88 CB + 29 00 00 00 00 00 08 CB 40 0A 00 00 00 00 40 /* HFP Setting */ + 29 00 00 00 00 00 04 B0 01 C0 CB + 29 00 00 00 00 00 08 CB 38 00 00 00 18 03 38 /* HFP Setting */ + 29 00 00 00 00 00 04 B0 00 10 F2 + 29 00 00 00 00 00 03 F2 24 A4 /* HFP Setting */ + 29 01 00 00 00 00 02 F7 0F /* 10ns dealy */ + 29 01 00 00 00 00 03 F0 A5 A5 /* 16.7ms Delay is moved to self_grid_on cmd */ + ]; + + samsung,lpm_off_tx_cmds_revI = [ + 29 00 00 00 00 00 03 F0 5A 5A + 29 00 00 00 00 00 04 B0 00 07 B5 + 29 00 00 00 00 00 04 B5 00 00 00 /* A SWIRE No Pulse */ + 29 00 00 00 00 00 04 B0 01 88 CB + 29 00 00 00 00 00 08 CB 45 0A 00 00 00 00 45 /* HFP Setting*/ + 29 00 00 00 00 00 04 B0 01 C0 CB + 29 00 00 00 00 00 08 CB 3D 00 00 00 18 03 3D /* HFP Setting*/ + 29 00 00 00 00 00 04 B0 00 10 F2 + 29 00 00 00 00 00 03 F2 26 F0 /* HFP Setting*/ + 29 00 00 00 00 00 03 91 02 01 /* Normal Setting */ + 29 00 00 00 00 00 02 53 20 /* Normal Mode*/ + 29 00 00 00 00 00 02 F7 0F + 29 01 00 00 00 00 03 F0 A5 A5 /* wait 33.4ms at lpm code*/ + ]; + + samsung,lpm_off_tx_cmds_revA = [ + 29 00 00 00 00 00 03 F0 5A 5A + 29 00 00 00 00 00 04 B0 00 07 B5 + 29 00 00 00 00 00 04 B5 00 00 00 /* A SWIRE No Pulse */ + 29 00 00 00 00 00 04 B0 01 88 CB + 29 00 00 00 00 00 08 CB 45 0A 00 00 00 00 45 /* HFP Setting*/ + 29 00 00 00 00 00 04 B0 01 C0 CB + 29 00 00 00 00 00 08 CB 3D 00 00 00 18 03 3D /* HFP Setting*/ + 29 00 00 00 00 00 04 B0 00 10 F2 + 29 00 00 00 00 00 03 F2 26 E4 /* HFP Setting*/ + 29 00 00 00 00 00 03 91 02 01 /* Normal Setting */ + 29 00 00 00 00 00 04 B0 00 91 63 + 29 00 00 00 00 00 02 63 20 + 29 00 00 00 00 00 02 53 20 /* Normal Mode*/ + 29 00 00 00 00 00 02 F7 0F + 29 01 00 00 00 00 03 F0 A5 A5 /* wait 33.4ms at lpm code*/ + ]; + + /* ALPM/HLPM 60/30/10/2nit control */ + samsung,lpm_60nit_tx_cmds_revA = [29 00 00 00 00 00 02 53 24]; + samsung,lpm_30nit_tx_cmds_revA = [29 00 00 00 00 00 02 53 25]; + samsung,lpm_10nit_tx_cmds_revA = [29 00 00 00 00 00 02 53 26]; + samsung,lpm_2nit_tx_cmds_revA = [29 00 00 00 00 00 02 53 27]; + + /* HLPM / ALPM brightness Commands: default alpm 2nit */ + samsung,lpm_brightnes_tx_cmds_revA = [ + 29 00 00 00 00 00 03 F0 5A 5A + 29 00 00 00 00 00 02 53 26 + 29 00 00 00 00 00 02 F7 0F + 29 01 00 00 00 00 03 F0 A5 A5 + ]; + + /* + * ************************************************************************************************************************ + * DMS (Dynamic Mode Switch) + * ************************************************************************************************************************ + */ + + qcom,mdss-dsi-display-timings { + fhd120 { + qcom,display-topology = <1 1 1>, <2 2 1>; // lm, enc, intf // JUN_TEMP_R8 + qcom,default-topology-index = <1>; // JUN_TEMP_R8 : 0 => 1 + qcom,mdss-dsi-timing-default; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2400>; + + qcom,mdss-dsi-h-pulse-width = <84>; + qcom,mdss-dsi-h-back-porch = <88>; + qcom,mdss-dsi-h-front-porch = <80>; + qcom,mdss-dsi-h-sync-skew = <0>; + + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-v-back-porch = <2>; + qcom,mdss-dsi-v-front-porch = <15>; + + qcom,mdss-dsi-panel-framerate = <120>; + samsung,mdss-dsi-sot-hs-mode; + + /* transfer time: 48Hz: 20032, 60Hz: 15866, 96Hz: 9616, 120Hz: 7533 */ + qcom,mdss-mdp-transfer-time-us = <7533>; + qcom,mdss-dsi-panel-clockrate = <1108000000>; /* ((1080 * 2400 * 24 * 132.7492367) / 4 ) / 3 ~ 1.9G*/ + //qcom,mdss-dsi-panel-phy-timings =[00 25 0A 0A 27 24 0A 0A 0A 02 04 00]; + qcom,mdss-dsi-panel-phy-timings = [00 25 0A 0A 27 24 0A 0A 09 02 04 00 20 0F]; + + qcom,mdss-dsi-t-clk-pre = <0x20>; + qcom,mdss-dsi-t-clk-post = <0x0F>; + + qcom,mdss-dsi-on-command = [ + /* Sleep out, wait 30ms (0x1E) */ + 05 01 00 00 1E 00 02 11 00 + + 29 00 00 00 00 00 03 F0 5A 5A + + /* Global Para Setting */ + 29 00 00 00 00 00 2A F2 + 00 05 0E 58 54 01 0C 00 + 04 27 24 2F B0 0C 09 74 + 26 E4 0C 00 04 10 00 10 + 26 A8 10 00 10 10 34 10 + 00 40 30 C8 00 C8 00 00 + CE + + /* TE Vsync On */ + 29 00 00 00 00 00 02 35 00 + + /* PAGE Address Setting */ + 29 00 00 00 00 00 05 2A 00 00 04 37 + 29 00 00 00 00 00 05 2B 00 00 09 5F + + /* FFC Setting */ + + /* ERR_FG Setting */ + 29 00 00 00 00 00 02 E5 15 + 29 00 00 00 00 00 04 ED 44 4C 20 + + /* Vsync Setting */ + 29 00 00 00 00 00 04 B0 00 04 F2 + 29 00 00 00 00 00 02 F2 54 + + /* PCD Setting */ + 29 00 00 00 00 00 03 CC 5C 51 + + /* DSC setting */ + 07 01 00 00 00 00 01 01 /* DSC enable : Compression Mode*/ + 0A 01 00 00 00 00 80 /* PPS setting */ + 11 00 00 89 30 80 09 60 + 04 38 00 28 02 1C 02 1C + 02 00 02 0E 00 20 03 DD + 00 07 00 0C 02 77 02 8B + 18 00 10 F0 03 0C 20 00 + 06 0B 0B 33 0E 1C 2A 38 + 46 54 62 69 70 77 79 7B + 7D 7E 01 02 01 00 09 40 + 09 BE 19 FC 19 FA 19 F8 + 1A 38 1A 78 1A B6 2A F6 + 2B 34 2B 74 3B 74 6B F4 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + + /* Freq setting */ + 29 00 00 00 00 00 04 B0 00 27 F2 + 29 00 00 00 00 00 02 F2 00 + + /* Porch Clock Set */ + 29 00 00 00 00 00 04 B0 00 2E F2 + 29 00 00 00 00 00 02 F2 55 + + 29 00 00 00 00 00 04 B0 00 92 63 + 29 00 00 00 00 00 02 63 04 /* smooth dimming 4frame*/ + + 29 00 00 00 00 00 02 F7 0F + 29 01 00 00 5A 00 03 F0 A5 A5 /* wait 90ms (0x5A) */ + ]; + + qcom,mdss-dsi-off-command = [ + /* DSC PPS cmd unlock & lock LEVEL0 KEY */ + 29 00 00 00 00 00 03 9F A5 A5 + 05 01 00 00 14 00 02 28 00 /* wait 20ms */ + 05 01 00 00 78 00 02 10 00 /* wait 120ms */ + 29 01 00 00 00 00 03 9F 5A 5A + ]; + + qcom,mdss-dsi-on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + + //qcom,partial-update-enabled = "single_roi"; + // JUN_TEMP_R8 qcom,panel-roi-alignment=<1080 40 1080 40 1080 40>; + + qcom,compression-mode = "dsc"; + qcom,lm-split = <540 540>; + qcom,mdss-dsc-encoders = <2>; + qcom,mdss-dsc-slice-height = <40>; + qcom,mdss-dsc-slice-width = <540>; + qcom,mdss-dsc-slice-per-pkt = <1>; + qcom,mdss-dsc-bit-per-component = <8>; + qcom,mdss-pps-delay-ms = <0>; + qcom,mdss-dsc-bit-per-pixel = <8>; + qcom,mdss-dsc-block-prediction-enable; + }; + + fhd60 { + qcom,display-topology = <1 1 1>, <2 2 1>; // JUN_TEMP_R8 + qcom,default-topology-index = <1>; // JUN_TEMP_R8 : 0 => 1 + qcom,mdss-dsi-timing-default; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2400>; + + qcom,mdss-dsi-h-pulse-width = <84>; + qcom,mdss-dsi-h-back-porch = <88>; + qcom,mdss-dsi-h-front-porch = <80>; + qcom,mdss-dsi-h-sync-skew = <0>; + + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-v-back-porch = <2>; + qcom,mdss-dsi-v-front-porch = <16>; + + qcom,mdss-dsi-panel-framerate = <60>; + samsung,mdss-dsi-sot-hs-mode; + + /* transfer time: 48Hz: 20032, 60Hz: 15866, 96Hz: 9616, 120Hz: 7533 */ + qcom,mdss-mdp-transfer-time-us = <15866>; + qcom,mdss-dsi-panel-clockrate = <1108000000>; /* ((1080 * 2400 * 24 * 132.7492367) / 4 ) / 3 ~ 1.9G*/ + //qcom,mdss-dsi-panel-phy-timings =[00 25 0A 0A 27 24 0A 0A 0A 02 04 00]; + qcom,mdss-dsi-panel-phy-timings = [00 25 0A 0A 27 24 0A 0A 09 02 04 00 20 0F]; + qcom,mdss-dsi-t-clk-pre = <0x20>; + qcom,mdss-dsi-t-clk-post = <0x0F>; + + qcom,mdss-dsi-on-command = [ + /* Sleep out, wait 30ms (0x1E) */ + 05 01 00 00 1E 00 02 11 00 + + 29 00 00 00 00 00 03 F0 5A 5A + + /* Global Para Setting */ + 29 00 00 00 00 00 2A F2 + 00 05 0E 58 54 01 0C 00 + 04 27 24 2F B0 0C 09 74 + 26 E4 0C 00 04 10 00 10 + 26 A8 10 00 10 10 3C 10 + 00 40 30 C8 00 C8 00 00 + CE + + /* TE Vsync On */ + 29 00 00 00 00 00 02 35 00 + + /* PAGE Address Setting */ + 29 00 00 00 00 00 05 2A 00 00 04 37 + 29 00 00 00 00 00 05 2B 00 00 09 5F + + /* FFC Setting */ + + /* ERR_FG Setting */ + 29 00 00 00 00 00 02 E5 15 + 29 00 00 00 00 00 04 ED 44 4C 20 + + /* Vsync Setting */ + 29 00 00 00 00 00 04 B0 00 04 F2 + 29 00 00 00 00 00 02 F2 54 + + /* PCD Setting */ + 29 00 00 00 00 00 03 CC 5C 51 + + /* DSC setting */ + 07 01 00 00 00 00 01 01 /* DSC enable : Compression Mode*/ + 0A 01 00 00 00 00 80 /* PPS setting */ + 11 00 00 89 30 80 09 60 + 04 38 00 28 02 1C 02 1C + 02 00 02 0E 00 20 03 DD + 00 07 00 0C 02 77 02 8B + 18 00 10 F0 03 0C 20 00 + 06 0B 0B 33 0E 1C 2A 38 + 46 54 62 69 70 77 79 7B + 7D 7E 01 02 01 00 09 40 + 09 BE 19 FC 19 FA 19 F8 + 1A 38 1A 78 1A B6 2A F6 + 2B 34 2B 74 3B 74 6B F4 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + + /* Freq setting */ + 29 00 00 00 00 00 04 B0 00 27 F2 + 29 00 00 00 00 00 02 F2 00 + + /* Porch Clock Set */ + 29 00 00 00 00 00 04 B0 00 2E F2 + 29 00 00 00 00 00 02 F2 55 + + 29 00 00 00 00 00 04 B0 00 92 63 + 29 00 00 00 00 00 02 63 04 /* smooth dimming 4frame*/ + + 29 00 00 00 00 00 02 F7 0F + 29 01 00 00 5A 00 03 F0 A5 A5 /* wait 90ms (0x5A) */ + ]; + + qcom,mdss-dsi-off-command = [ + /* DSC PPS cmd unlock & lock LEVEL0 KEY */ + 29 00 00 00 00 00 03 9F A5 A5 + 05 01 00 00 14 00 02 28 00 /* wait 20ms */ + 05 01 00 00 78 00 02 10 00 /* wait 120ms */ + 29 01 00 00 00 00 03 9F 5A 5A + ]; + + qcom,mdss-dsi-on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + + //qcom,partial-update-enabled = "single_roi"; + // JUN_TEMP_R8 qcom,panel-roi-alignment=<1080 40 1080 40 1080 40>; + + qcom,compression-mode = "dsc"; + qcom,lm-split = <540 540>; + qcom,mdss-dsc-encoders = <2>; + qcom,mdss-dsc-slice-height = <40>; + qcom,mdss-dsc-slice-width = <540>; + qcom,mdss-dsc-slice-per-pkt = <1>; + qcom,mdss-dsc-bit-per-component = <8>; + qcom,mdss-pps-delay-ms = <0>; + qcom,mdss-dsc-bit-per-pixel = <8>; + qcom,mdss-dsc-block-prediction-enable; + }; + }; + }; +}; diff --git a/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_mdnie_S6E3FC3_AMS646YD01.h b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_mdnie_S6E3FC3_AMS646YD01.h new file mode 100644 index 000000000..0c70d4903 --- /dev/null +++ b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_mdnie_S6E3FC3_AMS646YD01.h @@ -0,0 +1,5068 @@ +/* + * ================================================================= + * + * + * Description: samsung display common file + * + * Author: jb09.kim + * Company: Samsung Electronics + * + * ================================================================ + */ +/* + +Copyright (C) 2012, Samsung Electronics. 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. + * + * You should have received a copy of the GNU General Public License +*/ +#ifndef _SAMSUNG_DSI_MDNIE_S6E3FC3_AMS646YD01_ +#define _SAMSUNG_DSI_MDNIE_S6E3FC3_AMS646YD01_ + +#include "ss_dsi_mdnie_lite_common.h" + +#define MDNIE_COLOR_BLINDE_CMD_OFFSET 2 + +#define ADDRESS_SCR_WHITE_RED 0x14 +#define ADDRESS_SCR_WHITE_GREEN 0x15 +#define ADDRESS_SCR_WHITE_BLUE 0x16 + +#define MDNIE_STEP1_INDEX 4 +#define MDNIE_STEP2_INDEX 5 +#define MDNIE_STEP3_INDEX 6 + +static char level_0_key_on[] = { + 0x9F, + 0xA5, 0xA5 +}; + +static char level_0_key_off[] = { + 0x9F, + 0x5a, 0x5a +}; + +static char level_1_key_on[] = { + 0xF0, + 0x5A, 0x5A +}; + +static char level_1_key_off[] = { + 0xF0, + 0xA5, 0xA5 +}; + +static char multi_cmd_on[] = { + 0x72, + 0x2C, 0x21 +}; + +static char multi_cmd_off[] = { + 0x72, + 0x2C, 0x01 +}; + +static char multi_cmd_dummy[] = { + 0x0A, + 0x00 +}; + +static char adjust_ldu_data_1[] = { + 0xff, 0xff, 0xff, + 0xfd, 0xfd, 0xff, + 0xfb, 0xfb, 0xff, + 0xf9, 0xf8, 0xff, + 0xf6, 0xf6, 0xff, + 0xf4, 0xf4, 0xff, +}; + +static char adjust_ldu_data_2[] = { + 0xff, 0xfc, 0xf6, + 0xfd, 0xfa, 0xf6, + 0xfb, 0xf7, 0xf6, + 0xf9, 0xf5, 0xf6, + 0xf4, 0xf0, 0xf6, + 0xf2, 0xee, 0xf6, +}; + +static char *adjust_ldu_data[MAX_MODE] = { + adjust_ldu_data_2, + adjust_ldu_data_2, + adjust_ldu_data_2, + adjust_ldu_data_1, + adjust_ldu_data_1, +}; + +static char night_mode_data[] = { + 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xec, 0x00, 0xf8, 0xec, 0xff, 0x00, 0xec, 0xff, 0xf8, 0x00, 0xff, 0xf8, 0xec, 0xff, 0x00, 0x00, /* 6500K */ + 0xff, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0xe5, 0x00, 0xf6, 0xe5, 0xff, 0x00, 0xe5, 0xff, 0xf6, 0x00, 0xff, 0xf6, 0xe5, 0xff, 0x00, 0x00, /* 6300K */ + 0xff, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0xdb, 0x00, 0xf2, 0xdb, 0xff, 0x00, 0xdb, 0xff, 0xf2, 0x00, 0xff, 0xf2, 0xdb, 0xff, 0x00, 0x00, /* 6100K */ + 0xff, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0xd0, 0x00, 0xef, 0xd0, 0xff, 0x00, 0xd0, 0xff, 0xef, 0x00, 0xff, 0xef, 0xd0, 0xff, 0x00, 0x00, /* 5900K */ + 0xff, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0xc4, 0x00, 0xec, 0xc4, 0xff, 0x00, 0xc4, 0xff, 0xec, 0x00, 0xff, 0xec, 0xc4, 0xff, 0x00, 0x00, /* 5700K */ + 0xff, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xb9, 0x00, 0xe8, 0xb9, 0xff, 0x00, 0xb9, 0xff, 0xe8, 0x00, 0xff, 0xe8, 0xb9, 0xff, 0x00, 0x00, /* 5500K */ + 0xff, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x99, 0x00, 0xd9, 0x99, 0xff, 0x00, 0x99, 0xff, 0xd9, 0x00, 0xff, 0xd9, 0x99, 0xff, 0x00, 0x00, /* 4900K */ + 0xff, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x79, 0x00, 0xc8, 0x79, 0xff, 0x00, 0x79, 0xff, 0xc8, 0x00, 0xff, 0xc8, 0x79, 0xff, 0x00, 0x00, /* 4300K */ + 0xff, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x58, 0x00, 0xb3, 0x58, 0xff, 0x00, 0x58, 0xff, 0xb3, 0x00, 0xff, 0xb3, 0x58, 0xff, 0x00, 0x00, /* 3700K */ + 0xff, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x36, 0x00, 0x9a, 0x36, 0xff, 0x00, 0x36, 0xff, 0x9a, 0x00, 0xff, 0x9a, 0x36, 0xff, 0x00, 0x00, /* 3100K */ + 0xff, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x6c, 0x13, 0xff, 0x00, 0x13, 0xff, 0x6c, 0x00, 0xff, 0x6c, 0x13, 0xff, 0x00, 0x00, /* 2300K */ + 0xff, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xd8, 0x00, 0xf1, 0xd8, 0xff, 0x00, 0xd8, 0xff, 0xf1, 0x00, 0xff, 0xf1, 0xd8, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xd6, 0x00, 0xf0, 0xd6, 0xff, 0x00, 0xd6, 0xff, 0xf0, 0x00, 0xff, 0xf0, 0xd6, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0xd3, 0x00, 0xef, 0xd3, 0xff, 0x00, 0xd3, 0xff, 0xef, 0x00, 0xff, 0xef, 0xd3, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xd1, 0x00, 0xee, 0xd1, 0xff, 0x00, 0xd1, 0xff, 0xee, 0x00, 0xff, 0xee, 0xd1, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0xce, 0x00, 0xec, 0xce, 0xff, 0x00, 0xce, 0xff, 0xec, 0x00, 0xff, 0xec, 0xce, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xcc, 0x00, 0xeb, 0xcc, 0xff, 0x00, 0xcc, 0xff, 0xeb, 0x00, 0xff, 0xeb, 0xcc, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xc9, 0x00, 0xea, 0xc9, 0xff, 0x00, 0xc9, 0xff, 0xea, 0x00, 0xff, 0xea, 0xc9, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0xc7, 0x00, 0xe9, 0xc7, 0xff, 0x00, 0xc7, 0xff, 0xe9, 0x00, 0xff, 0xe9, 0xc7, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xc5, 0x00, 0xe8, 0xc5, 0xff, 0x00, 0xc5, 0xff, 0xe8, 0x00, 0xff, 0xe8, 0xc5, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xc2, 0x00, 0xe7, 0xc2, 0xff, 0x00, 0xc2, 0xff, 0xe7, 0x00, 0xff, 0xe7, 0xc2, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xe6, 0xc0, 0xff, 0x00, 0xc0, 0xff, 0xe6, 0x00, 0xff, 0xe6, 0xc0, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xbd, 0x00, 0xe5, 0xbd, 0xff, 0x00, 0xbd, 0xff, 0xe5, 0x00, 0xff, 0xe5, 0xbd, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0xbb, 0x00, 0xe4, 0xbb, 0xff, 0x00, 0xbb, 0xff, 0xe4, 0x00, 0xff, 0xe4, 0xbb, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xb8, 0x00, 0xe3, 0xb8, 0xff, 0x00, 0xb8, 0xff, 0xe3, 0x00, 0xff, 0xe3, 0xb8, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0xb6, 0x00, 0xe2, 0xb6, 0xff, 0x00, 0xb6, 0xff, 0xe2, 0x00, 0xff, 0xe2, 0xb6, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xb3, 0x00, 0xe1, 0xb3, 0xff, 0x00, 0xb3, 0xff, 0xe1, 0x00, 0xff, 0xe1, 0xb3, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xb1, 0x00, 0xdf, 0xb1, 0xff, 0x00, 0xb1, 0xff, 0xdf, 0x00, 0xff, 0xdf, 0xb1, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0xae, 0x00, 0xde, 0xae, 0xff, 0x00, 0xae, 0xff, 0xde, 0x00, 0xff, 0xde, 0xae, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xac, 0x00, 0xdd, 0xac, 0xff, 0x00, 0xac, 0xff, 0xdd, 0x00, 0xff, 0xdd, 0xac, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xa9, 0x00, 0xdc, 0xa9, 0xff, 0x00, 0xa9, 0xff, 0xdc, 0x00, 0xff, 0xdc, 0xa9, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0xa7, 0x00, 0xda, 0xa7, 0xff, 0x00, 0xa7, 0xff, 0xda, 0x00, 0xff, 0xda, 0xa7, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xd9, 0xa4, 0xff, 0x00, 0xa4, 0xff, 0xd9, 0x00, 0xff, 0xd9, 0xa4, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0xa1, 0x00, 0xd8, 0xa1, 0xff, 0x00, 0xa1, 0xff, 0xd8, 0x00, 0xff, 0xd8, 0xa1, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x9e, 0x00, 0xd7, 0x9e, 0xff, 0x00, 0x9e, 0xff, 0xd7, 0x00, 0xff, 0xd7, 0x9e, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x9b, 0x00, 0xd6, 0x9b, 0xff, 0x00, 0x9b, 0xff, 0xd6, 0x00, 0xff, 0xd6, 0x9b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x99, 0x00, 0xd4, 0x99, 0xff, 0x00, 0x99, 0xff, 0xd4, 0x00, 0xff, 0xd4, 0x99, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x96, 0x00, 0xd3, 0x96, 0xff, 0x00, 0x96, 0xff, 0xd3, 0x00, 0xff, 0xd3, 0x96, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x93, 0x00, 0xd2, 0x93, 0xff, 0x00, 0x93, 0xff, 0xd2, 0x00, 0xff, 0xd2, 0x93, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x90, 0x00, 0xd1, 0x90, 0xff, 0x00, 0x90, 0xff, 0xd1, 0x00, 0xff, 0xd1, 0x90, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x8d, 0x00, 0xcf, 0x8d, 0xff, 0x00, 0x8d, 0xff, 0xcf, 0x00, 0xff, 0xcf, 0x8d, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0x8a, 0x00, 0xce, 0x8a, 0xff, 0x00, 0x8a, 0xff, 0xce, 0x00, 0xff, 0xce, 0x8a, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x87, 0x00, 0xcc, 0x87, 0xff, 0x00, 0x87, 0xff, 0xcc, 0x00, 0xff, 0xcc, 0x87, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x84, 0x00, 0xcb, 0x84, 0xff, 0x00, 0x84, 0xff, 0xcb, 0x00, 0xff, 0xcb, 0x84, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x81, 0x00, 0xc9, 0x81, 0xff, 0x00, 0x81, 0xff, 0xc9, 0x00, 0xff, 0xc9, 0x81, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc8, 0x7e, 0xff, 0x00, 0x7e, 0xff, 0xc8, 0x00, 0xff, 0xc8, 0x7e, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, /* 37 step */ + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x7b, 0x00, 0xc6, 0x7b, 0xff, 0x00, 0x7b, 0xff, 0xc6, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xf8, 0x00, 0x07, 0x07, 0xbe, 0x19, 0xea, 0xd1, 0xe1, 0x00, 0xc8, 0xd4, 0xd2, 0x02, 0xff, 0xf8, 0xec, 0xff, 0x00, 0x00, /* 6500K */ + 0xc6, 0x00, 0x00, 0x10, 0xf6, 0x00, 0x07, 0x07, 0xb8, 0x19, 0xe8, 0xcb, 0xe1, 0x00, 0xc2, 0xd4, 0xd0, 0x02, 0xff, 0xf6, 0xe5, 0xff, 0x00, 0x00, /* 6300K */ + 0xc6, 0x00, 0x00, 0x10, 0xf2, 0x00, 0x07, 0x07, 0xb0, 0x19, 0xe5, 0xc2, 0xe1, 0x00, 0xba, 0xd4, 0xcd, 0x02, 0xff, 0xf2, 0xdb, 0xff, 0x00, 0x00, /* 6100K */ + 0xc6, 0x00, 0x00, 0x10, 0xef, 0x00, 0x07, 0x07, 0xa7, 0x19, 0xe2, 0xb8, 0xe1, 0x00, 0xb0, 0xd4, 0xca, 0x02, 0xff, 0xef, 0xd0, 0xff, 0x00, 0x00, /* 5900K */ + 0xc6, 0x00, 0x00, 0x10, 0xec, 0x00, 0x07, 0x06, 0x9e, 0x19, 0xdf, 0xae, 0xe1, 0x00, 0xa6, 0xd4, 0xc8, 0x02, 0xff, 0xec, 0xc4, 0xff, 0x00, 0x00, /* 5700K */ + 0xc6, 0x00, 0x00, 0x10, 0xe8, 0x00, 0x07, 0x06, 0x95, 0x19, 0xdb, 0xa4, 0xe1, 0x00, 0x9d, 0xd4, 0xc5, 0x01, 0xff, 0xe8, 0xb9, 0xff, 0x00, 0x00, /* 5500K */ + 0xc6, 0x00, 0x00, 0x10, 0xd9, 0x00, 0x07, 0x06, 0x7b, 0x19, 0xcd, 0x88, 0xe1, 0x00, 0x82, 0xd4, 0xb8, 0x01, 0xff, 0xd9, 0x99, 0xff, 0x00, 0x00, /* 4900K */ + 0xc6, 0x00, 0x00, 0x10, 0xc8, 0x00, 0x07, 0x05, 0x61, 0x19, 0xbd, 0x6b, 0xe1, 0x00, 0x66, 0xd4, 0xa9, 0x01, 0xff, 0xc8, 0x79, 0xff, 0x00, 0x00, /* 4300K */ + 0xc6, 0x00, 0x00, 0x10, 0xb3, 0x00, 0x07, 0x05, 0x47, 0x19, 0xa9, 0x4e, 0xe1, 0x00, 0x4b, 0xd4, 0x98, 0x01, 0xff, 0xb3, 0x58, 0xff, 0x00, 0x00, /* 3700K */ + 0xc6, 0x00, 0x00, 0x10, 0x9a, 0x00, 0x07, 0x04, 0x2b, 0x19, 0x92, 0x30, 0xe1, 0x00, 0x2e, 0xd4, 0x82, 0x00, 0xff, 0x9a, 0x36, 0xff, 0x00, 0x00, /* 3100K */ + 0xc6, 0x00, 0x00, 0x10, 0x6c, 0x00, 0x07, 0x03, 0x0f, 0x19, 0x66, 0x11, 0xe1, 0x00, 0x10, 0xd4, 0x5b, 0x00, 0xff, 0x6c, 0x13, 0xff, 0x00, 0x00, /* 2300K */ + 0xc6, 0x00, 0x00, 0x10, 0xf1, 0x00, 0x07, 0x06, 0xad, 0x19, 0xe3, 0xbf, 0xe1, 0x00, 0xb6, 0xd4, 0xcc, 0x01, 0xff, 0xf1, 0xd8, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xf0, 0x00, 0x07, 0x06, 0xac, 0x19, 0xe2, 0xbd, 0xe1, 0x00, 0xb5, 0xd4, 0xcb, 0x01, 0xff, 0xf0, 0xd6, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xef, 0x00, 0x07, 0x06, 0xa9, 0x19, 0xe1, 0xbb, 0xe1, 0x00, 0xb2, 0xd4, 0xca, 0x01, 0xff, 0xef, 0xd3, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xee, 0x00, 0x07, 0x06, 0xa8, 0x19, 0xe0, 0xb9, 0xe1, 0x00, 0xb1, 0xd4, 0xc9, 0x01, 0xff, 0xee, 0xd1, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xec, 0x00, 0x07, 0x06, 0xa5, 0x19, 0xdf, 0xb6, 0xe1, 0x00, 0xae, 0xd4, 0xc7, 0x01, 0xff, 0xec, 0xce, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xeb, 0x00, 0x07, 0x06, 0xa4, 0x19, 0xde, 0xb4, 0xe1, 0x00, 0xac, 0xd4, 0xc7, 0x01, 0xff, 0xeb, 0xcc, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xea, 0x00, 0x07, 0x06, 0xa1, 0x19, 0xdd, 0xb2, 0xe1, 0x00, 0xaa, 0xd4, 0xc6, 0x01, 0xff, 0xea, 0xc9, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe9, 0x00, 0x07, 0x06, 0x9f, 0x19, 0xdc, 0xb0, 0xe1, 0x00, 0xa8, 0xd4, 0xc5, 0x01, 0xff, 0xe9, 0xc7, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe8, 0x00, 0x07, 0x06, 0x9e, 0x19, 0xdb, 0xae, 0xe1, 0x00, 0xa6, 0xd4, 0xc4, 0x01, 0xff, 0xe8, 0xc5, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe7, 0x00, 0x07, 0x06, 0x9b, 0x19, 0xda, 0xab, 0xe1, 0x00, 0xa4, 0xd4, 0xc3, 0x01, 0xff, 0xe7, 0xc2, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe6, 0x00, 0x07, 0x06, 0x9a, 0x19, 0xd9, 0xaa, 0xe1, 0x00, 0xa2, 0xd4, 0xc2, 0x01, 0xff, 0xe6, 0xc0, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe5, 0x00, 0x07, 0x06, 0x97, 0x19, 0xd8, 0xa7, 0xe1, 0x00, 0xa0, 0xd4, 0xc1, 0x01, 0xff, 0xe5, 0xbd, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe4, 0x00, 0x07, 0x06, 0x96, 0x19, 0xd7, 0xa5, 0xe1, 0x00, 0x9e, 0xd4, 0xc1, 0x01, 0xff, 0xe4, 0xbb, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe3, 0x00, 0x07, 0x06, 0x93, 0x19, 0xd6, 0xa3, 0xe1, 0x00, 0x9b, 0xd4, 0xc0, 0x01, 0xff, 0xe3, 0xb8, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe2, 0x00, 0x07, 0x06, 0x92, 0x19, 0xd5, 0xa1, 0xe1, 0x00, 0x9a, 0xd4, 0xbf, 0x01, 0xff, 0xe2, 0xb6, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xe1, 0x00, 0x07, 0x06, 0x8f, 0x19, 0xd4, 0x9e, 0xe1, 0x00, 0x97, 0xd4, 0xbe, 0x01, 0xff, 0xe1, 0xb3, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xdf, 0x00, 0x07, 0x06, 0x8e, 0x19, 0xd2, 0x9c, 0xe1, 0x00, 0x95, 0xd4, 0xbc, 0x01, 0xff, 0xdf, 0xb1, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xde, 0x00, 0x07, 0x06, 0x8b, 0x19, 0xd1, 0x9a, 0xe1, 0x00, 0x93, 0xd4, 0xbc, 0x01, 0xff, 0xde, 0xae, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xdd, 0x00, 0x07, 0x06, 0x8a, 0x19, 0xd0, 0x98, 0xe1, 0x00, 0x91, 0xd4, 0xbb, 0x01, 0xff, 0xdd, 0xac, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xdc, 0x00, 0x07, 0x06, 0x87, 0x19, 0xcf, 0x95, 0xe1, 0x00, 0x8f, 0xd4, 0xba, 0x01, 0xff, 0xdc, 0xa9, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xda, 0x00, 0x07, 0x05, 0x86, 0x19, 0xce, 0x94, 0xe1, 0x00, 0x8d, 0xd4, 0xb8, 0x01, 0xff, 0xda, 0xa7, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd9, 0x00, 0x07, 0x05, 0x83, 0x19, 0xcd, 0x91, 0xe1, 0x00, 0x8a, 0xd4, 0xb7, 0x01, 0xff, 0xd9, 0xa4, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd8, 0x00, 0x07, 0x05, 0x81, 0x19, 0xcc, 0x8e, 0xe1, 0x00, 0x88, 0xd4, 0xb6, 0x01, 0xff, 0xd8, 0xa1, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd7, 0x00, 0x07, 0x05, 0x7f, 0x19, 0xcb, 0x8c, 0xe1, 0x00, 0x85, 0xd4, 0xb6, 0x01, 0xff, 0xd7, 0x9e, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd6, 0x00, 0x07, 0x05, 0x7c, 0x19, 0xca, 0x89, 0xe1, 0x00, 0x83, 0xd4, 0xb5, 0x01, 0xff, 0xd6, 0x9b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd4, 0x00, 0x07, 0x05, 0x7b, 0x19, 0xc8, 0x87, 0xe1, 0x00, 0x81, 0xd4, 0xb3, 0x01, 0xff, 0xd4, 0x99, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd3, 0x00, 0x07, 0x05, 0x78, 0x19, 0xc7, 0x84, 0xe1, 0x00, 0x7f, 0xd4, 0xb2, 0x01, 0xff, 0xd3, 0x96, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd2, 0x00, 0x07, 0x05, 0x76, 0x19, 0xc6, 0x82, 0xe1, 0x00, 0x7c, 0xd4, 0xb1, 0x01, 0xff, 0xd2, 0x93, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xd1, 0x00, 0x07, 0x05, 0x73, 0x19, 0xc5, 0x7f, 0xe1, 0x00, 0x79, 0xd4, 0xb1, 0x01, 0xff, 0xd1, 0x90, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x07, 0x05, 0x71, 0x19, 0xc3, 0x7c, 0xe1, 0x00, 0x77, 0xd4, 0xaf, 0x01, 0xff, 0xcf, 0x8d, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xce, 0x00, 0x07, 0x05, 0x6e, 0x19, 0xc2, 0x7a, 0xe1, 0x00, 0x74, 0xd4, 0xae, 0x01, 0xff, 0xce, 0x8a, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xcc, 0x00, 0x07, 0x05, 0x6c, 0x19, 0xc0, 0x77, 0xe1, 0x00, 0x72, 0xd4, 0xac, 0x01, 0xff, 0xcc, 0x87, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xcb, 0x00, 0x07, 0x05, 0x6a, 0x19, 0xbf, 0x74, 0xe1, 0x00, 0x6f, 0xd4, 0xab, 0x01, 0xff, 0xcb, 0x84, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc9, 0x00, 0x07, 0x05, 0x67, 0x19, 0xbd, 0x72, 0xe1, 0x00, 0x6d, 0xd4, 0xaa, 0x01, 0xff, 0xc9, 0x81, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc8, 0x00, 0x07, 0x05, 0x65, 0x19, 0xbd, 0x6f, 0xe1, 0x00, 0x6a, 0xd4, 0xa9, 0x00, 0xff, 0xc8, 0x7e, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, /* 37 step */ + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x10, 0xc6, 0x00, 0x07, 0x05, 0x62, 0x19, 0xbb, 0x6d, 0xe1, 0x00, 0x68, 0xd4, 0xa7, 0x00, 0xff, 0xc6, 0x7b, 0xff, 0x00, 0x00, +}; + +static char DSI0_BYPASS_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x00, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_BYPASS_MDNIE_2[] = { + 0x62, // CRC + 0x01, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xff, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xff, // crc_lut_mode1_wg + 0xff, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_BYPASS_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_BYPASS_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_COLOR_BLIND_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_COLOR_BLIND_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xff, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xff, // crc_lut_mode1_wg + 0xff, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_COLOR_BLIND_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_COLOR_BLIND_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_NIGHT_MODE_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_NIGHT_MODE_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xff, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xff, // crc_lut_mode1_wg + 0xff, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_NIGHT_MODE_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_NIGHT_MODE_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_HBM_CE_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x02, // ACE on/off + 0x1f, // ACE gain + 0x02, // ORE on/off + 0x70, // ORE level +}; + +static char DSI0_HBM_CE_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xf5, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xff, // crc_lut_mode1_wg + 0xff, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_HBM_CE_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_HBM_CE_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_HBM_CE_D65_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x02, // ACE on/off + 0x1f, // ACE gain + 0x02, // ORE on/off + 0x70, // ORE level +}; + +static char DSI0_HBM_CE_D65_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xf5, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xf8, // crc_lut_mode1_wg + 0xec, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_HBM_CE_D65_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_HBM_CE_D65_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_RGB_SENSOR_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_RGB_SENSOR_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xff, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xff, // crc_lut_mode1_wg + 0xff, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_RGB_SENSOR_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_RGB_SENSOR_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_SCREEN_CURTAIN_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_SCREEN_CURTAIN_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0x00, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0x00, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0x00, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0x00, // crc_lut_mode1_cg + 0x00, // crc_lut_mode1_cb + 0x00, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0x00, // crc_lut_mode1_mb + 0x00, // crc_lut_mode1_yr + 0x00, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0x00, // crc_lut_mode1_wr + 0x00, // crc_lut_mode1_wg + 0x00, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_SCREEN_CURTAIN_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_SCREEN_CURTAIN_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_LIGHT_NOTIFICATION_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_LIGHT_NOTIFICATION_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x60, // crc_lut_mode1_rg + 0x13, // crc_lut_mode1_rb + 0x66, // crc_lut_mode1_gr + 0xf9, // crc_lut_mode1_gg + 0x13, // crc_lut_mode1_gb + 0x66, // crc_lut_mode1_br + 0x60, // crc_lut_mode1_bg + 0xac, // crc_lut_mode1_bb + 0x66, // crc_lut_mode1_cr + 0xf9, // crc_lut_mode1_cg + 0xac, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x60, // crc_lut_mode1_mg + 0xac, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xf9, // crc_lut_mode1_yg + 0x13, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xf9, // crc_lut_mode1_wg + 0xac, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_LIGHT_NOTIFICATION_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_LIGHT_NOTIFICATION_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_HDR_VIDEO_1_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_HDR_VIDEO_1_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xc6, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x10, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x07, // crc_lut_mode1_br + 0x07, // crc_lut_mode1_bg + 0xcd, // crc_lut_mode1_bb + 0x19, // crc_lut_mode1_cr + 0xf1, // crc_lut_mode1_cg + 0xe2, // crc_lut_mode1_cb + 0xe1, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xd8, // crc_lut_mode1_mb + 0xe4, // crc_lut_mode1_yr + 0xd8, // crc_lut_mode1_yg + 0x02, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xf8, // crc_lut_mode1_wg + 0xec, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_HDR_VIDEO_1_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_HDR_VIDEO_1_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_HDR_VIDEO_2_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_HDR_VIDEO_2_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xc6, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x10, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x07, // crc_lut_mode1_br + 0x07, // crc_lut_mode1_bg + 0xcd, // crc_lut_mode1_bb + 0x19, // crc_lut_mode1_cr + 0xf1, // crc_lut_mode1_cg + 0xe2, // crc_lut_mode1_cb + 0xe1, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xd8, // crc_lut_mode1_mb + 0xe4, // crc_lut_mode1_yr + 0xd8, // crc_lut_mode1_yg + 0x02, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xf8, // crc_lut_mode1_wg + 0xec, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_HDR_VIDEO_2_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_HDR_VIDEO_2_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_HDR_VIDEO_3_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_HDR_VIDEO_3_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xc6, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x10, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x07, // crc_lut_mode1_br + 0x07, // crc_lut_mode1_bg + 0xcd, // crc_lut_mode1_bb + 0x19, // crc_lut_mode1_cr + 0xf1, // crc_lut_mode1_cg + 0xe2, // crc_lut_mode1_cb + 0xe1, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xd8, // crc_lut_mode1_mb + 0xe4, // crc_lut_mode1_yr + 0xd8, // crc_lut_mode1_yg + 0x02, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xf8, // crc_lut_mode1_wg + 0xec, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_HDR_VIDEO_3_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_HDR_VIDEO_3_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_UI_DYNAMIC_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_UI_DYNAMIC_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xc6, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x10, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x07, // crc_lut_mode1_br + 0x07, // crc_lut_mode1_bg + 0xcd, // crc_lut_mode1_bb + 0x19, // crc_lut_mode1_cr + 0xf1, // crc_lut_mode1_cg + 0xe2, // crc_lut_mode1_cb + 0xe1, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xd8, // crc_lut_mode1_mb + 0xe4, // crc_lut_mode1_yr + 0xd8, // crc_lut_mode1_yg + 0x02, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xf8, // crc_lut_mode1_wg + 0xec, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_UI_DYNAMIC_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_UI_DYNAMIC_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_UI_AUTO_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x02, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_UI_AUTO_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xff, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xff, // crc_lut_mode1_wg + 0xff, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_UI_AUTO_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_UI_AUTO_MDNIE_4[] = { + 0x62, // TCS + 0x20, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x12, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_GALLERY_AUTO_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x02, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_GALLERY_AUTO_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x15, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xff, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xf0, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xff, // crc_lut_mode1_wg + 0xff, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_GALLERY_AUTO_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_GALLERY_AUTO_MDNIE_4[] = { + 0x62, // TCS + 0x20, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_EBOOK_AUTO_MDNIE_1[] = { + //start + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_EBOOK_AUTO_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xff, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xf1, // crc_lut_mode1_wg + 0xd7, // crc_lut_mode1_wb + 0xff, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_EBOOK_AUTO_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_EBOOK_AUTO_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static char DSI0_HMT_COLOR_TEMP_6500K_MDNIE_1[] = { + 0x5D, // CRC + 0x06, // CRC on/off + 0x00, + 0x00, // TCS on/off + 0x00, // ACE on/off + 0x00, // ACE gain + 0x00, // ORE on/off + 0x00, // ORE level +}; + +static char DSI0_HMT_COLOR_TEMP_6500K_MDNIE_2[] = { + 0x62, // CRC + 0x00, // crc_bypass + 0xff, // crc_lut_mode1_rr + 0x00, // crc_lut_mode1_rg + 0x00, // crc_lut_mode1_rb + 0x00, // crc_lut_mode1_gr + 0xff, // crc_lut_mode1_gg + 0x00, // crc_lut_mode1_gb + 0x00, // crc_lut_mode1_br + 0x00, // crc_lut_mode1_bg + 0xf5, // crc_lut_mode1_bb + 0x00, // crc_lut_mode1_cr + 0xff, // crc_lut_mode1_cg + 0xff, // crc_lut_mode1_cb + 0xff, // crc_lut_mode1_mr + 0x00, // crc_lut_mode1_mg + 0xff, // crc_lut_mode1_mb + 0xff, // crc_lut_mode1_yr + 0xff, // crc_lut_mode1_yg + 0x00, // crc_lut_mode1_yb + 0xff, // crc_lut_mode1_wr + 0xfa, // crc_lut_mode1_wg + 0xf8, // crc_lut_mode1_wb + 0xec, // crc_lut_mode2_rr_temp + 0x00, // crc_lut_mode2_rg_temp + 0x00, // crc_lut_mode2_rb_temp +}; + +static char DSI0_HMT_COLOR_TEMP_6500K_MDNIE_3[] = { + 0xb0, + 0x00, + 0xa0, + 0x62, +}; + +static char DSI0_HMT_COLOR_TEMP_6500K_MDNIE_4[] = { + 0x62, // TCS + 0x21, // bypass, y_type + 0x01, // obj_sel, skin_boundary_para + 0x79, // skin_boundary_para + 0x00, + 0x01, + 0x00, + 0x04, + 0x01, + 0x1E, + 0x80, + 0x01, + 0x00, + 0x02, + 0x01, // grass_boundary_para + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x59, + 0x01, // sky_boundary_para + 0x02, + 0x49, + 0x01, + 0x00, + 0x60, + 0x01, + 0x02, + 0x5A, + 0x01, + 0x00, + 0x63, + 0x00, // skin_boundary_para + 0x00, + 0xFF, + 0x00, + 0x00, + 0x86, + 0x00, + 0x11, + 0xAC, + 0x00, + 0x00, + 0xFF, + 0x00, // grass_boundary_para + 0x00, + 0x9F, + 0x00, + 0x00, + 0x33, + 0x00, + 0x00, + 0xF0, + 0x00, + 0x00, + 0x72, + 0x00, // sky_boundary_para + 0x01, + 0xAE, + 0x00, + 0x00, + 0x89, + 0x00, + 0x02, + 0x16, + 0x00, + 0x00, + 0xB3, + 0x00, // skin_boundary_para + 0x00, + 0x04, + 0x00, + 0x8F, + 0x00, + 0x01, + 0x00, + 0x87, + 0x01, + 0x02, + 0x22, + 0x00, // grass_boundary_para + 0x0B, + 0x24, + 0x00, + 0x0A, + 0x18, + 0x01, + 0x04, + 0x6A, + 0x01, + 0x06, + 0xCD, + 0x00, // sky_boundary_para + 0x04, + 0x98, + 0x00, + 0x0F, + 0xC1, + 0x01, + 0x06, + 0xE6, + 0x01, + 0x0A, + 0xE1, + 0x64, // skin_boundary_idx + 0x62, // grass_boundary_idx + 0x61, // sky_boundary_idx + 0x24, // Skin Color Gain + 0x80, // grass Color Gain + 0x80, // sky Color Gai + 0x80, // Target Skin Color (Cb) + 0x52, // Target grass Color (Cb) + 0xAE, // Target Sky Color (Cb) + 0x86, // Target Skin Color (Cr) + 0x69, // Target grass Color (Cr) + 0x58, // Target Sky Color (Cr) + 0x00, // Threshold Value of Skin Color Detection + 0x00, // Threshold Value of grass Color Detection + 0x00, // Threshold Value of Sky Color Detection + 0x32, // Minumum Y of Skin Brightness Control + 0x1E, // Minumum Y of grass Brightness Control + 0x1E, // Minumum Y of Sky Brightness Control + 0xDC, // Maximum Y of Skin Brightness Control + 0xC8, // Maximum Y of grass Brightness Control + 0xC8, // Maximum Y of Sky Brightness Control + 0x88, // Reference Y of Skin Brightness Control + 0x78, // Reference Y of grass Brightness Control + 0x78, // Reference Y of Sky Brightness Control + 0x8A, // Target Y of Skin Brihgtness Contol + 0x78, // Target Y of grass Brihgtness Contol + 0x78, // Target Y of Sky Brihgtness Contol + 0x00, // Brightness Parameter + 0x24, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8A, + 0x00, + 0x80, + 0x00, + 0x80, + 0x01, + 0x86, + 0x00, + 0x00, + 0x00, + 0x00, + 0x82, + 0xFA, + 0x80, + 0x00, + 0x80, + 0x00, + 0x7C, + 0xF4, + 0x80, + 0x00, + 0x80, + 0x00, + 0x00, // dummy 0x62 P326 + 0x00, // dummy 0x62 P327 + 0x00, // dummy 0x62 P328 + 0x00, // dummy 0x62 P329 + 0x00, // dummy 0x62 P330 + 0x00, // ACE bypass : 0x01, ACE on : 0x00 + 0xf0, + 0x03, + 0xff, + 0x04, + 0xc8, + 0xc8, + 0xff, + 0xff, + 0x28, + 0x28, + 0x3c, + 0x00, + 0x00, + 0x05, + 0x00, + 0x64, + 0x1e, + 0x1e, + 0x10, + 0x01, + 0x00, + 0x10, + 0x64, + 0x06, + 0x08, + 0x08, + 0x10, + 0x00, + 0x20, + 0x00, + 0x10, + 0x00, + 0x04, + 0x10, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x04, + 0x00, + 0xff, + 0x00, + 0xff, + 0x00, +}; + +static struct dsi_cmd_desc DSI0_BYPASS_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_BYPASS_MDNIE_1), DSI0_BYPASS_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_BYPASS_MDNIE_2), DSI0_BYPASS_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_BYPASS_MDNIE_3), DSI0_BYPASS_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_BYPASS_MDNIE_4), DSI0_BYPASS_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_COLOR_BLIND_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_COLOR_BLIND_MDNIE_1), DSI0_COLOR_BLIND_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_COLOR_BLIND_MDNIE_2), DSI0_COLOR_BLIND_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_COLOR_BLIND_MDNIE_3), DSI0_COLOR_BLIND_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_COLOR_BLIND_MDNIE_4), DSI0_COLOR_BLIND_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_NIGHT_MODE_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_NIGHT_MODE_MDNIE_1), DSI0_NIGHT_MODE_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_NIGHT_MODE_MDNIE_2), DSI0_NIGHT_MODE_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_NIGHT_MODE_MDNIE_3), DSI0_NIGHT_MODE_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_NIGHT_MODE_MDNIE_4), DSI0_NIGHT_MODE_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_HBM_CE_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_MDNIE_1), DSI0_HBM_CE_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_MDNIE_2), DSI0_HBM_CE_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_MDNIE_3), DSI0_HBM_CE_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_MDNIE_4), DSI0_HBM_CE_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_HBM_CE_D65_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_D65_MDNIE_1), DSI0_HBM_CE_D65_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_D65_MDNIE_2), DSI0_HBM_CE_D65_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_D65_MDNIE_3), DSI0_HBM_CE_D65_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HBM_CE_D65_MDNIE_4), DSI0_HBM_CE_D65_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_RGB_SENSOR_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_RGB_SENSOR_MDNIE_1), DSI0_RGB_SENSOR_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_RGB_SENSOR_MDNIE_2), DSI0_RGB_SENSOR_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_RGB_SENSOR_MDNIE_3), DSI0_RGB_SENSOR_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_RGB_SENSOR_MDNIE_4), DSI0_RGB_SENSOR_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_SCREEN_CURTAIN_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_SCREEN_CURTAIN_MDNIE_1), DSI0_SCREEN_CURTAIN_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_SCREEN_CURTAIN_MDNIE_2), DSI0_SCREEN_CURTAIN_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_SCREEN_CURTAIN_MDNIE_3), DSI0_SCREEN_CURTAIN_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_SCREEN_CURTAIN_MDNIE_4), DSI0_SCREEN_CURTAIN_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_LIGHT_NOTIFICATION_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_LIGHT_NOTIFICATION_MDNIE_1), DSI0_LIGHT_NOTIFICATION_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_LIGHT_NOTIFICATION_MDNIE_2), DSI0_LIGHT_NOTIFICATION_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_LIGHT_NOTIFICATION_MDNIE_3), DSI0_LIGHT_NOTIFICATION_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_LIGHT_NOTIFICATION_MDNIE_4), DSI0_LIGHT_NOTIFICATION_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_HDR_VIDEO_1_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_1_MDNIE_1), DSI0_HDR_VIDEO_1_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_1_MDNIE_2), DSI0_HDR_VIDEO_1_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_1_MDNIE_3), DSI0_HDR_VIDEO_1_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_1_MDNIE_4), DSI0_HDR_VIDEO_1_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_HDR_VIDEO_2_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_2_MDNIE_1), DSI0_HDR_VIDEO_2_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_2_MDNIE_2), DSI0_HDR_VIDEO_2_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_2_MDNIE_3), DSI0_HDR_VIDEO_2_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_2_MDNIE_4), DSI0_HDR_VIDEO_2_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_HDR_VIDEO_3_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_3_MDNIE_1), DSI0_HDR_VIDEO_3_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_3_MDNIE_2), DSI0_HDR_VIDEO_3_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_3_MDNIE_3), DSI0_HDR_VIDEO_3_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HDR_VIDEO_3_MDNIE_4), DSI0_HDR_VIDEO_3_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_UI_DYNAMIC_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_DYNAMIC_MDNIE_1), DSI0_UI_DYNAMIC_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_DYNAMIC_MDNIE_2), DSI0_UI_DYNAMIC_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_DYNAMIC_MDNIE_3), DSI0_UI_DYNAMIC_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_DYNAMIC_MDNIE_4), DSI0_UI_DYNAMIC_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_UI_AUTO_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_AUTO_MDNIE_1), DSI0_UI_AUTO_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_AUTO_MDNIE_2), DSI0_UI_AUTO_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_AUTO_MDNIE_3), DSI0_UI_AUTO_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_UI_AUTO_MDNIE_4), DSI0_UI_AUTO_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_GALLERY_AUTO_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_GALLERY_AUTO_MDNIE_1), DSI0_GALLERY_AUTO_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_GALLERY_AUTO_MDNIE_2), DSI0_GALLERY_AUTO_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_GALLERY_AUTO_MDNIE_3), DSI0_GALLERY_AUTO_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_GALLERY_AUTO_MDNIE_4), DSI0_GALLERY_AUTO_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_EBOOK_AUTO_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_EBOOK_AUTO_MDNIE_1), DSI0_EBOOK_AUTO_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_EBOOK_AUTO_MDNIE_2), DSI0_EBOOK_AUTO_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_EBOOK_AUTO_MDNIE_3), DSI0_EBOOK_AUTO_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_EBOOK_AUTO_MDNIE_4), DSI0_EBOOK_AUTO_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc DSI0_HMT_COLOR_TEMP_6500K_MDNIE[] = { + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_on), level_0_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_on), level_1_key_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_on), multi_cmd_on, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HMT_COLOR_TEMP_6500K_MDNIE_1), DSI0_HMT_COLOR_TEMP_6500K_MDNIE_1, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HMT_COLOR_TEMP_6500K_MDNIE_2), DSI0_HMT_COLOR_TEMP_6500K_MDNIE_2, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HMT_COLOR_TEMP_6500K_MDNIE_3), DSI0_HMT_COLOR_TEMP_6500K_MDNIE_3, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(DSI0_HMT_COLOR_TEMP_6500K_MDNIE_4), DSI0_HMT_COLOR_TEMP_6500K_MDNIE_4, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_off), multi_cmd_off, 0, NULL}, false, 20}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(multi_cmd_dummy), multi_cmd_dummy, 0, NULL}, false, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_1_key_off), level_1_key_off, 0, NULL}, true, 0}, + {{0, MIPI_DSI_DCS_LONG_WRITE, 0, 0, 0, sizeof(level_0_key_off), level_0_key_off, 0, NULL}, true, 0}, +}; + +static struct dsi_cmd_desc *mdnie_tune_value_dsi0[MAX_APP_MODE][MAX_MODE][MAX_OUTDOOR_MODE] = { + /* + DYNAMIC_MODE + STANDARD_MODE + NATURAL_MODE + MOVIE_MODE + AUTO_MODE + READING_MODE + */ + /* UI_APP */ + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_UI_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, + /* VIDEO_APP*/ + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_GALLERY_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, + /* VIDEO_WARM_APP*/ + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + /* VIDEO_COLD_APP*/ + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + /* CAMERA_APP*/ + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_GALLERY_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, + /* NAVI_APP*/ + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + /* GALLERY_APP*/ + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_GALLERY_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, + /* VT_APP*/ + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + /* BROWSER_APP*/ + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_GALLERY_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, + /* eBOOK_APP*/ + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, + // EMAIL_APP + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_UI_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, + // GAME_LOW_APP + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + // GAME_MID_APP + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + // GAME_HIGH_APP + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + // VIDEO_ENHANCER_APP + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + // VIDEO_ENHANCER_THIRD_APP + { + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + }, + /* TDMB_APP*/ + { + {DSI0_UI_DYNAMIC_MDNIE, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {NULL, NULL}, + {DSI0_GALLERY_AUTO_MDNIE, NULL}, + {DSI0_EBOOK_AUTO_MDNIE, NULL}, + }, +}; +static struct dsi_cmd_desc *hmt_color_temperature_tune_value_dsi0[HMT_COLOR_TEMP_MAX] = { + /* + HMT_COLOR_TEMP_3000K, // 3000K + HMT_COLOR_TEMP_4000K, // 4000K + HMT_COLOR_TEMP_5000K, // 5000K + HMT_COLOR_TEMP_6500K, // 6500K + HMT_COLOR_TEMP_7500K, // 7500K + */ + NULL, + NULL, + NULL, + NULL, + DSI0_HMT_COLOR_TEMP_6500K_MDNIE, + NULL, +}; + +static struct dsi_cmd_desc *light_notification_tune_value_dsi0[LIGHT_NOTIFICATION_MAX] = { + NULL, + DSI0_LIGHT_NOTIFICATION_MDNIE, +}; + +static struct dsi_cmd_desc *hdr_tune_value_dsi0[HDR_MAX] = { + NULL, + DSI0_HDR_VIDEO_1_MDNIE, + DSI0_HDR_VIDEO_2_MDNIE, + DSI0_HDR_VIDEO_3_MDNIE, + NULL, + NULL, +}; + +#define DSI0_RGB_SENSOR_MDNIE_1_SIZE ARRAY_SIZE(DSI0_RGB_SENSOR_MDNIE_1) +#define DSI0_RGB_SENSOR_MDNIE_2_SIZE ARRAY_SIZE(DSI0_RGB_SENSOR_MDNIE_2) +#define DSI0_RGB_SENSOR_MDNIE_3_SIZE ARRAY_SIZE(DSI0_RGB_SENSOR_MDNIE_3) +#define DSI0_RGB_SENSOR_MDNIE_4_SIZE ARRAY_SIZE(DSI0_RGB_SENSOR_MDNIE_4) + +#endif diff --git a/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.c b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.c new file mode 100644 index 000000000..86af257c8 --- /dev/null +++ b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.c @@ -0,0 +1,1335 @@ +/* + * ================================================================= + * + * + * Description: samsung display panel file + * + * Author: jb09.kim + * Company: Samsung Electronics + * + * ================================================================ + */ +/* + +Copyright (C) 2017, Samsung Electronics. All rights reserved. + +* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ +#include "ss_dsi_panel_S6E3FC3_AMS646YD01.h" +#include "ss_dsi_mdnie_S6E3FC3_AMS646YD01.h" + +static int samsung_panel_on_pre(struct samsung_display_driver_data *vdd) +{ + if (IS_ERR_OR_NULL(vdd)) { + pr_err("%s: Invalid data vdd : 0x%zx", __func__, (size_t)vdd); + return false; + } + + LCD_INFO("+: ndx=%d\n", vdd->ndx); + ss_panel_attach_set(vdd, true); + + return true; +} + +static int samsung_panel_on_post(struct samsung_display_driver_data *vdd) +{ + /* Module info */ + if (!vdd->module_info_loaded_dsi) { + if (IS_ERR_OR_NULL(vdd->panel_func.samsung_module_info_read)) + LCD_ERR("no samsung_module_info_read function\n"); + else + vdd->module_info_loaded_dsi = vdd->panel_func.samsung_module_info_read(vdd); + } + + /* Manufacture date */ + if (!vdd->manufacture_date_loaded_dsi) { + if (IS_ERR_OR_NULL(vdd->panel_func.samsung_manufacture_date_read)) + LCD_ERR("no samsung_manufacture_date_read function\n"); + else + vdd->manufacture_date_loaded_dsi = vdd->panel_func.samsung_manufacture_date_read(vdd); + } + + /* DDI ID */ + if (!vdd->ddi_id_loaded_dsi) { + if (IS_ERR_OR_NULL(vdd->panel_func.samsung_ddi_id_read)) + LCD_ERR("no samsung_ddi_id_read function\n"); + else + vdd->ddi_id_loaded_dsi = vdd->panel_func.samsung_ddi_id_read(vdd); + } + + /* MDNIE X,Y (1.Manufacture Date -> 2.MDNIE X,Y -> 3.Cell ID -> 4.OCTA ID) */ + if (!vdd->mdnie_loaded_dsi) { + if (IS_ERR_OR_NULL(vdd->panel_func.samsung_mdnie_read)) + LCD_ERR("no samsung_mdnie_read function\n"); + else + vdd->mdnie_loaded_dsi = vdd->panel_func.samsung_mdnie_read(vdd); + } + + /* Panel Unique Cell ID (1.Manufacture Date -> 2.MDNIE X,Y -> 3.Cell ID -> 4.OCTA ID) */ + if (!vdd->cell_id_loaded_dsi) { + if (IS_ERR_OR_NULL(vdd->panel_func.samsung_cell_id_read)) + LCD_ERR("no samsung_cell_id_read function\n"); + else + vdd->cell_id_loaded_dsi = vdd->panel_func.samsung_cell_id_read(vdd); + } + + /* Panel Unique OCTA ID (1.Manufacture Date -> 2.MDNIE X,Y -> 3.Cell ID -> 4.OCTA ID) */ + if (!vdd->octa_id_loaded_dsi) { + if (IS_ERR_OR_NULL(vdd->panel_func.samsung_octa_id_read)) + LCD_ERR("no samsung_octa_id_read function\n"); + else + vdd->octa_id_loaded_dsi = vdd->panel_func.samsung_octa_id_read(vdd); + } + + /* self mask cmd send again under splash mode(cause,sleep out cmd) */ + if (vdd->self_disp.self_mask_img_write) + vdd->self_disp.self_mask_img_write(vdd); + + if (vdd->self_disp.self_mask_on) + vdd->self_disp.self_mask_on(vdd, true); + + return true; +} + +static char ss_panel_revision(struct samsung_display_driver_data *vdd) +{ + if (vdd->manufacture_id_dsi == PBA_ID) + ss_panel_attach_set(vdd, false); + else + ss_panel_attach_set(vdd, true); + + switch (ss_panel_rev_get(vdd)) { + case 0x00: + vdd->panel_revision = 'A'; + break; + case 0x01: + vdd->panel_revision = 'B'; + break; + case 0x02 ... 0x05: + vdd->panel_revision = 'C'; + break; + case 0x06 ... 0x09: + vdd->panel_revision = 'G'; + break; + case 0x0A: + vdd->panel_revision = 'I'; + break; + default: + vdd->panel_revision = 'I'; + LCD_ERR("Invalid panel_rev(default rev : %c)\n", + vdd->panel_revision); + break; + } + + vdd->panel_revision -= 'A'; + + LCD_INFO_ONCE("panel_revision = %c %d \n", + vdd->panel_revision + 'A', vdd->panel_revision); + + return (vdd->panel_revision + 'A'); +} + +static struct dsi_panel_cmd_set *__ss_vrr(struct samsung_display_driver_data *vdd, + int *level_key, bool is_hbm, bool is_hmt) +{ + struct dsi_panel *panel = GET_DSI_PANEL(vdd); + struct dsi_panel_cmd_set *vrr_cmds = ss_get_cmds(vdd, TX_VRR); + struct vrr_info *vrr = &vdd->vrr; + + int cur_rr; + bool cur_hs; + + if (SS_IS_CMDS_NULL(vrr_cmds)) { + LCD_INFO("no vrr cmds\n"); + return NULL; + } + + if (panel && panel->cur_mode) { + LCD_INFO("VRR: cur_mode: %dx%d@%d%s, is_hbm: %d\n", + panel->cur_mode->timing.h_active, + panel->cur_mode->timing.v_active, + panel->cur_mode->timing.refresh_rate, + panel->cur_mode->timing.sot_hs_mode ? "HS" : "NM", + is_hbm); + + if (panel->cur_mode->timing.refresh_rate != vrr->adjusted_refresh_rate || + panel->cur_mode->timing.sot_hs_mode != vrr->adjusted_sot_hs_mode) + LCD_DEBUG("VRR: unmatched RR mode (%dhz%s / %dhz%s)\n", + panel->cur_mode->timing.refresh_rate, + panel->cur_mode->timing.sot_hs_mode ? "HS" : "NM", + vrr->adjusted_refresh_rate, + vrr->adjusted_sot_hs_mode ? "HS" : "NM"); + } + + cur_rr = vrr->cur_refresh_rate; + cur_hs = vrr->cur_sot_hs_mode; + + if (cur_rr == 60) { + vrr_cmds->cmds[0].msg.tx_buf[1] = 0x00; /* 60 HZ */ + } else { + vrr_cmds->cmds[0].msg.tx_buf[1] = 0x08; /* 120 HZ */ + } + + LCD_INFO("VRR: (cur: %d%s, adj: %d%s)\n", + cur_rr, + cur_hs ? "HS" : "NM", + vrr->adjusted_refresh_rate, + vrr->adjusted_sot_hs_mode ? "HS" : "NM"); + + return vrr_cmds; +} + +static struct dsi_panel_cmd_set *ss_vrr(struct samsung_display_driver_data *vdd, int *level_key) +{ + bool is_hbm = false; + bool is_hmt = false; + + return __ss_vrr(vdd, level_key, is_hbm, is_hmt); +} + +static struct dsi_panel_cmd_set *ss_vrr_hbm(struct samsung_display_driver_data *vdd, int *level_key) +{ + bool is_hbm = true; + bool is_hmt = false; + + return __ss_vrr(vdd, level_key, is_hbm, is_hmt); +} + +#define FRAME_WAIT_60FPS (17) +#define FRAME_WAIT_90FPS (12) +#define FRAME_WAIT_120FPS (9) +#define HBM_NORMAL_DELAY_60FPS (9) +#define HBM_NORMAL_DELAY_90FPS (3) +#define HBM_NORMAL_DELAY_120FPS (9) + +#define get_bit(value, shift, width) ((value >> shift) & (GENMASK(width - 1, 0))) +static struct dsi_panel_cmd_set *ss_brightness_gamma_mode2_normal + (struct samsung_display_driver_data *vdd, int *level_key) +{ + struct dsi_panel_cmd_set *pcmds; + int cd_index = vdd->br_info.common_br.cd_idx ; + int finger_mask_update_delay; + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR(": Invalid data vdd : 0x%zx\n", (size_t)vdd); + return NULL; + } + + if (cd_index > ARRAY_SIZE(normal_aor_manual)) { + LCD_ERR(": Invalid data cd_index : %d array_max_size : %d\n", + cd_index, ARRAY_SIZE(normal_aor_manual)); + return NULL; + } + + pcmds = ss_get_cmds(vdd, TX_GAMMA_MODE2_NORMAL); + + if (ss_panel_revision(vdd) >= 'I') { + finger_mask_update_delay = vdd->vrr.cur_refresh_rate > 60 ? 9000 : 17000; + if (pcmds->cmds[6].last_command == 1) + usleep_range(finger_mask_update_delay, finger_mask_update_delay + 1); + + /* + This cmd sustain 0x20 value before brightness change. + This is display lab request point. + */ + pcmds->cmds[1].msg.tx_buf[1] = vdd->finger_mask_updated ? 0x20 : 0x60; + + /* Smooth transition : 0x28 */ + pcmds->cmds[4].msg.tx_buf[1] = vdd->finger_mask_updated ? 0x20 : 0x28; + + pcmds->cmds[5].msg.tx_buf[1] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 8, 8); + pcmds->cmds[5].msg.tx_buf[2] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 0, 8); + + pcmds->cmds[6].msg.tx_buf[1] = vdd->br_info.temperature > 0 ? + vdd->br_info.temperature : (char)(BIT(7) | (-1 * vdd->br_info.temperature)); + + if (vdd->finger_mask_updated) { + /* + There is panel limitation for HBM & AOR setting. + TE ->hbm cmd excluded aor cmd -> delay(90 fps 3ms or 60 fps 9ms) -> + aor cmd -> mask image + */ + pcmds->cmds[6].last_command = 1; + + if (vdd->vrr.cur_refresh_rate > 60) + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_120FPS; + else + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_60FPS; + } else { + pcmds->cmds[6].last_command = 0; + pcmds->cmds[6].post_wait_ms = 0; + } + + pcmds->cmds[10].msg.tx_buf[1] = normal_aor_manual[cd_index].aor_63h_119; + pcmds->cmds[10].msg.tx_buf[2] = normal_aor_manual[cd_index].aor_63h_120; + pcmds->cmds[10].msg.tx_buf[3] = normal_aor_manual[cd_index].aor_63h_121; + } + else if (ss_panel_revision(vdd) >= 'G') { + /* Smooth transition : 0x28 */ + pcmds->cmds[1].msg.tx_buf[1] = vdd->finger_mask_updated ? 0x20 : 0x28; + + pcmds->cmds[2].msg.tx_buf[1] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 8, 8); + pcmds->cmds[2].msg.tx_buf[2] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 0, 8); + + pcmds->cmds[3].msg.tx_buf[1] = vdd->br_info.temperature > 0 ? + vdd->br_info.temperature : (char)(BIT(7) | (-1 * vdd->br_info.temperature)); + + pcmds->cmds[5].msg.tx_buf[1] = normal_aor_manual[cd_index].aor_63h_119; + pcmds->cmds[5].msg.tx_buf[2] = normal_aor_manual[cd_index].aor_63h_120; + pcmds->cmds[5].msg.tx_buf[3] = normal_aor_manual[cd_index].aor_63h_121; + } else { + finger_mask_update_delay = vdd->vrr.cur_refresh_rate > 60 ? 9000 : 17000; + if (pcmds->cmds[6].last_command == 1) + usleep_range(finger_mask_update_delay, finger_mask_update_delay + 1); + + /* + * This cmd sustain 0x20 value before brightness change. + * This is display lab request point. + */ + pcmds->cmds[1].msg.tx_buf[1] = vdd->finger_mask_updated ? 0x20 : 0x60; + + /* Smooth transition : 0x28 */ + pcmds->cmds[4].msg.tx_buf[1] = vdd->finger_mask_updated ? 0x20 : 0x28; + + pcmds->cmds[5].msg.tx_buf[1] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 8, 8); + pcmds->cmds[5].msg.tx_buf[2] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 0, 8); + + pcmds->cmds[6].msg.tx_buf[1] = vdd->br_info.temperature > 0 ? + vdd->br_info.temperature : (char)(BIT(7) | (-1 * vdd->br_info.temperature)); + + if (vdd->finger_mask_updated) { + /* + * There is panel limitation for HBM & AOR setting. + * TE ->hbm cmd excluded aor cmd -> delay(90 fps 3ms or 60 fps 9ms) -> + * aor cmd -> mask image + */ + pcmds->cmds[6].last_command = 1; + + if (vdd->vrr.cur_refresh_rate > 60) + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_120FPS; + else + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_60FPS; + } else { + pcmds->cmds[6].last_command = 0; + pcmds->cmds[6].post_wait_ms = 0; + } + } + *level_key = LEVEL_KEY_NONE; + + return pcmds; +} + +static struct dsi_panel_cmd_set *ss_brightness_gamma_mode2_hbm + (struct samsung_display_driver_data *vdd, int *level_key) +{ + struct dsi_panel_cmd_set *pcmds; + struct dsi_panel_cmd_set *pcmds_smooth_off; + int cd_index = vdd->br_info.common_br.cd_idx ; + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR(": Invalid data vdd : 0x%zx\n", (size_t)vdd); + return NULL; + } + + if (cd_index > ARRAY_SIZE(hbm_aor_manual)) { + LCD_ERR(": Invalid data cd_index : %d array_max_size : %d\n", + cd_index, ARRAY_SIZE(hbm_aor_manual)); + return NULL; + } + + pcmds = ss_get_cmds(vdd, TX_GAMMA_MODE2_HBM); + pcmds_smooth_off = ss_get_cmds(vdd, TX_SMOOTH_DIMMING_OFF); + + if (ss_panel_revision(vdd) >= 'I') { + pcmds->cmds[5].msg.tx_buf[1] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 8, 8); + pcmds->cmds[5].msg.tx_buf[2] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 0, 8); + + pcmds->cmds[6].msg.tx_buf[1] = vdd->br_info.temperature > 0 ? + vdd->br_info.temperature : (char)(BIT(7) | (-1 * vdd->br_info.temperature)); + + if (vdd->finger_mask_updated) { + /* + * There is panel limitation for HBM & AOR setting. + * TE ->hbm cmd excluded aor cmd -> delay(90 fps 3ms or 60 fps 9ms) -> + * aor cmd -> mask image + */ + pcmds->cmds[6].last_command = 1; + + if (vdd->vrr.cur_refresh_rate > 60) + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_120FPS; + else + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_60FPS; + } else { + pcmds->cmds[6].last_command = 0; + pcmds->cmds[6].post_wait_ms = 0; + } + + pcmds->cmds[10].msg.tx_buf[1] = hbm_aor_manual[cd_index].aor_63h_119; + pcmds->cmds[10].msg.tx_buf[2] = hbm_aor_manual[cd_index].aor_63h_120; + pcmds->cmds[10].msg.tx_buf[3] = hbm_aor_manual[cd_index].aor_63h_121; + } else if (ss_panel_revision(vdd) >= 'G') { + pcmds->cmds[2].msg.tx_buf[1] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 8, 8); + pcmds->cmds[2].msg.tx_buf[2] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 0, 8); + + pcmds->cmds[3].msg.tx_buf[1] = vdd->br_info.temperature > 0 ? + vdd->br_info.temperature : (char)(BIT(7) | (-1 * vdd->br_info.temperature)); + + pcmds->cmds[5].msg.tx_buf[1] = hbm_aor_manual[cd_index].aor_63h_119; + pcmds->cmds[5].msg.tx_buf[2] = hbm_aor_manual[cd_index].aor_63h_120; + pcmds->cmds[5].msg.tx_buf[3] = hbm_aor_manual[cd_index].aor_63h_121; + } else { + pcmds->cmds[5].msg.tx_buf[1] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 8, 8); + pcmds->cmds[5].msg.tx_buf[2] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 0, 8); + + pcmds->cmds[6].msg.tx_buf[1] = vdd->br_info.temperature > 0 ? + vdd->br_info.temperature : (char)(BIT(7) | (-1 * vdd->br_info.temperature)); + + if (vdd->finger_mask_updated) { + /* Smooth Dimming Off First */ + if (vdd->vrr.cur_refresh_rate > 60) + pcmds_smooth_off->cmds[3].post_wait_ms = FRAME_WAIT_120FPS; + else + pcmds_smooth_off->cmds[3].post_wait_ms = FRAME_WAIT_60FPS; + + ss_send_cmd(vdd, TX_SMOOTH_DIMMING_OFF); + + /* + * There is panel limitation for HBM & AOR setting. + * TE ->hbm cmd excluded aor cmd -> delay(90 fps 3ms or 60 fps 9ms) -> + * aor cmd -> mask image + */ + pcmds->cmds[6].last_command = 1; + + if (vdd->vrr.cur_refresh_rate > 60) + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_120FPS; + else + pcmds->cmds[6].post_wait_ms = HBM_NORMAL_DELAY_60FPS; + } else { + pcmds->cmds[6].last_command = 0; + pcmds->cmds[6].post_wait_ms = 0; + } + } + + *level_key = LEVEL_KEY_NONE; + + return pcmds; +} + +#undef COORDINATE_DATA_SIZE +#define COORDINATE_DATA_SIZE 6 + +#define F1(x, y) ((y)-((39*(x))/38)-95) +#define F2(x, y) ((y)-((36*(x))/35)-56) +#define F3(x, y) ((y)+((7*(x))/1)-24728) +#define F4(x, y) ((y)+((25*(x))/7)-14031) + +#if 0 +/* Normal Mode */ +static char coordinate_data_1[][COORDINATE_DATA_SIZE] = { + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* dummy */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_1 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_2 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_3 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_4 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_5 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_6 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_7 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_8 */ + {0xff, 0x00, 0xff, 0x00, 0xff, 0x00}, /* Tune_9 */ +}; + +/* sRGB/Adobe RGB Mode */ +static char coordinate_data_2[][COORDINATE_DATA_SIZE] = { + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* dummy */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_1 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_2 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_3 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_4 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_5 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_6 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_7 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_8 */ + {0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00}, /* Tune_9 */ +}; + +static char (*coordinate_data_multi[MAX_MODE])[COORDINATE_DATA_SIZE] = { + coordinate_data_2, /* DYNAMIC - DCI */ + coordinate_data_2, /* STANDARD - sRGB/Adobe RGB */ + coordinate_data_2, /* NATURAL - sRGB/Adobe RGB */ + coordinate_data_1, /* MOVIE - Normal */ + coordinate_data_1, /* AUTO - Normal */ + coordinate_data_1, /* READING - Normal */ +}; +#endif + +static int mdnie_coordinate_index(int x, int y) +{ + int tune_number = 0; + + if (F1(x, y) > 0) { + if (F3(x, y) > 0) { + tune_number = 3; + } else { + if (F4(x, y) < 0) + tune_number = 1; + else + tune_number = 2; + } + } else { + if (F2(x, y) < 0) { + if (F3(x, y) > 0) { + tune_number = 9; + } else { + if (F4(x, y) < 0) + tune_number = 7; + else + tune_number = 8; + } + } else { + if (F3(x, y) > 0) + tune_number = 6; + else { + if (F4(x, y) < 0) + tune_number = 4; + else + tune_number = 5; + } + } + } + + return tune_number; +} + +static int ss_elvss_read(struct samsung_display_driver_data *vdd) +{ + return true; +} + +static int ss_module_info_read(struct samsung_display_driver_data *vdd) +{ + unsigned char buf[11] = {0,}; + int year, month, day; + int hour, min; + int mdnie_tune_index = 0; + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR("Invalid data vdd : 0x%zx", (size_t)vdd); + return false; + } + + if (ss_get_cmds(vdd, RX_MODULE_INFO)->count) { + ss_panel_data_read(vdd, RX_MODULE_INFO, buf, LEVEL1_KEY); + + /* Manufacture Date */ + + year = buf[4] & 0xf0; + year >>= 4; + year += 2011; // 0 = 2011 year + month = buf[4] & 0x0f; + day = buf[5] & 0x1f; + hour = buf[6] & 0x0f; + min = buf[7] & 0x1f; + + vdd->manufacture_date_dsi = year * 10000 + month * 100 + day; + vdd->manufacture_time_dsi = hour * 100 + min; + + LCD_INFO("manufacture_date DSI%d = (%d%04d) - year(%d) month(%d) day(%d) hour(%d) min(%d)\n", + vdd->ndx, vdd->manufacture_date_dsi, vdd->manufacture_time_dsi, + year, month, day, hour, min); + + /* While Coordinates */ + vdd->mdnie.mdnie_x = buf[0] << 8 | buf[1]; /* X */ + vdd->mdnie.mdnie_y = buf[2] << 8 | buf[3]; /* Y */ + + mdnie_tune_index = mdnie_coordinate_index(vdd->mdnie.mdnie_x, vdd->mdnie.mdnie_y); +#if 0 + coordinate_tunning_multi(vdd, coordinate_data_multi, mdnie_tune_index, + ADDRESS_SCR_WHITE_RED, COORDINATE_DATA_SIZE); +#endif + + LCD_INFO("DSI%d : X-%d Y-%d \n", vdd->ndx, + vdd->mdnie.mdnie_x, vdd->mdnie.mdnie_y); + + /* CELL ID (manufacture date + white coordinates) */ + /* Manufacture Date */ + vdd->cell_id_dsi[0] = buf[4]; + vdd->cell_id_dsi[1] = buf[5]; + vdd->cell_id_dsi[2] = buf[6]; + vdd->cell_id_dsi[3] = buf[7]; + vdd->cell_id_dsi[4] = buf[8]; + vdd->cell_id_dsi[5] = buf[9]; + vdd->cell_id_dsi[6] = buf[10]; + /* White Coordinates */ + vdd->cell_id_dsi[7] = buf[0]; + vdd->cell_id_dsi[8] = buf[1]; + vdd->cell_id_dsi[9] = buf[2]; + vdd->cell_id_dsi[10] = buf[3]; + + LCD_INFO("DSI%d CELL ID : %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + vdd->ndx, vdd->cell_id_dsi[0], + vdd->cell_id_dsi[1], vdd->cell_id_dsi[2], + vdd->cell_id_dsi[3], vdd->cell_id_dsi[4], + vdd->cell_id_dsi[5], vdd->cell_id_dsi[6], + vdd->cell_id_dsi[7], vdd->cell_id_dsi[8], + vdd->cell_id_dsi[9], vdd->cell_id_dsi[10]); + } + else { + LCD_ERR("DSI%d no module_info_rx_cmds cmds(%d)", vdd->ndx, vdd->panel_revision); + return false; + } + + return true; +} + + +static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) +{ + struct mdnie_lite_tune_data *mdnie_data; + + mdnie_data = kzalloc(sizeof(struct mdnie_lite_tune_data), GFP_KERNEL); + if (!mdnie_data) { + LCD_ERR("fail to allocate mdnie_data memory\n"); + return -ENOMEM; + } + + /* Update mdnie command */ + mdnie_data->DSI_RGB_SENSOR_MDNIE_1 = DSI0_RGB_SENSOR_MDNIE_1; + mdnie_data->DSI_RGB_SENSOR_MDNIE_2 = DSI0_RGB_SENSOR_MDNIE_2; + mdnie_data->DSI_RGB_SENSOR_MDNIE_3 = DSI0_RGB_SENSOR_MDNIE_3; + mdnie_data->DSI_UI_DYNAMIC_MDNIE_2 = DSI0_UI_DYNAMIC_MDNIE_2; + mdnie_data->DSI_UI_AUTO_MDNIE_2 = DSI0_UI_AUTO_MDNIE_2; + mdnie_data->DSI_GALLERY_AUTO_MDNIE_2 = DSI0_GALLERY_AUTO_MDNIE_2; + mdnie_data->DSI_EBOOK_AUTO_MDNIE_2 = DSI0_EBOOK_AUTO_MDNIE_2; + + mdnie_data->DSI_BYPASS_MDNIE = DSI0_BYPASS_MDNIE; + mdnie_data->DSI_COLOR_BLIND_MDNIE = DSI0_COLOR_BLIND_MDNIE; + mdnie_data->DSI_HBM_CE_MDNIE = DSI0_HBM_CE_MDNIE; + mdnie_data->DSI_HBM_CE_D65_MDNIE = DSI0_HBM_CE_D65_MDNIE; + mdnie_data->DSI_RGB_SENSOR_MDNIE = DSI0_RGB_SENSOR_MDNIE; + mdnie_data->DSI_UI_DYNAMIC_MDNIE = DSI0_UI_DYNAMIC_MDNIE; + mdnie_data->DSI_UI_AUTO_MDNIE = DSI0_UI_AUTO_MDNIE; + mdnie_data->DSI_GALLERY_AUTO_MDNIE = DSI0_GALLERY_AUTO_MDNIE; + mdnie_data->DSI_EBOOK_AUTO_MDNIE = DSI0_EBOOK_AUTO_MDNIE; + mdnie_data->DSI_CURTAIN = DSI0_SCREEN_CURTAIN_MDNIE; + mdnie_data->DSI_NIGHT_MODE_MDNIE = DSI0_NIGHT_MODE_MDNIE; + mdnie_data->DSI_NIGHT_MODE_MDNIE_SCR = DSI0_NIGHT_MODE_MDNIE_2; + mdnie_data->DSI_COLOR_BLIND_MDNIE_SCR = DSI0_COLOR_BLIND_MDNIE_2; + mdnie_data->DSI_RGB_SENSOR_MDNIE_SCR = DSI0_RGB_SENSOR_MDNIE_2; + + mdnie_data->mdnie_tune_value_dsi = mdnie_tune_value_dsi0; + mdnie_data->light_notification_tune_value_dsi = light_notification_tune_value_dsi0; + mdnie_data->hdr_tune_value_dsi = hdr_tune_value_dsi0; + mdnie_data->hmt_color_temperature_tune_value_dsi = hmt_color_temperature_tune_value_dsi0; + + /* Update MDNIE data related with size, offset or index */ + mdnie_data->dsi_bypass_mdnie_size = ARRAY_SIZE(DSI0_BYPASS_MDNIE); + mdnie_data->mdnie_color_blinde_cmd_offset = MDNIE_COLOR_BLINDE_CMD_OFFSET; + mdnie_data->mdnie_step_index[MDNIE_STEP1] = MDNIE_STEP1_INDEX; + mdnie_data->mdnie_step_index[MDNIE_STEP2] = MDNIE_STEP2_INDEX; + mdnie_data->mdnie_step_index[MDNIE_STEP3] = MDNIE_STEP3_INDEX; + mdnie_data->address_scr_white[ADDRESS_SCR_WHITE_RED_OFFSET] = ADDRESS_SCR_WHITE_RED; + mdnie_data->address_scr_white[ADDRESS_SCR_WHITE_GREEN_OFFSET] = ADDRESS_SCR_WHITE_GREEN; + mdnie_data->address_scr_white[ADDRESS_SCR_WHITE_BLUE_OFFSET] = ADDRESS_SCR_WHITE_BLUE; + mdnie_data->dsi_rgb_sensor_mdnie_1_size = DSI0_RGB_SENSOR_MDNIE_1_SIZE; + mdnie_data->dsi_rgb_sensor_mdnie_2_size = DSI0_RGB_SENSOR_MDNIE_2_SIZE; + mdnie_data->dsi_rgb_sensor_mdnie_3_size = DSI0_RGB_SENSOR_MDNIE_3_SIZE; + + mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; + mdnie_data->dsi_max_adjust_ldu = 6; + mdnie_data->dsi_night_mode_table = night_mode_data; + mdnie_data->dsi_max_night_mode_index = 102; + mdnie_data->dsi_white_default_r = 0xff; + mdnie_data->dsi_white_default_g = 0xff; + mdnie_data->dsi_white_default_b = 0xff; + mdnie_data->dsi_white_balanced_r = 0; + mdnie_data->dsi_white_balanced_g = 0; + mdnie_data->dsi_white_balanced_b = 0; + mdnie_data->dsi_scr_step_index = MDNIE_STEP2_INDEX; + + vdd->mdnie.mdnie_data = mdnie_data; + + return 0; +} + +static int ss_ddi_id_read(struct samsung_display_driver_data *vdd) +{ + char ddi_id[5]; + int loop; + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR("Invalid data vdd : 0x%zx", (size_t)vdd); + return false; + } + + /* Read mtp (D6h 1~5th) for ddi id */ + if (ss_get_cmds(vdd, RX_DDI_ID)->count) { + ss_panel_data_read(vdd, RX_DDI_ID, ddi_id, LEVEL1_KEY); + + for (loop = 0; loop < 5; loop++) + vdd->ddi_id_dsi[loop] = ddi_id[loop]; + + LCD_INFO("DSI%d : %02x %02x %02x %02x %02x\n", vdd->ndx, + vdd->ddi_id_dsi[0], vdd->ddi_id_dsi[1], + vdd->ddi_id_dsi[2], vdd->ddi_id_dsi[3], + vdd->ddi_id_dsi[4]); + } else { + LCD_ERR("DSI%d no ddi_id_rx_cmds cmds", vdd->ndx); + return false; + } + + return true; +} + +static int ss_octa_id_read(struct samsung_display_driver_data *vdd) +{ + char cell_id_buffer[MAX_CELL_ID] = {0,}; + int loop; + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR("Invalid data vdd : 0x%zx", (size_t)vdd); + return false; + } + + /* Read Panel Unique OCTA ID (A1 12th ~ 15th(4bytes) + Cell ID(16bytes)) */ + if (ss_get_cmds(vdd, RX_OCTA_ID)->count) { + memset(vdd->octa_id_dsi, 0x00, MAX_OCTA_ID); + + /* Read A1 12th ~ 15th(4bytes) */ + ss_panel_data_read(vdd, RX_OCTA_ID, + vdd->octa_id_dsi, LEVEL1_KEY); + + if (ss_get_cmds(vdd, RX_CELL_ID)->count) { + memset(cell_id_buffer, 0x00, MAX_CELL_ID); + /* Read 92h 3rd ~ 18th */ + ss_panel_data_read(vdd, RX_CELL_ID, cell_id_buffer, LEVEL1_KEY); + } + + /* Copy from cell_id(16bytes) */ + for (loop = 0; loop < MAX_CELL_ID; loop++) + vdd->octa_id_dsi[loop + 4] = cell_id_buffer[loop]; + LCD_INFO("octa id: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + vdd->octa_id_dsi[0], vdd->octa_id_dsi[1], + vdd->octa_id_dsi[2], vdd->octa_id_dsi[3], + vdd->octa_id_dsi[4], vdd->octa_id_dsi[5], + vdd->octa_id_dsi[6], vdd->octa_id_dsi[7], + vdd->octa_id_dsi[8], vdd->octa_id_dsi[9], + vdd->octa_id_dsi[10], vdd->octa_id_dsi[11], + vdd->octa_id_dsi[12], vdd->octa_id_dsi[13], + vdd->octa_id_dsi[14], vdd->octa_id_dsi[15], + vdd->octa_id_dsi[16], vdd->octa_id_dsi[17], + vdd->octa_id_dsi[18], vdd->octa_id_dsi[19]); + + } else { + LCD_ERR("DSI%d no octa_id_rx_cmds cmd\n", vdd->ndx); + return false; + } + + return true; +} + +static struct dsi_panel_cmd_set *ss_acl_on_hbm(struct samsung_display_driver_data *vdd, int *level_key) +{ + struct dsi_panel_cmd_set *pcmds; + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR("Invalid data vdd : 0x%zx", (size_t)vdd); + return NULL; + } + + pcmds = ss_get_cmds(vdd, TX_ACL_ON); + if (SS_IS_CMDS_NULL(pcmds)) { + LCD_ERR("No cmds for TX_ACL_ON..\n"); + return NULL; + } + + pcmds->cmds[2].msg.tx_buf[1] = 0x01; /* ACL 8% in HBM */ + + LCD_INFO("HBM: gradual_acl: %d, acl per: 0x%x", + vdd->br_info.gradual_acl_val, pcmds->cmds[2].msg.tx_buf[1]); + + return pcmds; +} + +static struct dsi_panel_cmd_set *ss_acl_on(struct samsung_display_driver_data *vdd, int *level_key) +{ + struct dsi_panel_cmd_set *pcmds; + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR("Invalid data vdd : 0x%zx", (size_t)vdd); + return NULL; + } + + pcmds = ss_get_cmds(vdd, TX_ACL_ON); + if (SS_IS_CMDS_NULL(pcmds)) { + LCD_ERR("No cmds for TX_ACL_ON..\n"); + return NULL; + } + + pcmds->cmds[2].msg.tx_buf[1] = 0x03; /* ACL 15% in normal brightness */ + + LCD_INFO("gradual_acl: %d, acl per: 0x%x", + vdd->br_info.gradual_acl_val, pcmds->cmds[2].msg.tx_buf[1]); + + return pcmds; +} + +static struct dsi_panel_cmd_set *ss_acl_off(struct samsung_display_driver_data *vdd, int *level_key) +{ + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR("Invalid data vdd : 0x%zx", (size_t)vdd); + return NULL; + } + + LCD_INFO("ACL off\n"); + return ss_get_cmds(vdd, TX_ACL_OFF); +} + + +enum LPMON_CMD_ID { + LPM_BL_CMDID_CTRL = 1, + LPM_ON_CMDID_BL = 2, +}; + +static void ss_set_panel_lpm_brightness(struct samsung_display_driver_data *vdd) +{ + struct dsi_panel_cmd_set *set = ss_get_cmds(vdd, TX_LPM_BL_CMD); + struct dsi_panel_cmd_set *set_lpm_bl; + + if (SS_IS_CMDS_NULL(set)) { + LCD_ERR("No cmds for TX_LPM_BL_CMD\n"); + return; + } + + /* LPM_ON: 3. HLPM brightness */ + switch (vdd->panel_lpm.lpm_bl_level) { + case LPM_60NIT: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_60NIT_CMD); + break; + case LPM_30NIT: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_30NIT_CMD); + break; + case LPM_10NIT: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_10NIT_CMD); + break; + case LPM_2NIT: + default: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_2NIT_CMD); + break; + } + + if (SS_IS_CMDS_NULL(set_lpm_bl)) { + LCD_ERR("No cmds for alpm_ctrl..\n"); + return; + } + + memcpy(&set->cmds[LPM_BL_CMDID_CTRL].msg.tx_buf[1], + &set_lpm_bl->cmds->msg.tx_buf[1], + sizeof(char) * (set->cmds[LPM_BL_CMDID_CTRL].msg.tx_len - 1)); + + /* send lpm bl cmd */ + ss_send_cmd(vdd, TX_LPM_BL_CMD); + + LCD_INFO("[Panel LPM] bl_level : %s\n", + /* Check current brightness level */ + vdd->panel_lpm.lpm_bl_level == LPM_2NIT ? "2NIT" : + vdd->panel_lpm.lpm_bl_level == LPM_10NIT ? "10NIT" : + vdd->panel_lpm.lpm_bl_level == LPM_30NIT ? "30NIT" : + vdd->panel_lpm.lpm_bl_level == LPM_60NIT ? "60NIT" : "UNKNOWN"); +} + +static void ss_update_panel_lpm_ctrl_cmd(struct samsung_display_driver_data *vdd) +{ + struct dsi_panel_cmd_set *set_lpm_on = ss_get_cmds(vdd, TX_LPM_ON); + struct dsi_panel_cmd_set *set_lpm_off = ss_get_cmds(vdd, TX_LPM_OFF); + struct dsi_panel_cmd_set *set_lpm_bl; + + LCD_INFO("%s++\n", __func__); + + if (SS_IS_CMDS_NULL(set_lpm_on) || SS_IS_CMDS_NULL(set_lpm_off)) { + LCD_ERR("No cmds for TX_LPM_ON/OFF\n"); + goto start_lpm_bl; + } + +start_lpm_bl: + /* LPM_ON: 3. HLPM brightness */ + /* should restore normal brightness in LPM off sequence to prevent flicker.. */ + switch (vdd->panel_lpm.lpm_bl_level) { + case LPM_60NIT: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_60NIT_CMD); + break; + case LPM_30NIT: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_30NIT_CMD); + break; + case LPM_10NIT: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_10NIT_CMD); + break; + case LPM_2NIT: + default: + set_lpm_bl = ss_get_cmds(vdd, TX_LPM_2NIT_CMD); + break; + } + + if (SS_IS_CMDS_NULL(set_lpm_bl)) { + LCD_ERR("No cmds for alpm_ctrl..\n"); + return; + } + + memcpy(&set_lpm_on->cmds[LPM_ON_CMDID_BL].msg.tx_buf[1], + &set_lpm_bl->cmds->msg.tx_buf[1], + sizeof(char) * set_lpm_on->cmds[LPM_ON_CMDID_BL].msg.tx_len - 1); + + LCD_INFO("%s--\n", __func__); +} + + +static int ss_brightness_tot_level(struct samsung_display_driver_data *vdd) +{ + int tot_level_key = 0; + + tot_level_key = LEVEL1_KEY; + + return tot_level_key; +} + +static int samsung_panel_off_pre(struct samsung_display_driver_data *vdd) +{ + int rc = 0; + return rc; +} + +static int samsung_panel_off_post(struct samsung_display_driver_data *vdd) +{ + int rc = 0; + return rc; +} + +#if 1 +static int ss_dyn_mipi_pre(struct samsung_display_driver_data *vdd) +{ + int rc = 0; + + ss_send_cmd(vdd, TX_FFC_OFF); + LCD_INFO("[DISPLAY_%d] tx FFC OFF\n", vdd->ndx); + + return rc; +} + +#define FFC_CMD_LEN (4) +#define FFC_START_IDX (2) +static int ss_dyn_mipi_post(struct samsung_display_driver_data *vdd) +{ + struct dsi_panel_cmd_set *ffc_set; + struct dsi_panel_cmd_set *dyn_ffc_set; + + int idx; + int ffc_idx, dyn_ffc_idx; + int loop; + + mutex_lock(&vdd->dyn_mipi_clk.dyn_mipi_lock); + idx = ss_find_dyn_mipi_clk_timing_idx(vdd); + mutex_unlock(&vdd->dyn_mipi_clk.dyn_mipi_lock); + + if (idx < 0) { + LCD_ERR("[S6E3FC3_AMS646YD01] Failed to find MIPI clock timing (%d)\n", idx); + return 0; + } + + LCD_INFO("[DISPLAY_%d] +++ clk idx: %d, tx FFC\n", vdd->ndx, idx); + + ffc_set = ss_get_cmds(vdd, TX_FFC); + dyn_ffc_set = ss_get_cmds(vdd, TX_DYNAMIC_FFC_SET); + + if (SS_IS_CMDS_NULL(ffc_set) || SS_IS_CMDS_NULL(dyn_ffc_set)) { + LCD_ERR("No cmds for TX_FFC..\n"); + return -EINVAL; + } + + for (loop = 0; loop < FFC_CMD_LEN; loop++) { + ffc_idx = FFC_START_IDX + loop; + dyn_ffc_idx = (FFC_CMD_LEN * idx) + loop; + + if (ffc_set->cmds[ffc_idx].msg.tx_len == + dyn_ffc_set->cmds[dyn_ffc_idx].msg.tx_len) { + memcpy(ffc_set->cmds[ffc_idx].msg.tx_buf, + dyn_ffc_set->cmds[dyn_ffc_idx].msg.tx_buf, + ffc_set->cmds[ffc_idx].msg.tx_len); + } else { + LCD_INFO("[DISPLAY_%d] ffc cmd(%d) doesn't match\n", vdd->ndx, loop); + } + } + + ss_send_cmd(vdd, TX_FFC); + + LCD_INFO("[DISPLAY_%d] --- clk idx: %d, tx FFC\n", vdd->ndx, idx); + + return 0; +} +#else +#define FFC_CMD_LEN (4) +#define FFC_START_IDX (2) +static int ss_ffc(struct samsung_display_driver_data *vdd, int idx) +{ + struct dsi_panel_cmd_set *ffc_set; + struct dsi_panel_cmd_set *dyn_ffc_set; + + int ffc_idx, dyn_ffc_idx; + int loop; + + LCD_INFO("[DISPLAY_%d] +++ clk idx: %d, tx FFC\n", vdd->ndx, idx); + + ffc_set = ss_get_cmds(vdd, TX_FFC); + dyn_ffc_set = ss_get_cmds(vdd, TX_DYNAMIC_FFC_SET); + + if (SS_IS_CMDS_NULL(ffc_set) || SS_IS_CMDS_NULL(dyn_ffc_set)) { + LCD_ERR("No cmds for TX_FFC..\n"); + return -EINVAL; + } + + for (loop = 0; loop < FFC_CMD_LEN; loop++) { + ffc_idx = FFC_START_IDX + loop; + dyn_ffc_idx = (FFC_CMD_LEN * idx) + loop; + + if (ffc_set->cmds[ffc_idx].msg.tx_len == + dyn_ffc_set->cmds[dyn_ffc_idx].msg.tx_len) { + memcpy(ffc_set->cmds[ffc_idx].msg.tx_buf, + dyn_ffc_set->cmds[dyn_ffc_idx].msg.tx_buf, + ffc_set->cmds[ffc_idx].msg.tx_len); + } else { + LCD_INFO("[DISPLAY_%d] ffc cmd(%d) doesn't match\n", vdd->ndx, loop); + } + } + + ss_send_cmd(vdd, TX_FFC); + + LCD_INFO("[DISPLAY_%d] --- clk idx: %d, tx FFC\n", vdd->ndx, idx); + + return 0; +} +#endif + +#if 0 +static int ss_self_display_data_init(struct samsung_display_driver_data *vdd) +{ + LCD_INFO("++\n"); + + if (IS_ERR_OR_NULL(vdd)) { + LCD_ERR("vdd is null or error\n"); + return -ENODEV; + } + + if (!vdd->self_disp.is_support) { + LCD_ERR("Self Display is not supported\n"); + return -EINVAL; + } + + vdd->self_disp.operation[FLAG_SELF_MASK].img_buf = self_mask_img_data; + vdd->self_disp.operation[FLAG_SELF_MASK].img_size = ARRAY_SIZE(self_mask_img_data); + make_self_dispaly_img_cmds_FC3(vdd, TX_SELF_MASK_IMAGE, FLAG_SELF_MASK); + + vdd->self_disp.operation[FLAG_SELF_MASK_CRC].img_buf = self_mask_img_fhd_crc_data; + vdd->self_disp.operation[FLAG_SELF_MASK_CRC].img_size = ARRAY_SIZE(self_mask_img_fhd_crc_data); + make_self_dispaly_img_cmds_FC3(vdd, TX_SELF_MASK_IMAGE_CRC, FLAG_SELF_MASK_CRC); + + LCD_INFO("--\n"); + return 1; +} +#endif + +static int ss_vrr_init(struct vrr_info *vrr) +{ + LCD_INFO("S6E3FC3_AMS646YD01 ++\n"); + + mutex_init(&vrr->vrr_lock); + mutex_init(&vrr->brr_lock); + + /* Bootloader: FHD@120hz HSl mode */ + vrr->cur_refresh_rate = vrr->adjusted_refresh_rate = 120; + vrr->cur_sot_hs_mode = vrr->adjusted_sot_hs_mode = true; + vrr->max_h_active_support_120hs = 1080; /* supports 120hz until FHD 1080 */ + + vrr->vrr_workqueue = create_singlethread_workqueue("vrr_workqueue"); + INIT_WORK(&vrr->vrr_work, ss_panel_vrr_switch_work); + + LCD_INFO("S6E3FC3_AMS646YD01 --\n"); + + return 0; +} + +#if 0 +static void make_brightness_packet(struct samsung_display_driver_data *vdd, + struct dsi_cmd_desc *packet, int *cmd_cnt, enum BR_TYPE br_type) +{ + if (br_type == BR_TYPE_NORMAL) { + if (vdd->br_info.smart_dimming_loaded_dsi) { /* OCTA PANEL */ + /* hbm off */ + if (vdd->br_info.is_hbm) + ss_add_brightness_packet(vdd, BR_FUNC_HBM_OFF, packet, cmd_cnt); + + /* aid/aor */ + ss_add_brightness_packet(vdd, BR_FUNC_AID, packet, cmd_cnt); + + /* acl */ + if (vdd->br_info.acl_status || vdd->siop_status) { + ss_add_brightness_packet(vdd, BR_FUNC_ACL_ON, packet, cmd_cnt); + ss_add_brightness_packet(vdd, BR_FUNC_ACL_PERCENT_PRE, packet, cmd_cnt); + ss_add_brightness_packet(vdd, BR_FUNC_ACL_PERCENT, packet, cmd_cnt); + } else { + ss_add_brightness_packet(vdd, BR_FUNC_ACL_OFF, packet, cmd_cnt); + } + + /* elvss */ + ss_add_brightness_packet(vdd, BR_FUNC_ELVSS_PRE, packet, cmd_cnt); + ss_add_brightness_packet(vdd, BR_FUNC_ELVSS, packet, cmd_cnt); + + /* temperature elvss */ + ss_add_brightness_packet(vdd, BR_FUNC_ELVSS_TEMP1, packet, cmd_cnt); + ss_add_brightness_packet(vdd, BR_FUNC_ELVSS_TEMP2, packet, cmd_cnt); + + /* caps*/ + ss_add_brightness_packet(vdd, BR_FUNC_CAPS_PRE, packet, cmd_cnt); + ss_add_brightness_packet(vdd, BR_FUNC_CAPS, packet, cmd_cnt); + + /* Manual DBV (for DIA setting) */ + ss_add_brightness_packet(vdd, BR_FUNC_DBV, packet, cmd_cnt); + + /* vint */ + ss_add_brightness_packet(vdd, BR_FUNC_VINT, packet, cmd_cnt); + + /* IRC */ + ss_add_brightness_packet(vdd, BR_FUNC_IRC, packet, cmd_cnt); + + /* LTPS: used for normal and HBM brightness */ + ss_add_brightness_packet(vdd, BR_FUNC_LTPS, packet, cmd_cnt); + + /* PANEL SPECIFIC SETTINGS */ + ss_add_brightness_packet(vdd, BR_FUNC_ETC, packet, cmd_cnt); + + /* mAFPC */ + if (vdd->mafpc.is_support) + ss_add_brightness_packet(vdd, BR_FUNC_MAFPC_SCALE, packet, cmd_cnt); + + /* gamma */ + ss_add_brightness_packet(vdd, BR_FUNC_GAMMA, packet, cmd_cnt); + + /* VRR */ + ss_add_brightness_packet(vdd, BR_FUNC_VRR, packet, cmd_cnt); + } else { /* Gamma Mode2 or TFT PANEL */ + + ss_add_brightness_packet(vdd, BR_FUNC_1, packet, cmd_cnt); + + /* ACL */ + if (vdd->br_info.acl_status || vdd->siop_status) { + ss_add_brightness_packet(vdd, BR_FUNC_ACL_ON, packet, cmd_cnt); + ss_add_brightness_packet(vdd, BR_FUNC_ACL_PERCENT_PRE, packet, cmd_cnt); + ss_add_brightness_packet(vdd, BR_FUNC_ACL_PERCENT, packet, cmd_cnt); + } else { + ss_add_brightness_packet(vdd, BR_FUNC_ACL_OFF, packet, cmd_cnt); + } + + /* TFM_PWM */ + ss_add_brightness_packet(vdd, BR_FUNC_TFT_PWM, packet, cmd_cnt); + + /* mAFPC */ + if (vdd->mafpc.is_support) + ss_add_brightness_packet(vdd, BR_FUNC_MAFPC_SCALE, packet, cmd_cnt); + + /* gamma */ + ss_add_brightness_packet(vdd, BR_FUNC_GAMMA, packet, cmd_cnt); + + /* gamma compensation for gamma mode2 VRR modes */ + ss_add_brightness_packet(vdd, BR_FUNC_GAMMA_COMP, packet, cmd_cnt); + + /* vint */ + ss_add_brightness_packet(vdd, BR_FUNC_VINT, packet, cmd_cnt); + + /* VRR */ + ss_add_brightness_packet(vdd, BR_FUNC_VRR, packet, cmd_cnt); + + } + } else if (br_type == BR_TYPE_HBM) { + /* acl */ + if (vdd->br_info.acl_status || vdd->siop_status) { + ss_add_brightness_packet(vdd, BR_FUNC_HBM_ACL_ON, packet, cmd_cnt); + } else { + ss_add_brightness_packet(vdd, BR_FUNC_HBM_ACL_OFF, packet, cmd_cnt); + } + + /* IRC */ + ss_add_brightness_packet(vdd, BR_FUNC_HBM_IRC, packet, cmd_cnt); + + /* Gamma */ + ss_add_brightness_packet(vdd, BR_FUNC_HBM_GAMMA, packet, cmd_cnt); + + /* vint */ + ss_add_brightness_packet(vdd, BR_FUNC_HBM_VINT, packet, cmd_cnt); + + /* LTPS: used for normal and HBM brightness */ + ss_add_brightness_packet(vdd, BR_FUNC_HBM_LTPS, packet, cmd_cnt); + + /* mAFPC */ + if (vdd->mafpc.is_support) + ss_add_brightness_packet(vdd, BR_FUNC_MAFPC_SCALE, packet, cmd_cnt); + + /* hbm etc */ + ss_add_brightness_packet(vdd, BR_FUNC_HBM_ETC, packet, cmd_cnt); + + /* VRR */ + ss_add_brightness_packet(vdd, BR_FUNC_HBM_VRR, packet, cmd_cnt); + } else if (br_type == BR_TYPE_HMT) { + if (vdd->br_info.smart_dimming_hmt_loaded_dsi) { + /* aid/aor B2 */ + ss_add_brightness_packet(vdd, BR_FUNC_HMT_AID, packet, cmd_cnt); + + /* elvss B5 */ + ss_add_brightness_packet(vdd, BR_FUNC_HMT_ELVSS, packet, cmd_cnt); + + /* vint F4 */ + ss_add_brightness_packet(vdd, BR_FUNC_HMT_VINT, packet, cmd_cnt); + + /* gamma CA */ + ss_add_brightness_packet(vdd, BR_FUNC_HMT_GAMMA, packet, cmd_cnt); + + /* VRR */ + ss_add_brightness_packet(vdd, BR_FUNC_HMT_VRR, packet, cmd_cnt); + } else { + ss_add_brightness_packet(vdd, BR_FUNC_HMT_GAMMA, packet, cmd_cnt); + } + } else { + LCD_ERR("undefined br_type (%d) \n", br_type); + } + + return; +} +#endif + +static void samsung_panel_init(struct samsung_display_driver_data *vdd) +{ + LCD_INFO("S6E3FC3_AMS646YD01 : ++\n"); + LCD_ERR("%s\n", ss_get_panel_name(vdd)); + + /* Default Panel Power Status is OFF */ + vdd->panel_state = PANEL_PWR_OFF; + + /* ON/OFF */ + vdd->panel_func.samsung_panel_on_pre = samsung_panel_on_pre; + vdd->panel_func.samsung_panel_on_post = samsung_panel_on_post; + vdd->panel_func.samsung_panel_off_pre = samsung_panel_off_pre; + vdd->panel_func.samsung_panel_off_post = samsung_panel_off_post; + + /* DDI RX */ + vdd->panel_func.samsung_panel_revision = ss_panel_revision; + vdd->panel_func.samsung_module_info_read = ss_module_info_read; + vdd->panel_func.samsung_ddi_id_read = ss_ddi_id_read; + vdd->panel_func.samsung_octa_id_read = ss_octa_id_read; + vdd->panel_func.samsung_elvss_read = ss_elvss_read; + + /* Make brightness packet */ + //vdd->panel_func.make_brightness_packet = make_brightness_packet; + + /* Brightness */ + vdd->panel_func.samsung_brightness_gamma = ss_brightness_gamma_mode2_normal; + vdd->panel_func.samsung_brightness_acl_on = ss_acl_on; + vdd->panel_func.samsung_brightness_acl_off = ss_acl_off; + vdd->panel_func.samsung_brightness_vrr = ss_vrr; + + /* HBM */ + vdd->panel_func.samsung_hbm_gamma = ss_brightness_gamma_mode2_hbm; + vdd->panel_func.samsung_hbm_acl_on = ss_acl_on_hbm; + vdd->panel_func.samsung_hbm_acl_off = ss_acl_off; + vdd->panel_func.samsung_brightness_vrr_hbm = ss_vrr_hbm; + + /* VRR */ + ss_vrr_init(&vdd->vrr); + + /* Panel LPM */ + vdd->panel_func.samsung_update_lpm_ctrl_cmd = ss_update_panel_lpm_ctrl_cmd; // JUN_TEMP_R8 + vdd->panel_func.samsung_set_lpm_brightness = ss_set_panel_lpm_brightness; + + /* Total level key in brightness */ + vdd->panel_func.samsung_brightness_tot_level = ss_brightness_tot_level; + + /* default brightness */ + vdd->br_info.common_br.bl_level = 255; + + /* ACL default ON */ + vdd->br_info.acl_status = 1; + vdd->br_info.temperature = 20; // default temperature + + /* ACL default status in acl on */ + vdd->br_info.gradual_acl_val = 1; + + /* Self display */ + //vdd->self_disp.is_support = true; + //vdd->self_disp.factory_support = true; + //vdd->self_disp.init = self_display_init_FC3; + //vdd->self_disp.data_init = ss_self_display_data_init; + + /* FFC */ // JUN_TEMP_R8 + // vdd->panel_func.set_ffc = ss_ffc; + /* Dynamic(Adaptive) MIPI Clock */ + vdd->panel_func.samsung_dyn_mipi_pre = ss_dyn_mipi_pre; + vdd->panel_func.samsung_dyn_mipi_post = ss_dyn_mipi_post; + + /* SAMSUNG_FINGERPRINT */ + vdd->panel_hbm_entry_delay = 0; + + /* te high -> 52us (120fps) -> te low -> tx start */ + vdd->panel_hbm_entry_after_te = 60; //52us is TE high time + vdd->panel_hbm_exit_delay = 0; + + /* mdnie */ + vdd->mdnie.support_mdnie = true; + vdd->mdnie.support_trans_dimming = false; + vdd->mdnie.mdnie_tune_size[0] = sizeof(DSI0_BYPASS_MDNIE_1); + vdd->mdnie.mdnie_tune_size[1] = sizeof(DSI0_BYPASS_MDNIE_2); + vdd->mdnie.mdnie_tune_size[2] = sizeof(DSI0_BYPASS_MDNIE_3); + vdd->mdnie.mdnie_tune_size[3] = sizeof(DSI0_BYPASS_MDNIE_4); + + dsi_update_mdnie_data(vdd); + LCD_INFO("S6E3FC3_AMS646YD01 : --\n"); +} + +static int __init samsung_panel_initialize(void) +{ + struct samsung_display_driver_data *vdd; + enum ss_display_ndx ndx; + char panel_string[] = "ss_dsi_panel_S6E3FC3_AMS646YD01_FHD"; + char panel_name[MAX_CMDLINE_PARAM_LEN]; + char panel_secondary_name[MAX_CMDLINE_PARAM_LEN]; + + LCD_INFO("S6E3FC3_AMS646YD01 : ++\n"); + + ss_get_primary_panel_name_cmdline(panel_name); + ss_get_secondary_panel_name_cmdline(panel_secondary_name); + + /* TODO: use component_bind with panel_func + * and match by panel_string, instead. + */ + if (!strncmp(panel_string, panel_name, strlen(panel_string))) + ndx = PRIMARY_DISPLAY_NDX; + else if (!strncmp(panel_string, panel_secondary_name, strlen(panel_string))) + ndx = SECONDARY_DISPLAY_NDX; + else { + LCD_ERR("can not find panel_name (%s) / (%s)\n", panel_string, panel_name); + LCD_INFO("S6E3FC3_AMS646YD01 : --\n"); + return 0; + } + + vdd = ss_get_vdd(ndx); + vdd->panel_func.samsung_panel_init = samsung_panel_init; + + LCD_INFO("%s done..\n", panel_name); + LCD_INFO("S6E3FC3_AMS646YD01 : --\n"); + + return 0; +} + +early_initcall(samsung_panel_initialize); diff --git a/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.h b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.h new file mode 100644 index 000000000..912c58815 --- /dev/null +++ b/techpack/display/msm/samsung/S6E3FC3_AMS646YD01/ss_dsi_panel_S6E3FC3_AMS646YD01.h @@ -0,0 +1,2207 @@ +/* + * ================================================================= + * + * + * Description: samsung display panel file + * + * Author: jb09.kim + * Company: Samsung Electronics + * + * ================================================================ + */ +/* + +Copyright (C) 2012, Samsung Electronics. 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. + * + * +*/ +#ifndef SAMSUNG_DSI_PANEL_S6E3FC3_AMS646YD01_H +#define SAMSUNG_DSI_PANEL_S6E3FC3_AMS646YD01_H + +#include +#include "ss_dsi_panel_common.h" +//#include "../SELF_DISPLAY/self_display_FC3.h" + +struct AOR_MANUAL { + char aor_63h_119; + char aor_63h_120; + char aor_63h_121; +}; + +struct AOR_MANUAL normal_aor_manual[] = { + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, + {0x00, 0x00, 0x18}, +}; + + +struct AOR_MANUAL hbm_aor_manual[] = { + {0x01, 0x01, 0x90}, + {0x01, 0x01, 0x8B}, + {0x01, 0x01, 0x86}, + {0x01, 0x01, 0x81}, + {0x01, 0x01, 0x7C}, + {0x01, 0x01, 0x77}, + {0x01, 0x01, 0x72}, + {0x01, 0x01, 0x6D}, + {0x01, 0x01, 0x68}, + {0x01, 0x01, 0x63}, + {0x01, 0x01, 0x5E}, + {0x01, 0x01, 0x59}, + {0x01, 0x01, 0x54}, + {0x01, 0x01, 0x4F}, + {0x01, 0x01, 0x4A}, + {0x01, 0x01, 0x45}, + {0x01, 0x01, 0x40}, + {0x01, 0x01, 0x3B}, + {0x01, 0x01, 0x36}, + {0x01, 0x01, 0x31}, + {0x01, 0x01, 0x2C}, + {0x01, 0x01, 0x27}, + {0x01, 0x01, 0x22}, + {0x01, 0x01, 0x1D}, + {0x01, 0x01, 0x18}, + {0x01, 0x01, 0x13}, + {0x01, 0x01, 0x0E}, + {0x01, 0x01, 0x09}, + {0x01, 0x01, 0x04}, + {0x01, 0x00, 0xFF}, + {0x01, 0x00, 0xFA}, + {0x01, 0x00, 0xF5}, + {0x01, 0x00, 0xF0}, + {0x01, 0x00, 0xEB}, + {0x01, 0x00, 0xE6}, + {0x01, 0x00, 0xE1}, + {0x01, 0x00, 0xDC}, + {0x01, 0x00, 0xD7}, + {0x01, 0x00, 0xD2}, + {0x01, 0x00, 0xCD}, + {0x01, 0x00, 0xC8}, + {0x01, 0x00, 0xC3}, + {0x01, 0x00, 0xBE}, + {0x01, 0x00, 0xB9}, + {0x01, 0x00, 0xB4}, + {0x01, 0x00, 0xAF}, + {0x01, 0x00, 0xAA}, + {0x01, 0x00, 0xA5}, + {0x01, 0x00, 0xA0}, + {0x01, 0x00, 0x9B}, + {0x01, 0x00, 0x96}, + {0x01, 0x00, 0x91}, + {0x01, 0x00, 0x8C}, + {0x01, 0x00, 0x87}, + {0x01, 0x00, 0x82}, + {0x01, 0x00, 0x7D}, + {0x01, 0x00, 0x78}, + {0x01, 0x00, 0x73}, + {0x01, 0x00, 0x6E}, + {0x01, 0x00, 0x69}, + {0x01, 0x00, 0x64}, + {0x01, 0x00, 0x5F}, + {0x01, 0x00, 0x5A}, + {0x01, 0x00, 0x55}, + {0x01, 0x00, 0x50}, + {0x01, 0x00, 0x4B}, + {0x01, 0x00, 0x46}, + {0x01, 0x00, 0x41}, + {0x01, 0x00, 0x3C}, + {0x01, 0x00, 0x37}, + {0x01, 0x00, 0x32}, + {0x01, 0x00, 0x2D}, + {0x01, 0x00, 0x28}, + {0x01, 0x00, 0x23}, + {0x01, 0x00, 0x1E}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, + {0x01, 0x00, 0x18}, +}; + +static char self_mask_img_data[] = { + 0xc0, 0x4a, 0x41, 0xf1, 0x41, 0xd9, 0x41, 0xc4, + 0x41, 0xae, 0x41, 0x9e, 0x41, 0x8f, 0x41, 0x80, + 0x41, 0x70, 0x41, 0x66, 0x41, 0x5e, 0x41, 0x50, + 0x41, 0x47, 0x41, 0x40, 0x41, 0x38, 0x42, 0x30, + 0x41, 0x25, 0x42, 0x20, 0x41, 0x1c, 0x49, 0x10, + 0x41, 0x05, 0x83, 0x68, 0x41, 0x07, 0x49, 0x10, + 0x41, 0x1d, 0x42, 0x20, 0x41, 0x26, 0x42, 0x30, + 0x41, 0x3b, 0x41, 0x40, 0x41, 0x4d, 0x41, 0x50, + 0x41, 0x5f, 0x41, 0x64, 0x41, 0x74, 0x41, 0x83, + 0x41, 0x93, 0x41, 0xa2, 0x41, 0xb2, 0x41, 0xc4, + 0x41, 0xd9, 0x41, 0xf1, 0xc0, 0x8b, 0x41, 0xf9, + 0x1b, 0xed, 0x17, 0xeb, 0x13, 0xa9, 0x0f, 0x47, + 0x0a, 0xe5, 0x06, 0xa3, 0x04, 0x62, 0x00, 0x00, + 0x83, 0xa4, 0x00, 0x00, 0x02, 0x41, 0x06, 0xa3, + 0x0a, 0xe5, 0x0f, 0x47, 0x13, 0xa9, 0x17, 0xeb, + 0x1b, 0xed, 0x41, 0xf8, 0xc0, 0x7c, 0x41, 0xfe, + 0x1b, 0xed, 0x15, 0xea, 0x0f, 0x67, 0x08, 0xe4, + 0x02, 0x41, 0x00, 0x00, 0x83, 0xb4, 0x00, 0x00, + 0x02, 0x41, 0x08, 0xc4, 0x0f, 0x47, 0x13, 0xc9, + 0x1b, 0xed, 0x41, 0xfb, 0xc0, 0x72, 0x41, 0xf4, + 0x17, 0xeb, 0x0f, 0x67, 0x06, 0xa3, 0x00, 0x20, + 0x83, 0xc0, 0x00, 0x00, 0x06, 0xa3, 0x0f, 0x47, + 0x15, 0xea, 0x41, 0xeb, 0xc0, 0x6a, 0x41, 0xf8, + 0x17, 0xeb, 0x0f, 0x47, 0x06, 0x83, 0x00, 0x00, + 0x83, 0xc8, 0x00, 0x00, 0x04, 0x82, 0x0f, 0x47, + 0x17, 0xeb, 0x41, 0xfb, 0xc0, 0x63, 0x41, 0xf1, + 0x15, 0xea, 0x08, 0xe4, 0x00, 0x20, 0x83, 0xd0, + 0x00, 0x20, 0x0b, 0x05, 0x15, 0xea, 0x41, 0xf4, + 0xc0, 0x5d, 0x41, 0xf6, 0x15, 0xea, 0x08, 0xe4, + 0x00, 0x00, 0x83, 0xd6, 0x00, 0x00, 0x08, 0xe4, + 0x15, 0xea, 0x41, 0xfb, 0xc0, 0x58, 0x1b, 0xed, + 0x0d, 0x26, 0x02, 0x21, 0x83, 0xdc, 0x02, 0x41, + 0x0f, 0x67, 0x1b, 0xed, 0xc0, 0x54, 0x17, 0xeb, + 0x06, 0xa3, 0x83, 0xe1, 0x41, 0x01, 0x08, 0xc4, + 0x15, 0xea, 0x41, 0xfe, 0xc0, 0x4f, 0x17, 0xeb, + 0x06, 0x83, 0x83, 0xe6, 0x04, 0x62, 0x13, 0xc9, + 0x41, 0xfa, 0xc0, 0x4a, 0x41, 0xfe, 0x15, 0xea, + 0x06, 0x83, 0x83, 0xea, 0x04, 0x62, 0x15, 0xea, + 0x41, 0xfe, 0xc0, 0x47, 0x19, 0xec, 0x04, 0x82, + 0x83, 0xee, 0x04, 0x82, 0x17, 0xeb, 0xc0, 0x44, + 0x41, 0xe9, 0x0b, 0x05, 0x41, 0x01, 0x83, 0xf1, + 0x08, 0xe4, 0x1b, 0xed, 0xc0, 0x40, 0x41, 0xfe, + 0x13, 0xc9, 0x02, 0x21, 0x83, 0xf4, 0x41, 0x09, + 0x11, 0x88, 0x41, 0xfc, 0xc0, 0x3d, 0x1b, 0xed, + 0x06, 0x83, 0x83, 0xf8, 0x06, 0x83, 0x1b, 0xed, + 0xc0, 0x3b, 0x13, 0xc9, 0x41, 0x09, 0x83, 0xfa, + 0x41, 0x0c, 0x15, 0xea, 0xc0, 0x38, 0x41, 0xf2, + 0x0a, 0xe5, 0x83, 0xfe, 0x0d, 0x26, 0x41, 0xf5, + 0xc0, 0x35, 0x1b, 0xed, 0x04, 0x62, 0x84, 0x00, + 0x04, 0x82, 0x1b, 0xed, 0xc0, 0x33, 0x17, 0xeb, + 0x41, 0x0d, 0x84, 0x02, 0x41, 0x0f, 0x17, 0xeb, + 0xc0, 0x31, 0x13, 0xc9, 0x41, 0x03, 0x84, 0x04, + 0x41, 0x06, 0x15, 0xea, 0xc0, 0x2f, 0x11, 0x88, + 0x84, 0x07, 0x41, 0x03, 0x13, 0xa9, 0xc0, 0x2d, + 0x0f, 0x67, 0x84, 0x0a, 0x0f, 0x67, 0xc0, 0x2b, + 0x0f, 0x67, 0x84, 0x0c, 0x0f, 0x67, 0xc0, 0x29, + 0x13, 0xa9, 0x84, 0x0e, 0x11, 0x88, 0xc0, 0x27, + 0x15, 0xea, 0x41, 0x03, 0x84, 0x0f, 0x13, 0xc9, + 0xc0, 0x25, 0x17, 0xeb, 0x41, 0x06, 0x84, 0x10, + 0x41, 0x03, 0x17, 0xeb, 0xc0, 0x23, 0x35, 0xba, + 0x41, 0x0f, 0x84, 0x12, 0x41, 0x0d, 0x35, 0xba, + 0xc0, 0x21, 0x41, 0xf6, 0x0a, 0x45, 0x84, 0x14, + 0x08, 0x44, 0x41, 0xf2, 0xc0, 0x20, 0x0d, 0x26, + 0x84, 0x16, 0x0a, 0xe5, 0xc0, 0x1f, 0x15, 0xea, + 0x84, 0x18, 0x13, 0xc9, 0xc0, 0x1d, 0x37, 0xbb, + 0x41, 0x0c, 0x84, 0x18, 0x41, 0x09, 0x35, 0xba, + 0xc0, 0x1b, 0x41, 0xfc, 0x0c, 0x66, 0x84, 0x1a, + 0x0c, 0x66, 0x41, 0xfe, 0xc0, 0x1a, 0x11, 0x88, + 0x82, 0x09, 0x00, 0x00, 0x0e, 0x27, 0x18, 0x4c, + 0x1e, 0x4f, 0x24, 0x72, 0x24, 0x72, 0x1e, 0x4f, + 0x18, 0x4c, 0x0e, 0x27, 0x00, 0x00, 0x82, 0x09, + 0x25, 0x32, 0xc0, 0x19, 0x37, 0xbb, 0x41, 0x09, + 0x82, 0x05, 0x06, 0x03, 0x1e, 0x4f, 0x38, 0x9c, + 0x3e, 0xdf, 0x41, 0xfb, 0xc0, 0x08, 0x41, 0xfb, + 0x3e, 0xdf, 0x38, 0x9c, 0x1e, 0x4f, 0x06, 0x03, + 0x82, 0x05, 0x04, 0x22, 0x41, 0xe9, 0xc0, 0x18, + 0x12, 0x89, 0x82, 0x03, 0x41, 0x02, 0x1c, 0x4e, + 0x3e, 0xbf, 0x41, 0xf9, 0xc0, 0x10, 0x41, 0xf9, + 0x3e, 0xbf, 0x1c, 0x4e, 0x41, 0x02, 0x82, 0x03, + 0x0b, 0x05, 0xc0, 0x17, 0x2d, 0x76, 0x82, 0x02, + 0x41, 0x04, 0x22, 0x51, 0x3e, 0xdf, 0xc0, 0x16, + 0x3e, 0xdf, 0x22, 0x51, 0x41, 0x04, 0x82, 0x01, + 0x41, 0x01, 0x31, 0x98, 0xc0, 0x15, 0x41, 0xfe, + 0x0a, 0x45, 0x82, 0x01, 0x14, 0x2a, 0x3e, 0xdf, + 0xc0, 0x1a, 0x3e, 0xdf, 0x14, 0x2a, 0x82, 0x01, + 0x0a, 0x45, 0x41, 0xfe, 0xc0, 0x14, 0x29, 0x54, + 0x82, 0x00, 0x41, 0x08, 0x38, 0x9c, 0xc0, 0x1e, + 0x38, 0x9c, 0x41, 0x08, 0x82, 0x00, 0x2b, 0x55, + 0xc0, 0x13, 0x41, 0xfa, 0x08, 0x44, 0x81, 0xff, + 0x0c, 0x26, 0x3e, 0xdf, 0xc0, 0x20, 0x3e, 0xdf, + 0x0c, 0x26, 0x81, 0xff, 0x0c, 0x66, 0xc0, 0x13, + 0x27, 0x33, 0x81, 0xff, 0x14, 0x2a, 0x41, 0xec, + 0xc0, 0x22, 0x41, 0xec, 0x14, 0x2a, 0x81, 0xff, + 0x2d, 0x76, 0xc0, 0x11, 0x41, 0xfe, 0x08, 0x44, + 0x81, 0xfe, 0x18, 0x4c, 0x41, 0xf6, 0xc0, 0x24, + 0x41, 0xf6, 0x18, 0x4c, 0x81, 0xfe, 0x0c, 0x66, + 0xc0, 0x11, 0x2b, 0x55, 0x81, 0xfe, 0x14, 0x2a, + 0x41, 0xf6, 0xc0, 0x26, 0x41, 0xf6, 0x14, 0x2a, + 0x81, 0xfe, 0x2d, 0x76, 0xc0, 0x10, 0x10, 0x88, + 0x81, 0xfd, 0x08, 0x44, 0x41, 0xec, 0xc0, 0x28, + 0x41, 0xec, 0x08, 0x44, 0x81, 0xfd, 0x0e, 0x67, + 0xc0, 0x0f, 0x37, 0xbb, 0x41, 0x01, 0x81, 0xfc, + 0x41, 0x08, 0x35, 0xba, 0xc0, 0x2a, 0x35, 0xba, + 0x41, 0x08, 0x81, 0xfd, 0x35, 0xba, 0xc0, 0x0e, + 0x1c, 0xee, 0x81, 0xfd, 0x38, 0x9c, 0xc0, 0x2c, + 0x38, 0x9c, 0x81, 0xfd, 0x1a, 0xcd, 0xc0, 0x0d, + 0x41, 0xfb, 0x06, 0x23, 0x81, 0xfc, 0x0e, 0x67, + 0xc0, 0x2e, 0x0e, 0x67, 0x81, 0xfc, 0x02, 0x01, + 0x41, 0xf6, 0xc0, 0x0c, 0x2b, 0x55, 0x81, 0xfc, + 0x41, 0x04, 0x35, 0xba, 0xc0, 0x2e, 0x35, 0xba, + 0x41, 0x04, 0x81, 0xfc, 0x29, 0x54, 0xc0, 0x0c, + 0x12, 0x89, 0x81, 0xfc, 0x16, 0xab, 0xc0, 0x30, + 0x16, 0xab, 0x81, 0xfc, 0x12, 0x89, 0xc0, 0x0b, + 0x41, 0xf4, 0x00, 0x00, 0x81, 0xfb, 0x41, 0x02, + 0x35, 0xba, 0xc0, 0x30, 0x35, 0xba, 0x41, 0x02, + 0x81, 0xfb, 0x00, 0x00, 0x41, 0xf1, 0xc0, 0x0a, + 0x2b, 0x55, 0x81, 0xfc, 0x12, 0x89, 0xc0, 0x32, + 0x12, 0x89, 0x81, 0xfc, 0x29, 0x54, 0xc0, 0x0a, + 0x16, 0xab, 0x81, 0xfc, 0x2b, 0x55, 0xc0, 0x32, + 0x2b, 0x55, 0x81, 0xfc, 0x12, 0x89, 0xc0, 0x09, + 0x41, 0xfb, 0x02, 0x01, 0x81, 0xfb, 0x04, 0x22, + 0x41, 0xf9, 0xc0, 0x32, 0x41, 0xf9, 0x04, 0x22, + 0x81, 0xfb, 0x02, 0x01, 0x41, 0xf8, 0xc0, 0x08, + 0x2f, 0x77, 0x81, 0xfc, 0x14, 0xaa, 0xc0, 0x34, + 0x14, 0xaa, 0x81, 0xfc, 0x2f, 0x77, 0xc0, 0x08, + 0x1c, 0xee, 0x81, 0xfc, 0x27, 0x33, 0xc0, 0x34, + 0x27, 0x33, 0x81, 0xfc, 0x1c, 0xee, 0xc0, 0x08, + 0x0a, 0x45, 0x81, 0xfc, 0x35, 0xba, 0xc0, 0x34, + 0x35, 0xba, 0x81, 0xfc, 0x0c, 0x66, 0xc0, 0x07, + 0x41, 0xeb, 0x00, 0x00, 0x81, 0xfb, 0x00, 0x00, + 0x41, 0xfb, 0xc0, 0x34, 0x41, 0xfb, 0x00, 0x00, + 0x81, 0xfb, 0x00, 0x00, 0x41, 0xf4, 0xc0, 0x06, + 0x2b, 0x55, 0x81, 0xfc, 0x08, 0x44, 0xc0, 0x36, + 0x08, 0x44, 0x81, 0xfc, 0x2f, 0x77, 0xc0, 0x06, + 0x1c, 0xee, 0x81, 0xfc, 0x10, 0x88, 0xc0, 0x36, + 0x10, 0x88, 0x81, 0xfc, 0x1e, 0xef, 0xc0, 0x06, + 0x0e, 0x67, 0x81, 0xfc, 0x14, 0xaa, 0xc0, 0x36, + 0x14, 0xaa, 0x81, 0xfc, 0x0e, 0x67, 0xc0, 0x05, + 0x41, 0xfc, 0x02, 0x01, 0x81, 0xfc, 0x18, 0xcc, + 0xc0, 0x36, 0x18, 0xcc, 0x81, 0xfc, 0x02, 0x01, + 0x41, 0xfe, 0xc0, 0x04, 0x35, 0xba, 0x81, 0xfd, + 0x18, 0xcc, 0xc0, 0x36, 0x18, 0xcc, 0x81, 0xfd, + 0x37, 0xbb, 0xc0, 0x04, 0x27, 0x33, 0x81, 0xfd, + 0x14, 0xaa, 0xc0, 0x36, 0x14, 0xaa, 0x81, 0xfd, + 0x2b, 0x55, 0xc0, 0x04, 0x1c, 0xee, 0x81, 0xfd, + 0x10, 0x88, 0xc0, 0x36, 0x10, 0x88, 0x81, 0xfd, + 0x1e, 0xef, 0xc0, 0x04, 0x10, 0x88, 0x81, 0xfd, + 0x08, 0x44, 0xc0, 0x36, 0x08, 0x44, 0x81, 0xfd, + 0x12, 0x89, 0xc0, 0x04, 0x06, 0x23, 0x81, 0xfd, + 0x00, 0x00, 0x41, 0xfb, 0xc0, 0x34, 0x41, 0xfb, + 0x00, 0x00, 0x81, 0xfd, 0x06, 0x23, 0xc0, 0x03, + 0x41, 0xf8, 0x00, 0x00, 0x81, 0xfe, 0x35, 0xba, + 0xc0, 0x34, 0x35, 0xba, 0x81, 0xfe, 0x00, 0x00, + 0x41, 0xf9, 0xc0, 0x02, 0x35, 0xba, 0x81, 0xff, + 0x27, 0x33, 0xc0, 0x34, 0x27, 0x33, 0x81, 0xff, + 0x37, 0xbb, 0xc0, 0x02, 0x2d, 0x76, 0x81, 0xff, + 0x14, 0xaa, 0xc0, 0x34, 0x14, 0xaa, 0x81, 0xff, + 0x2d, 0x76, 0xc0, 0x02, 0x25, 0x32, 0x81, 0xff, + 0x04, 0x22, 0x41, 0xf9, 0xc0, 0x32, 0x41, 0xf9, + 0x04, 0x22, 0x81, 0xff, 0x25, 0x32, 0xc0, 0x02, + 0x1c, 0xee, 0x82, 0x00, 0x2b, 0x55, 0xc0, 0x32, + 0x2b, 0x55, 0x82, 0x00, 0x1c, 0xee, 0xc0, 0x02, + 0x14, 0xaa, 0x82, 0x00, 0x12, 0x89, 0xc0, 0x32, + 0x12, 0x89, 0x82, 0x00, 0x14, 0xaa, 0xc0, 0x02, + 0x0c, 0x66, 0x82, 0x00, 0x41, 0x02, 0x35, 0xba, + 0xc0, 0x30, 0x35, 0xba, 0x41, 0x02, 0x82, 0x00, + 0x0e, 0x67, 0xc0, 0x02, 0x06, 0x23, 0x82, 0x01, + 0x16, 0xab, 0xc0, 0x30, 0x16, 0xab, 0x82, 0x01, + 0x08, 0x44, 0xc0, 0x02, 0x02, 0x01, 0x82, 0x01, + 0x41, 0x04, 0x35, 0xba, 0xc0, 0x2e, 0x35, 0xba, + 0x41, 0x04, 0x82, 0x01, 0x02, 0x01, 0x41, 0xff, + 0x41, 0xf1, 0x82, 0x03, 0x0e, 0x67, 0xc0, 0x2e, + 0x0e, 0x67, 0x82, 0x03, 0x41, 0xf1, 0x41, 0xd9, + 0x82, 0x04, 0x13, 0xc9, 0xc0, 0x2c, 0x13, 0xc9, + 0x82, 0x04, 0x41, 0xd9, 0x41, 0xc4, 0x82, 0x04, + 0x41, 0x08, 0x35, 0xba, 0xc0, 0x2a, 0x35, 0xba, + 0x41, 0x08, 0x82, 0x04, 0x41, 0xc4, 0x41, 0xb2, + 0x82, 0x05, 0x08, 0x44, 0x41, 0xec, 0xc0, 0x28, + 0x41, 0xec, 0x08, 0x44, 0x82, 0x05, 0x41, 0xae, + 0x41, 0xa2, 0x82, 0x06, 0x06, 0xa3, 0x41, 0xf6, + 0xc0, 0x26, 0x41, 0xf6, 0x06, 0xa3, 0x82, 0x06, + 0x41, 0x9e, 0x41, 0x93, 0x82, 0x07, 0x08, 0xc4, + 0x41, 0xf6, 0xc0, 0x24, 0x41, 0xf6, 0x08, 0xc4, + 0x82, 0x07, 0x41, 0x8f, 0x41, 0x83, 0x82, 0x08, + 0x06, 0xa3, 0x41, 0xec, 0xc0, 0x22, 0x41, 0xec, + 0x06, 0xa3, 0x82, 0x08, 0x41, 0x80, 0x41, 0x74, + 0x82, 0x09, 0x04, 0x62, 0x1b, 0xed, 0xc0, 0x20, + 0x1b, 0xed, 0x04, 0x62, 0x82, 0x09, 0x41, 0x70, + 0x41, 0x65, 0x82, 0x0a, 0x41, 0x08, 0x13, 0xc9, + 0xc0, 0x1e, 0x13, 0xc9, 0x41, 0x08, 0x82, 0x0a, + 0x41, 0x65, 0x41, 0x5f, 0x82, 0x0c, 0x06, 0xa3, + 0x1b, 0xed, 0xc0, 0x1a, 0x1b, 0xed, 0x06, 0xa3, + 0x82, 0x0c, 0x41, 0x5e, 0x41, 0x50, 0x82, 0x0d, + 0x41, 0x04, 0x0b, 0x05, 0x1b, 0xed, 0xc0, 0x16, + 0x1b, 0xed, 0x0b, 0x05, 0x41, 0x04, 0x82, 0x0d, + 0x41, 0x50, 0x41, 0x4d, 0x82, 0x0f, 0x41, 0x02, + 0x08, 0xe4, 0x15, 0xea, 0x41, 0xf9, 0xc0, 0x10, + 0x41, 0xf9, 0x15, 0xea, 0x08, 0xe4, 0x41, 0x02, + 0x82, 0x0f, 0x41, 0x47, 0x41, 0x40, 0x82, 0x12, + 0x02, 0x21, 0x0a, 0xe5, 0x13, 0xc9, 0x1b, 0xed, + 0x41, 0xfb, 0xc0, 0x08, 0x41, 0xfb, 0x1b, 0xed, + 0x13, 0xc9, 0x0a, 0xe5, 0x02, 0x21, 0x82, 0x12, + 0x41, 0x40, 0x41, 0x3b, 0x82, 0x16, 0x00, 0x00, + 0x04, 0x62, 0x08, 0xc4, 0x0a, 0xe5, 0x0d, 0x26, + 0x0d, 0x26, 0x0a, 0xe5, 0x08, 0xc4, 0x04, 0x62, + 0x00, 0x00, 0x82, 0x16, 0x41, 0x38, 0x41, 0x30, + 0x84, 0x36, 0x42, 0x30, 0x84, 0x36, 0x41, 0x30, + 0x41, 0x26, 0x84, 0x36, 0x41, 0x25, 0x41, 0x20, + 0x84, 0x36, 0x42, 0x20, 0x84, 0x36, 0x41, 0x20, + 0x41, 0x1d, 0x84, 0x36, 0x41, 0x1c, 0x41, 0x10, + 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, + 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, + 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, + 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, + 0x84, 0x36, 0x41, 0x10, 0x41, 0x06, 0x84, 0x36, + 0x41, 0x06, 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, + 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, + 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, + 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, + 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, + 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, + 0xbf, 0xfc, 0xbf, 0xfc, 0xb1, 0xec, 0x41, 0x02, + 0x84, 0x36, 0x41, 0x03, 0x41, 0x10, 0x84, 0x36, + 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, + 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, + 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, + 0x42, 0x10, 0x84, 0x36, 0x42, 0x10, 0x84, 0x36, + 0x41, 0x10, 0x41, 0x12, 0x84, 0x36, 0x41, 0x13, + 0x41, 0x20, 0x84, 0x36, 0x42, 0x20, 0x84, 0x36, + 0x42, 0x20, 0x84, 0x36, 0x41, 0x20, 0x41, 0x24, + 0x84, 0x36, 0x41, 0x22, 0x41, 0x30, 0x84, 0x36, + 0x42, 0x30, 0x84, 0x36, 0x41, 0x30, 0x41, 0x38, + 0x84, 0x36, 0x41, 0x36, 0x41, 0x40, 0x84, 0x36, + 0x41, 0x40, 0x41, 0x4b, 0x84, 0x36, 0x41, 0x48, + 0x41, 0x50, 0x84, 0x36, 0x41, 0x50, 0x41, 0x5e, + 0x84, 0x36, 0x41, 0x5c, 0x41, 0x68, 0x84, 0x36, + 0x41, 0x67, 0x41, 0x74, 0x84, 0x36, 0x41, 0x73, + 0x41, 0x80, 0x84, 0x36, 0x41, 0x80, 0x41, 0x8f, + 0x84, 0x36, 0x41, 0x8e, 0x41, 0x9e, 0x84, 0x36, + 0x41, 0x9f, 0x41, 0xae, 0x84, 0x36, 0x41, 0xb2, + 0x41, 0xc2, 0x84, 0x36, 0x41, 0xc3, 0x41, 0xd5, + 0x84, 0x36, 0x41, 0xd6, 0x41, 0xe9, 0x84, 0x36, + 0x41, 0xeb, 0x41, 0xfe, 0x00, 0x00, 0x84, 0x34, + 0x00, 0x00, 0xc0, 0x02, 0x06, 0x23, 0x84, 0x34, + 0x06, 0x23, 0xc0, 0x02, 0x0c, 0x66, 0x84, 0x34, + 0x0c, 0x66, 0xc0, 0x02, 0x14, 0xaa, 0x84, 0x34, + 0x14, 0xaa, 0xc0, 0x02, 0x1c, 0xee, 0x84, 0x34, + 0x1c, 0xee, 0xc0, 0x02, 0x23, 0x11, 0x84, 0x34, + 0x23, 0x11, 0xc0, 0x02, 0x2b, 0x55, 0x84, 0x34, + 0x2b, 0x55, 0xc0, 0x02, 0x35, 0xba, 0x84, 0x34, + 0x35, 0xba, 0xc0, 0x02, 0x41, 0xf8, 0x00, 0x00, + 0x84, 0x32, 0x00, 0x00, 0x41, 0xf8, 0xc0, 0x03, + 0x08, 0x44, 0x84, 0x32, 0x08, 0x44, 0xc0, 0x04, + 0x12, 0x89, 0x84, 0x32, 0x12, 0x89, 0xc0, 0x04, + 0x1c, 0xee, 0x84, 0x32, 0x1c, 0xee, 0xc0, 0x04, + 0x29, 0x54, 0x84, 0x32, 0x29, 0x54, 0xc0, 0x04, + 0x35, 0xba, 0x84, 0x32, 0x35, 0xba, 0xc0, 0x04, + 0x41, 0xfc, 0x02, 0x01, 0x84, 0x30, 0x02, 0x01, + 0x41, 0xfc, 0xc0, 0x05, 0x0e, 0x67, 0x84, 0x30, + 0x0e, 0x67, 0xc0, 0x06, 0x1c, 0xee, 0x84, 0x30, + 0x1c, 0xee, 0xc0, 0x06, 0x2d, 0x76, 0x84, 0x30, + 0x2d, 0x76, 0xc0, 0x06, 0x41, 0xec, 0x00, 0x00, + 0x84, 0x2e, 0x00, 0x00, 0x41, 0xea, 0xc0, 0x07, + 0x0a, 0x45, 0x84, 0x2e, 0x0a, 0x45, 0xc0, 0x08, + 0x1c, 0xee, 0x84, 0x2e, 0x1c, 0xee, 0xc0, 0x08, + 0x2f, 0x77, 0x84, 0x2e, 0x2d, 0x76, 0xc0, 0x08, + 0x41, 0xf8, 0x02, 0x01, 0x84, 0x2c, 0x02, 0x01, + 0x41, 0xf7, 0xc0, 0x09, 0x14, 0xaa, 0x84, 0x2c, + 0x12, 0x89, 0xc0, 0x0a, 0x29, 0x54, 0x84, 0x2c, + 0x27, 0x33, 0xc0, 0x0a, 0x41, 0xf1, 0x00, 0x00, + 0x84, 0x2a, 0x00, 0x00, 0x41, 0xee, 0xc0, 0x0b, + 0x12, 0x89, 0x84, 0x2a, 0x12, 0x89, 0xc0, 0x0c, + 0x29, 0x54, 0x84, 0x2a, 0x2b, 0x55, 0xc0, 0x0c, + 0x41, 0xf6, 0x02, 0x01, 0x84, 0x28, 0x04, 0x22, + 0x41, 0xf9, 0xc0, 0x0d, 0x18, 0xcc, 0x84, 0x28, + 0x1a, 0xcd, 0xc0, 0x0e, 0x35, 0xba, 0x84, 0x28, + 0x35, 0xba, 0xc0, 0x0f, 0x0e, 0x67, 0x84, 0x26, + 0x10, 0x88, 0xc0, 0x10, 0x2b, 0x55, 0x84, 0x26, + 0x2d, 0x76, 0xc0, 0x10, 0x41, 0xfe, 0x08, 0x44, + 0x84, 0x24, 0x08, 0x44, 0x41, 0xfe, 0xc0, 0x11, + 0x29, 0x54, 0x84, 0x24, 0x29, 0x54, 0xc0, 0x12, + 0x41, 0xfc, 0x08, 0x44, 0x84, 0x22, 0x08, 0x44, + 0x41, 0xfc, 0xc0, 0x13, 0x29, 0x54, 0x84, 0x22, + 0x29, 0x54, 0xc0, 0x14, 0x41, 0xfe, 0x0a, 0x45, + 0x84, 0x20, 0x0a, 0x45, 0x41, 0xfe, 0xc0, 0x15, + 0x2f, 0x77, 0x84, 0x20, 0x2d, 0x76, 0xc0, 0x17, + 0x14, 0xaa, 0x84, 0x1e, 0x12, 0x89, 0xc0, 0x18, + 0x39, 0xdc, 0x41, 0x09, 0x84, 0x1c, 0x41, 0x08, + 0x37, 0xbb, 0xc0, 0x19, 0x32, 0x99, 0x84, 0x1c, + 0x32, 0x99, 0xc0, 0x1a, 0x41, 0xfd, 0x0e, 0x67, + 0x84, 0x1a, 0x0e, 0x67, 0x41, 0xfd, 0xc0, 0x1b, + 0x37, 0xbb, 0x41, 0x0a, 0x84, 0x18, 0x41, 0x0a, + 0x37, 0xbb, 0xc0, 0x1d, 0x36, 0x9b, 0x84, 0x18, + 0x38, 0x9c, 0xc0, 0x1f, 0x1e, 0x4f, 0x84, 0x16, + 0x20, 0x50, 0xc0, 0x20, 0x41, 0xf4, 0x0a, 0x45, + 0x84, 0x14, 0x0a, 0x45, 0x41, 0xf4, 0xc0, 0x21, + 0x35, 0xba, 0x41, 0x0d, 0x84, 0x12, 0x41, 0x0d, + 0x35, 0xba, 0xc0, 0x23, 0x3e, 0xbf, 0x41, 0x03, + 0x84, 0x10, 0x41, 0x05, 0x3e, 0xbf, 0xc0, 0x25, + 0x38, 0x9c, 0x84, 0x0f, 0x41, 0x01, 0x3c, 0xbe, + 0xc0, 0x27, 0x30, 0x98, 0x84, 0x0e, 0x32, 0x99, + 0xc0, 0x29, 0x2c, 0x76, 0x84, 0x0c, 0x2c, 0x76, + 0xc0, 0x2b, 0x2c, 0x76, 0x84, 0x0a, 0x30, 0x98, + 0xc0, 0x2d, 0x30, 0x98, 0x84, 0x08, 0x32, 0x99, + 0xc0, 0x2f, 0x3a, 0x9d, 0x41, 0x06, 0x84, 0x04, + 0x41, 0x03, 0x38, 0x9c, 0xc0, 0x31, 0x3e, 0xbf, + 0x41, 0x10, 0x84, 0x02, 0x41, 0x0e, 0x3e, 0xbf, + 0xc0, 0x33, 0x3e, 0xdf, 0x0c, 0x26, 0x84, 0x00, + 0x0c, 0x26, 0x3e, 0xdf, 0xc0, 0x35, 0x41, 0xf3, + 0x20, 0x50, 0x83, 0xfe, 0x1e, 0x4f, 0x41, 0xf0, + 0xc0, 0x38, 0x38, 0x9c, 0x41, 0x08, 0x83, 0xfa, + 0x41, 0x08, 0x36, 0x9b, 0xc0, 0x3b, 0x3e, 0xdf, + 0x12, 0x29, 0x83, 0xf8, 0x14, 0x2a, 0x3e, 0xdf, + 0xc0, 0x3d, 0x41, 0xfb, 0x32, 0x99, 0x41, 0x08, + 0x83, 0xf4, 0x41, 0x0a, 0x36, 0x9b, 0x41, 0xfd, + 0xc0, 0x40, 0x3e, 0xdf, 0x1a, 0x4d, 0x83, 0xf2, + 0x1e, 0x4f, 0x3e, 0xdf, 0xc0, 0x44, 0x3e, 0xbf, + 0x10, 0x28, 0x83, 0xee, 0x12, 0x29, 0x3e, 0xdf, + 0xc0, 0x47, 0x41, 0xfc, 0x3c, 0xbe, 0x0c, 0x26, + 0x83, 0xea, 0x10, 0x28, 0x3c, 0xbe, 0x41, 0xfe, + 0xc0, 0x4a, 0x41, 0xfc, 0x3c, 0xbe, 0x0e, 0x27, + 0x83, 0xe6, 0x18, 0x4c, 0x3e, 0xbf, 0xc0, 0x4f, + 0x41, 0xfe, 0x3e, 0xbf, 0x18, 0x4c, 0x41, 0x01, + 0x83, 0xe0, 0x41, 0x04, 0x20, 0x50, 0x3e, 0xdf, + 0xc0, 0x54, 0x3e, 0xdf, 0x28, 0x74, 0x04, 0x02, + 0x83, 0xdc, 0x06, 0x03, 0x28, 0x74, 0x3e, 0xdf, + 0xc0, 0x58, 0x41, 0xf9, 0x3e, 0xbf, 0x1e, 0x4f, + 0x02, 0x01, 0x83, 0xd6, 0x06, 0x03, 0x24, 0x72, + 0x3e, 0xbf, 0x41, 0xfb, 0xc0, 0x5d, 0x41, 0xee, + 0x3c, 0xbe, 0x1e, 0x4f, 0x04, 0x02, 0x83, 0xd0, + 0x06, 0x03, 0x24, 0x72, 0x3e, 0xbf, 0x41, 0xfb, + 0xc0, 0x63, 0x41, 0xf9, 0x3e, 0xbf, 0x30, 0x98, + 0x1e, 0x4f, 0x0e, 0x27, 0x00, 0x00, 0x83, 0xc6, + 0x00, 0x00, 0x0e, 0x27, 0x1e, 0x4f, 0x30, 0x98, + 0x3e, 0xbf, 0x41, 0xfb, 0xc0, 0x6b, 0x41, 0xf5, + 0x3e, 0xdf, 0x38, 0x9c, 0x28, 0x74, 0x16, 0x2b, + 0x04, 0x02, 0x83, 0xbc, 0x04, 0x02, 0x16, 0x2b, + 0x28, 0x74, 0x38, 0x9c, 0x3e, 0xdf, 0x41, 0xf5, + 0xc0, 0x76, 0x3e, 0xff, 0x3e, 0xbf, 0x30, 0x98, + 0x1e, 0x4f, 0x0e, 0x27, 0x00, 0x00, 0x83, 0xb0, + 0x00, 0x00, 0x0e, 0x27, 0x1e, 0x4f, 0x30, 0x98, + 0x3e, 0xbf, 0x3e, 0xff, 0xc0, 0x81, 0x41, 0xf5, + 0x3e, 0xdf, 0x38, 0x9c, 0x28, 0x74, 0x16, 0x2b, + 0x0c, 0x26, 0x06, 0x03, 0x00, 0x00, 0x83, 0xa2, + 0x00, 0x00, 0x06, 0x03, 0x0c, 0x26, 0x16, 0x2b, + 0x28, 0x74, 0x38, 0x9c, 0x3e, 0xdf, 0x41, 0xf5, + 0xc0, 0x8e, 0x41, 0xf8, 0x41, 0xeb, 0x41, 0xdf, + 0x41, 0xd0, 0x41, 0xc2, 0x41, 0xb5, 0x41, 0xa9, + 0x41, 0x9c, 0x41, 0x8f, 0x41, 0x80, 0x41, 0x73, + 0x41, 0x66, 0x41, 0x5a, 0x41, 0x4d, 0x41, 0x40, + 0x41, 0x30, 0x41, 0x24, 0x44, 0x20, 0x41, 0x19, + 0x4f, 0x10, 0x41, 0x06, 0x83, 0x56, 0x41, 0x06, + 0x4f, 0x10, 0x41, 0x19, 0x44, 0x20, 0x41, 0x24, + 0x41, 0x30, 0x41, 0x40, 0x41, 0x4d, 0x41, 0x5a, + 0x41, 0x66, 0x41, 0x73, 0x41, 0x80, 0x41, 0x8f, + 0x41, 0x9c, 0x41, 0xa9, 0x41, 0xb5, 0x41, 0xc2, + 0x41, 0xd0, 0x41, 0xdf, 0x41, 0xeb, 0x41, 0xf8, + 0xc0, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static char self_mask_img_fhd_crc_data[] = { + 0x80, 0x28, 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, + 0x80, 0x28, 0x56, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, + 0x41, 0xff, 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, + 0x41, 0x00, 0x41, 0x80, 0x41, 0xff, 0x41, 0x00, + 0xc1, 0x7c, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x55, 0x80, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0xc1, 0x7c, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x55, 0x80, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, + 0x41, 0x00, 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, + 0x17, 0x0b, 0x41, 0xff, 0x41, 0x00, 0x17, 0x0b, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, + 0x41, 0xff, 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, + 0x41, 0x00, 0x09, 0x04, 0x41, 0xff, 0x41, 0x00, + 0xc1, 0x7c, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0xc0, 0x28, 0x80, 0x28, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0xc0, 0x28, 0x80, 0x28, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, 0x20, 0x50, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, + 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, 0x17, 0x0b, + 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, 0x4b, 0x80, + 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, 0x5c, 0x80, + 0x4b, 0x80, 0x17, 0x0b, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x28, + 0x5c, 0x80, 0x4c, 0x80, 0xc0, 0x28, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, + 0x80, 0x14, 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, + 0x54, 0x80, 0xc0, 0x14, 0x80, 0x14, 0x54, 0x80, + 0xc0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#endif diff --git a/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/dsi_panel_S6E3HA9_AMF670UH01_fhd_octa_cmd.dtsi b/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/dsi_panel_S6E3HA9_AMF670UH01_fhd_octa_cmd.dtsi index ca1430d53..18a8d6090 100755 --- a/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/dsi_panel_S6E3HA9_AMF670UH01_fhd_octa_cmd.dtsi +++ b/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/dsi_panel_S6E3HA9_AMF670UH01_fhd_octa_cmd.dtsi @@ -1457,6 +1457,14 @@ 3 9400 25500 60 >; + samsung,aod_candela_map_table_jpn_revA = < + /* */ + 0 0 4899 2 + 1 4900 10399 10 + 2 10400 13399 30 + 3 13400 25500 60 + >; + samsung,hbm_candela_map_table_revA = < /* idx from end cd auto */ 0 258 260 405 6 diff --git a/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_mdnie_S6E3HA9_AMF670UH01.h b/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_mdnie_S6E3HA9_AMF670UH01.h index 731e4a646..91d18bd4f 100755 --- a/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_mdnie_S6E3HA9_AMF670UH01.h +++ b/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_mdnie_S6E3HA9_AMF670UH01.h @@ -88,7 +88,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe2, 0x00, 0xa5, 0x00, 0xff, 0x00, 0x00, 0xe2, 0xa5, 0x00, 0xff, 0x00, 0xe2, 0x00, 0x00, 0xa5, 0xff, 0x00, 0xe2, 0x00, 0xa5, 0x00, /* 3700K */ 0x00, 0xff, 0xd5, 0x00, 0x87, 0x00, 0xff, 0x00, 0x00, 0xd5, 0x87, 0x00, 0xff, 0x00, 0xd5, 0x00, 0x00, 0x87, 0xff, 0x00, 0xd5, 0x00, 0x87, 0x00, /* 3100K */ 0x00, 0xff, 0xbc, 0x00, 0x5a, 0x00, 0xff, 0x00, 0x00, 0xbc, 0x5a, 0x00, 0xff, 0x00, 0xbc, 0x00, 0x00, 0x5a, 0xff, 0x00, 0xbc, 0x00, 0x5a, 0x00, /* 2300K */ - 0x00, 0xff, 0xfe, 0x00, 0xfb, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xfb, 0x00, 0xff, 0x00, 0xfe, 0x00, 0x00, 0xfb, 0xff, 0x00, 0xfe, 0x00, 0xfb, 0x00, /* GAME_MODE */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x2d, 0xeb, 0xf9, 0x0d, 0xed, 0x00, 0xf3, 0x16, 0x10, 0xf0, 0xed, 0x00, 0xf5, 0x14, 0xf6, 0x07, 0x00, 0xe8, 0xff, 0x00, 0xfc, 0x00, 0xf6, 0x00, /* 6500K */ 0x2d, 0xeb, 0xf8, 0x0d, 0xea, 0x00, 0xf3, 0x16, 0x10, 0xef, 0xea, 0x00, 0xf5, 0x14, 0xf5, 0x07, 0x00, 0xe5, 0xff, 0x00, 0xfb, 0x00, 0xf3, 0x00, /* 6300K */ 0x2d, 0xeb, 0xf7, 0x0d, 0xe8, 0x00, 0xf3, 0x16, 0x10, 0xee, 0xe8, 0x00, 0xf5, 0x14, 0xf4, 0x07, 0x00, 0xe2, 0xff, 0x00, 0xfa, 0x00, 0xf0, 0x00, /* 6100K */ @@ -100,7 +190,97 @@ static char night_mode_data[] = { 0x2d, 0xeb, 0xdf, 0x0c, 0x9f, 0x00, 0xf3, 0x16, 0x0e, 0xd7, 0x9f, 0x00, 0xf5, 0x14, 0xdd, 0x06, 0x00, 0x9b, 0xff, 0x00, 0xe2, 0x00, 0xa5, 0x00, /* 3700K */ 0x2d, 0xeb, 0xd2, 0x0b, 0x82, 0x00, 0xf3, 0x16, 0x0d, 0xcb, 0x82, 0x00, 0xf5, 0x14, 0xd0, 0x06, 0x00, 0x7f, 0xff, 0x00, 0xd5, 0x00, 0x87, 0x00, /* 3100K */ 0x2d, 0xeb, 0xba, 0x0a, 0x57, 0x00, 0xf3, 0x16, 0x0c, 0xb3, 0x57, 0x00, 0xf5, 0x14, 0xb8, 0x05, 0x00, 0x55, 0xff, 0x00, 0xbc, 0x00, 0x5a, 0x00, /* 2300K */ - 0x00, 0xff, 0xfe, 0x00, 0xfb, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xfb, 0x00, 0xff, 0x00, 0xfe, 0x00, 0x00, 0xfb, 0xff, 0x00, 0xfe, 0x00, 0xfb, 0x00, /* GAME_MODE */ + 0x2d, 0xeb, 0xf6, 0x0c, 0xe4, 0x00, 0xf3, 0x16, 0x0f, 0xed, 0xe4, 0x00, 0xf5, 0x14, 0xf3, 0x06, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x2d, 0xeb, 0xf6, 0x0c, 0xe4, 0x00, 0xf3, 0x16, 0x0f, 0xed, 0xe4, 0x00, 0xf5, 0x14, 0xf3, 0x06, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x2d, 0xeb, 0xf6, 0x0c, 0xe3, 0x00, 0xf3, 0x16, 0x0f, 0xed, 0xe3, 0x00, 0xf5, 0x14, 0xf3, 0x06, 0x00, 0xd6, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x2d, 0xeb, 0xf6, 0x0c, 0xe3, 0x00, 0xf3, 0x16, 0x0f, 0xed, 0xe3, 0x00, 0xf5, 0x14, 0xf3, 0x06, 0x00, 0xd6, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x2d, 0xeb, 0xf5, 0x0c, 0xe2, 0x00, 0xf3, 0x16, 0x0f, 0xec, 0xe2, 0x00, 0xf5, 0x14, 0xf2, 0x06, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x2d, 0xeb, 0xf5, 0x0c, 0xe2, 0x00, 0xf3, 0x16, 0x0f, 0xec, 0xe2, 0x00, 0xf5, 0x14, 0xf2, 0x06, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x2d, 0xeb, 0xf5, 0x0c, 0xe1, 0x00, 0xf3, 0x16, 0x0f, 0xec, 0xe1, 0x00, 0xf5, 0x14, 0xf2, 0x06, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x2d, 0xeb, 0xf5, 0x0c, 0xe1, 0x00, 0xf3, 0x16, 0x0f, 0xec, 0xe1, 0x00, 0xf5, 0x14, 0xf2, 0x06, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x2d, 0xeb, 0xf5, 0x0c, 0xe0, 0x00, 0xf3, 0x16, 0x0f, 0xec, 0xe0, 0x00, 0xf5, 0x14, 0xf2, 0x06, 0x00, 0xd3, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x2d, 0xeb, 0xf5, 0x0c, 0xe0, 0x00, 0xf3, 0x16, 0x0f, 0xec, 0xe0, 0x00, 0xf5, 0x14, 0xf2, 0x06, 0x00, 0xd3, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x2d, 0xeb, 0xf4, 0x0c, 0xdf, 0x00, 0xf3, 0x16, 0x0f, 0xeb, 0xdf, 0x00, 0xf5, 0x14, 0xf1, 0x06, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x2d, 0xeb, 0xf4, 0x0c, 0xdf, 0x00, 0xf3, 0x16, 0x0f, 0xeb, 0xdf, 0x00, 0xf5, 0x14, 0xf1, 0x06, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x2d, 0xeb, 0xf4, 0x0c, 0xde, 0x00, 0xf3, 0x16, 0x0f, 0xeb, 0xde, 0x00, 0xf5, 0x14, 0xf1, 0x06, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x2d, 0xeb, 0xf4, 0x0c, 0xde, 0x00, 0xf3, 0x16, 0x0f, 0xeb, 0xde, 0x00, 0xf5, 0x14, 0xf1, 0x06, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x2d, 0xeb, 0xf4, 0x0c, 0xdd, 0x00, 0xf3, 0x16, 0x0f, 0xeb, 0xdd, 0x00, 0xf5, 0x14, 0xf1, 0x06, 0x00, 0xd1, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x2d, 0xeb, 0xf4, 0x0c, 0xdd, 0x00, 0xf3, 0x16, 0x0f, 0xeb, 0xdd, 0x00, 0xf5, 0x14, 0xf1, 0x06, 0x00, 0xd1, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x2d, 0xeb, 0xf3, 0x0c, 0xdc, 0x00, 0xf3, 0x16, 0x0f, 0xea, 0xdc, 0x00, 0xf5, 0x14, 0xf0, 0x06, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x2d, 0xeb, 0xf3, 0x0c, 0xdc, 0x00, 0xf3, 0x16, 0x0f, 0xea, 0xdc, 0x00, 0xf5, 0x14, 0xf0, 0x06, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x2d, 0xeb, 0xf3, 0x0c, 0xdb, 0x00, 0xf3, 0x16, 0x0f, 0xea, 0xdb, 0x00, 0xf5, 0x14, 0xf0, 0x06, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x2d, 0xeb, 0xf3, 0x0c, 0xda, 0x00, 0xf3, 0x16, 0x0f, 0xea, 0xda, 0x00, 0xf5, 0x14, 0xf0, 0x06, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x2d, 0xeb, 0xf3, 0x0c, 0xda, 0x00, 0xf3, 0x16, 0x0f, 0xea, 0xda, 0x00, 0xf5, 0x14, 0xf0, 0x06, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x2d, 0xeb, 0xf3, 0x0c, 0xda, 0x00, 0xf3, 0x16, 0x0f, 0xea, 0xda, 0x00, 0xf5, 0x14, 0xf0, 0x06, 0x00, 0xcd, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x2d, 0xeb, 0xf2, 0x0c, 0xda, 0x00, 0xf3, 0x16, 0x0f, 0xe9, 0xda, 0x00, 0xf5, 0x14, 0xef, 0x06, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x2d, 0xeb, 0xf2, 0x0c, 0xd9, 0x00, 0xf3, 0x16, 0x0f, 0xe9, 0xd9, 0x00, 0xf5, 0x14, 0xef, 0x06, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x2d, 0xeb, 0xf2, 0x0c, 0xd9, 0x00, 0xf3, 0x16, 0x0f, 0xe9, 0xd9, 0x00, 0xf5, 0x14, 0xef, 0x06, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x2d, 0xeb, 0xf2, 0x0c, 0xd8, 0x00, 0xf3, 0x16, 0x0f, 0xe9, 0xd8, 0x00, 0xf5, 0x14, 0xef, 0x06, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x2d, 0xeb, 0xf2, 0x0c, 0xd8, 0x00, 0xf3, 0x16, 0x0f, 0xe9, 0xd8, 0x00, 0xf5, 0x14, 0xef, 0x06, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x2d, 0xeb, 0xf2, 0x0c, 0xd7, 0x00, 0xf3, 0x16, 0x0f, 0xe9, 0xd7, 0x00, 0xf5, 0x14, 0xef, 0x06, 0x00, 0xca, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x2d, 0xeb, 0xf1, 0x0c, 0xd6, 0x00, 0xf3, 0x16, 0x0f, 0xe8, 0xd6, 0x00, 0xf5, 0x14, 0xee, 0x06, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x2d, 0xeb, 0xf1, 0x0c, 0xd6, 0x00, 0xf3, 0x16, 0x0f, 0xe8, 0xd6, 0x00, 0xf5, 0x14, 0xee, 0x06, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x2d, 0xeb, 0xf1, 0x0c, 0xd5, 0x00, 0xf3, 0x16, 0x0f, 0xe8, 0xd5, 0x00, 0xf5, 0x14, 0xee, 0x06, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x2d, 0xeb, 0xf1, 0x0c, 0xd5, 0x00, 0xf3, 0x16, 0x0f, 0xe8, 0xd5, 0x00, 0xf5, 0x14, 0xee, 0x06, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x2d, 0xeb, 0xf1, 0x0c, 0xd4, 0x00, 0xf3, 0x16, 0x0f, 0xe8, 0xd4, 0x00, 0xf5, 0x14, 0xee, 0x06, 0x00, 0xc8, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x2d, 0xeb, 0xf1, 0x0c, 0xd4, 0x00, 0xf3, 0x16, 0x0f, 0xe8, 0xd4, 0x00, 0xf5, 0x14, 0xee, 0x06, 0x00, 0xc8, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x2d, 0xeb, 0xf0, 0x0c, 0xd3, 0x00, 0xf3, 0x16, 0x0f, 0xe7, 0xd3, 0x00, 0xf5, 0x14, 0xed, 0x06, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x2d, 0xeb, 0xf0, 0x0c, 0xd3, 0x00, 0xf3, 0x16, 0x0f, 0xe7, 0xd3, 0x00, 0xf5, 0x14, 0xed, 0x06, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x2d, 0xeb, 0xf0, 0x0c, 0xd2, 0x00, 0xf3, 0x16, 0x0f, 0xe7, 0xd2, 0x00, 0xf5, 0x14, 0xed, 0x06, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x2d, 0xeb, 0xf0, 0x0c, 0xd1, 0x00, 0xf3, 0x16, 0x0f, 0xe7, 0xd1, 0x00, 0xf5, 0x14, 0xed, 0x06, 0x00, 0xc5, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x2d, 0xeb, 0xf0, 0x0c, 0xd1, 0x00, 0xf3, 0x16, 0x0f, 0xe7, 0xd1, 0x00, 0xf5, 0x14, 0xed, 0x06, 0x00, 0xc5, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x2d, 0xeb, 0xef, 0x0c, 0xd0, 0x00, 0xf3, 0x16, 0x0f, 0xe6, 0xd0, 0x00, 0xf5, 0x14, 0xec, 0x06, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x2d, 0xeb, 0xef, 0x0c, 0xd0, 0x00, 0xf3, 0x16, 0x0f, 0xe6, 0xd0, 0x00, 0xf5, 0x14, 0xec, 0x06, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x2d, 0xeb, 0xef, 0x0c, 0xcf, 0x00, 0xf3, 0x16, 0x0f, 0xe6, 0xcf, 0x00, 0xf5, 0x14, 0xec, 0x06, 0x00, 0xc3, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x2d, 0xeb, 0xef, 0x0c, 0xcf, 0x00, 0xf3, 0x16, 0x0f, 0xe6, 0xcf, 0x00, 0xf5, 0x14, 0xec, 0x06, 0x00, 0xc3, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x2d, 0xeb, 0xee, 0x0c, 0xce, 0x00, 0xf3, 0x16, 0x0f, 0xe5, 0xce, 0x00, 0xf5, 0x14, 0xeb, 0x06, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x2d, 0xeb, 0xee, 0x0c, 0xce, 0x00, 0xf3, 0x16, 0x0f, 0xe5, 0xce, 0x00, 0xf5, 0x14, 0xeb, 0x06, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x2d, 0xeb, 0xee, 0x0c, 0xcd, 0x00, 0xf3, 0x16, 0x0f, 0xe5, 0xcd, 0x00, 0xf5, 0x14, 0xeb, 0x06, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x2d, 0xeb, 0xee, 0x0c, 0xcc, 0x00, 0xf3, 0x16, 0x0f, 0xe5, 0xcc, 0x00, 0xf5, 0x14, 0xeb, 0x06, 0x00, 0xc0, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x2d, 0xeb, 0xee, 0x0c, 0xcc, 0x00, 0xf3, 0x16, 0x0f, 0xe5, 0xcc, 0x00, 0xf5, 0x14, 0xeb, 0x06, 0x00, 0xc0, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x2d, 0xeb, 0xed, 0x0c, 0xcb, 0x00, 0xf3, 0x16, 0x0f, 0xe4, 0xcb, 0x00, 0xf5, 0x14, 0xea, 0x06, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x2d, 0xeb, 0xed, 0x0c, 0xcb, 0x00, 0xf3, 0x16, 0x0f, 0xe4, 0xcb, 0x00, 0xf5, 0x14, 0xea, 0x06, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x2d, 0xeb, 0xed, 0x0c, 0xca, 0x00, 0xf3, 0x16, 0x0f, 0xe4, 0xca, 0x00, 0xf5, 0x14, 0xea, 0x06, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x2d, 0xeb, 0xed, 0x0c, 0xca, 0x00, 0xf3, 0x16, 0x0f, 0xe4, 0xca, 0x00, 0xf5, 0x14, 0xea, 0x06, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x2d, 0xeb, 0xec, 0x0c, 0xc9, 0x00, 0xf3, 0x16, 0x0e, 0xe3, 0xc9, 0x00, 0xf5, 0x14, 0xe9, 0x06, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x2d, 0xeb, 0xec, 0x0c, 0xc9, 0x00, 0xf3, 0x16, 0x0e, 0xe3, 0xc9, 0x00, 0xf5, 0x14, 0xe9, 0x06, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x2d, 0xeb, 0xec, 0x0c, 0xc8, 0x00, 0xf3, 0x16, 0x0e, 0xe3, 0xc8, 0x00, 0xf5, 0x14, 0xe9, 0x06, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x2d, 0xeb, 0xec, 0x0c, 0xc7, 0x00, 0xf3, 0x16, 0x0e, 0xe3, 0xc7, 0x00, 0xf5, 0x14, 0xe9, 0x06, 0x00, 0xbc, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x2d, 0xeb, 0xec, 0x0c, 0xc7, 0x00, 0xf3, 0x16, 0x0e, 0xe3, 0xc7, 0x00, 0xf5, 0x14, 0xe9, 0x06, 0x00, 0xbc, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x2d, 0xeb, 0xeb, 0x0c, 0xc6, 0x00, 0xf3, 0x16, 0x0e, 0xe2, 0xc6, 0x00, 0xf5, 0x14, 0xe8, 0x06, 0x00, 0xbb, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x2d, 0xeb, 0xeb, 0x0c, 0xc5, 0x00, 0xf3, 0x16, 0x0e, 0xe2, 0xc5, 0x00, 0xf5, 0x14, 0xe8, 0x06, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x2d, 0xeb, 0xeb, 0x0c, 0xc4, 0x00, 0xf3, 0x16, 0x0e, 0xe2, 0xc4, 0x00, 0xf5, 0x14, 0xe8, 0x06, 0x00, 0xb9, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x2d, 0xeb, 0xeb, 0x0c, 0xc4, 0x00, 0xf3, 0x16, 0x0e, 0xe2, 0xc4, 0x00, 0xf5, 0x14, 0xe8, 0x06, 0x00, 0xb9, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x2d, 0xeb, 0xea, 0x0c, 0xc3, 0x00, 0xf3, 0x16, 0x0e, 0xe1, 0xc3, 0x00, 0xf5, 0x14, 0xe7, 0x06, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x2d, 0xeb, 0xea, 0x0c, 0xc2, 0x00, 0xf3, 0x16, 0x0e, 0xe1, 0xc2, 0x00, 0xf5, 0x14, 0xe7, 0x06, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x2d, 0xeb, 0xea, 0x0c, 0xc2, 0x00, 0xf3, 0x16, 0x0e, 0xe1, 0xc2, 0x00, 0xf5, 0x14, 0xe7, 0x06, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x2d, 0xeb, 0xea, 0x0c, 0xc1, 0x00, 0xf3, 0x16, 0x0e, 0xe1, 0xc1, 0x00, 0xf5, 0x14, 0xe7, 0x06, 0x00, 0xb6, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x2d, 0xeb, 0xea, 0x0c, 0xc0, 0x00, 0xf3, 0x16, 0x0e, 0xe1, 0xc0, 0x00, 0xf5, 0x14, 0xe7, 0x06, 0x00, 0xb5, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x2d, 0xeb, 0xe9, 0x0c, 0xbf, 0x00, 0xf3, 0x16, 0x0e, 0xe0, 0xbf, 0x00, 0xf5, 0x14, 0xe6, 0x06, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x2d, 0xeb, 0xe9, 0x0c, 0xbf, 0x00, 0xf3, 0x16, 0x0e, 0xe0, 0xbf, 0x00, 0xf5, 0x14, 0xe6, 0x06, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x2d, 0xeb, 0xe9, 0x0c, 0xbf, 0x00, 0xf3, 0x16, 0x0e, 0xe0, 0xbf, 0x00, 0xf5, 0x14, 0xe6, 0x06, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x2d, 0xeb, 0xe9, 0x0c, 0xbe, 0x00, 0xf3, 0x16, 0x0e, 0xe0, 0xbe, 0x00, 0xf5, 0x14, 0xe6, 0x06, 0x00, 0xb3, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x2d, 0xeb, 0xe8, 0x0b, 0xbd, 0x00, 0xf3, 0x16, 0x0e, 0xdf, 0xbd, 0x00, 0xf5, 0x14, 0xe5, 0x06, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x2d, 0xeb, 0xe8, 0x0b, 0xbd, 0x00, 0xf3, 0x16, 0x0e, 0xdf, 0xbd, 0x00, 0xf5, 0x14, 0xe5, 0x06, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x2d, 0xeb, 0xe8, 0x0b, 0xbc, 0x00, 0xf3, 0x16, 0x0e, 0xdf, 0xbc, 0x00, 0xf5, 0x14, 0xe5, 0x06, 0x00, 0xb1, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x2d, 0xeb, 0xe8, 0x0b, 0xbb, 0x00, 0xf3, 0x16, 0x0e, 0xdf, 0xbb, 0x00, 0xf5, 0x14, 0xe5, 0x06, 0x00, 0xb0, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x2d, 0xeb, 0xe7, 0x0b, 0xba, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xba, 0x00, 0xf5, 0x14, 0xe4, 0x06, 0x00, 0xaf, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x2d, 0xeb, 0xe7, 0x0b, 0xb9, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xb9, 0x00, 0xf5, 0x14, 0xe4, 0x06, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x2d, 0xeb, 0xe7, 0x0b, 0xb8, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xb8, 0x00, 0xf5, 0x14, 0xe4, 0x06, 0x00, 0xad, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x2d, 0xeb, 0xe7, 0x0b, 0xb8, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xb8, 0x00, 0xf5, 0x14, 0xe4, 0x06, 0x00, 0xad, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x2d, 0xeb, 0xe6, 0x0b, 0xb7, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xb7, 0x00, 0xf5, 0x14, 0xe3, 0x06, 0x00, 0xac, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x2d, 0xeb, 0xe6, 0x0b, 0xb6, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xb6, 0x00, 0xf5, 0x14, 0xe3, 0x06, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x2d, 0xeb, 0xe6, 0x0b, 0xb5, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xb5, 0x00, 0xf5, 0x14, 0xe3, 0x06, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x2d, 0xeb, 0xe6, 0x0b, 0xb4, 0x00, 0xf3, 0x16, 0x0e, 0xde, 0xb4, 0x00, 0xf5, 0x14, 0xe3, 0x06, 0x00, 0xaa, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x2d, 0xeb, 0xe5, 0x0b, 0xb3, 0x00, 0xf3, 0x16, 0x0e, 0xdd, 0xb3, 0x00, 0xf5, 0x14, 0xe2, 0x06, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x2d, 0xeb, 0xe5, 0x0b, 0xb2, 0x00, 0xf3, 0x16, 0x0e, 0xdd, 0xb2, 0x00, 0xf5, 0x14, 0xe2, 0x06, 0x00, 0xa8, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x2d, 0xeb, 0xe5, 0x0b, 0xb1, 0x00, 0xf3, 0x16, 0x0e, 0xdd, 0xb1, 0x00, 0xf5, 0x14, 0xe2, 0x06, 0x00, 0xa7, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x2d, 0xeb, 0xe4, 0x0b, 0xb0, 0x00, 0xf3, 0x16, 0x0e, 0xdc, 0xb0, 0x00, 0xf5, 0x14, 0xe1, 0x06, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x2d, 0xeb, 0xe4, 0x0b, 0xb0, 0x00, 0xf3, 0x16, 0x0e, 0xdc, 0xb0, 0x00, 0xf5, 0x14, 0xe1, 0x06, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x2d, 0xeb, 0xe4, 0x0b, 0xaf, 0x00, 0xf3, 0x16, 0x0e, 0xdc, 0xaf, 0x00, 0xf5, 0x14, 0xe1, 0x06, 0x00, 0xa5, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x2d, 0xeb, 0xe4, 0x0b, 0xae, 0x00, 0xf3, 0x16, 0x0e, 0xdc, 0xae, 0x00, 0xf5, 0x14, 0xe1, 0x06, 0x00, 0xa4, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x2d, 0xeb, 0xe3, 0x0b, 0xad, 0x00, 0xf3, 0x16, 0x0e, 0xdb, 0xad, 0x00, 0xf5, 0x14, 0xe0, 0x06, 0x00, 0xa3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x2d, 0xeb, 0xe3, 0x0b, 0xac, 0x00, 0xf3, 0x16, 0x0e, 0xdb, 0xac, 0x00, 0xf5, 0x14, 0xe0, 0x06, 0x00, 0xa2, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_panel_S6E3HA9_AMF670UH01.c b/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_panel_S6E3HA9_AMF670UH01.c index c3285cf40..2cd799afe 100755 --- a/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_panel_S6E3HA9_AMF670UH01.c +++ b/techpack/display/msm/samsung/S6E3HA9_AMF670UH01/ss_dsi_panel_S6E3HA9_AMF670UH01.c @@ -1403,7 +1403,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 12; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/dsi_panel_S6E3HAB_AMB623TS01_wqhd_octa_cmd.dtsi b/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/dsi_panel_S6E3HAB_AMB623TS01_wqhd_octa_cmd.dtsi index 48d29ff45..0f96fc0e7 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/dsi_panel_S6E3HAB_AMB623TS01_wqhd_octa_cmd.dtsi +++ b/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/dsi_panel_S6E3HAB_AMB623TS01_wqhd_octa_cmd.dtsi @@ -1765,6 +1765,14 @@ 3 9400 25500 60 >; + samsung,aod_candela_map_table_jpn_revA = < + /* */ + 0 0 4899 2 + 1 4900 10399 10 + 2 10400 13399 30 + 3 13400 25500 60 + >; + samsung,hbm_candela_map_table_revA = < /* idx from end cd auto */ 0 258 260 405 6 diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_mdnie_S6E3HAB_AMB623TS01.h b/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_mdnie_S6E3HAB_AMB623TS01.h index 2ff88e982..78aa2d61f 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_mdnie_S6E3HAB_AMB623TS01.h +++ b/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_mdnie_S6E3HAB_AMB623TS01.h @@ -88,6 +88,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xde, 0x00, 0xa1, 0x00, 0xff, 0x00, 0x00, 0xde, 0xa1, 0x00, 0xff, 0x00, 0xde, 0x00, 0x00, 0xa1, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x00, 0xff, 0xd1, 0x00, 0x83, 0x00, 0xff, 0x00, 0x00, 0xd1, 0x83, 0x00, 0xff, 0x00, 0xd1, 0x00, 0x00, 0x83, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x30, 0xf1, 0xfc, 0x0a, 0xf4, 0x00, 0xf1, 0x1d, 0x00, 0xf8, 0xed, 0x00, 0xf8, 0x14, 0xf9, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xfc, 0x00, 0xf5, 0x00, /* 6500K */ 0x30, 0xf1, 0xfb, 0x0a, 0xf0, 0x00, 0xf1, 0x1d, 0x00, 0xf7, 0xe9, 0x00, 0xf8, 0x14, 0xf8, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xfb, 0x00, 0xf1, 0x00, /* 6300K */ 0x30, 0xf1, 0xfa, 0x0a, 0xec, 0x00, 0xf1, 0x1d, 0x00, 0xf6, 0xe6, 0x00, 0xf8, 0x14, 0xf7, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xfa, 0x00, 0xed, 0x00, /* 6100K */ @@ -99,6 +190,97 @@ static char night_mode_data[] = { 0x30, 0xf1, 0xde, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xdb, 0x9c, 0x00, 0xf8, 0x14, 0xdb, 0x00, 0x00, 0x99, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x30, 0xf1, 0xd1, 0x08, 0x82, 0x00, 0xf1, 0x1d, 0x00, 0xce, 0x7f, 0x00, 0xf8, 0x14, 0xcf, 0x00, 0x00, 0x7d, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x30, 0xf1, 0xba, 0x07, 0x5d, 0x00, 0xf1, 0x1d, 0x00, 0xb7, 0x5a, 0x00, 0xf8, 0x14, 0xb8, 0x00, 0x00, 0x59, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xda, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd3, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd2, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd5, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xcf, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd0, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xca, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcb, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc1, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc5, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbf, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc4, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbe, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc2, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbc, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc0, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xba, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xbf, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xb9, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbd, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbc, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb7, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xba, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb5, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xb9, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb4, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb1, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb8, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb3, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xb0, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb7, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb2, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xaf, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb5, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xb0, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xad, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb4, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xaf, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xac, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb3, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xae, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb2, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xad, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xaa, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xac, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xae, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa9, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xad, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa8, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xac, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa7, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xab, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa6, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_panel_S6E3HAB_AMB623TS01.c b/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_panel_S6E3HAB_AMB623TS01.c index 10bd6771f..b7cd137e6 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_panel_S6E3HAB_AMB623TS01.c +++ b/techpack/display/msm/samsung/S6E3HAB_AMB623TS01/ss_dsi_panel_S6E3HAB_AMB623TS01.c @@ -1747,7 +1747,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/dsi_panel_S6E3HAB_AMB677TY01_wqhd_octa_cmd.dtsi b/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/dsi_panel_S6E3HAB_AMB677TY01_wqhd_octa_cmd.dtsi index aaf501e02..388ceef0d 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/dsi_panel_S6E3HAB_AMB677TY01_wqhd_octa_cmd.dtsi +++ b/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/dsi_panel_S6E3HAB_AMB677TY01_wqhd_octa_cmd.dtsi @@ -1761,6 +1761,14 @@ 3 9400 25500 60 >; + samsung,aod_candela_map_table_jpn_revA = < + /* */ + 0 0 4899 2 + 1 4900 10399 10 + 2 10400 13399 30 + 3 13400 25500 60 + >; + samsung,hbm_candela_map_table_revA = < /* idx from end cd auto */ 0 258 260 405 6 diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_mdnie_S6E3HAB_AMB677TY01.h b/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_mdnie_S6E3HAB_AMB677TY01.h index ca91e9d9b..894bd8dc7 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_mdnie_S6E3HAB_AMB677TY01.h +++ b/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_mdnie_S6E3HAB_AMB677TY01.h @@ -88,6 +88,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xde, 0x00, 0xa1, 0x00, 0xff, 0x00, 0x00, 0xde, 0xa1, 0x00, 0xff, 0x00, 0xde, 0x00, 0x00, 0xa1, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x00, 0xff, 0xd1, 0x00, 0x83, 0x00, 0xff, 0x00, 0x00, 0xd1, 0x83, 0x00, 0xff, 0x00, 0xd1, 0x00, 0x00, 0x83, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x30, 0xf1, 0xfc, 0x0a, 0xf4, 0x00, 0xf1, 0x1d, 0x00, 0xf8, 0xed, 0x00, 0xf8, 0x14, 0xf9, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xfc, 0x00, 0xf5, 0x00, /* 6500K */ 0x30, 0xf1, 0xfb, 0x0a, 0xf0, 0x00, 0xf1, 0x1d, 0x00, 0xf7, 0xe9, 0x00, 0xf8, 0x14, 0xf8, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xfb, 0x00, 0xf1, 0x00, /* 6300K */ 0x30, 0xf1, 0xfa, 0x0a, 0xec, 0x00, 0xf1, 0x1d, 0x00, 0xf6, 0xe6, 0x00, 0xf8, 0x14, 0xf7, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xfa, 0x00, 0xed, 0x00, /* 6100K */ @@ -99,6 +190,97 @@ static char night_mode_data[] = { 0x30, 0xf1, 0xde, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xdb, 0x9c, 0x00, 0xf8, 0x14, 0xdb, 0x00, 0x00, 0x99, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x30, 0xf1, 0xd1, 0x08, 0x82, 0x00, 0xf1, 0x1d, 0x00, 0xce, 0x7f, 0x00, 0xf8, 0x14, 0xcf, 0x00, 0x00, 0x7d, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x30, 0xf1, 0xba, 0x07, 0x5d, 0x00, 0xf1, 0x1d, 0x00, 0xb7, 0x5a, 0x00, 0xf8, 0x14, 0xb8, 0x00, 0x00, 0x59, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xda, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd3, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd2, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd5, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xcf, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd0, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xca, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcb, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc1, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc5, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbf, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc4, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbe, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc2, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbc, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc0, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xba, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xbf, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xb9, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbd, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbc, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb7, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xba, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb5, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xb9, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb4, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb1, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb8, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb3, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xb0, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb7, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb2, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xaf, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb5, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xb0, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xad, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb4, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xaf, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xac, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb3, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xae, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb2, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xad, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xaa, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xac, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xae, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa9, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xad, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa8, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xac, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa7, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xab, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa6, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_panel_S6E3HAB_AMB677TY01.c b/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_panel_S6E3HAB_AMB677TY01.c index 91fb126af..1c679c61e 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_panel_S6E3HAB_AMB677TY01.c +++ b/techpack/display/msm/samsung/S6E3HAB_AMB677TY01/ss_dsi_panel_S6E3HAB_AMB677TY01.c @@ -1747,7 +1747,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_mdnie_S6E3HAB_AMB687TZ01.h b/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_mdnie_S6E3HAB_AMB687TZ01.h index 2b5c11666..e76b7c4c4 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_mdnie_S6E3HAB_AMB687TZ01.h +++ b/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_mdnie_S6E3HAB_AMB687TZ01.h @@ -87,7 +87,98 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe7, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xbb, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe7, 0x00, 0xbb, 0x00, /* 4300K */ 0x00, 0xff, 0xde, 0x00, 0xa1, 0x00, 0xff, 0x00, 0x00, 0xde, 0xa1, 0x00, 0xff, 0x00, 0xde, 0x00, 0x00, 0xa1, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x00, 0xff, 0xd1, 0x00, 0x83, 0x00, 0xff, 0x00, 0x00, 0xd1, 0x83, 0x00, 0xff, 0x00, 0xd1, 0x00, 0x00, 0x83, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ - 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x30, 0xf1, 0xfc, 0x0a, 0xf4, 0x00, 0xf1, 0x1d, 0x00, 0xf8, 0xed, 0x00, 0xf8, 0x14, 0xf9, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xfc, 0x00, 0xf5, 0x00, /* 6500K */ 0x30, 0xf1, 0xfb, 0x0a, 0xf0, 0x00, 0xf1, 0x1d, 0x00, 0xf7, 0xe9, 0x00, 0xf8, 0x14, 0xf8, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xfb, 0x00, 0xf1, 0x00, /* 6300K */ 0x30, 0xf1, 0xfa, 0x0a, 0xec, 0x00, 0xf1, 0x1d, 0x00, 0xf6, 0xe6, 0x00, 0xf8, 0x14, 0xf7, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xfa, 0x00, 0xed, 0x00, /* 6100K */ @@ -99,6 +190,97 @@ static char night_mode_data[] = { 0x30, 0xf1, 0xde, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xdb, 0x9c, 0x00, 0xf8, 0x14, 0xdb, 0x00, 0x00, 0x99, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x30, 0xf1, 0xd1, 0x08, 0x82, 0x00, 0xf1, 0x1d, 0x00, 0xce, 0x7f, 0x00, 0xf8, 0x14, 0xcf, 0x00, 0x00, 0x7d, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x30, 0xf1, 0xba, 0x07, 0x5d, 0x00, 0xf1, 0x1d, 0x00, 0xb7, 0x5a, 0x00, 0xf8, 0x14, 0xb8, 0x00, 0x00, 0x59, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xda, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd3, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd2, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd5, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xcf, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd0, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xca, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcb, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc1, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc5, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbf, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc4, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbe, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc2, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbc, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc0, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xba, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xbf, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xb9, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbd, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbc, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb7, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xba, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb5, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xb9, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb4, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb1, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb8, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb3, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xb0, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb7, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb2, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xaf, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb5, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xb0, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xad, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb4, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xaf, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xac, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb3, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xae, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb2, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xad, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xaa, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xac, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xae, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa9, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xad, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa8, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xac, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa7, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xab, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa6, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_panel_S6E3HAB_AMB687TZ01.c b/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_panel_S6E3HAB_AMB687TZ01.c index c4f4eaaf5..38676b3cd 100644 --- a/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_panel_S6E3HAB_AMB687TZ01.c +++ b/techpack/display/msm/samsung/S6E3HAB_AMB687TZ01/ss_dsi_panel_S6E3HAB_AMB687TZ01.c @@ -1753,7 +1753,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_mdnie_S6E3HAC_AMB687VX01.h b/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_mdnie_S6E3HAC_AMB687VX01.h index fc3f7d088..8e72d0a0a 100644 --- a/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_mdnie_S6E3HAC_AMB687VX01.h +++ b/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_mdnie_S6E3HAC_AMB687VX01.h @@ -88,6 +88,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xde, 0x00, 0xa1, 0x00, 0xff, 0x00, 0x00, 0xde, 0xa1, 0x00, 0xff, 0x00, 0xde, 0x00, 0x00, 0xa1, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x00, 0xff, 0xd1, 0x00, 0x83, 0x00, 0xff, 0x00, 0x00, 0xd1, 0x83, 0x00, 0xff, 0x00, 0xd1, 0x00, 0x00, 0x83, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x30, 0xf1, 0xfc, 0x0a, 0xf4, 0x00, 0xf1, 0x1d, 0x00, 0xf8, 0xed, 0x00, 0xf8, 0x14, 0xf9, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xfc, 0x00, 0xf5, 0x00, /* 6500K */ 0x30, 0xf1, 0xfb, 0x0a, 0xf0, 0x00, 0xf1, 0x1d, 0x00, 0xf7, 0xe9, 0x00, 0xf8, 0x14, 0xf8, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xfb, 0x00, 0xf1, 0x00, /* 6300K */ 0x30, 0xf1, 0xfa, 0x0a, 0xec, 0x00, 0xf1, 0x1d, 0x00, 0xf6, 0xe6, 0x00, 0xf8, 0x14, 0xf7, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xfa, 0x00, 0xed, 0x00, /* 6100K */ @@ -99,6 +190,97 @@ static char night_mode_data[] = { 0x30, 0xf1, 0xde, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xdb, 0x9c, 0x00, 0xf8, 0x14, 0xdb, 0x00, 0x00, 0x99, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x30, 0xf1, 0xd1, 0x08, 0x82, 0x00, 0xf1, 0x1d, 0x00, 0xce, 0x7f, 0x00, 0xf8, 0x14, 0xcf, 0x00, 0x00, 0x7d, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x30, 0xf1, 0xba, 0x07, 0x5d, 0x00, 0xf1, 0x1d, 0x00, 0xb7, 0x5a, 0x00, 0xf8, 0x14, 0xb8, 0x00, 0x00, 0x59, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xda, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd3, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd2, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd5, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xcf, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd0, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xca, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcb, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc1, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc5, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbf, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc4, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbe, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc2, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbc, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc0, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xba, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xbf, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xb9, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbd, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbc, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb7, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xba, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb5, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xb9, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb4, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb1, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb8, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb3, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xb0, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb7, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb2, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xaf, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb5, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xb0, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xad, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb4, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xaf, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xac, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb3, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xae, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb2, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xad, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xaa, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xac, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xae, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa9, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xad, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa8, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xac, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa7, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xab, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa6, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_panel_S6E3HAC_AMB687VX01.c b/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_panel_S6E3HAC_AMB687VX01.c index 905d0e7f5..068c9a346 100644 --- a/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_panel_S6E3HAC_AMB687VX01.c +++ b/techpack/display/msm/samsung/S6E3HAC_AMB687VX01/ss_dsi_panel_S6E3HAC_AMB687VX01.c @@ -2156,7 +2156,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_mdnie_S6E3XA0_AMB729WA01.h b/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_mdnie_S6E3XA0_AMB729WA01.h index 10a2e0772..9040b1f2c 100644 --- a/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_mdnie_S6E3XA0_AMB729WA01.h +++ b/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_mdnie_S6E3XA0_AMB729WA01.h @@ -88,7 +88,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe2, 0x00, 0xa8, 0x00, 0xff, 0x00, 0x00, 0xe2, 0xa8, 0x00, 0xff, 0x00, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe2, 0x00, 0xa8, 0x00, /* 3700K */ 0x00, 0xff, 0xd7, 0x00, 0x89, 0x00, 0xff, 0x00, 0x00, 0xd7, 0x89, 0x00, 0xff, 0x00, 0xd7, 0x00, 0x00, 0x89, 0xff, 0x00, 0xd7, 0x00, 0x89, 0x00, /* 3100K */ 0x00, 0xff, 0xbd, 0x00, 0x60, 0x00, 0xff, 0x00, 0x00, 0xbd, 0x60, 0x00, 0xff, 0x00, 0xbd, 0x00, 0x00, 0x60, 0xff, 0x00, 0xbd, 0x00, 0x60, 0x00, /* 2300K */ - 0x00, 0xff, 0xfe, 0x00, 0xfb, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xfb, 0x00, 0xff, 0x00, 0xfe, 0x00, 0x00, 0xfb, 0xff, 0x00, 0xfe, 0x00, 0xfb, 0x00, /* GAME_MODE */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xfb, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xfb, 0x00, 0xff, 0x00, 0xfe, 0x00, 0x00, 0xfb, 0xff, 0x00, 0xfe, 0x00, 0xfb, 0x00, /* 6750K */ 0x00, 0xff, 0xfd, 0x00, 0xf8, 0x00, 0xff, 0x00, 0x00, 0xfd, 0xf8, 0x00, 0xff, 0x00, 0xfd, 0x00, 0x00, 0xf8, 0xff, 0x00, 0xfd, 0x00, 0xf8, 0x00, /* 6500K */ 0x00, 0xff, 0xfc, 0x00, 0xf4, 0x00, 0xff, 0x00, 0x00, 0xfc, 0xf4, 0x00, 0xff, 0x00, 0xfc, 0x00, 0x00, 0xf4, 0xff, 0x00, 0xfc, 0x00, 0xf4, 0x00, /* 6250K */ @@ -100,7 +190,97 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe2, 0x00, 0xa8, 0x00, 0xff, 0x00, 0x00, 0xe2, 0xa8, 0x00, 0xff, 0x00, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe2, 0x00, 0xa8, 0x00, /* 3700K */ 0x00, 0xff, 0xd7, 0x00, 0x89, 0x00, 0xff, 0x00, 0x00, 0xd7, 0x89, 0x00, 0xff, 0x00, 0xd7, 0x00, 0x00, 0x89, 0xff, 0x00, 0xd7, 0x00, 0x89, 0x00, /* 3100K */ 0x00, 0xff, 0xbd, 0x00, 0x60, 0x00, 0xff, 0x00, 0x00, 0xbd, 0x60, 0x00, 0xff, 0x00, 0xbd, 0x00, 0x00, 0x60, 0xff, 0x00, 0xbd, 0x00, 0x60, 0x00, /* 2300K */ - 0x00, 0xff, 0xfe, 0x00, 0xfb, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xfb, 0x00, 0xff, 0x00, 0xfe, 0x00, 0x00, 0xfb, 0xff, 0x00, 0xfe, 0x00, 0xfb, 0x00, /* GAME_MODE */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_panel_S6E3XA0_AMB729WA01.c b/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_panel_S6E3XA0_AMB729WA01.c index 0abab91ca..61d9fcda8 100644 --- a/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_panel_S6E3XA0_AMB729WA01.c +++ b/techpack/display/msm/samsung/S6E3XA0_AMB729WA01/ss_dsi_panel_S6E3XA0_AMB729WA01.c @@ -1365,7 +1365,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 12; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/dsi_panel_S6E3XA1_AMF759VG01_qxga_octa_cmd.dtsi b/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/dsi_panel_S6E3XA1_AMF759VG01_qxga_octa_cmd.dtsi index aea1c8f71..cb517e98d 100755 --- a/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/dsi_panel_S6E3XA1_AMF759VG01_qxga_octa_cmd.dtsi +++ b/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/dsi_panel_S6E3XA1_AMF759VG01_qxga_octa_cmd.dtsi @@ -23,8 +23,8 @@ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; qcom,mdss-dsi-bl-min-level = <1>; - qcom,mdss-dsi-bl-max-level = <400>; - qcom,mdss-brightness-max-level = <400>; + qcom,mdss-dsi-bl-max-level = <453>; + qcom,mdss-brightness-max-level = <453>; qcom,mdss-brightness-default-level = <255>; qcom,mdss-dsi-interleave-mode = <0>; qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; @@ -1254,7 +1254,7 @@ 141 397 397 1002 695 0 142 398 398 1009 697 0 143 399 399 1016 698 0 - 144 400 400 1023 700 0 + 144 400 453 1023 700 0 >; samsung,aod_candela_map_table_revA = < diff --git a/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_mdnie_S6E3XA1_AMF759VG01.h b/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_mdnie_S6E3XA1_AMF759VG01.h index d76f5590a..11bcd8d53 100755 --- a/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_mdnie_S6E3XA1_AMF759VG01.h +++ b/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_mdnie_S6E3XA1_AMF759VG01.h @@ -87,7 +87,98 @@ static char night_mode_data[] = { 0x00, 0xff, 0xe7, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xbb, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe7, 0x00, 0xbb, 0x00, /* 4300K */ 0x00, 0xff, 0xde, 0x00, 0xa1, 0x00, 0xff, 0x00, 0x00, 0xde, 0xa1, 0x00, 0xff, 0x00, 0xde, 0x00, 0x00, 0xa1, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x00, 0xff, 0xd1, 0x00, 0x83, 0x00, 0xff, 0x00, 0x00, 0xd1, 0x83, 0x00, 0xff, 0x00, 0xd1, 0x00, 0x00, 0x83, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ - 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xba, 0x00, 0x5d, 0x00, 0xff, 0x00, 0x00, 0xba, 0x5d, 0x00, 0xff, 0x00, 0xba, 0x00, 0x00, 0x5d, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xed, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xed, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xed, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf9, 0x00, 0xec, 0x00, 0xff, 0x00, 0x00, 0xf9, 0xec, 0x00, 0xff, 0x00, 0xf9, 0x00, 0x00, 0xec, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xeb, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xeb, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xeb, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xea, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xea, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xea, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf8, 0x00, 0xe9, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xe9, 0x00, 0xff, 0x00, 0xf8, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe8, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe8, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe8, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe7, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe7, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe7, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf7, 0x00, 0xe6, 0x00, 0xff, 0x00, 0x00, 0xf7, 0xe6, 0x00, 0xff, 0x00, 0xf7, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe5, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe5, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe5, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe4, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe4, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe4, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe3, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe3, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe3, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x00, 0xff, 0xf6, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf6, 0xe2, 0x00, 0xff, 0x00, 0xf6, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe2, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe2, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe1, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe1, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe1, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xe0, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xe0, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xe0, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x00, 0xff, 0xf5, 0x00, 0xdf, 0x00, 0xff, 0x00, 0x00, 0xf5, 0xdf, 0x00, 0xff, 0x00, 0xf5, 0x00, 0x00, 0xdf, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xde, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xde, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xde, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdd, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdd, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdd, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf4, 0x00, 0xdc, 0x00, 0xff, 0x00, 0x00, 0xf4, 0xdc, 0x00, 0xff, 0x00, 0xf4, 0x00, 0x00, 0xdc, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xdb, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xdb, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xdb, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xda, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xda, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xda, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf3, 0x00, 0xd9, 0x00, 0xff, 0x00, 0x00, 0xf3, 0xd9, 0x00, 0xff, 0x00, 0xf3, 0x00, 0x00, 0xd9, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd8, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd8, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf2, 0x00, 0xd7, 0x00, 0xff, 0x00, 0x00, 0xf2, 0xd7, 0x00, 0xff, 0x00, 0xf2, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd6, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd6, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd5, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd5, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf1, 0x00, 0xd4, 0x00, 0xff, 0x00, 0x00, 0xf1, 0xd4, 0x00, 0xff, 0x00, 0xf1, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd3, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd3, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xf0, 0x00, 0xd2, 0x00, 0xff, 0x00, 0x00, 0xf0, 0xd2, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd1, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd1, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xd0, 0x00, 0xff, 0x00, 0x00, 0xef, 0xd0, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xef, 0x00, 0xcf, 0x00, 0xff, 0x00, 0x00, 0xef, 0xcf, 0x00, 0xff, 0x00, 0xef, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xce, 0x00, 0xff, 0x00, 0x00, 0xee, 0xce, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xce, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcd, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcd, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xee, 0x00, 0xcc, 0x00, 0xff, 0x00, 0x00, 0xee, 0xcc, 0x00, 0xff, 0x00, 0xee, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xcb, 0x00, 0xff, 0x00, 0x00, 0xed, 0xcb, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xca, 0x00, 0xff, 0x00, 0x00, 0xed, 0xca, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xca, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc9, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc9, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x00, 0xff, 0xed, 0x00, 0xc8, 0x00, 0xff, 0x00, 0x00, 0xed, 0xc8, 0x00, 0xff, 0x00, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc7, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc7, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc6, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc6, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x00, 0xff, 0xec, 0x00, 0xc5, 0x00, 0xff, 0x00, 0x00, 0xec, 0xc5, 0x00, 0xff, 0x00, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc4, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc4, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc3, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc3, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x00, 0xff, 0xeb, 0x00, 0xc2, 0x00, 0xff, 0x00, 0x00, 0xeb, 0xc2, 0x00, 0xff, 0x00, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc1, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc1, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xc0, 0x00, 0xff, 0x00, 0x00, 0xea, 0xc0, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xea, 0x00, 0xbf, 0x00, 0xff, 0x00, 0x00, 0xea, 0xbf, 0x00, 0xff, 0x00, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbe, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbe, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbd, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbd, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbc, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbc, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x00, 0xff, 0xe9, 0x00, 0xbb, 0x00, 0xff, 0x00, 0x00, 0xe9, 0xbb, 0x00, 0xff, 0x00, 0xe9, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xba, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xba, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb9, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb9, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x00, 0xff, 0xe8, 0x00, 0xb8, 0x00, 0xff, 0x00, 0x00, 0xe8, 0xb8, 0x00, 0xff, 0x00, 0xe8, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb7, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb7, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb6, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb6, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x00, 0xff, 0xe7, 0x00, 0xb5, 0x00, 0xff, 0x00, 0x00, 0xe7, 0xb5, 0x00, 0xff, 0x00, 0xe7, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x00, 0xff, 0xe6, 0x00, 0xb3, 0x00, 0xff, 0x00, 0x00, 0xe6, 0xb3, 0x00, 0xff, 0x00, 0xe6, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, 0x30, 0xf1, 0xfc, 0x0a, 0xf4, 0x00, 0xf1, 0x1d, 0x00, 0xf8, 0xed, 0x00, 0xf8, 0x14, 0xf9, 0x00, 0x00, 0xe9, 0xff, 0x00, 0xfc, 0x00, 0xf5, 0x00, /* 6500K */ 0x30, 0xf1, 0xfb, 0x0a, 0xf0, 0x00, 0xf1, 0x1d, 0x00, 0xf7, 0xe9, 0x00, 0xf8, 0x14, 0xf8, 0x00, 0x00, 0xe6, 0xff, 0x00, 0xfb, 0x00, 0xf1, 0x00, /* 6300K */ 0x30, 0xf1, 0xfa, 0x0a, 0xec, 0x00, 0xf1, 0x1d, 0x00, 0xf6, 0xe6, 0x00, 0xf8, 0x14, 0xf7, 0x00, 0x00, 0xe2, 0xff, 0x00, 0xfa, 0x00, 0xed, 0x00, /* 6100K */ @@ -99,6 +190,97 @@ static char night_mode_data[] = { 0x30, 0xf1, 0xde, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xdb, 0x9c, 0x00, 0xf8, 0x14, 0xdb, 0x00, 0x00, 0x99, 0xff, 0x00, 0xde, 0x00, 0xa1, 0x00, /* 3700K */ 0x30, 0xf1, 0xd1, 0x08, 0x82, 0x00, 0xf1, 0x1d, 0x00, 0xce, 0x7f, 0x00, 0xf8, 0x14, 0xcf, 0x00, 0x00, 0x7d, 0xff, 0x00, 0xd1, 0x00, 0x83, 0x00, /* 3100K */ 0x30, 0xf1, 0xba, 0x07, 0x5d, 0x00, 0xf1, 0x1d, 0x00, 0xb7, 0x5a, 0x00, 0xf8, 0x14, 0xb8, 0x00, 0x00, 0x59, 0xff, 0x00, 0xba, 0x00, 0x5d, 0x00, /* 2300K */ + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe2, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdc, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd8, 0xff, 0x00, 0xf9, 0x00, 0xed, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf6, 0x09, 0xe1, 0x00, 0xf1, 0x1d, 0x00, 0xf2, 0xdb, 0x00, 0xf8, 0x14, 0xf3, 0x00, 0x00, 0xd7, 0xff, 0x00, 0xf9, 0x00, 0xec, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xe0, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xda, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd6, 0xff, 0x00, 0xf8, 0x00, 0xeb, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xdf, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd9, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd5, 0xff, 0x00, 0xf8, 0x00, 0xea, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf5, 0x09, 0xde, 0x00, 0xf1, 0x1d, 0x00, 0xf1, 0xd8, 0x00, 0xf8, 0x14, 0xf2, 0x00, 0x00, 0xd4, 0xff, 0x00, 0xf8, 0x00, 0xe9, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd7, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe8, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdd, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd6, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd3, 0xff, 0x00, 0xf7, 0x00, 0xe7, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf4, 0x09, 0xdc, 0x00, 0xf1, 0x1d, 0x00, 0xf0, 0xd5, 0x00, 0xf8, 0x14, 0xf1, 0x00, 0x00, 0xd2, 0xff, 0x00, 0xf7, 0x00, 0xe6, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xdb, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd4, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd1, 0xff, 0x00, 0xf6, 0x00, 0xe5, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xda, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd3, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xd0, 0xff, 0x00, 0xf6, 0x00, 0xe4, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd9, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xcf, 0xff, 0x00, 0xf6, 0x00, 0xe3, 0x00, + 0x30, 0xf1, 0xf3, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xef, 0xd2, 0x00, 0xf8, 0x14, 0xf0, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf6, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd8, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd2, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xce, 0xff, 0x00, 0xf5, 0x00, 0xe2, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd7, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd1, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcd, 0xff, 0x00, 0xf5, 0x00, 0xe1, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd6, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xd0, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcc, 0xff, 0x00, 0xf5, 0x00, 0xe0, 0x00, + 0x30, 0xf1, 0xf2, 0x09, 0xd5, 0x00, 0xf1, 0x1d, 0x00, 0xee, 0xcf, 0x00, 0xf8, 0x14, 0xef, 0x00, 0x00, 0xcb, 0xff, 0x00, 0xf5, 0x00, 0xdf, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd4, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xce, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xca, 0xff, 0x00, 0xf4, 0x00, 0xde, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd3, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcd, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdd, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf1, 0x09, 0xd2, 0x00, 0xf1, 0x1d, 0x00, 0xed, 0xcc, 0x00, 0xf8, 0x14, 0xee, 0x00, 0x00, 0xc9, 0xff, 0x00, 0xf4, 0x00, 0xdc, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd1, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xcb, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc8, 0xff, 0x00, 0xf3, 0x00, 0xdb, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xd0, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xca, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc7, 0xff, 0x00, 0xf3, 0x00, 0xda, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xf0, 0x09, 0xcf, 0x00, 0xf1, 0x1d, 0x00, 0xec, 0xc9, 0x00, 0xf8, 0x14, 0xed, 0x00, 0x00, 0xc6, 0xff, 0x00, 0xf3, 0x00, 0xd9, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xce, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc8, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc5, 0xff, 0x00, 0xf2, 0x00, 0xd8, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xef, 0x09, 0xcd, 0x00, 0xf1, 0x1d, 0x00, 0xeb, 0xc7, 0x00, 0xf8, 0x14, 0xec, 0x00, 0x00, 0xc4, 0xff, 0x00, 0xf2, 0x00, 0xd7, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcc, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc6, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xf1, 0x00, 0xd6, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xcb, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc2, 0xff, 0x00, 0xf1, 0x00, 0xd5, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xee, 0x09, 0xca, 0x00, 0xf1, 0x1d, 0x00, 0xea, 0xc5, 0x00, 0xf8, 0x14, 0xeb, 0x00, 0x00, 0xc1, 0xff, 0x00, 0xf1, 0x00, 0xd4, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc9, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc4, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xc0, 0xff, 0x00, 0xf0, 0x00, 0xd3, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xed, 0x09, 0xc8, 0x00, 0xf1, 0x1d, 0x00, 0xe9, 0xc3, 0x00, 0xf8, 0x14, 0xea, 0x00, 0x00, 0xbf, 0xff, 0x00, 0xf0, 0x00, 0xd2, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc2, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd1, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc7, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc1, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbe, 0xff, 0x00, 0xef, 0x00, 0xd0, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xec, 0x09, 0xc6, 0x00, 0xf1, 0x1d, 0x00, 0xe8, 0xc0, 0x00, 0xf8, 0x14, 0xe9, 0x00, 0x00, 0xbd, 0xff, 0x00, 0xef, 0x00, 0xcf, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc5, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbf, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbc, 0xff, 0x00, 0xee, 0x00, 0xce, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc4, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbe, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xbb, 0xff, 0x00, 0xee, 0x00, 0xcd, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xeb, 0x09, 0xc3, 0x00, 0xf1, 0x1d, 0x00, 0xe7, 0xbd, 0x00, 0xf8, 0x14, 0xe8, 0x00, 0x00, 0xba, 0xff, 0x00, 0xee, 0x00, 0xcc, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc2, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbc, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb9, 0xff, 0x00, 0xed, 0x00, 0xcb, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc1, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xbb, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb8, 0xff, 0x00, 0xed, 0x00, 0xca, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xc0, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xba, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb7, 0xff, 0x00, 0xed, 0x00, 0xc9, 0x00, + 0x30, 0xf1, 0xea, 0x09, 0xbf, 0x00, 0xf1, 0x1d, 0x00, 0xe6, 0xb9, 0x00, 0xf8, 0x14, 0xe7, 0x00, 0x00, 0xb6, 0xff, 0x00, 0xed, 0x00, 0xc8, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbe, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb5, 0xff, 0x00, 0xec, 0x00, 0xc7, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbd, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb8, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc6, 0x00, + 0x30, 0xf1, 0xe9, 0x09, 0xbc, 0x00, 0xf1, 0x1d, 0x00, 0xe5, 0xb7, 0x00, 0xf8, 0x14, 0xe6, 0x00, 0x00, 0xb4, 0xff, 0x00, 0xec, 0x00, 0xc5, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xbb, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb6, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb3, 0xff, 0x00, 0xeb, 0x00, 0xc4, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xba, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb5, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb2, 0xff, 0x00, 0xeb, 0x00, 0xc3, 0x00, + 0x30, 0xf1, 0xe8, 0x09, 0xb9, 0x00, 0xf1, 0x1d, 0x00, 0xe4, 0xb4, 0x00, 0xf8, 0x14, 0xe5, 0x00, 0x00, 0xb1, 0xff, 0x00, 0xeb, 0x00, 0xc2, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb8, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb3, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xb0, 0xff, 0x00, 0xea, 0x00, 0xc1, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb7, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb2, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xaf, 0xff, 0x00, 0xea, 0x00, 0xc0, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe7, 0x09, 0xb6, 0x00, 0xf1, 0x1d, 0x00, 0xe3, 0xb1, 0x00, 0xf8, 0x14, 0xe4, 0x00, 0x00, 0xae, 0xff, 0x00, 0xea, 0x00, 0xbf, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb5, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xb0, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xad, 0xff, 0x00, 0xe9, 0x00, 0xbe, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb4, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xaf, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xac, 0xff, 0x00, 0xe9, 0x00, 0xbd, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb3, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xae, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xab, 0xff, 0x00, 0xe9, 0x00, 0xbc, 0x00, + 0x30, 0xf1, 0xe6, 0x09, 0xb2, 0x00, 0xf1, 0x1d, 0x00, 0xe2, 0xad, 0x00, 0xf8, 0x14, 0xe3, 0x00, 0x00, 0xaa, 0xff, 0x00, 0xe9, 0x00, 0xbb, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xac, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xba, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xb1, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa9, 0xff, 0x00, 0xe8, 0x00, 0xb9, 0x00, + 0x30, 0xf1, 0xe5, 0x09, 0xa0, 0x00, 0xf1, 0x1d, 0x00, 0xe1, 0xab, 0x00, 0xf8, 0x14, 0xe2, 0x00, 0x00, 0xa8, 0xff, 0x00, 0xe8, 0x00, 0xb8, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xaf, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xaa, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa7, 0xff, 0x00, 0xe7, 0x00, 0xb7, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xae, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa9, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa6, 0xff, 0x00, 0xe7, 0x00, 0xb6, 0x00, + 0x30, 0xf1, 0xe4, 0x09, 0xad, 0x00, 0xf1, 0x1d, 0x00, 0xe0, 0xa8, 0x00, 0xf8, 0x14, 0xe1, 0x00, 0x00, 0xa5, 0xff, 0x00, 0xe7, 0x00, 0xb5, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xac, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa7, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa4, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, + 0x30, 0xf1, 0xe3, 0x09, 0xab, 0x00, 0xf1, 0x1d, 0x00, 0xdf, 0xa6, 0x00, 0xf8, 0x14, 0xe0, 0x00, 0x00, 0xa3, 0xff, 0x00, 0xe6, 0x00, 0xb3, 0x00, }; static char color_lens_data[] = { diff --git a/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_panel_S6E3XA1_AMF759VG01.c b/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_panel_S6E3XA1_AMF759VG01.c index caebae354..6b3bf25e8 100755 --- a/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_panel_S6E3XA1_AMF759VG01.c +++ b/techpack/display/msm/samsung/S6E3XA1_AMF759VG01/ss_dsi_panel_S6E3XA1_AMF759VG01.c @@ -1392,7 +1392,7 @@ static int dsi_update_mdnie_data(struct samsung_display_driver_data *vdd) mdnie_data->dsi_adjust_ldu_table = adjust_ldu_data; mdnie_data->dsi_max_adjust_ldu = 6; mdnie_data->dsi_night_mode_table = night_mode_data; - mdnie_data->dsi_max_night_mode_index = 11; + mdnie_data->dsi_max_night_mode_index = 102; mdnie_data->dsi_color_lens_table = color_lens_data; mdnie_data->dsi_white_default_r = 0xff; mdnie_data->dsi_white_default_g = 0xff; diff --git a/techpack/display/msm/samsung/S6TUUM3_AMSA24VU01/ss_dsi_panel_S6TUUM3_AMSA24VU01.c b/techpack/display/msm/samsung/S6TUUM3_AMSA24VU01/ss_dsi_panel_S6TUUM3_AMSA24VU01.c index 75ffa2c42..78ef0928a 100755 --- a/techpack/display/msm/samsung/S6TUUM3_AMSA24VU01/ss_dsi_panel_S6TUUM3_AMSA24VU01.c +++ b/techpack/display/msm/samsung/S6TUUM3_AMSA24VU01/ss_dsi_panel_S6TUUM3_AMSA24VU01.c @@ -46,6 +46,12 @@ ktime_t time_vrr; int init_smooth_off; int poc_done; +/* Add finger_exit_cnt flag to keep smooth off + * until 2nd brightness event comes from HBM->Normal + * after finger_mask_updated. + */ +static bool finger_exit_cnt; + static struct dsi_panel_cmd_set *__ss_vrr(struct samsung_display_driver_data *vdd, int *level_key, bool is_hbm, bool is_hmt) { @@ -637,6 +643,7 @@ static int samsung_panel_on_pre(struct samsung_display_driver_data *vdd) prev_refresh_rate = 0; /* make previous refresh_rate 0 before start */ time_vrr = 0; /* make timestamp 0 for freq calculation */ init_smooth_off = 1; + finger_exit_cnt = 0; if (vdd->manufacture_id_dsi > 0x801413) {/* Support Samsung IP if higher revision*/ LCD_INFO("Support mdnie, selfmask.\n"); @@ -809,10 +816,11 @@ static struct dsi_panel_cmd_set * ss_brightness_gamma_mode2_normal(struct samsun pcmds = ss_get_cmds(vdd, TX_GAMMA_MODE2_NORMAL); - LCD_INFO("Normal : bl_level:%d, prev_bl:%d, finger:%d Pstate:%d(2:on),%d,%d\n", - vdd->br_info.common_br.bl_level, prev_bl_s6tuum3, vdd->finger_mask_updated, + LCD_INFO("Normal : bl_level:%d, prev_bl:%d, finger:%d exit_cnt:%d Pstate:%d(2:on),%d,%d\n", + vdd->br_info.common_br.bl_level, prev_bl_s6tuum3, vdd->finger_mask_updated, finger_exit_cnt, vdd->panel_state, vdd->display_status_dsi.wait_disp_on, init_smooth_off); - if (vdd->finger_mask_updated) + + if (vdd->finger_mask_updated || finger_exit_cnt) pcmds->cmds[2].msg.tx_buf[1] = 0x20; else if (vdd->display_status_dsi.wait_disp_on) pcmds->cmds[2].msg.tx_buf[1] = 0x20; @@ -834,6 +842,11 @@ static struct dsi_panel_cmd_set * ss_brightness_gamma_mode2_normal(struct samsun pcmds->cmds[1].msg.tx_buf[1] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 0, 8); /* DBV [7:0] */ pcmds->cmds[1].msg.tx_buf[2] = get_bit(vdd->br_info.common_br.gm2_wrdisbv, 8, 3); /* DBV [10:8] */ + if (vdd->finger_mask_updated) + finger_exit_cnt = 1; + else + finger_exit_cnt = 0; + *level_key = LEVEL_KEY_NONE; prev_bl_s6tuum3 = vdd->br_info.common_br.bl_level; diff --git a/techpack/display/msm/samsung/ss_dsi_mdnie_lite_common.c b/techpack/display/msm/samsung/ss_dsi_mdnie_lite_common.c index 479a82744..62a6e659b 100644 --- a/techpack/display/msm/samsung/ss_dsi_mdnie_lite_common.c +++ b/techpack/display/msm/samsung/ss_dsi_mdnie_lite_common.c @@ -205,8 +205,6 @@ int update_dsi_tcon_mdnie_register(struct samsung_display_driver_data *vdd) tune_data_dsi = mdnie_data->DSI_GRAYSCALE_NEGATIVE_MDNIE; } else if (tune->color_lens_enable == true) { tune_data_dsi = mdnie_data->DSI_COLOR_LENS_MDNIE; - } else if (tune->hdr) { - tune_data_dsi = mdnie_data->hdr_tune_value_dsi[tune->hdr]; } else if (tune->hmt_color_temperature) { tune_data_dsi = mdnie_data->hmt_color_temperature_tune_value_dsi[tune->hmt_color_temperature]; @@ -223,6 +221,8 @@ int update_dsi_tcon_mdnie_register(struct samsung_display_driver_data *vdd) } else { tune_data_dsi = mdnie_data->DSI_HBM_CE_D65_MDNIE; } + } else if (tune->hdr) { + tune_data_dsi = mdnie_data->hdr_tune_value_dsi[tune->hdr]; } else if (tune->mdnie_app == EMAIL_APP) { /* Some kind of panel doesn't suooprt EMAIL_APP mode, but SSRM module use same control logic. diff --git a/techpack/display/msm/samsung/ss_dsi_panel_common.c b/techpack/display/msm/samsung/ss_dsi_panel_common.c index b3fb08f7d..485bd6f4e 100644 --- a/techpack/display/msm/samsung/ss_dsi_panel_common.c +++ b/techpack/display/msm/samsung/ss_dsi_panel_common.c @@ -2496,6 +2496,11 @@ int ss_panel_on_pre(struct samsung_display_driver_data *vdd) vdd->read_panel_status_from_lk = 1; } + if (vdd->skip_read_on_pre) { + LCD_INFO("Skip read operation in on_pre\n"); + goto skip_read; + } + /* Module info */ if (!vdd->module_info_loaded_dsi) { if (IS_ERR_OR_NULL(vdd->panel_func.samsung_module_info_read)) @@ -2680,6 +2685,7 @@ int ss_panel_on_pre(struct samsung_display_driver_data *vdd) } } +skip_read: if (!IS_ERR_OR_NULL(vdd->panel_func.samsung_panel_on_pre)) vdd->panel_func.samsung_panel_on_pre(vdd); @@ -3715,10 +3721,20 @@ static void ss_panel_parse_dt_bright_tables(struct device_node *np, "samsung,candela_map_table_rev", panel_rev, ss_parse_candella_mapping_table); +#if (defined(CONFIG_MACH_X1Q_JPN_SINGLE) || \ + (defined(CONFIG_MACH_Y2Q_JPN_SINGLE) && !defined(CONFIG_MACH_Y2Q_JPN_DCMOLY)) || \ + defined(CONFIG_MACH_BLOOMXQ_JPN_SINGLE)) + LCD_INFO("parse jpn AOD brightness table\n"); + parse_dt_data(np, &info->candela_map_table[AOD][panel_rev], + sizeof(struct candela_map_table), + "samsung,aod_candela_map_table_jpn_rev", panel_rev, + ss_parse_candella_mapping_table); +#else parse_dt_data(np, &info->candela_map_table[AOD][panel_rev], sizeof(struct candela_map_table), "samsung,aod_candela_map_table_rev", panel_rev, ss_parse_candella_mapping_table); +#endif parse_dt_data(np, &info->candela_map_table[HBM][panel_rev], sizeof(struct candela_map_table), @@ -4304,6 +4320,9 @@ static void ss_panel_parse_dt(struct samsung_display_driver_data *vdd) vdd->dtsi_data.panel_lpm_enable = of_property_read_bool(np, "samsung,panel-lpm-enable"); LCD_ERR("alpm enable %s\n", vdd->dtsi_data.panel_lpm_enable ? "enabled" : "disabled"); + vdd->skip_read_on_pre = of_property_read_bool(np, "samsung,skip_read_on_pre"); + LCD_ERR("Skip read on pre %s\n", vdd->skip_read_on_pre ? "enabled" : "disabled"); + /* Set HALL IC */ vdd->support_hall_ic = of_property_read_bool(np, "samsung,mdss_dsi_hall_ic_enable"); LCD_ERR("hall_ic %s\n", vdd->support_hall_ic ? "enabled" : "disabled"); @@ -7858,6 +7877,14 @@ int ss_early_display_init(struct samsung_display_driver_data *vdd) vdd->module_info_loaded_dsi = vdd->panel_func.samsung_module_info_read(vdd); } + /* MDNIE X,Y */ + if (!vdd->mdnie_loaded_dsi) { + if (IS_ERR_OR_NULL(vdd->panel_func.samsung_mdnie_read)) + LCD_ERR("no samsung_mdnie_read function\n"); + else + vdd->mdnie_loaded_dsi = vdd->panel_func.samsung_mdnie_read(vdd); + } + /* Panel Unique Cell ID */ if (!vdd->cell_id_loaded_dsi) { if (IS_ERR_OR_NULL(vdd->panel_func.samsung_cell_id_read)) diff --git a/techpack/display/msm/samsung/ss_dsi_panel_common.h b/techpack/display/msm/samsung/ss_dsi_panel_common.h index d83fcea72..e41adc377 100644 --- a/techpack/display/msm/samsung/ss_dsi_panel_common.h +++ b/techpack/display/msm/samsung/ss_dsi_panel_common.h @@ -1693,6 +1693,9 @@ struct samsung_display_driver_data { ktime_t sleep_out_time; ktime_t tx_set_on_time; + /* Some panel read operation should be called after on-command. */ + bool skip_read_on_pre; + /* Support Global Para */ int gpara; diff --git a/techpack/display/msm/samsung/ss_flash_table_data_common.c b/techpack/display/msm/samsung/ss_flash_table_data_common.c index 72acb798a..9170aaf48 100644 --- a/techpack/display/msm/samsung/ss_flash_table_data_common.c +++ b/techpack/display/msm/samsung/ss_flash_table_data_common.c @@ -52,6 +52,28 @@ static void init_br_info(struct samsung_display_driver_data *vdd, LCD_INFO("br_data_size (%d) = hbm_size (%d) + normal_size (%d) + hmd_size (%d)\n", gamma_tbl->br_data_size, hbm_size, normal_size, hmd_size); + /* In general gamma flash, HBM has no gamma data, but some DDI, like hubble HAB, it has 800nit gamma data + * for HBM mode.. And its gamma flash is way different from general gamma flash.. + * So, in general gamma flash calculation, br_data_size = 7358 bytes, + * but hubble DDI's real br_data_size = 7392.. + * In result, + * - out of bounds access: br_data_raw is allocated with 7358 bytes, but will be accessed with 7392 bytes.. + * - 48/96hz mode cannot have enough and right gamma flash raw data due to ss_copy_flash_gamma(). + * It is HMD AOR data area for HBM 48/96hz mode, and there is no scenario for this, so no impact to customer. + * To resolve this, update br_data_size with real flash size. + */ + if (!strcmp(vdd->br_info.flash_gamma_type, "flash")) { + int start_addr = gamma_tbl->flash_gamma_bank_start; + int end_addr = gamma_tbl->flash_gamma_bank_end; + int total_size = end_addr - start_addr + 1; + + if (gamma_tbl->br_data_size < total_size) { + LCD_INFO("flash size is greater than table size.. update: %d -> %d\n", + gamma_tbl->br_data_size, total_size); + gamma_tbl->br_data_size = total_size; + } + } + /* free alloc memory : test purpose for slab memory integrity */ diff --git a/techpack/display/msm/samsung/ss_interpolation_common.c b/techpack/display/msm/samsung/ss_interpolation_common.c index d8ee3309c..90c4f8307 100644 --- a/techpack/display/msm/samsung/ss_interpolation_common.c +++ b/techpack/display/msm/samsung/ss_interpolation_common.c @@ -817,7 +817,10 @@ static int gen_normal_interpolation_aor_gamma(struct samsung_display_driver_data vdd->panel_func.convert_GAMMA_to_V(min_gamma, min_gammaV); max_cd = normal_tbl->candela_table[reverse_loop]; - min_cd = normal_tbl->candela_table[reverse_loop + 1]; + if (reverse_loop == normal_table_size - 1) + min_cd = max_cd; + else + min_cd = normal_tbl->candela_table[reverse_loop + 1]; dimming_mode_curr = DIMMING_MODE_MAX; diff --git a/techpack/display/msm/samsung/ss_panel_notify.h b/techpack/display/msm/samsung/ss_panel_notify.h index c76b68477..fdf6430a9 100755 --- a/techpack/display/msm/samsung/ss_panel_notify.h +++ b/techpack/display/msm/samsung/ss_panel_notify.h @@ -55,6 +55,7 @@ struct panel_dms_data { int lfd_min_freq; int lfd_max_freq; int display_idx; + int finger_mask_hbm_on; }; enum panel_state { diff --git a/techpack/display/msm/sde/sde_encoder.c b/techpack/display/msm/sde/sde_encoder.c index 5bcd1b3e0..b644a973d 100644 --- a/techpack/display/msm/sde/sde_encoder.c +++ b/techpack/display/msm/sde/sde_encoder.c @@ -5026,12 +5026,6 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, bool needs_hw_reset = false, is_cmd_mode; int i, rc, ret = 0; struct msm_display_info *disp_info; -#if defined(CONFIG_DISPLAY_SAMSUNG) - /* DSC Mismatch Debug, Case #04007749*/ - struct sde_connector *sde_con; - struct dsi_display *display; - struct dsi_display_mode_priv_info *priv_info; -#endif if (!drm_enc || !params || !drm_enc->dev || !drm_enc->dev->dev_private) { @@ -5133,21 +5127,6 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, sde_configure_qdss(sde_enc, sde_enc->cur_master->hw_qdss, sde_enc->cur_master, sde_kms->qdss_enabled); -#if defined(CONFIG_DISPLAY_SAMSUNG) - /* DSC Mismatch Debug, Case #04007749*/ - sde_con = to_sde_connector(sde_enc->cur_master->connector); - display = sde_con->display; - priv_info = display->modes->priv_info; - - if (disp_info->intf_type == DRM_MODE_CONNECTOR_DSI && !_sde_encoder_is_dsc_enabled(drm_enc) && priv_info->dsc_enabled) { - pr_err("DSC is disabled\n"); - if (sde_enc && sde_enc->phys_encs[0] && sde_enc->phys_encs[0]->connector) { - SDE_EVT32(sde_connector_get_topology_name(sde_enc->phys_encs[0]->connector), 0x9999); - } - SDE_DBG_DUMP("all", "dbg_bus", "panic"); - } -#endif - end: SDE_ATRACE_END("sde_encoder_prepare_for_kickoff"); return ret;