commit dec6356988d77d1cd8f4d115f0f5f36e1e9a8725 Author: thead_admin Date: Tue Sep 13 10:34:53 2022 +0800 Linux_SDK_V0.9.5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed465b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +/.auto.deps +/.config.cmd +/.config.old +/..config.tmp +/.config +*.tmp +*.depend +*.o +*.a +*.o.d +*.o.cmd +*.a.cmd +*.ko.cmd +*.ko +*.mod +*.mod.c +*.mod.cmd +*.order +*.orig +Module.symvers +output/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f60c6fb --- /dev/null +++ b/Makefile @@ -0,0 +1,147 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +test = $(shell if [ -f "../.param" ]; then echo "exist"; else echo "noexist"; fi) +ifeq ("$(test)", "exist") + include ../.param +endif + +CONFIG_DRIVER_BUILD_PARAMS=KERNEL=$(LINUX_DIR) CROSS=$(CROSS_COMPILE) ARCH=$(ARCH) BOARD_NAME=$(BOARD_NAME) +CONFIG_LIB_BUILD_PARAMS=CROSS=$(CROSS_COMPILE) ARCH=$(ARCH) BOARD_NAME=$(BOARD_NAME) +CONFIG_TEST_BUILD_PARAMS=CROSS=$(CROSS_COMPILE) ARCH=$(ARCH) BOARD_NAME=$(BOARD_NAME) + +MODULE_NAME=BAREMETAL +BUILD_LOG_START="\033[47;30m>>> $(MODULE_NAME) $@ begin\033[0m" +BUILD_LOG_END ="\033[47;30m<<< $(MODULE_NAME) $@ end\033[0m" + +DIR_TARGET_BASE=bsp/baremetal +DIR_TARGET_LIB =bsp/baremetal/lib +DIR_TARGET_KO =bsp/baremetal/ko +DIR_TARGET_TEST=bsp/baremetal/test +DIR_TARGET_TOOLS=bsp/baremetal/tools + +# +# Do a parallel build with multiple jobs, based on the number of CPUs online +# in this system: 'make -j8' on a 8-CPU system, etc. +# +# (To override it, run 'make JOBS=1' and similar.) +# +ifeq ($(JOBS),) + JOBS := $(shell grep -c ^processor /proc/cpuinfo 2>/dev/null) + ifeq ($(JOBS),) + JOBS := 1 + endif +endif + +all: info lib driver test tools install_local_output install_rootfs +.PHONY: info driver lib test tools install_local_output install_rootfs \ + clean_driver clean_lib clean_test clean_tools clean_output clean + +info: + @echo $(BUILD_LOG_START) + @echo " ====== Build Info from repo project ======" + @echo " BUILDROOT_DIR="$(BUILDROOT_DIR) + @echo " CROSS_COMPILE="$(CROSS_COMPILE) + @echo " LINUX_DIR="$(LINUX_DIR) + @echo " ARCH="$(ARCH) + @echo " BOARD_NAME="$(BOARD_NAME) + @echo " KERNEL_ID="$(KERNELVERSION) + @echo " KERNEL_DIR="$(LINUX_DIR) + @echo " INSTALL_DIR_ROOTFS="$(INSTALL_DIR_ROOTFS) + @echo " INSTALL_DIR_SDK="$(INSTALL_DIR_SDK) + @echo " CONFIG_DRIVER_BUILD_PARAMS="$(CONFIG_DRIVER_BUILD_PARAMS) + @echo " CONFIG_LIB_BUILD_PARAMS="$(CONFIG_LIB_BUILD_PARAMS) + @echo " CONFIG_TEST_BUILD_PARAMS="$(CONFIG_TEST_BUILD_PARAMS) + @echo $(BUILD_LOG_END) + +driver: + @echo $(BUILD_LOG_START) + make -C driver/demo $(CONFIG_DRIVER_BUILD_PARAMS) + make -C driver/visys $(CONFIG_DRIVER_BUILD_PARAMS) #BUILD_TYPE=DEBUG + make -C driver/isp $(CONFIG_DRIVER_BUILD_PARAMS) + make -C driver/csi $(CONFIG_DRIVER_BUILD_PARAMS) BUILD_TYPE=DEBUG + @echo $(BUILD_LOG_END) + +clean_driver: + @echo $(BUILD_LOG_START) + make -C driver/demo $(CONFIG_DRIVER_BUILD_PARAMS) clean + make -C driver/visys $(CONFIG_DRIVER_BUILD_PARAMS) clean + make -C driver/isp $(CONFIG_DRIVER_BUILD_PARAMS) clean + make -C driver/csi $(CONFIG_DRIVER_BUILD_PARAMS) clean + @echo $(BUILD_LOG_END) + +lib: + @echo $(BUILD_LOG_START) + @echo $(BUILD_LOG_END) + +clean_lib: + @echo $(BUILD_LOG_START) + @echo $(BUILD_LOG_END) + +test: lib driver + @echo $(BUILD_LOG_START) + make -C test/visys + make -C test/csi + make -C test/isp + @echo $(BUILD_LOG_END) + +clean_test: + @echo $(BUILD_LOG_START) + make -C test/visys clean + make -C test/isp clean + @echo $(BUILD_LOG_END) + +tools: + @echo $(BUILD_LOG_START) + make -C tools/reg_analyzer -j $(JOBS) + @echo $(BUILD_LOG_END) + +clean_tools: + @echo $(BUILD_LOG_START) + make -C tools/reg_analyzer clean + make -C test/csi clean + make -C test/isp clean + @echo $(BUILD_LOG_END) + +install_local_output: driver lib test + @echo $(BUILD_LOG_START) + # driver files + mkdir -p ./output/rootfs/$(DIR_TARGET_KO) + cp -f ./driver/demo/*.ko ./output/rootfs/$(DIR_TARGET_KO) + cp -f ./driver/visys/*.ko ./output/rootfs/$(DIR_TARGET_KO) + cp -f ./driver/csi/*.ko ./output/rootfs/$(DIR_TARGET_KO) + cp -f ./driver/isp/*.ko ./output/rootfs/$(DIR_TARGET_KO) + # lib files + mkdir -p ./output/rootfs/$(DIR_TARGET_LIB) + # test files + mkdir -p ./output/rootfs/$(DIR_TARGET_TEST) + cp -rf ./test/visys/output/* ./output/rootfs/$(DIR_TARGET_TEST) + cp -rf ./test/isp/output/* ./output/rootfs/$(DIR_TARGET_TEST) + # tools files + mkdir -p ./output/rootfs/$(DIR_TARGET_TOOLS) + cp -f ./tools/reg_analyzer/output/* ./output/rootfs/$(DIR_TARGET_TOOLS) + cp -f ./test/csi/output/* ./output/rootfs/$(DIR_TARGET_TEST) + @if [ `command -v tree` != "" ]; then \ + tree ./output/rootfs -I 'sdk' | grep -v "\.json"; \ + echo "INFO: The files above, has filter out the sdk folder and .json files"; \ + fi + @echo $(BUILD_LOG_END) + +install_rootfs: install_local_output + @echo $(BUILD_LOG_START) +# cp -rf output/rootfs/* $(INSTALL_DIR_ROOTFS) + @echo $(BUILD_LOG_END) + +clean_output: + @echo $(BUILD_LOG_START) + rm -rf ./output + rm -rf $(INSTALL_DIR_ROOTFS)/$(DIR_TARGET_BASE) + @echo $(BUILD_LOG_END) + +clean: clean_output clean_driver clean_lib clean_test clean_tools + diff --git a/README.md b/README.md new file mode 100644 index 0000000..8d35b29 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# How to get the code +- git clone git@gitlab.alibaba-inc.com:thead-linux-private/bare-metal-drivers.git + +# How to build +## Build within repo project +- XX +## Build out of repo project +- YY + +# Description of each directories diff --git a/common/log_common.c b/common/log_common.c new file mode 100644 index 0000000..0061b14 --- /dev/null +++ b/common/log_common.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include +#include +#include + +#include "log_common.h" + +#define LOG_COLOR_RED_YELLO_BACK "\033[1;31;43m" +#define LOG_COLOR_RED "\033[2;31;49m" +#define LOG_COLOR_YELLOW "\033[2;33;49m" +#define LOG_COLOR_GREEN "\033[2;32;49m" +#define LOG_COLOR_GRAY "\033[1;30m" +#define LOG_COLOR_RESET "\033[0m" + +static char sprint_green_buf[1024]=LOG_COLOR_GREEN; +int printf_green(char *fmt, ...) +{ + va_list args; + int n; + + int color_len = strlen(LOG_COLOR_GREEN); + + va_start(args, fmt); + n = vsprintf(sprint_green_buf+color_len, fmt, args); + va_end(args); + + memcpy(sprint_green_buf+color_len+n, LOG_COLOR_RESET, strlen(LOG_COLOR_RESET)+1); + + printf("%s", sprint_green_buf); + return n; +} + +static char sprint_red_buf[1024]=LOG_COLOR_RED; +int printf_red(char *fmt, ...) +{ + va_list args; + int n; + + int color_len = strlen(LOG_COLOR_RED); + + va_start(args, fmt); + n = vsprintf(sprint_red_buf+color_len, fmt, args); + va_end(args); + + memcpy(sprint_red_buf+color_len+n, LOG_COLOR_RESET, strlen(LOG_COLOR_RESET)); + + printf("%s", sprint_red_buf); + return n; +} + diff --git a/common/log_common.h b/common/log_common.h new file mode 100644 index 0000000..08bc778 --- /dev/null +++ b/common/log_common.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 __LOG_COMMON_H__ +#define __LOG_COMMON_H__ +#include +#include +#include +#include +#include + +int printf_green(char *fmt, ...); +int printf_red(char *fmt, ...); + +#endif /* __LOG_COMMON_H__ */ + diff --git a/doc/devicetree/bm_csi.txt b/doc/devicetree/bm_csi.txt new file mode 100644 index 0000000..44dc8f7 --- /dev/null +++ b/doc/devicetree/bm_csi.txt @@ -0,0 +1,22 @@ +Video Input Subsystem Controller Modules device tree bindings +-------------------------------------------- +Module Description: +As part of the MPCore complex, Cortex-A5 and Cortex-A9 are provided +with a Snoop Control Unit. The register range is usually 256 (0x100) +bytes. + +References: +- Light: see Reference Manual: csi_sysreg_registers_85p.xlsx + +- compatible : Should be: + "thead,light-bm-csi" + +- reg : Specify the base address and the size of the csi register window. + +Example: + +bm_reset: reset@ffe4100000 { + compatible = "thead,light-bm-csi"; + reg = <0xff 0xe4100000 0x0 0x10000>; + status = "okay"; +}; diff --git a/doc/devicetree/bm_visys.txt b/doc/devicetree/bm_visys.txt new file mode 100644 index 0000000..88c17d0 --- /dev/null +++ b/doc/devicetree/bm_visys.txt @@ -0,0 +1,22 @@ +Video Input Subsystem Controller Modules device tree bindings +-------------------------------------------- +Module Description: +As part of the MPCore complex, Cortex-A5 and Cortex-A9 are provided +with a Snoop Control Unit. The register range is usually 256 (0x100) +bytes. + +References: +- Light: see Reference Manual: visys_sysreg_registers_85p.xlsx + +- compatible : Should be: + "thead,light-bm-visys" + +- reg : Specify the base address and the size of the visys register window. + +Example: + +bm_reset: reset@ffe4100000 { + compatible = "thead,light-bm-visys"; + reg = <0xff 0xe4100000 0x0 0x10000>; + status = "okay"; +}; diff --git a/driver/common/bm_printk.h b/driver/common/bm_printk.h new file mode 100644 index 0000000..4490bee --- /dev/null +++ b/driver/common/bm_printk.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 __BM_PRINTK__ +#define __BM_PRINTK__ + +#include +#include +#include +#include +#include + +/* + * These can be used to print at the various log levels. + * All of these will print unconditionally, although note that pr_debug() + * and other debug macros are compiled out unless either DEBUG is defined + * or CONFIG_DYNAMIC_DEBUG is set. + */ +#define bm_emerg(fmt, ...) \ + printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) +#define bm_alert(fmt, ...) \ + printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) +#define bm_crit(fmt, ...) \ + printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) +#define bm_err(fmt, ...) \ + printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +#define bm_warning(fmt, ...) \ + printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) +#define bm_warn pr_warning + +#ifdef DEBUG +#define bm_notice(fmt, ...) \ + printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) +#define bm_info(fmt, ...) \ + printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +#else +#define bm_notice(fmt, ...) +#define bm_info(fmt, ...) +#endif + +#endif /* __BM_PRINTK__ */ diff --git a/driver/csi/Makefile b/driver/csi/Makefile new file mode 100644 index 0000000..b12456d --- /dev/null +++ b/driver/csi/Makefile @@ -0,0 +1,46 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +TARGET = bm_csi + +KBUILD_EXTRA_SYMBOLS += $(shell pwd)/../visys/Module.symvers + +export KBUILD_EXTRA_SYMBOLS + +obj-m +=$(TARGET).o +##$(TARGET)-objs += bm_csi_dphy.o +$(TARGET)-objs += bm_csi_driver.o +$(TARGET)-objs += bm_csi_hw.o +$(TARGET)-objs += dw-csi-plat.o +$(TARGET)-objs += dw-csi-sysfs.o +$(TARGET)-objs += dw-mipi-csi.o +$(TARGET)-objs += dw-dphy-plat.o +$(TARGET)-objs += dw-dphy-rx.o +$(TARGET)-objs += dw-dphy-sysfs.o + + +EXTRA_CFLAGS += -I$(PWD)/./ +EXTRA_CFLAGS += -I$(PWD)/../common + +#DEFS = -DCONFIG_DWC_MIPI_TC_DPHY_GEN3 + +ifeq ($(BUILD_TYPE),DEBUG) + EXTRA_CFLAGS += -DDEBUG +endif + +EXTRA_CFLAGS += $(DEFS) + +PWD :=$(shell pwd) + +all: + make -C $(KERNEL) M=$(PWD) modules +modules_install: + make -C $(KERNEL_SRC) M=$(SRC) modules_install +clean: + rm -rf $($(TARGET)-objs) + make -C $(KERNEL) M=`pwd` clean diff --git a/driver/csi/bm_csi_dphy.h b/driver/csi/bm_csi_dphy.h new file mode 100644 index 0000000..5eb060f --- /dev/null +++ b/driver/csi/bm_csi_dphy.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: liuyitong + * + * 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 _BM_CSI_DPHY_H_ +#define _BM_CSI_DPHY_H_ + +#include + +int dw_dphy_rx_probe(struct platform_device *pdev, unsigned int dphyglueiftester, unsigned int sysreg_mipi_csi_ctrl); +int dw_dphy_rx_remove(struct platform_device *pdev); + +#endif /*_BM_CSI_DPHY_H_ */ + + diff --git a/driver/csi/bm_csi_driver.c b/driver/csi/bm_csi_driver.c new file mode 100644 index 0000000..de406e0 --- /dev/null +++ b/driver/csi/bm_csi_driver.c @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: liuyitong + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "bm_printk.h" +#include "bm_csi_ioctl.h" +#include "bm_csi_hw.h" +#include "bm_csi_dphy.h" + +#define BM_DRIVER_NAME "bm_csi" +#define BM_DRIVER_MAXCNT 3 + +static struct class *bm_driver_class; +static unsigned int bm_driver_major = 0; +static unsigned int bm_driver_minor = 0; +static unsigned int device_register_index = 0; + +#define check_retval(x)\ + do {\ + if ((x))\ + return -EIO;\ + } while (0) + +static unsigned int bm_csi_poll(struct file * filp, poll_table *wait) +{ + return 0; +} + +void bm_csi_work(struct work_struct *work) +{ +} + +irqreturn_t bm_csi_irq(int irq, void *dev_id) +{ + bm_info("enter %s\n", __func__); + return IRQ_HANDLED; +} + +static int bm_csi_runtime_suspend(struct device *dev) +{ + struct bm_csi_drvdata *pdriver_dev = dev_get_drvdata(dev); + dev_info(dev, "enter %s\n", __func__); + + if (pdriver_dev->pclk != NULL) { + clk_disable_unprepare(pdriver_dev->pclk); + } + + if (pdriver_dev->pixclk!= NULL) { + clk_disable_unprepare(pdriver_dev->pixclk); + } + + if (pdriver_dev->cfg_clk0!= NULL) { + clk_disable_unprepare(pdriver_dev->cfg_clk0); + } + + if (pdriver_dev->cfg_clk1!= NULL) { + clk_disable_unprepare(pdriver_dev->cfg_clk1); + } + + if (pdriver_dev->cfg_clk2!= NULL) { + clk_disable_unprepare(pdriver_dev->cfg_clk2); + } + + pr_info("exit %s\n", __func__); + return 0; +} +static int bm_csi_runtime_resume(struct device *dev) +{ + int ret = 0; + struct bm_csi_drvdata *pdriver_dev = dev_get_drvdata(dev); + dev_info(dev, "enter %s\n", __func__); + + if (pdriver_dev->pclk != NULL) { + ret = clk_prepare_enable(pdriver_dev->pclk); + if (ret < 0) { + dev_err(dev, "could not prepare or enable csi pclk\n"); + clk_disable_unprepare(pdriver_dev->pclk); + return -1; + } + } + + if (pdriver_dev->pixclk!= NULL) { + ret = clk_prepare_enable(pdriver_dev->pixclk); + if (ret < 0) { + dev_err(dev, "could not prepare or enable pixclk\n"); + clk_disable_unprepare(pdriver_dev->pixclk); + return -1; + } + } + + if (pdriver_dev->cfg_clk0 != NULL) { + ret = clk_prepare_enable(pdriver_dev->cfg_clk0); + if (ret < 0) { + dev_err(dev, "could not prepare or enable cfg_clk0\n"); + clk_disable_unprepare(pdriver_dev->cfg_clk0); + return -1; + } + } + + if (pdriver_dev->cfg_clk1 != NULL) { + ret = clk_prepare_enable(pdriver_dev->cfg_clk1); + if (ret < 0) { + dev_err(dev, "could not prepare or enable cfg_clk1\n"); + clk_disable_unprepare(pdriver_dev->cfg_clk1); + return -1; + } + } + + if (pdriver_dev->cfg_clk2 != NULL) { + ret = clk_prepare_enable(pdriver_dev->cfg_clk2); + if (ret < 0) { + dev_err(dev, "could not prepare or enable cfg_clk2\n"); + clk_disable_unprepare(pdriver_dev->cfg_clk2); + return -1; + } + } + + pr_info("%s csi Enabled clock\n", __func__); + return 0; +} + +static const struct dev_pm_ops bm_csi_runtime_pm_ops = { + SET_RUNTIME_PM_OPS(bm_csi_runtime_suspend, bm_csi_runtime_resume, NULL) +}; + +static int bm_csi_open(struct inode * inode, struct file * file) +{ + int ret = 0; + struct bm_csi_drvdata *drvdata; + struct device *dev; + + bm_info("enter %s\n", __func__); + dev_info(dev, "open mipi-csi dev\n"); + + drvdata = container_of(inode->i_cdev, struct bm_csi_drvdata, cdev); + file->private_data = drvdata; + dev = &drvdata->pdev->dev; + dev_info(dev, "open mipi-csi dev\n"); + if (pm_runtime_get_sync(dev)) { + ret = bm_csi_runtime_resume(dev); + if (ret) + pr_err("fail to resume csi %s %d\n", __func__, __LINE__); + } + + return 0; +}; + +static long bm_csi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + struct bm_csi_drvdata *drvdata; + bm_info("enter %s\n", __func__); + + drvdata = file->private_data; + if (drvdata == NULL) { + bm_err("%s:file private is null point error\n", __func__); + return -ENOMEM; + } + + mutex_lock(&drvdata->mutex); + switch (cmd) { + case BMCSI_IOC_WRITE_REG: + ret = bm_csi_write_reg(drvdata, (void *)arg); + break; + case BMCSI_IOC_READ_REG: + ret = bm_csi_read_reg(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_RESET: + ret = bm_csi_reset(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_POWER: + ret = bm_csi_set_power(drvdata, (void *)arg); + break; + case BMCSI_IOC_G_POWER: + ret = bm_csi_get_power(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_CLOCK: + ret = bm_csi_set_clock(drvdata, (void *)arg); + break; + case BMCSI_IOC_G_CLOCK: + ret = bm_csi_get_clock(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_STREAM: + ret = bm_csi_set_stream(drvdata, (void *)arg); + break; + case BMCSI_IOC_G_STREAM: + ret = bm_csi_get_stream(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_FMT: + ret = bm_csi_set_fmt(drvdata, (void *)arg); + break; + case BMCSI_IOC_G_FMT: + ret = bm_csi_get_fmt(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_VC_SELECT: + ret = bm_csi_set_vc_select(drvdata, (void *)arg); + break; + case BMCSI_IOC_G_VC_SELECT: + ret = bm_csi_get_vc_select(drvdata, (void *)arg); + break; + case BMCSI_IOC_IPI_START: + ret = bm_csi_ipi_enable(drvdata, (void *)arg); + break; + case BMCSI_IOC_IPI_STOP: + ret = bm_csi_ipi_disable(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_LANE_CFG: + ret = bm_csi_set_lane_cfg(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_HSA_CFG: + ret = bm_csi_set_hsa(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_HBP_CFG: + ret = bm_csi_set_hbp(drvdata, (void *)arg); + break; + case BMCSI_IOC_S_HSD_CFG: + ret = bm_csi_set_hsd(drvdata, (void *)arg); + break; + case BMCSI_IOC_SET_PIXCLK: + ret = bm_csi_set_pixclk(drvdata, (void *)arg); + break; + case BMCSI_IOC_GET_PIXCLK: + ret = bm_csi_get_pixclk(drvdata, (void *)arg); + break; + case BMCSI_IOC_MAX: + break; + default: + ret = -EPERM; + bm_err("%s: unsupported command %d", __func__, cmd); + break; + } + mutex_unlock(&drvdata->mutex); + return ret; +}; + +static int bm_csi_release(struct inode * inode, struct file * file) +{ + int ret = 0; + struct bm_csi_drvdata *drvdata; + struct device *dev; + + bm_info("enter %s\n", __func__); + + drvdata = container_of(inode->i_cdev, struct bm_csi_drvdata, cdev); + file->private_data = drvdata; + dev = &drvdata->pdev->dev; + dev_info(dev, "release mipi-csi dev\n"); + ret = bm_csi_dis_power(drvdata); + if (ret) { + pr_info("fail to disable csi power, %s %d\n", __func__, __LINE__); + } + + ret = pm_runtime_put_sync(dev); + if (ret) { + pr_info("fail to resume csi %s %d\n", __func__, __LINE__); + } + + return 0; +}; + +static int bm_csi_mmap(struct file *pFile, struct vm_area_struct *vma) +{ + bm_info("enter %s\n", __func__); + return 0; +}; + +struct file_operations bm_csi_fops = { + .owner = THIS_MODULE, + .open = bm_csi_open, + .release = bm_csi_release, + .unlocked_ioctl = bm_csi_ioctl, + .mmap = bm_csi_mmap, + .poll = bm_csi_poll, +}; + +static int bm_csi_probe(struct platform_device *pdev) +{ + int ret = 0; + struct bm_csi_drvdata *drvdata; + struct resource *iores_mem; + unsigned int dphyglueiftester= 0; + unsigned int sysreg_mipi_csi_ctrl = 0; + u32 value; + + bm_info("enter %s\n", __func__); + pdev->id = device_register_index; + if (pdev->id >= BM_DRIVER_MAXCNT) { + bm_err("%s:pdev id is %d error\n", __func__, pdev->id); + return -EINVAL; + } + + drvdata = devm_kzalloc(&pdev->dev,sizeof(struct bm_csi_drvdata), GFP_KERNEL); + if (drvdata == NULL) { + bm_err("%s:alloc struct drvdata error\n", __func__); + return -ENOMEM; + } + + iores_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + drvdata->base = devm_ioremap_resource(&pdev->dev, iores_mem); + bm_info("%s: [%s%d]: drvdata->base=0x%px, phy_addr base=0x%llx\n", __func__, + BM_DRIVER_NAME, pdev->id, drvdata->base, iores_mem->start); + + drvdata->reset = NULL; + drvdata->device_idx = pdev->id; + mutex_init(&drvdata->mutex); + drvdata->irq_num = platform_get_irq(pdev, 0); + bm_info("%s:[%s%d]: pdriver_dev->irq_num=%d\n", __func__, "BM_CSI", pdev->id, drvdata->irq_num); + + drvdata->pdev = pdev; + + /*parse clk info from dts*/ + drvdata->pclk = devm_clk_get(&pdev->dev, "pclk"); + if (IS_ERR(drvdata->pclk)) { + dev_err(&pdev->dev, "failed to get pclk"); + drvdata->pclk = NULL; + } + + drvdata->pixclk = devm_clk_get(&pdev->dev, "pixclk"); + if (IS_ERR(drvdata->pixclk)) { + dev_err(&pdev->dev, "failed to get pixclk"); + drvdata->pixclk = NULL; + } + + drvdata->cfg_clk0 = devm_clk_get(&pdev->dev, "cfg_clk0"); + if (IS_ERR(drvdata->cfg_clk0)) { + dev_err(&pdev->dev, "failed to get cfg_clk0"); + drvdata->cfg_clk0 = NULL; + } + + drvdata->cfg_clk1 = devm_clk_get(&pdev->dev, "cfg_clk1"); + if (IS_ERR(drvdata->cfg_clk1)) { + dev_err(&pdev->dev, "failed to get cfg_clk1"); + drvdata->cfg_clk1 = NULL; + } + + drvdata->cfg_clk2 = devm_clk_get(&pdev->dev, "cfg_clk2"); + if (IS_ERR(drvdata->cfg_clk2)) { + dev_err(&pdev->dev, "failed to get cfg_clk2"); + drvdata->cfg_clk2 = NULL; + } + + platform_set_drvdata(pdev, drvdata); + + if (pdev->id == 0) { + if (bm_driver_major == 0) { + ret = alloc_chrdev_region(&drvdata->devt, 0, BM_DRIVER_MAXCNT, BM_DRIVER_NAME); + if (ret != 0) { + bm_err("%s:alloc_chrdev_region error\n", __func__); + return ret; + } + bm_driver_major = MAJOR(drvdata->devt); + bm_driver_minor = MINOR(drvdata->devt); + } else { + drvdata->devt = MKDEV(bm_driver_major, bm_driver_minor); + ret = register_chrdev_region(drvdata->devt, BM_DRIVER_MAXCNT, BM_DRIVER_NAME); + if (ret) { + bm_err("%s:register_chrdev_region error\n", __func__); + return ret; + } + } + + bm_driver_class = class_create(THIS_MODULE, BM_DRIVER_NAME); + if (IS_ERR(bm_driver_class)) { + bm_err("%s[%d]:class_create error!\n", __func__, __LINE__); + return -EINVAL; + } + } + + drvdata->devt = MKDEV(bm_driver_major, bm_driver_minor + pdev->id); + cdev_init(&drvdata->cdev, &bm_csi_fops); + ret = cdev_add(&drvdata->cdev, drvdata->devt, 1); + if ( ret ) { + bm_err("%s[%d]:cdev_add error!\n", __func__, __LINE__); + return ret; + } else { + bm_info("%s[%d]:cdev_add OK, major=%d, minor=%d\n", __func__, __LINE__, + bm_driver_major, bm_driver_minor + pdev->id); + } + drvdata->class = bm_driver_class; + device_create(drvdata->class, NULL, drvdata->devt, + drvdata, "%s%d", BM_DRIVER_NAME, pdev->id); + + /*read version*/ + value = readl(drvdata->base + 0x0); + bm_info("offset=04, value is:0x%08x\n", value); + + device_property_read_u32(&pdev->dev, "dphyglueiftester", &dphyglueiftester); + bm_info("dphyglueiftester is:0x%x\n", dphyglueiftester); + device_property_read_u32(&pdev->dev, "sysreg_mipi_csi_ctrl", &sysreg_mipi_csi_ctrl); + bm_info("sysreg_mipi_csi_ctrl is:0x%x\n", sysreg_mipi_csi_ctrl); + + dw_dphy_rx_probe(pdev, dphyglueiftester, sysreg_mipi_csi_ctrl); + dw_csi_probe(pdev); + + pm_runtime_enable(&pdev->dev); + ret = bm_csi_runtime_resume(&pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "fail to resume csi\n"); + } + + ret = bm_csi_runtime_suspend(&pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "fail to suspend csi\n"); + } + + device_register_index++; + bm_info("exit %s:[%s%d]\n", __func__, BM_DRIVER_NAME, pdev->id); + + return 0; +} + +static int bm_csi_remove(struct platform_device *pdev) +{ + struct bm_csi_drvdata *drvdata; + + bm_info("enter %s\n", __func__); + dw_dphy_rx_remove(pdev); + dw_csi_remove(pdev); + + device_register_index--; + drvdata = platform_get_drvdata(pdev); + free_irq(drvdata->irq_num, drvdata); + cdev_del(&drvdata->cdev); + device_destroy(drvdata->class, drvdata->devt); + unregister_chrdev_region(drvdata->devt, BM_DRIVER_MAXCNT); + mutex_destroy(&drvdata->mutex); + if (device_register_index == 0) { + class_destroy(drvdata->class); + } + devm_kfree(&pdev->dev, drvdata); + + bm_info("exit %s\n", __func__); + return 0; +} + +static const struct of_device_id bm_csi_of_match[] = { + { .compatible = "thead,light-bm-csi", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, bm_csi_of_match); + +static struct platform_driver bm_csi_driver = { + .probe = bm_csi_probe, + .remove = bm_csi_remove, + .driver = { + .name = BM_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(bm_csi_of_match), + .pm = &bm_csi_runtime_pm_ops, + } +}; + +static int __init bm_csi_init_module(void) +{ + int ret = 0; + + bm_info("enter %s\n", __func__); + ret = platform_driver_register(&bm_csi_driver); + if (ret) { + bm_err("register platform driver failed.\n"); + return ret; + } + + return ret; +} + +static void __exit bm_csi_exit_module(void) +{ + bm_info("enter %s\n", __func__); + platform_driver_unregister(&bm_csi_driver); +} + +module_init(bm_csi_init_module); +module_exit(bm_csi_exit_module); + +MODULE_AUTHOR("Liu Yitong"); +MODULE_DESCRIPTION("BAREMETAL-CSI"); +MODULE_LICENSE("GPL"); diff --git a/driver/csi/bm_csi_hw.c b/driver/csi/bm_csi_hw.c new file mode 100644 index 0000000..8761a27 --- /dev/null +++ b/driver/csi/bm_csi_hw.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: liuyitong + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "bm_printk.h" +#include "bm_csi_ioctl.h" +#include "bm_csi_hw.h" +#include "dw-dphy-rx.h" +#include "bm_csi_dphy.h" + +#define check_retval(x)\ + do {\ + if ((x))\ + return -EIO;\ + } while (0) + +struct csi_format_context { + uint32_t format; + uint32_t width; + uint32_t height; +}; + + +int bm_csi_write_reg(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct bm_csi_reg_t reg; + check_retval(copy_from_user(®, args, sizeof(reg))); + writel(reg.value, drvdata->base + reg.offset); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, reg.offset, reg.value); + return 0; +} + +int bm_csi_read_reg(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct bm_csi_reg_t reg; + check_retval(copy_from_user(®, args, sizeof(reg))); + reg.value = readl(drvdata->base + reg.offset); + check_retval(copy_to_user(args, ®, sizeof(reg))); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, reg.offset, reg.value); + return 0; +} + +int bm_csi_reset(struct bm_csi_drvdata *drvdata, void *__user args) +{ + bm_info("%s: csi reset success\n", __func__); + dw_csi_soc_reset(); + dw_mipi_csi_reset(&drvdata->csi_dev); + dw_dphy_reset(drvdata->dphy->phy); + return 0; +} + +static uint32_t csi_power_on_sta = 0; + +int bm_csi_en_power(struct bm_csi_drvdata *drvdata) +{ + bm_info("%s: csi set power\n", __func__); + csi_power_on_sta = 1; + dw_mipi_csi_s_power(&drvdata->csi_dev, csi_power_on_sta); + return 0; +} + +int bm_csi_dis_power(struct bm_csi_drvdata *drvdata) +{ + bm_info("%s: csi set power\n", __func__); + csi_power_on_sta = 0; + dw_mipi_csi_s_power(&drvdata->csi_dev, csi_power_on_sta); + return 0; +} + +int bm_csi_set_power(struct bm_csi_drvdata *drvdata, void *__user args) +{ + bm_info("%s: csi set power\n", __func__); + check_retval(copy_from_user(&csi_power_on_sta, args, sizeof(csi_power_on_sta))); + dw_mipi_csi_s_power(&drvdata->csi_dev, csi_power_on_sta); + return 0; +} + +int bm_csi_get_power(struct bm_csi_drvdata *drvdata, void *__user args) +{ + bm_info("%s: csi get power\n", __func__); + check_retval(copy_to_user(args, &csi_power_on_sta, sizeof(csi_power_on_sta))); + return 0; +} + +int bm_csi_set_clock(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_dphy_rx *dphy = drvdata->dphy; + bm_info("%s: \n", __func__); + check_retval(copy_from_user(&dphy->dphy_freq, args, sizeof(dphy->dphy_freq))); + + return 0; +} + +int bm_csi_get_clock(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_dphy_rx *dphy = drvdata->dphy; + bm_info("%s: \n", __func__); + check_retval(copy_to_user(args, &dphy->dphy_freq, sizeof(dphy->dphy_freq))); + return 0; +} + +int bm_csi_set_pixclk(struct bm_csi_drvdata *drvdata, void *__user args) +{ + uint32_t freq_hz = 0; + bm_info("%s: \n", __func__); + check_retval(copy_from_user(&freq_hz, args, sizeof(freq_hz))); + return dw_csi_set_pixclk(freq_hz); +} + +int bm_csi_get_pixclk(struct bm_csi_drvdata *drvdata, void *__user args) +{ + uint32_t freq_hz = 0; + bm_info("%s: \n", __func__); + dw_csi_get_pixclk(&freq_hz); + check_retval(copy_to_user(args, &freq_hz, sizeof(freq_hz))); + return 0; +} + +int bm_csi_set_stream(struct bm_csi_drvdata *drvdata, void *__user args) +{ + bm_info("%s: \n", __func__); + return 0; +} + +int bm_csi_get_stream(struct bm_csi_drvdata *drvdata, void *__user args) +{ + bm_info("%s: \n", __func__); + check_retval(copy_to_user(args, &csi_power_on_sta, sizeof(csi_power_on_sta))); + return 0; +} + +int bm_csi_set_fmt(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_csi *csi_dev = &drvdata->csi_dev; + u8 dt = 0; + //struct csi_format_context fmt; + bm_info("%s: \n", __func__); + check_retval(copy_from_user(&dt, args, sizeof(dt))); +/* + csi_dev->fmt->mbus_code = fmt.format; + csi_dev->fmt->width = fmt.width; + csi_dev->fmt->height = fmt.height; + */ + + csi_dev->ipi_dt = dt; + dw_mipi_csi_set_ipi_fmt(csi_dev); +/* + if(fmt.height > 0 && fmt.width > 0) { + csi_dev->hw.ipi_color_mode = COLOR16; + csi_dev->hw.ipi_auto_flush = 1; + csi_dev->hw.ipi_adv_features = LINE_EVENT_SELECTION(EVSELAUTO); + csi_dev->hw.htotal = fmt.width + csi_dev->hw.hsa + csi_dev->hw.hbp + csi_dev->hw.hsd; + csi_dev->hw.vactive = fmt.height; + csi_dev->hw.output = 0; + } + */ + + return 0; +} + +int bm_csi_get_fmt(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_csi *csi_dev = &drvdata->csi_dev; + struct csi_format_context fmt; + bm_info("%s: \n", __func__); + fmt.format = csi_dev->fmt->mbus_code; + fmt.height = csi_dev->fmt->height; + fmt.width = csi_dev->fmt->width; + + check_retval(copy_to_user(args, &fmt, sizeof(fmt))); + return 0; +} + +int bm_csi_set_vc_select(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct csi_vc_select_context vc; + struct dw_csi *csi_dev = &drvdata->csi_dev; + bm_info("%s: \n", __func__); + check_retval(copy_from_user(&vc, args, sizeof(vc))); + + if (vc.ipi_idx == 1) { + csi_dev->hw.ipi1_en = true; + csi_dev->hw.virtual_ch = vc.vc_ch; + } else if (vc.ipi_idx == 2) { + csi_dev->hw.ipi2_en = true; + csi_dev->hw.ipi2_virtual_ch = vc.vc_ch; + } else if (vc.ipi_idx == 3) { + csi_dev->hw.ipi3_en = true; + csi_dev->hw.ipi3_virtual_ch = vc.vc_ch; + } + + return 0; +} + +int bm_csi_ipi_enable(struct bm_csi_drvdata *drvdata, void *__user args) +{ + int ipi_idx; + struct dw_csi *csi_dev = &drvdata->csi_dev; + bm_info("%s: \n", __func__); + check_retval(copy_from_user(&ipi_idx, args, sizeof(ipi_idx))); + + if (ipi_idx == 1) { + csi_dev->hw.ipi1_en = true; + } else if (ipi_idx == 2) { + csi_dev->hw.ipi2_en = true; + } else if (ipi_idx == 3) { + csi_dev->hw.ipi3_en = true; + } + + dw_mipi_csi_start(csi_dev); + return 0; +} + +int bm_csi_ipi_disable(struct bm_csi_drvdata *drvdata, void *__user args) +{ + int ipi_idx; + struct dw_csi *csi_dev = &drvdata->csi_dev; + bm_info("%s: \n", __func__); + check_retval(copy_from_user(&ipi_idx, args, sizeof(ipi_idx))); + + if (ipi_idx == 1) { + csi_dev->hw.ipi1_en = 0; + } else if (ipi_idx == 2) { + csi_dev->hw.ipi2_en = 0; + } else if (ipi_idx == 3) { + csi_dev->hw.ipi3_en = 0; + } + + dw_mipi_csi_stop(csi_dev); + return 0; +} + +int bm_csi_get_vc_select(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct csi_vc_select_context vc; + struct dw_csi *csi_dev = &drvdata->csi_dev; + bm_info("%s: \n", __func__); + + if (vc.ipi_idx == 1) { + vc.vc_ch = csi_dev->hw.virtual_ch; + } else if (vc.ipi_idx == 2) { + vc.vc_ch = csi_dev->hw.ipi2_virtual_ch; + } else if (vc.ipi_idx == 3) { + vc.vc_ch = csi_dev->hw.ipi3_virtual_ch; + } + + check_retval(copy_to_user(args, &vc, sizeof(vc))); + + return 0; +} + +int bm_csi_set_lane_cfg(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_csi *csi_dev = &drvdata->csi_dev; + bm_info("%s: \n", __func__); + + check_retval(copy_from_user(&csi_dev->hw.num_lanes, args, sizeof(csi_dev->hw.num_lanes))); + + return 0; +} + +typedef struct { + int ipi_idx; + int val; +} dw_csi_hsx_cfg_t; + +int bm_csi_set_hsa(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_csi *csi_dev = &drvdata->csi_dev; + dw_csi_hsx_cfg_t cfg; + bm_info("%s: \n", __func__); + + check_retval(copy_from_user(&cfg, args, sizeof(cfg))); + if (cfg.ipi_idx == 1) { + csi_dev->hw.hsa = cfg.val; + } else if(cfg.ipi_idx == 2) { + csi_dev->hw.ipi2_hsa = cfg.val; + } else if(cfg.ipi_idx == 3) { + csi_dev->hw.ipi3_hsa = cfg.val; + } else { + return -1; + } + + + return 0; +} + +int bm_csi_set_hbp(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_csi *csi_dev = &drvdata->csi_dev; + dw_csi_hsx_cfg_t cfg; + bm_info("%s: \n", __func__); + + check_retval(copy_from_user(&cfg, args, sizeof(cfg))); + if (cfg.ipi_idx == 1) { + csi_dev->hw.hbp = cfg.val; + } else if(cfg.ipi_idx == 2) { + csi_dev->hw.ipi2_hbp = cfg.val; + } else if(cfg.ipi_idx == 3) { + csi_dev->hw.ipi3_hbp = cfg.val; + } else { + return -1; + } + + return 0; +} + +int bm_csi_set_hsd(struct bm_csi_drvdata *drvdata, void *__user args) +{ + struct dw_csi *csi_dev = &drvdata->csi_dev; + dw_csi_hsx_cfg_t cfg; + bm_info("%s: \n", __func__); + + check_retval(copy_from_user(&cfg, args, sizeof(cfg))); + if (cfg.ipi_idx == 1) { + csi_dev->hw.hsd = cfg.val; + } else if(cfg.ipi_idx == 2) { + csi_dev->hw.ipi2_hsd = cfg.val; + } else if(cfg.ipi_idx == 3) { + csi_dev->hw.ipi3_hsd = cfg.val; + } else { + return -1; + } + + return 0; +} diff --git a/driver/csi/bm_csi_hw.h b/driver/csi/bm_csi_hw.h new file mode 100644 index 0000000..0c50e10 --- /dev/null +++ b/driver/csi/bm_csi_hw.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: liuyitong + * + * 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 _BM_CSI_HW_H_ +#define _BM_CSI_HW_H_ + +#include +#include +#include "dw-dphy-rx.h" +#include "dw-mipi-csi.h" +#include "dw-csi-data.h" +#include "dw-dphy-data.h" + +struct bm_csi_drvdata { + struct cdev cdev; + dev_t devt; + struct class *class; + struct mutex mutex; + unsigned int device_idx; + void __iomem *base; + void __iomem *reset; + struct dw_dphy_rx *dphy; + struct dw_csi csi_dev; + struct dw_csih_pdata csi_pdata; + struct dw_phy_pdata dphy_pdata; + int irq_num; + struct clk *pclk; + struct clk *pixclk; + struct clk *cfg_clk0; + struct clk *cfg_clk1; + struct clk *cfg_clk2; + struct platform_device *pdev; + void *private; // can be bm_csi_drvdata_private, but not use now +}; + +struct bm_csi_drvdata_private { + int private_tmp; +}; + +int bm_csi_write_reg(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_read_reg(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_init(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_exit(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_reset(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_power(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_get_power(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_en_power(struct bm_csi_drvdata *drvdata); +int bm_csi_dis_power(struct bm_csi_drvdata *drvdata); +int bm_csi_set_clock(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_get_clock(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_pixclk(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_get_pixclk(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_stream(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_get_stream(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_fmt(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_get_fmt(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_vc_select(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_get_vc_select(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_ipi_enable(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_ipi_disable(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_lane_cfg(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_hsa(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_hbp(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_set_hsd(struct bm_csi_drvdata *drvdata, void *__user args); + + +/*csi dphy*/ +int bm_csi_dphy_write_reg(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_dphy_init(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_dphy_uinit(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_dphy_reset(struct bm_csi_drvdata *drvdata, void *__user args); + +void dw_csi_soc_reset(void); +int dw_csi_probe(struct platform_device *pdev); +int dw_csi_remove(struct platform_device *pdev); + +int dw_csi_set_pixclk(uint32_t freq_hz); +int dw_csi_get_pixclk(uint32_t *freq_hz); + +#endif /* _BM_CSI_HW_H_*/ diff --git a/driver/csi/bm_csi_ioctl.h b/driver/csi/bm_csi_ioctl.h new file mode 100644 index 0000000..0db8508 --- /dev/null +++ b/driver/csi/bm_csi_ioctl.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: liuyitong + * + * 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 _BM_CSI_IOCTL_H_ +#define _BM_CSI_IOCTL_H_ + +#include + +enum { + BMCSI_IOC_S_RESET = 0x100, + BMCSI_IOC_S_POWER, + BMCSI_IOC_G_POWER, + BMCSI_IOC_S_CLOCK, + BMCSI_IOC_G_CLOCK, + BMCSI_IOC_S_STREAM, + BMCSI_IOC_G_STREAM, + BMCSI_IOC_S_FMT, + BMCSI_IOC_G_FMT, + BMCSI_IOC_S_VC_SELECT, + BMCSI_IOC_G_VC_SELECT, + BMCSI_IOC_IPI_START, + BMCSI_IOC_IPI_STOP, + BMCSI_IOC_S_LANE_CFG, + BMCSI_IOC_S_HSA_CFG, + BMCSI_IOC_S_HBP_CFG, + BMCSI_IOC_S_HSD_CFG, + BMCSI_IOC_WRITE_REG, + BMCSI_IOC_READ_REG, + BMCSI_IOC_SET_PIXCLK, + BMCSI_IOC_GET_PIXCLK, + BMCSI_IOC_MAX, +}; + +struct bm_csi_reg_t { + unsigned int offset; + unsigned int value; +}; + +struct csi_vc_select_context { + unsigned int ipi_idx; + unsigned int vc_ch; +}; + +#endif /* _BM_CSI_IOCTL_H_*/ diff --git a/driver/csi/dw-csi-data.h b/driver/csi/dw-csi-data.h new file mode 100644 index 0000000..10015fd --- /dev/null +++ b/driver/csi/dw-csi-data.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI CSI-2 platform data + * + * Author: Luis Oliveira + */ + +#include +#include "dw-mipi-csi-pltfrm.h" + +#ifndef __DW_CSI_DATA__ +#define __DW_CSI_DATA__ + +struct dw_csih_pdata { + u8 eotp_enabled; + u32 hs_freq; + u32 lanes; + u32 pclk; + u32 fps; + u32 bpp; + u8 id; +}; + +static const struct pdata_names csis[] = { + { .name = "dw-csi.0", }, + { .name = "dw-csi.1", }, +}; + +#endif /*__DW_CSI_DATA__ */ diff --git a/driver/csi/dw-csi-plat.c b/driver/csi/dw-csi-plat.c new file mode 100644 index 0000000..5b658e5 --- /dev/null +++ b/driver/csi/dw-csi-plat.c @@ -0,0 +1,431 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI CSI-2 Host controller driver. + * Platform driver + * + * Author: Luis Oliveira + */ + +#include "dw-csi-data.h" +#include "dw-dphy-data.h" +#include "dw-csi-plat.h" + +#include "bm_csi_hw.h" + +const struct mipi_dt csi_dt[] = { + { + .hex = CSI_2_YUV420_8, + .name = "YUV420_8bits", + }, { + .hex = CSI_2_YUV420_10, + .name = "YUV420_10bits", + }, { + .hex = CSI_2_YUV420_8_LEG, + .name = "YUV420_8bits_LEGACY", + }, { + .hex = CSI_2_YUV420_8_SHIFT, + .name = "YUV420_8bits_SHIFT", + }, { + .hex = CSI_2_YUV420_10_SHIFT, + .name = "YUV420_10bits_SHIFT", + }, { + .hex = CSI_2_YUV422_8, + .name = "YUV442_8bits", + }, { + .hex = CSI_2_YUV422_10, + .name = "YUV442_10bits", + }, { + .hex = CSI_2_RGB444, + .name = "RGB444", + }, { + .hex = CSI_2_RGB555, + .name = "RGB555", + }, { + .hex = CSI_2_RGB565, + .name = "RGB565", + }, { + .hex = CSI_2_RGB666, + .name = "RGB666", + }, { + .hex = CSI_2_RGB888, + .name = "RGB888", + }, { + .hex = CSI_2_RAW6, + .name = "RAW6", + }, { + .hex = CSI_2_RAW7, + .name = "RAW7", + }, { + .hex = CSI_2_RAW8, + .name = "RAW8", + }, { + .hex = CSI_2_RAW10, + .name = "RAW10", + }, { + .hex = CSI_2_RAW12, + .name = "RAW12", + }, { + .hex = CSI_2_RAW14, + .name = "RAW14", + }, { + .hex = CSI_2_RAW16, + .name = "RAW16", + }, +}; + +static struct mipi_fmt * +find_dw_mipi_csi_format(uint32_t mbus_code) +{ + unsigned int i; + + pr_info("%s entered mbus: 0x%x\n", __func__, mbus_code); + + for (i = 0; i < ARRAY_SIZE(dw_mipi_csi_formats); i++) + if (mbus_code == dw_mipi_csi_formats[i].mbus_code) { + pr_info("Found mbus 0x%x\n", dw_mipi_csi_formats[i].mbus_code); + return &dw_mipi_csi_formats[i]; + } + return NULL; +} + +int dw_mipi_csi_enum_mbus_code(int index, uint32_t *code) +{ + if (index != 0) + return -EINVAL; + + *code = dw_mipi_csi_formats[index].mbus_code; + return 0; +} + +static struct mipi_fmt * +dw_mipi_csi_try_format(uint32_t mbus_code) +{ + struct mipi_fmt *fmt; + + fmt = find_dw_mipi_csi_format(mbus_code); + if (!fmt) + fmt = &dw_mipi_csi_formats[0]; + + return fmt; +} + +struct mipi_fmt * +dw_mipi_csi_get_format(struct dw_csi *dev) +{ + dev_info(dev->dev, + "%s got v4l2_mbus_pixelcode. 0x%x\n", __func__, + dev->fmt->mbus_code); + dev_info(dev->dev, + "%s got width. 0x%x\n", __func__, + dev->fmt->width); + dev_info(dev->dev, + "%s got height. 0x%x\n", __func__, + dev->fmt->height); + return dev->fmt; +} + +int +dw_mipi_csi_set_fmt(struct platform_device *pdev, + uint32_t mbus_code, uint32_t width, uint32_t height) +{ + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *dev = &drvdata->csi_dev; + + struct mipi_fmt *dev_fmt = NULL; + int i; + dev_info(dev->dev, + "%s got mbus_pixelcode. 0x%x\n", __func__, + mbus_code); + + dev_fmt = dw_mipi_csi_try_format(mbus_code); + + dev_info(dev->dev, + "%s got v4l2_mbus_pixelcode. 0x%x\n", __func__, + dev_fmt->mbus_code); + if (!dev_fmt) + return -EINVAL; + + if (dev_fmt) { + dev->fmt->mbus_code = dev_fmt->mbus_code; + dev->fmt->width = width; + dev->fmt->height = height; + dw_mipi_csi_set_ipi_fmt(dev); + } + dev_info(dev->dev, "Width: %d, Height: %d of Demo\n", width, height); + if (width > 0 && height > 0) { + dw_mipi_csi_fill_timings(dev, width, height); +/* + demo_writel(dev, + DEMO_ACTIVE_WIDTH, fmt->format.width); + demo_writel(dev, + DEMO_ACTIVE_HEIGHT, fmt->format.height); +*/ + dev_vdbg(dev->dev, + "(core/demosaic) : width=%d/%d, height=%d/%d\n", + dev->hw.htotal - (dev->hw.hbp + + dev->hw.hsd + + dev->hw.hsa), + width, + dev->hw.vactive, + height); + dev_info(dev->dev, + "(core/demosaic) : width=%d/%d, height=%d/%d\n", + dev->hw.htotal - (dev->hw.hbp + + dev->hw.hsd + + dev->hw.hsa), + width, + dev->hw.vactive, + height); + + } else { + dev_vdbg(dev->dev, "%s unacceptable values 0x%x.\n", + __func__, width); + dev_vdbg(dev->dev, "%s unacceptable values 0x%x.\n", + __func__, height); + dev_info(dev->dev, "%s unacceptable values 0x%x.\n", + __func__, width); + dev_info(dev->dev, "%s unacceptable values 0x%x.\n", + __func__, height); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(csi_dt); i++) + if (csi_dt[i].hex == dev->ipi_dt) { + dev_vdbg(dev->dev, "Using data type %s\n", + csi_dt[i].name); + dev_info(dev->dev, "Using data type %s\n", + csi_dt[i].name); + } + return 0; +} + +int +dw_mipi_csi_get_fmt(struct platform_device *pdev, + struct mipi_fmt *fmt) +{ + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *dev = &drvdata->csi_dev; + + struct mipi_fmt *mf = dw_mipi_csi_get_format(dev); + if (!mf) + return -EINVAL; + + mutex_lock(&dev->lock); + *fmt = *mf; + mutex_unlock(&dev->lock); + + return 0; +} + +int dw_mipi_csi_s_power(struct dw_csi *dev, int on) +{ + dev_info(dev->dev, "%s: on=%d\n", __func__, on); + + if (on) { + dw_dphy_power_on(dev->phy); + dw_mipi_csi_hw_stdby(dev); + dw_mipi_csi_start(dev); + } else { + phy_power_off(dev->phy); + dw_mipi_csi_mask_irq_power_off(dev); + /* reset data type */ + dev->ipi_dt = 0x0; + } + return 0; +} + +int dw_mipi_csi_log_status(struct dw_csi *dev) +{ + dw_mipi_csi_dump(dev); + + return 0; +} + +#if IS_ENABLED(CONFIG_VIDEO_ADV_DEBUG) +int +dw_mipi_csi_g_register(struct v4l2_subdev *sd, uint32_t reg) +{ + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *dev = &drvdata->csi_dev; + + dev_vdbg(dev->dev, "%s: reg=%llu\n", __func__, reg); + reg->val = dw_mipi_csi_read(dev, reg); + + return 0; +} +#endif + +#if 0 +static int dw_mipi_csi_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct v4l2_mbus_framefmt *format = + v4l2_subdev_get_try_format(sd, cfg, 0); + + format->colorspace = V4L2_COLORSPACE_SRGB; + format->code = MEDIA_BUS_FMT_RGB888_1X24; + format->field = V4L2_FIELD_NONE; + + return 0; +} +#endif + +static irqreturn_t dw_mipi_csi_irq1(int irq, void *dev_id) +{ + struct dw_csi *csi_dev = dev_id; + + dw_mipi_csi_irq_handler(csi_dev); + + return IRQ_HANDLED; +} + +extern int k_bm_visys_write_reg(uint32_t offset, uint32_t value); +extern int k_bm_visys_read_reg(uint32_t offset, uint32_t *value); + +void dw_csi_soc_reset(void) +{ +#define VISYS_SW_RST 0x100 + uint32_t reg_val = 0; + k_bm_visys_read_reg(VISYS_SW_RST, ®_val); + reg_val &= ~(1 << 16); + k_bm_visys_write_reg(VISYS_SW_RST, reg_val); + reg_val |= 1 << 16; + k_bm_visys_write_reg(VISYS_SW_RST, reg_val); +} + +#define MIPI_CSI_PIXELCLK 0x30 +#define MIPI_CSI_PIXELSRC_CLK 2376000000 //hz + +int dw_csi_set_pixclk(uint32_t freq_hz) +{ + uint32_t reg_val = 0; + uint32_t div = (MIPI_CSI_PIXELSRC_CLK + (MIPI_CSI_PIXELSRC_CLK % freq_hz)) / freq_hz; + + if (freq_hz > MIPI_CSI_PIXELSRC_CLK || div > 0xf) { + return -1; + } + + k_bm_visys_read_reg(MIPI_CSI_PIXELCLK, ®_val); + reg_val &= ~0xf; + reg_val |= div; + k_bm_visys_write_reg(MIPI_CSI_PIXELCLK, reg_val); + + return 0; +} + +int dw_csi_get_pixclk(uint32_t *freq_hz) +{ + uint32_t reg_val = 0; + uint32_t div = 0; + k_bm_visys_read_reg(MIPI_CSI_PIXELCLK, ®_val); + div = reg_val & 0xf; + *freq_hz = MIPI_CSI_PIXELSRC_CLK / div; + return 0; +} + +static const struct of_device_id dw_mipi_csi_of_match[]; + +int dw_csi_probe(struct platform_device *pdev) +{ + + struct device *dev = &pdev->dev; + struct dw_csi *csi; + struct dw_dphy_rx *dphy; + struct dw_csih_pdata *pdata; + struct bm_csi_drvdata *drvdata; + int ret; + + if (!IS_ENABLED(CONFIG_OF)) + + dev_vdbg(dev, "Probing started\n"); + + /* Resource allocation */ + drvdata = platform_get_drvdata(pdev); + + csi = &drvdata->csi_dev; + dphy = drvdata->dphy; + pdata = &drvdata->csi_pdata; + + mutex_init(&csi->lock); + spin_lock_init(&csi->slock); + csi->dev = dev; + + /*set csi phy*/ + csi->phy = dphy->phy; + csi->base_address = drvdata->base; + if (IS_ERR(csi->base_address)) { + dev_err(dev, "base address not set.\n"); + return PTR_ERR(csi->base_address); + } + + csi->ctrl_irq_number = drvdata->irq_num; + if (csi->ctrl_irq_number < 0) { + dev_err(dev, "irq number %d not set.\n", csi->ctrl_irq_number); + ret = csi->ctrl_irq_number; + goto end; + } + + ret = devm_request_irq(dev, csi->ctrl_irq_number, + dw_mipi_csi_irq1, IRQF_SHARED, + dev_name(dev), csi); + if (ret) { + dev_err(dev, "irq csi %d failed\n", pdata->id); + goto end; + } + + csi->fmt = &dw_mipi_csi_formats[0]; + csi->fmt->mbus_code = dw_mipi_csi_formats[0].mbus_code; +/* + to do pad init +*/ + csi->hw.num_lanes = pdata->lanes; + csi->hw.pclk = pdata->pclk; + csi->hw.fps = pdata->fps; + csi->hw.dphy_freq = pdata->hs_freq; + csi->hw.ipi_mode = CAMERA_TIMING; + csi->hw.ipi_color_mode = COLOR16; + + //csi soc reset + dw_csi_soc_reset(); + dw_csi_create_capabilities_sysfs(pdev); + dw_mipi_csi_get_version(csi); + dw_mipi_csi_specific_mappings(csi); + dw_mipi_csi_mask_irq_power_off(csi); + + dev_info(dev, "DW MIPI CSI-2 Host registered successfully HW v%u.%u\n", + csi->hw_version_major, csi->hw_version_minor); + + ret = phy_reset(csi->phy); + if (ret) { + dev_err(&csi->phy->dev, "phy init failed --> %d\n", ret); + goto end; + } + ret = phy_init(csi->phy); + if (ret) { + dev_err(&csi->phy->dev, "phy init failed --> %d\n", ret); + goto end; + } + + return 0; +end: + return ret; +} + +int dw_csi_remove(struct platform_device *pdev) +{ + struct bm_csi_drvdata *drvdata; + drvdata = platform_get_drvdata(pdev); + dw_csi_remove_capabilities_sysfs(pdev); + //struct dw_csi *mipi_csi = &drvdata->csi_dev; + //csi soc reset + dw_csi_soc_reset(); + dev_info(&pdev->dev, "DW MIPI CSI-2 Host module removed\n"); + + return 0; +} + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Luis Oliveira "); +MODULE_DESCRIPTION("Synopsys DesignWare MIPI CSI-2 Host Platform driver"); diff --git a/driver/csi/dw-csi-plat.h b/driver/csi/dw-csi-plat.h new file mode 100644 index 0000000..37133fa --- /dev/null +++ b/driver/csi/dw-csi-plat.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018 Synopsys, Inc. + * + * Synopsys DesignWare MIPI CSI-2 Host controller driver. + * Supported bus formats + * + * Author: Luis Oliveira + */ + +#ifndef _DW_CSI_PLAT_H__ +#define _DW_CSI_PLAT_H__ + +#include "dw-mipi-csi.h" + +/** Color Space Converter Block **/ +#define CSC_UNIT_NR 1 +#define CSC_COREID 0x0000 +#define CSC_CFG 0x0004 +#define CSC_COEF_A(x) (0x0008 + ((x) * 4)) +#define CSC_COEF_B(x) (0x0018 + ((x) * 4)) +#define CSC_COEF_C(x) (0x0028 + ((x) * 4)) +#define CSC_LIMIT_DN 0x0038 +#define CSC_LIMIT_UP 0x003C +#define CSC_VID_CFG 0x0040 + +/** Demosaic Block **/ +#define DEMO_CONTROL 0x0 +#define DEMO_GLOBAL_INT_EN 0x4 +#define DEMO_IP_INT_EN_REG 0x8 +#define DEMO_IP_INT_SATUS_REG 0xC +#define DEMO_ACTIVE_WIDTH 0x10 +#define DEMO_ACTIVE_HEIGHT 0x18 +#define DEMO_BAYER_PHASE 0x28//0x20 + +#define BAYER_RGGB 0x0 +#define BAYER_GRBG 0x1 +#define BAYER_GBRG 0x2 +#define BAYER_BGGR 0x3 + +/* Video formats supported by the MIPI CSI-2 */ +static struct mipi_fmt dw_mipi_csi_formats[] = { + { + /* RAW 8 */ + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + .depth = 8, + }, +#if 0 + { + /* RAW 6 */ + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,/*modify by shenwuyi*/ + .depth = 8, + }, { + /* RAW 7 */ + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,/*modify by shenwuyi*/ + .depth = 8, + }, +#endif + { + /* RAW 10 */ + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .depth = 10, + }, { + /* RAW 8 */ + .mbus_code = 0x3001, + .depth = 8, + }, { + /* RAW 12 */ + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + .depth = 12, + }, { + /* RAW 14 */ + .mbus_code = MEDIA_BUS_FMT_SBGGR14_1X14, + .depth = 14, + }, { + /* RAW 16 */ + .mbus_code = MEDIA_BUS_FMT_SBGGR16_1X16, + .depth = 16, + }, { + /* RGB 666 */ + .mbus_code = MEDIA_BUS_FMT_RGB666_1X18, + .depth = 18, + }, { + /* RGB 565 */ + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_BE, + .depth = 16, + }, { + /* BGR 565 */ + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .depth = 16, + }, { + /* RGB 555 */ + .mbus_code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, + .depth = 16, + }, { + /* BGR 555 */ + .mbus_code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, + .depth = 16, + }, { + /* RGB 444 */ + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, + .depth = 16, + }, { + /* RGB 444 */ + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, + .depth = 16, + }, { + /* RGB 888 */ + .mbus_code = MEDIA_BUS_FMT_RGB888_2X12_LE, + .depth = 24, + }, { + /* BGR 888 */ + .mbus_code = MEDIA_BUS_FMT_RGB888_2X12_BE, + .depth = 24, + }, { + /* BGR 888 */ + .mbus_code = MEDIA_BUS_FMT_RGB888_1X24, + .depth = 24, + }, { + /* YUV 422 8-bit */ + .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16, + .depth = 16, + }, { + /* YUV 422 10-bit */ + .mbus_code = MEDIA_BUS_FMT_UYVY10_1X20, + .depth = 24, + }, { + /* YUV 420 8-bit LEGACY */ + .mbus_code = MEDIA_BUS_FMT_Y8_1X8, + .depth = 8, + }, { + /* YUV 420 8-bit LEGACY */ + .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16, + .depth = 24, + }, { + /* YUV 420 10-bit */ + .mbus_code = MEDIA_BUS_FMT_VUY8_1X24, + .depth = 24, + }, { + /* YUV 420 8-bit */ + .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, + .depth = 24, + }, { + /* YUV 420 10-bit */ + .mbus_code = MEDIA_BUS_FMT_Y10_1X10, + .depth = 10, + }, +}; + +#endif /* _DW_CSI_PLAT_H__ */ diff --git a/driver/csi/dw-csi-sysfs.c b/driver/csi/dw-csi-sysfs.c new file mode 100644 index 0000000..8709561 --- /dev/null +++ b/driver/csi/dw-csi-sysfs.c @@ -0,0 +1,1176 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI CSI-2 Host controller driver. + * SysFS components for the platform driver + * + * Author: Luis Oliveira + */ + +#include "dw-mipi-csi.h" +#include "bm_csi_hw.h" + +static ssize_t core_version_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "v.%d.%d*\n", csi_dev->hw_version_major, + csi_dev->hw_version_minor); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t n_lanes_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long lanes; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &lanes); + if (ret < 0) + return ret; + + if (lanes > 8) { + dev_err(dev, "Invalid number of lanes %lu\n", lanes); + return count; + } + + dev_info(dev, "Lanes %lu\n", lanes); + csi_dev->hw.num_lanes = lanes; + + return count; +} + +static ssize_t n_lanes_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.num_lanes); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t width_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long width; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &width); + if (ret < 0) + return ret; + + dev_info(dev, "width %lu\n", width); + csi_dev->hw.htotal = width; + + return count; +} + +static ssize_t width_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.htotal); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t height_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long height; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &height); + if (ret < 0) + return ret; + + dev_info(dev, "hight %lu\n", height); + csi_dev->hw.vactive = height; + + return count; +} + +static ssize_t height_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.vactive); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + + +static ssize_t core_reset_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + /* Reset Controller and DPHY */ + phy_reset(csi_dev->phy); + dw_mipi_csi_reset(csi_dev); + + snprintf(buffer, 10, "Reset\n"); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t data_type_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long dt; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &dt); + if (ret < 0) + return ret; + + if (dt < 0x18 || dt > 0x2F) { + dev_err(dev, "Invalid data type %lx\n", dt); + return count; + } + + dev_info(dev, "Data type 0x%lx\n", dt); + csi_dev->ipi_dt = dt; + + dw_mipi_csi_set_ipi_fmt(csi_dev); + + return count; +} + +static ssize_t data_type_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->ipi_dt); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +/*******************************************/ +static ssize_t hsa_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hsa; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hsa); + if (ret < 0) + return ret; + + if (hsa > 0xFFF) { + dev_err(dev, "Invalid HSA time %lx\n", hsa); + return count; + } + + dev_info(dev, "HSA time 0x%lx\n", hsa); + csi_dev->hw.hsa = hsa; + + return count; +} + +static ssize_t hsa_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.hsa); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t hbp_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hbp; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hbp); + if (ret < 0) + return ret; + + if (hbp > 0xFFF) { + dev_err(dev, "Invalid HBP time %lx\n", hbp); + return count; + } + + dev_info(dev, "HBP time 0x%lx\n", hbp); + csi_dev->hw.hbp = hbp; + + return count; +} + +static ssize_t hbp_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.hbp); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t hsd_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hsd; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hsd); + if (ret < 0) + return ret; + + if (hsd > 0xFFF) { + dev_err(dev, "Invalid HSD time %lx\n", hsd); + return count; + } + + dev_info(dev, "HSD time 0x%lx\n", hsd); + csi_dev->hw.hsd = hsd; + + return count; +} + +static ssize_t hsd_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.hsd); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi2_hsa_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hsa; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hsa); + if (ret < 0) + return ret; + + if (hsa > 0xFFF) { + dev_err(dev, "Invalid HSA time %lx\n", hsa); + return count; + } + + dev_info(dev, "HSA time 0x%lx\n", hsa); + csi_dev->hw.ipi2_hsa = hsa; + + return count; +} + +static ssize_t ipi2_hsa_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi2_hsa); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi2_hbp_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hbp; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hbp); + if (ret < 0) + return ret; + + if (hbp > 0xFFF) { + dev_err(dev, "Invalid HBP time %lx\n", hbp); + return count; + } + + dev_info(dev, "HBP time 0x%lx\n", hbp); + csi_dev->hw.ipi2_hbp = hbp; + + return count; +} + +static ssize_t ipi2_hbp_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi2_hbp); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi2_hsd_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hsd; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hsd); + if (ret < 0) + return ret; + + if (hsd > 0xFFF) { + dev_err(dev, "Invalid HSD time %lx\n", hsd); + return count; + } + + dev_info(dev, "HSD time 0x%lx\n", hsd); + csi_dev->hw.ipi2_hsd = hsd; + + return count; +} + +static ssize_t ipi2_hsd_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi2_hsd); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi3_hsa_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hsa; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hsa); + if (ret < 0) + return ret; + + if (hsa > 0xFFF) { + dev_err(dev, "Invalid HSA time %lx\n", hsa); + return count; + } + + dev_info(dev, "HSA time 0x%lx\n", hsa); + csi_dev->hw.ipi3_hsa = hsa; + + return count; +} + +static ssize_t ipi3_hsa_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi3_hsa); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi3_hbp_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hbp; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hbp); + if (ret < 0) + return ret; + + if (hbp > 0xFFF) { + dev_err(dev, "Invalid HBP time %lx\n", hbp); + return count; + } + + dev_info(dev, "HBP time 0x%lx\n", hbp); + csi_dev->hw.ipi3_hbp = hbp; + + return count; +} + +static ssize_t ipi3_hbp_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi3_hbp); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi3_hsd_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long hsd; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &hsd); + if (ret < 0) + return ret; + + if (hsd > 0xFFF) { + dev_err(dev, "Invalid HSD time %lx\n", hsd); + return count; + } + + dev_info(dev, "HSD time 0x%lx\n", hsd); + csi_dev->hw.ipi3_hsd = hsd; + + return count; +} + +static ssize_t ipi3_hsd_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.ipi3_hsd); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t vsa_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long vsa; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &vsa); + if (ret < 0) + return ret; + + if (vsa > 0x3FF) { + dev_err(dev, "Invalid VSA period %lx\n", vsa); + return count; + } + + dev_info(dev, "VSA period 0x%lx\n", vsa); + csi_dev->hw.vsa = vsa; + + return count; +} + +static ssize_t vsa_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.vsa); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t vbp_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long vbp; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &vbp); + if (ret < 0) + return ret; + + if (vbp > 0x2FF) { + dev_err(dev, "Invalid VBP period %lx\n", vbp); + return count; + } + + dev_info(dev, "VBP period 0x%lx\n", vbp); + csi_dev->hw.vbp = vbp; + + return count; +} + +static ssize_t vbp_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.vbp); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t vfp_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long vfp; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &vfp); + if (ret < 0) + return ret; + + if (vfp > 0x3ff) { + dev_err(dev, "Invalid VFP period %lx\n", vfp); + return count; + } + + dev_info(dev, "VFP period 0x%lx\n", vfp); + csi_dev->hw.vfp = vfp; + + return count; +} + +static ssize_t vfp_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%x\n", csi_dev->hw.vfp); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi_enable_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long enable_mask; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 16, &enable_mask); + if (ret < 0) + return ret; + + dev_info(dev, "enable_mask 0x%lx\n", enable_mask); + + if (enable_mask & 1) { + csi_dev->hw.ipi1_en = true; + } else { + csi_dev->hw.ipi1_en = false; + } + + if (enable_mask & 2) { + csi_dev->hw.ipi2_en = true; + } else { + csi_dev->hw.ipi2_en = false; + } + + if (enable_mask & 4) { + csi_dev->hw.ipi3_en = true; + } else { + csi_dev->hw.ipi3_en = false; + } + + dw_mipi_csi_start(csi_dev); + printk("enable mask is %lx\n", enable_mask); + return count; +} + +static ssize_t ipi_enable_mask_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + unsigned long enable_mask = 0; + + + if (csi_dev->hw.ipi1_en == true) { + enable_mask |= 1; + } + + if (csi_dev->hw.ipi2_en == true) { + enable_mask |= 2; + } + + if (csi_dev->hw.ipi3_en == true) { + enable_mask |= 4; + } + + snprintf(buffer, 10, "%lx\n", enable_mask); + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t virtual_channel_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long virtual_ch; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &virtual_ch); + if (ret < 0) + return ret; + + if ((signed int)virtual_ch < 0 || (signed int)virtual_ch > 8) { + dev_err(dev, "Invalid Virtual Channel %lu\n", virtual_ch); + return count; + } + + dev_info(dev, "Virtual Channel %lu\n", virtual_ch); + csi_dev->hw.virtual_ch = virtual_ch; + + return count; +} + +static ssize_t virtual_channel_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.virtual_ch); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi2_virtual_channel_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long virtual_ch; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &virtual_ch); + if (ret < 0) + return ret; + + if ((signed int)virtual_ch < 0 || (signed int)virtual_ch > 8) { + dev_err(dev, "Invalid Virtual Channel %lu\n", virtual_ch); + return count; + } + + dev_info(dev, "Virtual Channel %lu\n", virtual_ch); + csi_dev->hw.ipi2_virtual_ch = virtual_ch; + + return count; +} + +static ssize_t ipi2_virtual_channel_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi2_virtual_ch); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi3_virtual_channel_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long virtual_ch; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &virtual_ch); + if (ret < 0) + return ret; + + if ((signed int)virtual_ch < 0 || (signed int)virtual_ch > 8) { + dev_err(dev, "Invalid Virtual Channel %lu\n", virtual_ch); + return count; + } + + dev_info(dev, "Virtual Channel %lu\n", virtual_ch); + csi_dev->hw.ipi3_virtual_ch = virtual_ch; + + return count; +} + +static ssize_t ipi3_virtual_channel_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi3_virtual_ch); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi_color_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long ipi_color_mode; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &ipi_color_mode); + if (ret < 0) + return ret; + + if ((signed int)ipi_color_mode < 0 || (signed int)ipi_color_mode > 1) { + dev_err(dev, + "Wrong Color Mode %lu, (48 bits -> 0 or 16 bits -> 1\n", + ipi_color_mode); + return count; + } + + dev_info(dev, "IPI Color mode %lu\n", ipi_color_mode); + csi_dev->hw.ipi_color_mode = ipi_color_mode; + + return count; +} + +static ssize_t ipi_color_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_color_mode); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi_auto_flush_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long ipi_auto_flush; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &ipi_auto_flush); + if (ret < 0) + return ret; + + if ((signed int)ipi_auto_flush < 0 || (signed int)ipi_auto_flush > 1) { + dev_err(dev, + "Invalid Auto Flush Mode %lu, (No -> 0 or Yes -> 1\n", + ipi_auto_flush); + return count; + } + + dev_info(dev, "IPI Auto Flush %lu\n", ipi_auto_flush); + csi_dev->hw.ipi_auto_flush = ipi_auto_flush; + + return count; +} + +static ssize_t ipi_auto_flush_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_auto_flush); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t ipi_timings_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long ipi_mode; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &ipi_mode); + if (ret < 0) + return ret; + + if ((signed int)ipi_mode < 0 || (signed int)ipi_mode > 1) { + dev_err(dev, + "Invalid Timing Source %lu (Camera:0|Controller:1)\n", + ipi_mode); + return count; + } + + dev_info(dev, "IPI Color mode %lu\n", ipi_mode); + csi_dev->hw.ipi_mode = ipi_mode; + + return count; +} + +static ssize_t ipi_timings_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_mode); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t output_type_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned long output; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &output); + if (ret < 0) + return ret; + + if ((signed int)output < 0 || (signed int)output > 1) { + dev_err(dev, + "Invalid Core output %lu to be used \ + (IPI-> 0 or IDI->1 or BOTH- 2\n", + output); + return count; + } + + dev_info(dev, "IPI Color mode %lu\n", output); + csi_dev->hw.output = output; + + return count; +} + +static ssize_t output_type_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + char buffer[10]; + + snprintf(buffer, 10, "%d\n", csi_dev->hw.output); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t csi_power_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + + int ret; + unsigned long on; + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_csi *csi_dev = &drvdata->csi_dev; + + ret = kstrtoul(buf, 10, &on); + if (ret < 0) + return ret; + + dw_mipi_csi_s_power(csi_dev, on); + printk("csi set power: %lu\n", on); + + return count; +} + +static DEVICE_ATTR_RO(core_version); +static DEVICE_ATTR_RO(core_reset); +static DEVICE_ATTR_RW(n_lanes); +static DEVICE_ATTR_RW(width); +static DEVICE_ATTR_RW(height); +static DEVICE_ATTR_RW(data_type); +static DEVICE_ATTR_RW(hsa); +static DEVICE_ATTR_RW(hbp); +static DEVICE_ATTR_RW(hsd); +static DEVICE_ATTR_RW(vsa); +static DEVICE_ATTR_RW(vbp); +static DEVICE_ATTR_RW(vfp); +static DEVICE_ATTR_RW(virtual_channel); +static DEVICE_ATTR_RW(ipi_color_mode); +static DEVICE_ATTR_RW(ipi_auto_flush); +static DEVICE_ATTR_RW(ipi_timings_mode); +static DEVICE_ATTR_RW(output_type); +static DEVICE_ATTR_WO(csi_power); +static DEVICE_ATTR_RW(ipi2_virtual_channel); +static DEVICE_ATTR_RW(ipi3_virtual_channel); +static DEVICE_ATTR_RW(ipi_enable_mask); +static DEVICE_ATTR_RW(ipi2_hsa); +static DEVICE_ATTR_RW(ipi2_hbp); +static DEVICE_ATTR_RW(ipi2_hsd); +static DEVICE_ATTR_RW(ipi3_hsa); +static DEVICE_ATTR_RW(ipi3_hbp); +static DEVICE_ATTR_RW(ipi3_hsd); + + +int dw_csi_create_capabilities_sysfs(struct platform_device *pdev) +{ + device_create_file(&pdev->dev, &dev_attr_core_version); + device_create_file(&pdev->dev, &dev_attr_core_reset); + device_create_file(&pdev->dev, &dev_attr_n_lanes); + device_create_file(&pdev->dev, &dev_attr_height); + device_create_file(&pdev->dev, &dev_attr_width); + device_create_file(&pdev->dev, &dev_attr_data_type); + device_create_file(&pdev->dev, &dev_attr_hsa); + device_create_file(&pdev->dev, &dev_attr_hbp); + device_create_file(&pdev->dev, &dev_attr_hsd); + device_create_file(&pdev->dev, &dev_attr_vsa); + device_create_file(&pdev->dev, &dev_attr_vbp); + device_create_file(&pdev->dev, &dev_attr_vfp); + device_create_file(&pdev->dev, &dev_attr_virtual_channel); + device_create_file(&pdev->dev, &dev_attr_ipi_color_mode); + device_create_file(&pdev->dev, &dev_attr_ipi_auto_flush); + device_create_file(&pdev->dev, &dev_attr_ipi_timings_mode); + device_create_file(&pdev->dev, &dev_attr_output_type); + device_create_file(&pdev->dev, &dev_attr_csi_power); + device_create_file(&pdev->dev, &dev_attr_ipi2_virtual_channel); + device_create_file(&pdev->dev, &dev_attr_ipi3_virtual_channel); + device_create_file(&pdev->dev, &dev_attr_ipi_enable_mask); + device_create_file(&pdev->dev, &dev_attr_ipi2_hsa); + device_create_file(&pdev->dev, &dev_attr_ipi2_hbp); + device_create_file(&pdev->dev, &dev_attr_ipi2_hsd); + device_create_file(&pdev->dev, &dev_attr_ipi3_hsa); + device_create_file(&pdev->dev, &dev_attr_ipi3_hbp); + device_create_file(&pdev->dev, &dev_attr_ipi3_hsd); + + return 0; +} + +int dw_csi_remove_capabilities_sysfs(struct platform_device *pdev) +{ + device_remove_file(&pdev->dev, &dev_attr_core_version); + device_remove_file(&pdev->dev, &dev_attr_core_reset); + device_remove_file(&pdev->dev, &dev_attr_n_lanes); + device_remove_file(&pdev->dev, &dev_attr_height); + device_remove_file(&pdev->dev, &dev_attr_width); + device_remove_file(&pdev->dev, &dev_attr_data_type); + device_remove_file(&pdev->dev, &dev_attr_hsa); + device_remove_file(&pdev->dev, &dev_attr_hbp); + device_remove_file(&pdev->dev, &dev_attr_hsd); + device_remove_file(&pdev->dev, &dev_attr_vsa); + device_remove_file(&pdev->dev, &dev_attr_vbp); + device_remove_file(&pdev->dev, &dev_attr_vfp); + device_remove_file(&pdev->dev, &dev_attr_virtual_channel); + device_remove_file(&pdev->dev, &dev_attr_ipi_color_mode); + device_remove_file(&pdev->dev, &dev_attr_ipi_auto_flush); + device_remove_file(&pdev->dev, &dev_attr_ipi_timings_mode); + device_remove_file(&pdev->dev, &dev_attr_output_type); + device_remove_file(&pdev->dev, &dev_attr_csi_power); + device_remove_file(&pdev->dev, &dev_attr_ipi2_virtual_channel); + device_remove_file(&pdev->dev, &dev_attr_ipi3_virtual_channel); + device_remove_file(&pdev->dev, &dev_attr_ipi_enable_mask); + device_remove_file(&pdev->dev, &dev_attr_ipi2_hsa); + device_remove_file(&pdev->dev, &dev_attr_ipi2_hbp); + device_remove_file(&pdev->dev, &dev_attr_ipi2_hsd); + device_remove_file(&pdev->dev, &dev_attr_ipi3_hsa); + device_remove_file(&pdev->dev, &dev_attr_ipi3_hbp); + device_remove_file(&pdev->dev, &dev_attr_ipi3_hsd); + + return 0; +} diff --git a/driver/csi/dw-dphy-data.h b/driver/csi/dw-dphy-data.h new file mode 100644 index 0000000..bddd5eb --- /dev/null +++ b/driver/csi/dw-dphy-data.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI D-PHY platform data + * + * Author: Luis Oliveira + */ + +#include +#include +#include + +#ifndef __DW_DPHY_DATA_H__ +#define __DW_DPHY_DATA_H__ + +struct dw_phy_pdata { + u32 dphy_frequency; + u8 dphy_te_len; + u32 config_8l; + u8 dphy_gen; + u8 phy_type; + u8 id; +}; + +static const struct pdata_names phys[] = { + { .name = "phy-dw-dphy.0.0", }, + { .name = "phy-dw-dphy.1.1", }, +}; + +struct dw_dphy_rx; + +struct plat_dw_dphy { + int (*get_resources)(struct device *dev, struct dw_dphy_rx *dphy); +}; +#endif /*__DW_DPHY_DATA_H__ */ diff --git a/driver/csi/dw-dphy-plat.c b/driver/csi/dw-dphy-plat.c new file mode 100644 index 0000000..2fee75f --- /dev/null +++ b/driver/csi/dw-dphy-plat.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI D-PHY controller driver. + * Platform driver + * + * Author: Luis Oliveira + */ + +#include +#include +#include "dw-dphy-rx.h" +#include "bm_csi_hw.h" + +/* Global variable for compatibility mode, this could be override later */ +static int phy_type = 1; //Changed to fit single phy 0 - single | 1 - 8 lanes phy + +module_param(phy_type, int, 0664); +MODULE_PARM_DESC(phy_type, "Disable compatibility mode for D-PHY G128"); + +static struct phy_ops dw_dphy_ops = { + .init = dw_dphy_init, + .reset = dw_dphy_reset, + .power_on = dw_dphy_power_on, + .power_off = dw_dphy_power_off, + .owner = THIS_MODULE, +}; + +static int get_resources(struct device *dev, struct dw_dphy_rx *dphy) +{ + int ret = 0; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_phy_pdata *pdata = &drvdata->dphy_pdata; + + dphy->dphy_freq = pdata->dphy_frequency; + dphy->dphy_te_len = pdata->dphy_te_len; + dphy->dphy_gen = pdata->dphy_gen; + drvdata->dphy = dphy; + + return ret; +} + +static int phy_register(struct device *dev) +{ + int ret = 0; + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + struct dw_phy_pdata *pdata = &drvdata->dphy_pdata; + + ret = phy_create_lookup(dphy->phy, + phys[pdata->id].name, + csis[pdata->id].name); + if (ret) + dev_err(dev, "Failed to create dphy lookup\n"); + else + dev_warn(dev, "Created dphy lookup [%s] --> [%s]\n", + phys[pdata->id].name, csis[pdata->id].name); + + + return ret; +} + +static void phy_unregister(struct device *dev) +{ + if (!dev->of_node) { + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + struct dw_phy_pdata *pdata = &drvdata->dphy_pdata; + + phy_remove_lookup(dphy->phy, + phys[pdata->id].name, csis[pdata->id].name); + dev_warn(dev, "Removed dphy lookup [%s] --> [%s]\n", + phys[pdata->id].name, csis[pdata->id].name); + } +} + +#define REG_DPHY_OFFSET 0x40 +int dw_dphy_rx_probe(struct platform_device *pdev, unsigned int dphyglueiftester, unsigned int sysreg_mipi_csi_ctrl) +{ + struct device *dev = &pdev->dev; + struct dw_dphy_rx *dphy; + struct bm_csi_drvdata *drvdata; + + dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); + if (!dphy) + return -ENOMEM; + + drvdata = platform_get_drvdata(pdev); + dphy->base_address = drvdata->base + REG_DPHY_OFFSET; + drvdata->dphy= dphy; + dphy->dphyglueiftester = dphyglueiftester; + dphy->sysreg_mipi_csi_ctrl = sysreg_mipi_csi_ctrl; + + if (IS_ERR(dphy->base_address)) { + dev_err(&pdev->dev, "error requesting base address\n"); + return PTR_ERR(dphy->base_address); + } + + if (get_resources(dev, dphy)) { + dev_err(dev, "failed to parse PHY resources\n"); + return -EINVAL; + } + + dphy->phy = devm_phy_create(dev, NULL, &dw_dphy_ops); + if (IS_ERR(dphy->phy)) { + dev_err(dev, "failed to create PHY\n"); + return PTR_ERR(dphy->phy); + } + + phy_set_drvdata(dphy->phy, dphy); + + if (phy_register(dev)) { + dev_err(dev, "failed to register PHY\n"); + return -EINVAL; + } + + dphy->lp_time = 1000; /* 1000 ns */ + dphy->lanes_config = dw_dphy_setup_config(dphy); + + dev_info(&dphy->phy->dev, "Probing dphy finished\n"); + + dw_dphy_create_capabilities_sysfs(pdev); + + return 0; +} + +int dw_dphy_rx_remove(struct platform_device *pdev) +{ + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + + dev_info(&dphy->phy->dev, "phy removed\n"); + + phy_reset(dphy->phy); + phy_unregister(&pdev->dev); + dw_dphy_remove_capabilities_sysfs(pdev); + + return 0; +} + +MODULE_DESCRIPTION("Synopsys DesignWare MIPI DPHY Rx driver"); +MODULE_AUTHOR("Luis Oliveira "); +MODULE_LICENSE("GPL v2"); diff --git a/driver/csi/dw-dphy-rx.c b/driver/csi/dw-dphy-rx.c new file mode 100644 index 0000000..9fc4453 --- /dev/null +++ b/driver/csi/dw-dphy-rx.c @@ -0,0 +1,966 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI D-PHY controller driver + * Core functions + * + * Author: Luis Oliveira + */ + +#include "dw-dphy-rx.h" +#include "bm_csi_dphy.h" +#include "bm_printk.h" +#include + +struct range_dphy_gen2 { + u32 freq; + u8 hsfregrange; +}; + +struct range_dphy_gen2 range_gen2[] = { + { 80, 0x00 }, { 90, 0x10 }, { 100, 0x20 }, { 110, 0x30 }, + { 120, 0x01 }, { 130, 0x11 }, { 140, 0x21 }, { 150, 0x31 }, + { 160, 0x02 }, { 170, 0x12 }, { 180, 0x22 }, { 190, 0x32 }, + { 205, 0x03 }, { 220, 0x13 }, { 235, 0x23 }, { 250, 0x33 }, + { 275, 0x04 }, { 300, 0x14 }, { 325, 0x05 }, { 350, 0x15 }, + { 400, 0x25 }, { 450, 0x06 }, { 500, 0x16 }, { 550, 0x07 }, + { 600, 0x17 }, { 650, 0x08 }, { 700, 0x18 }, { 750, 0x09 }, + { 800, 0x19 }, { 850, 0x29 }, { 900, 0x39 }, { 950, 0x0A }, + { 1000, 0x1A }, { 1050, 0x2A }, { 1100, 0x3A }, { 1150, 0x0B }, + { 1200, 0x1B }, { 1250, 0x2B }, { 1300, 0x3B }, { 1350, 0x0C }, + { 1400, 0x1C }, { 1450, 0x2C }, { 1500, 0x3C }, { 1550, 0x0D }, + { 1600, 0x1D }, { 1650, 0x2D }, { 1700, 0x0E }, { 1750, 0x1E }, + { 1800, 0x2E }, { 1850, 0x3E }, { 1900, 0x0F }, { 1950, 0x1F }, + { 2000, 0x2F }, +}; + +struct range_dphy_gen3 { + u32 freq; + u8 hsfregrange; + u32 osc_freq_target; +}; + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +struct range_dphy_gen3 range_gen3[] = { + { 80, 0x00, 0x1B6 }, { 90, 0x10, 0x1B6 }, { 100, 0x20, 0x1B6 }, + { 110, 0x30, 0x1B6 }, { 120, 0x01, 0x1B6 }, { 130, 0x11, 0x1B6 }, + { 140, 0x21, 0x1B6 }, { 150, 0x31, 0x1B6 }, { 160, 0x02, 0x1B6 }, + { 170, 0x12, 0x1B6 }, { 180, 0x22, 0x1B6 }, { 190, 0x32, 0x1B6 }, + { 205, 0x03, 0x1B6 }, { 220, 0x13, 0x1B6 }, { 235, 0x23, 0x1B6 }, + { 250, 0x33, 0x1B6 }, { 275, 0x04, 0x1B6 }, { 300, 0x14, 0x1B6 }, + { 325, 0x25, 0x1B6 }, { 350, 0x35, 0x1B6 }, { 400, 0x05, 0x1B6 }, + { 450, 0x16, 0x1B6 }, { 500, 0x26, 0x1B6 }, { 550, 0x37, 0x1B6 }, + { 600, 0x07, 0x1B6 }, { 650, 0x18, 0x1B6 }, { 700, 0x28, 0x1B6 }, + { 750, 0x39, 0x1B6 }, { 800, 0x09, 0x1B6 }, { 850, 0x19, 0x1B6 }, + { 900, 0x29, 0x1B6 }, { 950, 0x3A, 0x1B6 }, { 1000, 0x0A, 0x1B6 }, + { 1050, 0x1A, 0x1B6 }, { 1100, 0x2A, 0x1B6 }, { 1150, 0x3B, 0x1B6 }, + { 1200, 0x0B, 0x1B6 }, { 1250, 0x1B, 0x1B6 }, { 1300, 0x2B, 0x1B6 }, + { 1350, 0x3C, 0x1B6 }, { 1400, 0x0C, 0x1B6 }, { 1450, 0x1C, 0x1B6 }, + { 1500, 0x2C, 0x1B6 }, { 1550, 0x3D, 0x10F }, { 1600, 0x0D, 0x118 }, + { 1650, 0x1D, 0x121 }, { 1700, 0x2E, 0x12A }, { 1750, 0x3E, 0x132 }, + { 1800, 0x0E, 0x13B }, { 1850, 0x1E, 0x144 }, { 1900, 0x2F, 0x14D }, + { 1950, 0x3F, 0x155 }, { 2000, 0x0F, 0x15E }, { 2050, 0x40, 0x167 }, + { 2100, 0x41, 0x170 }, { 2150, 0x42, 0x178 }, { 2200, 0x43, 0x181 }, + { 2250, 0x44, 0x18A }, { 2300, 0x45, 0x193 }, { 2350, 0x46, 0x19B }, + { 2400, 0x47, 0x1A4 }, { 2450, 0x48, 0x1AD }, { 2500, 0x49, 0x1B6 } +}; +#else +//for asic +struct range_dphy_gen3 range_gen3[] = { //TODO 根据手册更新osc_freq_target的值。 + { 80, 0x00, 460 }, { 90, 0x10, 460 }, { 100, 0x20, 460 }, + { 110, 0x30, 460 }, { 120, 0x01, 460 }, { 130, 0x11, 460 }, + { 140, 0x21, 460 }, { 150, 0x31, 460 }, { 160, 0x02, 460 }, + { 170, 0x12, 460 }, { 180, 0x22, 460 }, { 190, 0x32, 460 }, + { 205, 0x03, 460 }, { 220, 0x13, 460 }, { 235, 0x23, 460 }, + { 250, 0x33, 460 }, { 275, 0x04, 460 }, { 300, 0x14, 460 }, + { 325, 0x25, 460 }, { 350, 0x35, 460 }, { 400, 0x05, 460 }, + { 450, 0x16, 460 }, { 500, 0x26, 460 }, { 550, 0x37, 460 }, + { 600, 0x07, 460 }, { 650, 0x18, 460 }, { 700, 0x28, 460 }, + { 750, 0x39, 460 }, { 800, 0x09, 460 }, { 850, 0x19, 460 }, + { 900, 0x29, 460 }, { 950, 0x3A, 460 }, { 1000, 0x0A, 460 }, + { 1050, 0x1A, 460 }, { 1100, 0x2A, 460 }, { 1150, 0x3B, 460 }, + { 1200, 0x0B, 460 }, { 1250, 0x1B, 460 }, { 1300, 0x2B, 460 }, + { 1350, 0x3C, 460 }, { 1400, 0x0C, 460 }, { 1450, 0x1C, 460 }, + { 1500, 0x2C, 460 }, { 1550, 0x3D, 285 }, { 1600, 0x0D, 295 }, + { 1650, 0x1D, 304 }, { 1700, 0x2E, 313 }, { 1750, 0x3E, 322 }, + { 1800, 0x0E, 331 }, { 1850, 0x1E, 341 }, { 1900, 0x2F, 350 }, + { 1950, 0x3F, 359 }, { 2000, 0x0F, 368 }, { 2050, 0x40, 377 }, + { 2100, 0x41, 387 }, { 2150, 0x42, 396 }, { 2200, 0x43, 405 }, + { 2250, 0x44, 414 }, { 2300, 0x45, 423 }, { 2350, 0x46, 432 }, + { 2400, 0x47, 442 }, { 2450, 0x48, 451 }, { 2500, 0x49, 460 } +}; +#endif + +u8 dw_dphy_setup_config(struct dw_dphy_rx *dphy) +{ +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +#if 0 + int ret; + + if (dphy->max_lanes == CTRL_4_LANES) { + dev_vdbg(&dphy->phy->dev, "CONFIG 4L\n"); + return CTRL_4_LANES; + } + if (IS_ENABLED(CONFIG_OF)) { + ret = gpio_request(dphy->config_8l, "config"); + if (ret < 0) { + dev_vdbg(&dphy->phy->dev, + "could not acquire config (err=%d)\n", ret); + return ret; + } + ret = gpio_get_value(dphy->config_8l); + gpio_free(dphy->config_8l); + } else { + ret = dphy->config_8l; + } + + dev_vdbg(&dphy->phy->dev, + "Booting in [%s] mode\n", + ret == CTRL_8_LANES ? "8L" : "4+4L"); + return ret; +#endif +#endif /* CONFIG_DWC_MIPI_TC_DPHY_GEN3 */ + return CTRL_4_LANES; +} + +extern int k_bm_visys_write_reg(uint32_t offset, uint32_t value); +extern int k_bm_visys_read_reg(uint32_t offset, uint32_t *value); + +void dw_dphy_if_write(struct dw_dphy_rx *dphy, u32 address, u32 data) +{ + //writel(data, dphy->dphy1_if_addr + address); + k_bm_visys_write_reg(address, data); +} + +u32 dw_dphy_if_read(struct dw_dphy_rx *dphy, u32 address) +{ + u32 if1 = 0; + //if1 = readl(dphy->dphy1_if_addr + address); + k_bm_visys_read_reg(address, &if1); + return if1; +} + +void dw_dphy_write(struct dw_dphy_rx *dphy, u32 address, u32 data) +{ + writel(data, dphy->base_address + address); + + if (dphy->lanes_config == CTRL_4_LANES) + return; + return; + + if (address == R_CSI2_DPHY_TST_CTRL0) + iowrite32(data, dphy->base_address + R_CSI2_DPHY2_TST_CTRL0); + else if (address == R_CSI2_DPHY_TST_CTRL1) + iowrite32(data, dphy->base_address + R_CSI2_DPHY2_TST_CTRL1); +} + +u32 dw_dphy_read(struct dw_dphy_rx *dphy, u32 address) +{ + int dphy1 = 0, dphy2 = 0; + + dphy1 = readl(dphy->base_address + address); + + if (dphy->lanes_config == CTRL_4_LANES) + goto end; + + goto end; + + if (address == R_CSI2_DPHY_TST_CTRL0) + dphy2 = ioread32(dphy->base_address + R_CSI2_DPHY2_TST_CTRL0); + else if (address == R_CSI2_DPHY_TST_CTRL1) + dphy2 = ioread32(dphy->base_address + R_CSI2_DPHY2_TST_CTRL1); + else + return -ENODEV; +end: + return dphy1; +} + +void dw_dphy_write_msk(struct dw_dphy_rx *dev, u32 address, u32 data, u8 shift, + u8 width) +{ + u32 temp = dw_dphy_read(dev, address); + u32 mask = (1 << width) - 1; + + temp &= ~(mask << shift); + temp |= (data & mask) << shift; + dw_dphy_write(dev, address, temp); +} + +static void dw_dphy_te_12b_write(struct dw_dphy_rx *dphy, u16 addr, u8 data) +{ + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0x00, PHY_TESTDIN, 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)(addr >> 8), + PHY_TESTDIN, 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)addr, PHY_TESTDIN, + 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)data, PHY_TESTDIN, + 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); +} + +static void dw_dphy_te_8b_write(struct dw_dphy_rx *dphy, u8 addr, u8 data) +{ + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write(dphy, R_CSI2_DPHY_TST_CTRL1, addr); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + dw_dphy_write(dphy, R_CSI2_DPHY_TST_CTRL1, data); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); +} + +static void dw_dphy_te_write(struct dw_dphy_rx *dphy, u16 addr, u8 data) +{ + dphy->dphy_te_len = BIT12; + if (dphy->dphy_te_len == BIT12) + dw_dphy_te_12b_write(dphy, addr, data); + else + dw_dphy_te_8b_write(dphy, addr, data); +} + +static int dw_dphy_te_12b_read(struct dw_dphy_rx *dphy, u32 addr) +{ + u8 ret; + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0x00, PHY_TESTDIN, 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)(addr >> 8), + PHY_TESTDIN, 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)addr, PHY_TESTDIN, + 8); + + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0x00, 0, PHY_TESTDIN); + + ret = dw_dphy_read_msk(dphy, R_CSI2_DPHY_TST_CTRL1, PHY_TESTDOUT, 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + + return ret; +} + +static int dw_dphy_te_8b_read(struct dw_dphy_rx *dphy, u32 addr) +{ + u8 ret; + + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, addr, PHY_TESTDIN, 8); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTDIN, 8); + ret = dw_dphy_read_msk(dphy, R_CSI2_DPHY_TST_CTRL1, PHY_TESTDOUT, 8); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1); + + return ret; +} + +int dw_dphy_te_read(struct dw_dphy_rx *dphy, u32 addr) +{ + int ret; + + if (dphy->dphy_te_len == BIT12) + ret = dw_dphy_te_12b_read(dphy, addr); + else + ret = dw_dphy_te_12b_read(dphy, addr); + //ret = dw_dphy_te_8b_read(dphy, addr); + + return ret; +} + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +static void dw_dphy_if_init(struct dw_dphy_rx *dphy) +{ + bm_info("enter %s\n", __func__); + //dw_dphy_if_write(dphy, dphy->dphy1_if_addr, RESET); + //dw_dphy_if_write(dphy, dphy->dphy1_if_addr, TX_PHY); + //dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1); + //dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1); + //dw_dphy_if_write(dphy, DPHYZCALCTRL, 0); + //dw_dphy_if_write(dphy, DPHYZCALCTRL, 1); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RESET); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, GLUELOGIC); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1); + //dw_dphy_if_write(dphy, DPHYZCALCTRL, 0); + //dw_dphy_if_write(dphy, DPHYZCALCTRL, 1); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RESET); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RX_PHY); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1); + //dw_dphy_if_write(dphy, DPHYZCALCTRL, 0); + //dw_dphy_if_write(dphy, DPHYZCALCTRL, 1); +} +#endif + +static void dw_dphy_gen3_12bit_tc_power_up(struct dw_dphy_rx *dphy, uint8_t hsfregrange) +{ +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RESET); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, GLUELOGIC); //用fpga时候是写到子板专有寄存器内,芯片要写到visys reg + dw_dphy_te_write(dphy, CFGCLKFREQRANGE_RX, 0x1C); //TODO ASCI 改为通过vi sys寄存器去配置src clk + dw_dphy_te_write(dphy, 0x6, hsfregrange); //TODO ASCI 改为通过vi sys寄存器去配置src clk +#endif + + +#if !IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + u32 reg_val = 0; + reg_val = dw_dphy_if_read(dphy, dphy->sysreg_mipi_csi_ctrl); //TODO ASCI 改为通过vi sys寄存器去配置src clk + reg_val &= ~0x3f; + reg_val |= 0x1c; + dw_dphy_if_write(dphy, dphy->sysreg_mipi_csi_ctrl, reg_val); //TODO ASCI 改为通过vi sys寄存器去配置src clk + reg_val &= ~(0x7f << 8); + reg_val |= (hsfregrange << 8); + dw_dphy_if_write(dphy, dphy->sysreg_mipi_csi_ctrl, reg_val); //TODO ASCI 改为通过vi sys寄存器去配置src clk +#endif + + /* CLKSEL | UPDATEPLL | SHADOW_CLEAR | SHADOW_CTRL | FORCEPLL */ + //dw_dphy_te_write(dphy, BYPASS, 0x3F); + /* IO_DS3 | IO_DS2 | IO_DS1 | IO_DS0 */ + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + if ((dphy->dphy_freq/1000) > 1500) { + dw_dphy_te_write(dphy, IO_DS, 0x0F); + } + + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RESET); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RX_PHY | 0x2); +#endif +} + +static void dw_dphy_gen3_8bit_tc_power_up(struct dw_dphy_rx *dphy) +{ + u32 input_freq = dphy->dphy_freq / 1000; +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RESET); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, GLUELOGIC); + dw_dphy_te_write(dphy, CFGCLKFREQRANGE_RX, 0x1C); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RESET); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, RX_PHY); +#endif + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX0_MSB, 0x03); + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX0_LSB, 0x02); + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX1_MSB, 0x03); + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX1_LSB, 0x02); + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX2_MSB, 0x03); + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX2_LSB, 0x02); + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX3_MSB, 0x03); + dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX3_LSB, 0x02); + dw_dphy_te_write(dphy, BANDGAP_CTRL, 0x80); + + if (input_freq < 2000) + dw_dphy_te_write(dphy, HS_RX_CTRL_LANE0, 0xC0); + + if (input_freq < 1000) { + dw_dphy_te_write(dphy, HS_RX_CTRL_LANE1, 0xC0); + dw_dphy_te_write(dphy, HS_RX_CTRL_LANE2, 0xC0); + dw_dphy_te_write(dphy, HS_RX_CTRL_LANE3, 0xC0); + } +} + +int dw_dphy_g118_settle(struct dw_dphy_rx *dphy) +{ + u32 input_freq, total_settle, settle_time, byte_clk, lp_time; + + lp_time = dphy->lp_time; + input_freq = dphy->dphy_freq / 1000; + + settle_time = (8 * (1000000 / (input_freq))) + 115000; + byte_clk = (8000000 / (input_freq)); + total_settle = (settle_time + lp_time * 1000) / byte_clk; + + if (total_settle > 0xFF) + total_settle = 0xFF; + + return total_settle; +} + +static void dw_dphy_pwr_down(struct dw_dphy_rx *dphy) +{ + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); + + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1); + if (dphy->lanes_config == CTRL_8_LANES) + dw_dphy_write_msk(dphy, R_CSI2_DPHY2_TST_CTRL0, 0, PHY_TESTCLK, 1); + + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0); +} + +static void dw_dphy_pwr_up(struct dw_dphy_rx *dphy) +{ + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1); + if (dphy->lanes_config == CTRL_8_LANES) + dw_dphy_write_msk(dphy, R_CSI2_DPHY2_TST_CTRL0, 1, PHY_TESTCLK, + 1); + dev_vdbg(&dphy->phy->dev, "DPHY power up.\n"); + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1); + udelay(1); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); + udelay(1); +} + +static int dw_dphy_gen3_12bit_configure(struct dw_dphy_rx *dphy, int abphy_flag) +{ + u32 input_freq = dphy->dphy_freq; + u8 range = 0; + u32 reg_val = 0; + + dev_vdbg(&dphy->phy->dev, "12bit: PHY GEN 3: Freq: %u\n", input_freq); + for (range = 0; (range < ARRAY_SIZE(range_gen3) - 1) && + ((input_freq / 1000) > range_gen3[range].freq); + range++); + + input_freq /= 1000; + + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1); + udelay(1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1); + + dw_dphy_gen3_12bit_tc_power_up(dphy, range_gen3[range].hsfregrange); + + //uint8_t lp_time = dphy->lp_time; + //dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_17, lp_time);//SET SETTLE TIME + + //位置1 + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_te_write(dphy, RX_SYS_1, range_gen3[range].hsfregrange); + dw_dphy_te_write(dphy, RX_SYS_0, 0x20); + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_2, 0xcc); +#else + //used for asic + if (input_freq > 1500) { + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_2, (u8)(range_gen3[range].osc_freq_target & 0xff)); + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_3, (u8)(range_gen3[range].osc_freq_target >> 8)); + } +#endif + + + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_4, 0x21); //TODO fpga val=0x21, chip val=0x11 + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_5, 0x01); //TODO 顺序位置配置可能需要调到位置1 +#else + + reg_val = dw_dphy_te_read(dphy, RX_RX_STARTUP_OVR_4); + reg_val &= ~(0xf0); + reg_val |= (1 << 4); + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_4, reg_val); + + if (input_freq > 1500) { + reg_val = dw_dphy_te_read(dphy, RX_RX_STARTUP_OVR_4); + reg_val |= 1; + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_4, reg_val); //TODO fpga val=0x21, chip val=0x11 + } + + reg_val = dw_dphy_te_read(dphy, RX_RX_STARTUP_OVR_5); + reg_val |= 1; + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_5, reg_val); //TODO 顺序位置配置可能需要调到位置1 + + reg_val = dw_dphy_te_read(dphy, RX_RX_CB_1); //TODO used to chip + reg_val &= ~0x3; + reg_val |= 2; + dw_dphy_te_write(dphy, RX_RX_CB_1, reg_val); //TODO used to chip + + + reg_val = dw_dphy_te_read(dphy, RX_RX_CB_2); //TODO used to chip + reg_val |= (1 << 6); + dw_dphy_te_write(dphy, RX_RX_CB_2, reg_val); //TODO used to chip + + + if (abphy_flag) { + reg_val = dw_dphy_te_read(dphy, RX_RX_CLKLANE_LANE_6); //TODO used to chip + reg_val |= (1 << 7); + dw_dphy_te_write(dphy, RX_RX_CLKLANE_LANE_6, reg_val); //TODO used to chip + } + + if (input_freq <= 1500) { + reg_val = dw_dphy_te_read(dphy, 0x607); //TODO used to chip + reg_val |= 0x3f; + dw_dphy_te_write(dphy, 0x607, reg_val); //TODO used to chip + + reg_val = dw_dphy_te_read(dphy, 0x807); //TODO used to chip + reg_val |= 0x3f; + dw_dphy_te_write(dphy, 0x807, reg_val); //TODO used to chip + + reg_val = dw_dphy_te_read(dphy, 0xa07); //TODO used to chip + reg_val |= 0x3f; + dw_dphy_te_write(dphy, 0xa07, reg_val); //TODO used to chip + + reg_val = dw_dphy_te_read(dphy, 0xc07); //TODO used to chip + reg_val |= 0x3f; + dw_dphy_te_write(dphy, 0xc07, reg_val); //TODO used to chip + } else { + dw_dphy_te_write(dphy, RX_SYS_9, 0x43); //TODO used to chip + } + + //for chip dphy->sysreg_mipi_csi_ctrl: csi2_0, csi2_1, csi2_2 -> 0x140, 0x144, 0x148 + reg_val = dw_dphy_if_read(dphy, dphy->sysreg_mipi_csi_ctrl); + reg_val |= (1 << 28) | (1 << 25) | (7 << 20); + dw_dphy_if_write(dphy, dphy->sysreg_mipi_csi_ctrl, reg_val); //TODO set visys reg basedir_0 =1, set visys reg forcerxmode_0123=1 +#endif + + udelay(1); + + if (dphy->phy_type) { +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_1, 0x01); + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_0, 0x80); +#endif + } + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_te_write(dphy, RX_SYS_3, 0x59); +#endif + + if (dphy->phy_type || input_freq <= 1500) { + reg_val = dw_dphy_te_read(dphy, RX_SYS_7); + reg_val |= (1 << 5); + dw_dphy_te_write(dphy, RX_SYS_7, reg_val); + } + + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); + udelay(1); + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1); + + udelay(600); + + //TODO set visys reg mipi_csi2x2_a_forcerxmode_0=0 这个先不要配置,应该不需要设置为0 + + reg_val = dw_dphy_if_read(dphy, dphy->sysreg_mipi_csi_ctrl); + reg_val &= ~((1 << 25) | (7 << 20)); + dw_dphy_if_write(dphy, dphy->sysreg_mipi_csi_ctrl, reg_val); //TODO set visys reg basedir_0 =1, set visys reg forcerxmode_0123=0 + return 0; +} + +static void dw_dphy_combination_4lane_switch_master(struct dw_dphy_rx *dphy) +{ + u32 sys_reg_val = 0; + sys_reg_val = dw_dphy_if_read(dphy, dphy->sysreg_mipi_csi_ctrl); + sys_reg_val |= 1; + dw_dphy_if_write(dphy, dphy->sysreg_mipi_csi_ctrl, sys_reg_val); //切换寄存器到master +} + +static void dw_dphy_combination_4lane_switch_slave(struct dw_dphy_rx *dphy) +{ + u32 sys_reg_val = 0; + sys_reg_val = dw_dphy_if_read(dphy, dphy->sysreg_mipi_csi_ctrl); + sys_reg_val &= ~1; + dw_dphy_if_write(dphy, dphy->sysreg_mipi_csi_ctrl, sys_reg_val); //切换寄存器到slave +} + +#if !IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +//用于dphy 两个2lane组合成4lane的模式下phy初始化 +static int dw_dphy_12bit_combination_4lane_configure(struct dw_dphy_rx *dphy) +{ + u32 input_freq = dphy->dphy_freq; + u32 phy_reg_val = 0; + u8 range = 0; + + dw_dphy_pwr_down(dphy); + dev_vdbg(&dphy->phy->dev, "12bit: PHY GEN 3: Freq: %u\n", input_freq); + for (range = 0; (range < ARRAY_SIZE(range_gen3) - 1) && + ((input_freq / 1000) > range_gen3[range].freq); + range++); + + + //Define master PHY and slave PHY and configure each accordingly + //(this choice needs to be coherent with wiring connections mentioned above): + dw_dphy_combination_4lane_switch_master(dphy); + dw_dphy_te_write(dphy, RX_RX_DUAL_PHY_0, 0x01); //2lane合并为4lane,设置master + dw_dphy_combination_4lane_switch_slave(dphy); + dw_dphy_te_write(dphy, RX_RX_DUAL_PHY_0, 0x00); //2lane合并为4lane,设置slave + + //Configure master PHY clock lane to drive long channel clock + dw_dphy_combination_4lane_switch_master(dphy); + phy_reg_val = dw_dphy_te_read(dphy, RX_RX_CLKLANE_LANE_6); + phy_reg_val |= (1 << 2); + dw_dphy_te_write(dphy, RX_RX_CLKLANE_LANE_6, phy_reg_val); //2lane合并为4lane,设置master + + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val &= ~(1 << 2); + dw_dphy_te_write(dphy, RX_RX_CLKLANE_LANE_6, phy_reg_val); //2lane合并为4lane,设置slave + + //Configure both master and slave PHY data lanes to get clock from long channel: + dw_dphy_combination_4lane_switch_master(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x508); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0x508, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x508); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0x508, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_master(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x708); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0x708, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x708); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0x708, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_master(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x908); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0x908, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x908); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0x908, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_master(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0xB08); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0xB08, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0xB08); + phy_reg_val |= (1 << 5); + dw_dphy_te_write(dphy, 0xB08, phy_reg_val); //2lane合并为4lane,设置slave + + //Configure slave PHY clock lane to bypass long channel clock to DDR clock: + dw_dphy_combination_4lane_switch_master(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x308); + phy_reg_val &= ~(1 << 3); + dw_dphy_te_write(dphy, 0x308, phy_reg_val); //2lane合并为4lane,设置slave + + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x308); + phy_reg_val |= (1 << 3); + dw_dphy_te_write(dphy, 0x308, phy_reg_val); //2lane合并为4lane,设置slave + + //Override slave PHY DDR clock lane enable (DPHYHSRX_div124 module): + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x0e1); + phy_reg_val |= (1 << 1); + dw_dphy_te_write(dphy, 0x0e1, phy_reg_val); //2lane合并为4lane,设置slave + + phy_reg_val = dw_dphy_te_read(dphy, RX_RX_CLKLANE_LANE_6); + phy_reg_val |= (1 << 3); + dw_dphy_te_write(dphy, RX_RX_CLKLANE_LANE_6, phy_reg_val); //2lane合并为4lane,设置slave + + //Turn off slave PHY LP-RX clock lane: + dw_dphy_combination_4lane_switch_slave(dphy); + phy_reg_val = dw_dphy_te_read(dphy, 0x304); + phy_reg_val &= ~0x1f; + phy_reg_val |= 0xa; + dw_dphy_te_write(dphy, 0x304, phy_reg_val); //2lane合并为4lane,设置slave + + + //Configure both PHYs as described in“Start-Up Sequence” on page 81 + //until step enable_n and enableclk=1'b1 (skip step Configure register + //0x307 to set rxclk_rxhs_pull_long_channel_if_rw signal (bit 8) to 1'b1). + dw_dphy_gen3_12bit_configure(dphy, 1); + + + //Set shutdownz=1'b1 in master and slave PHYs. + dw_dphy_combination_4lane_switch_master(dphy); + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1); + dw_dphy_combination_4lane_switch_slave(dphy); + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1); + + //Release reset for master PHY (rstz=1'b1). + dw_dphy_combination_4lane_switch_master(dphy); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); + + udelay(1); + //Release reset for slave PHY (rstz=1'b1). + dw_dphy_combination_4lane_switch_slave(dphy); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); + + udelay(600); + //Set forcerxmode_n in master and slave PHY = 1'b0. + //??? + + + + +#if 0 + dw_dphy_gen3_12bit_tc_power_up(dphy, range_gen3[range].hsfregrange); + + //uint8_t lp_time = dphy->lp_time; + //dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_17, lp_time);//SET SETTLE TIME + + //位置1 + dw_dphy_te_write(dphy, RX_SYS_1, range_gen3[range].hsfregrange); + dw_dphy_te_write(dphy, RX_SYS_0, 0x20); + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_2, 0xcc); +#else + //used for asic + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_2, (u8)(range_gen3[range].osc_freq_target & 0xff)); +#endif + + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_3, + (u8)(range_gen3[range].osc_freq_target >> 8)); + + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_4, 0x21); //TODO fpga val=0x21, chip val=0x11 + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_5, 0x01); //TODO 顺序位置配置可能需要调到位置1 +#else + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_4, 0x11); //TODO fpga val=0x21, chip val=0x11 + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_5, 0x01); //TODO 顺序位置配置可能需要调到位置1 + dw_dphy_te_write(dphy, RX_RX_CB_1, 0x02); //TODO used to chip + dw_dphy_te_write(dphy, RX_RX_CB_2, 0x1 << 6); //TODO used to chip + dw_dphy_te_write(dphy, RX_SYS_9, 0x43); //TODO used to chip + dw_dphy_te_write(dphy, RX_RX_CLKLANE_LANE_6, 0x1 << 7); //TODO used to chip + + //for chip dphy->dphyglueiftester : csi2_0, csi2_1, csi2_2 -> 0x140, 0x144, 0x148 + reg_val = dw_dphy_if_read(dphy, dphy->dphyglueiftester); + reg_val |= (1 << 28) | (1 << 25); + dw_dphy_if_write(dphy, dphy->dphyglueiftester, reg_val); //TODO set visys reg basedir_0 =1, set visys reg forcerxmode_0=1 +#endif + + if (dphy->phy_type) { + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_1, 0x01); + dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_0, 0x80); + } + + dw_dphy_te_write(dphy, RX_SYS_3, 0x59); + + dw_dphy_te_write(dphy, RX_SYS_7, 0x38); + if (dphy->phy_type || input_freq <= 1500) + dw_dphy_te_write(dphy, RX_SYS_7, 0x38); + + //TODO set visys reg mipi_csi2x2_a_forcerxmode_0=0 这个先不要配置,应该不需要设置为0 + //reg_val &= ~(1 << 25); + //dw_dphy_if_write(dphy, dphy->dphyglueiftester, reg_val); +#endif + return 0; +} +#endif + + +static int dw_dphy_gen3_8bit_configure(struct dw_dphy_rx *dphy) +{ + u32 input_freq = dphy->dphy_freq; + u8 data; + u8 range = 0; + + dev_vdbg(&dphy->phy->dev, "8bit: PHY GEN 3: Freq: %u\n", input_freq); + for (range = 0; (range < ARRAY_SIZE(range_gen3) - 1) && + ((input_freq / 1000) > range_gen3[range].freq); + range++) + ; + + dw_dphy_te_write(dphy, RX_SKEW_CAL, dw_dphy_g118_settle(dphy)); + data = 1 << 7 | range_gen3[range].hsfregrange; + dw_dphy_te_write(dphy, HSFREQRANGE_8BIT, data); + dw_dphy_gen3_8bit_tc_power_up(dphy); + + return 0; +} + +static int dw_dphy_gen2_configure(struct dw_dphy_rx *dphy) +{ + u32 input_freq = dphy->dphy_freq; + u8 data; + u8 range = 0; + + /* provide an initial active-high test clear pulse in TESTCLR */ + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1); + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1); + + dev_vdbg(&dphy->phy->dev, "PHY GEN 2: Freq: %u\n", input_freq); + for (range = 0; (range < ARRAY_SIZE(range_gen2) - 1) && + ((input_freq / 1000) > range_gen2[range].freq); range++) + ; + + data = range_gen2[range].hsfregrange << 1; + dw_dphy_te_write(dphy, HSFREQRANGE_8BIT, data); + + return 0; +} + +static int dw_dphy_configure(struct dw_dphy_rx *dphy) +{ + + bm_info("enter %s\n", __func__); + dw_dphy_pwr_down(dphy); + dphy->dphy_gen = GEN3; + if (dphy->dphy_gen == GEN3) { +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + dw_dphy_if_init(dphy); +#endif + dphy->dphy_te_len = BIT12; + if (dphy->dphy_te_len == BIT12) + dw_dphy_gen3_12bit_configure(dphy, 1); + else + dw_dphy_gen3_8bit_configure(dphy); + } else { + dw_dphy_gen2_configure(dphy); + } + dw_dphy_pwr_up(dphy); + + return 0; +} + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + +#if 0 +int dw_dphy_if_set_idelay(struct dw_dphy_rx *dphy, u8 dly, u8 cells) +{ + u32 val = 0; + + dw_dphy_if_write(dphy, IDLYCFG, 0); + dw_dphy_if_write(dphy, IDLYSEL, cells); + dw_dphy_if_write(dphy, IDLYCNTINVAL, dly); + + /* Pulse Value Set */ + dw_dphy_if_write(dphy, IDLYCFG, 1); + usleep_range(10, 20); + dw_dphy_if_write(dphy, IDLYCFG, 0); + + /* Pulse IDELAY CTRL Reset */ + dw_dphy_if_write(dphy, DPHY1REGRSTN, 0); + usleep_range(10, 20); + dw_dphy_if_write(dphy, DPHY1REGRSTN, 1); + + /* Get Value*/ + val = dw_dphy_if_read(dphy, IDLYCNTOUTVAL); + + if (val != dly) { + dev_vdbg(&dphy->phy->dev, + "odelay config failed, set %d get %d", dly, val); + return -EINVAL; + } + + return 0; +} + +int dw_dphy_if_get_idelay(struct dw_dphy_rx *dphy) +{ + return dw_dphy_if_read(dphy, IDLYCNTOUTVAL); +} + +int dw_dphy_if_set_idelay_lane(struct dw_dphy_rx *dphy, u8 dly, u8 lane) +{ + int cell; + + switch (lane) { + case 0: + for (cell = 3; cell <= 10; cell++) + dw_dphy_if_set_idelay(dphy, dly, cell); + break; + case 1: + for (cell = 14; cell <= 21; cell++) + dw_dphy_if_set_idelay(dphy, dly, cell); + break; + case 2: + for (cell = 24; cell <= 31; cell++) + dw_dphy_if_set_idelay(dphy, dly, cell); + break; + case 3: + for (cell = 34; cell <= 41; cell++) + dw_dphy_if_set_idelay(dphy, dly, cell); + break; + case 4: /* ALL */ + dw_dphy_if_set_idelay(dphy, dly, 0x7F); + break; + default: + dev_err(&dphy->phy->dev, "Lane Value not recognized\n"); + return -1; + } + return 0; +} +#endif +#endif + +int dw_dphy_init(struct phy *phy) +{ + struct dw_dphy_rx *dphy = phy_get_drvdata(phy); + + dev_warn(&dphy->phy->dev, "Init DPHY.\n"); + + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0); + + return 0; +} + +static int dw_dphy_set_phy_state(struct dw_dphy_rx *dphy, u32 on) +{ + + u8 hs_freq; + + bm_info("enter %s\n", __func__); + dphy->lanes_config = dw_dphy_setup_config(dphy); + + if (dphy->dphy_te_len == BIT12) + hs_freq = RX_SYS_1; + else + hs_freq = HSFREQRANGE_8BIT; + + if (on) { + dw_dphy_configure(dphy); + dev_info(&dphy->phy->dev, + "HS Code: 0X%x\n", dw_dphy_te_read(dphy, hs_freq)); + } else { + dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); + } + + return 0; +} + +int dw_dphy_power_on(struct phy *phy) +{ + struct dw_dphy_rx *dphy = phy_get_drvdata(phy); + + dev_info(&dphy->phy->dev, "DPHY Power ON\n"); + bm_info("enter %s\n", __func__); + + dphy->phy_type = 1; + return dw_dphy_set_phy_state(dphy, 1); +} + +int dw_dphy_power_off(struct phy *phy) +{ + struct dw_dphy_rx *dphy = phy_get_drvdata(phy); + + return dw_dphy_set_phy_state(dphy, 0); +} + +int dw_dphy_reset(struct phy *phy) +{ + struct dw_dphy_rx *dphy = phy_get_drvdata(phy); + + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); + usleep_range(100, 200); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); + + return 0; +} diff --git a/driver/csi/dw-dphy-rx.h b/driver/csi/dw-dphy-rx.h new file mode 100644 index 0000000..9c37da4 --- /dev/null +++ b/driver/csi/dw-dphy-rx.h @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI D-PHY controller driver + * + * Author: Luis Oliveira + */ + +#ifndef __PHY_SNPS_DPHY_RX_H__ +#define __PHY_SNPS_DPHY_RX_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* DPHY interface register bank*/ + +#define R_CSI2_DPHY_SHUTDOWNZ 0x0 +#define R_CSI2_DPHY_RSTZ 0x4 +#define R_CSI2_DPHY_RX 0x8 +#define R_CSI2_DPHY_STOPSTATE 0xC +#define R_CSI2_DPHY_TST_CTRL0 0x10 +#define R_CSI2_DPHY_TST_CTRL1 0x14 +#define R_CSI2_DPHY2_TST_CTRL0 0x18 +#define R_CSI2_DPHY2_TST_CTRL1 0x1C + +enum dphy_id_mask { + DPHY_ID_LANE_SUPPORT = 0, + DPHY_ID_IF = 4, + DPHY_ID_GEN = 8, +}; + +enum dphy_gen_values { + GEN1, + GEN2, + GEN3, +}; + +enum dphy_interface_length { + BIT8 = 8, + BIT12 = 12, +}; + +enum tst_ctrl0 { + PHY_TESTCLR, + PHY_TESTCLK, +}; + +enum tst_ctrl1 { + PHY_TESTDIN = 0, + PHY_TESTDOUT = 8, + PHY_TESTEN = 16, +}; + +enum lanes_config_values { + CTRL_4_LANES, + CTRL_8_LANES, +}; + +enum dphy_tc { + CFGCLKFREQRANGE_TX = 0x02, + CFGCLKFREQRANGE_RX = 0x05, + BYPASS = 0x20, + IO_DS = 0x30, +}; + +enum dphy_8bit_interface_addr { + BANDGAP_CTRL = 0x24, + HS_RX_CTRL_LANE0 = 0x42, + HSFREQRANGE_8BIT = 0x44, + OSC_FREQ_TARGET_RX0_LSB = 0x4e, + OSC_FREQ_TARGET_RX0_MSB = 0x4f, + HS_RX_CTRL_LANE1 = 0x52, + OSC_FREQ_TARGET_RX1_LSB = 0x5e, + OSC_FREQ_TARGET_RX1_MSB = 0x5f, + RX_SKEW_CAL = 0x7e, + HS_RX_CTRL_LANE2 = 0x82, + OSC_FREQ_TARGET_RX2_LSB = 0x8e, + OSC_FREQ_TARGET_RX2_MSB = 0x8f, + HS_RX_CTRL_LANE3 = 0x92, + OSC_FREQ_TARGET_RX3_LSB = 0x9e, + OSC_FREQ_TARGET_RX3_MSB = 0x9f, +}; + +enum dphy_12bit_interface_addr { + RX_SYS_0 = 0x01, + RX_SYS_1 = 0x02, + RX_SYS_3 = 0x05, + RX_SYS_7 = 0x08, + RX_SYS_9 = 0x0a, + RX_RX_STARTUP_OVR_0 = 0xe0, + RX_RX_STARTUP_OVR_1 = 0xe1, + RX_RX_STARTUP_OVR_2 = 0xe2, + RX_RX_STARTUP_OVR_3 = 0xe3, + RX_RX_STARTUP_OVR_4 = 0xe4, + RX_RX_STARTUP_OVR_5 = 0xe5, + RX_RX_STARTUP_OVR_17 = 0xf1, + RX_RX_DUAL_PHY_0 = 0x133, + RX_RX_CB_1 = 0x1ab, + RX_RX_CB_2 = 0x1ac, + RX_RX_CLKLANE_LANE_6 = 0x307, +}; + +//#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +/* Testchip interface register bank */ +#define IDLYCFG 0x00 +#define IDLYSEL 0x04 +#define IDLYCNTINVAL 0x08 +#define IDLYCNTOUTVAL 0x0c +#define DPHY1REGRSTN 0x10 +#define DPHYZCALSTAT 0x14 +#define DPHYZCALCTRL 0x18 +#define DPHYLANE0STAT 0x1c +#define DPHYLANE1STAT 0x20 +#define DPHYLANE2STAT 0x24 +#define DPHYLANE3STAT 0x28 +#define DPHYCLKSTAT 0x2c +#define DPHYZCLKCTRL 0x30 +#define TCGENPURPOSOUT 0x34 +#define TCGENPURPOSIN 0x38 +#define DPHYGENERICOUT 0x3c +#define DPHYGENERICIN 0x40 + +#define DPHYGLUEIFTESTER 0x180 +#define DPHYID 0x100 + +#define DPHY_DEFAULT_FREQ 300000 + +enum glueiftester { + RESET = 0, + TX_PHY = 0x100 | (0x1 << 4), + RX_PHY = 0x100 | (0x2 << 4), + GLUELOGIC = 0x100 | (0x4 << 4), +}; +//#endif + +/** + * struct phy specifies associated phy component + * struct cfg to pass mipi dphy specific configurations + * @lanes_config lanes configuration + * @dphy_freq operating frequency of the d-phy (mbps) + * @phy_type dphy can be of two types, passed here + * @dphy_gen dphy can be of three generations, passed here + * @dphy_te_len bus width + * @max_lanes maximum number of lanes + * @lp_time time in low-power + * @base_address memmory address of dphy test interface + * @dphy1_if_addr gluelogic dphy 1 memmory address of interface + * @dphy2_if_addr gluelogic dphy 2 memmory address of interface + * @config_8l eight lanes configuration + */ + +struct dw_dphy_rx { + struct phy *phy; + struct phy_configure_opts_mipi_dphy *cfg; + u32 lanes_config; + u32 dphy_freq; //MBPS + u32 phy_type; + u32 dphy_gen; + u32 dphy_te_len; + u32 max_lanes; + u32 lp_time; + u32 dphyglueiftester; + u32 sysreg_mipi_csi_ctrl; + void __iomem *base_address; +//#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) + void __iomem *dphy1_if_addr; + void __iomem *dphy2_if_addr; + u8 config_8l; + u8 (*get_config_8l)(struct device *dev, struct dw_dphy_rx *dphy); +//#endif + u8 (*phy_register)(struct device *dev); + void (*phy_unregister)(struct device *dev); +}; + +int dw_dphy_init(struct phy *phy); +int dw_dphy_reset(struct phy *phy); +int dw_dphy_power_off(struct phy *phy); +int dw_dphy_power_on(struct phy *phy); +u8 dw_dphy_setup_config(struct dw_dphy_rx *dphy); +void dw_dphy_write(struct dw_dphy_rx *dphy, u32 address, u32 data); +u32 dw_dphy_read(struct dw_dphy_rx *dphy, u32 address); +int dw_dphy_te_read(struct dw_dphy_rx *dphy, u32 addr); + +//#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +u32 dw_dphy_if_read(struct dw_dphy_rx *dphy, u32 address); +int dw_dphy_if_get_idelay(struct dw_dphy_rx *dphy); +int dw_dphy_if_set_idelay_lane(struct dw_dphy_rx *dphy, u8 dly, u8 lane); +int dw_dphy_create_capabilities_sysfs(struct platform_device *pdev); +int dw_dphy_remove_capabilities_sysfs(struct platform_device *pdev); + +static inline +u32 dw_dphy_if_read_msk(struct dw_dphy_rx *dphy, + u32 address, u8 shift, u8 width) +{ + return (dw_dphy_if_read(dphy, address) >> shift) & ((1 << width) - 1); +} +//#endif /*IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)*/ + +static inline struct phy *dw_dphy_xlate(struct device *dev, + struct of_phandle_args *args) +{ + struct dw_dphy_rx *dphy = dev_get_drvdata(dev); + + return dphy->phy; +} + +static inline +u32 dw_dphy_read_msk(struct dw_dphy_rx *dev, u32 address, u8 shift, u8 width) +{ + return (dw_dphy_read(dev, address) >> shift) & ((1 << width) - 1); +} +#endif /*__PHY_SNPS_DPHY_RX_H__*/ diff --git a/driver/csi/dw-dphy-sysfs.c b/driver/csi/dw-dphy-sysfs.c new file mode 100644 index 0000000..a7e8e18 --- /dev/null +++ b/driver/csi/dw-dphy-sysfs.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI D-PHY controller driver. + * SysFS components for the platform driver + * + * Author: Luis Oliveira + */ + +//#define DEBUG 1 +#include "dw-dphy-rx.h" +#include "bm_csi_hw.h" + +static ssize_t dphy_reset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + char buffer[15]; + + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); + usleep_range(100, 200); + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t dphy_freq_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int ret; + unsigned long freq; + + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + + ret = kstrtoul(buf, 10, &freq); + if (ret < 0) + return ret; + + if (freq > 2500) { + dev_info(dev, "Freq must be under 2500 Mhz\n"); + return count; + } + if (freq < 80) { + dev_info(dev, "Freq must be over 80 Mhz\n"); + return count; + } + + dev_vdbg(dev, "Data Rate %lu Mbps\n", freq); + dphy->dphy_freq = freq*1000; + + return count; +} + +static ssize_t dphy_freq_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + char buffer[15]; + + snprintf(buffer, + sizeof(buffer), + "Freq %d\n", dphy->dphy_freq); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t dphy_addr_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + char buffer[100]; + unsigned long addr; + unsigned long data; + int ret; + + ret = kstrtoul(buf, 16, &addr); + if (ret < 0) { + return ret; + } + + data = dw_dphy_read(dphy, addr); + + snprintf(buffer, + sizeof(buffer), + "reg_0x%x = 0x%x\n", addr, data); + + + return strlcpy(buf, buffer, PAGE_SIZE); +} + + +static ssize_t dphy_addr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + unsigned long addr; + unsigned long data; + int ret; + + ret = kstrtoul(buf, 16, &addr); + + if (ret < 0) { + return ret; + } + + data = addr & 0xff; + addr &= 0xfff00; + addr = addr >> 8; + + dw_dphy_write(dphy, addr, data); + printk("dphy write reg_0x%x = 0x%x", addr, data); + + + return count; +} + + + +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +#if 0 +static ssize_t idelay_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + char buffer[15]; + + snprintf(buffer, + sizeof(buffer), "idelay %d\n", dw_dphy_if_get_idelay(dphy)); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t idelay_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + unsigned long val; + u8 lane, delay; + int ret; + + ret = kstrtoul(buf, 16, &val); + if (ret < 0) + return ret; + + lane = (u8)val; + delay = (u8)(val >> 8); + + dev_vdbg(dev, "Lanes %u\n", lane); + dev_vdbg(dev, "Delay %u\n", delay); + + dw_dphy_if_set_idelay_lane(dphy, delay, lane); + + return count; +} +#endif +#endif + +static ssize_t len_config_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + unsigned long length; + int ret; + + ret = kstrtoul(buf, 10, &length); + if (ret < 0) + return ret; + + if (length == BIT8) + dev_vdbg(dev, "Configured for 8-bit interface\n"); + else if (length == BIT12) + dev_vdbg(dev, "Configured for 12-bit interface\n"); + else + return count; + + dphy->dphy_te_len = length; + + return count; +} + +static ssize_t len_config_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + char buffer[20]; + + snprintf(buffer, sizeof(buffer), "Length %d\n", dphy->dphy_te_len); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static ssize_t dw_dphy_g118_settle_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + unsigned long lp_time; + int ret; + + ret = kstrtoul(buf, 10, &lp_time); + if (ret < 0) + return ret; + + if (lp_time > 1 && lp_time < 10000) { + dphy->lp_time = lp_time; + } else { + dev_vdbg(dev, "Invalid Value configuring for 1000 ns\n"); + dphy->lp_time = 1000; + } + + dphy->lp_time = lp_time; + + return count; +} + +static ssize_t dw_dphy_g118_settle_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); + struct dw_dphy_rx *dphy = drvdata->dphy; + char buffer[10]; + + snprintf(buffer, sizeof(buffer), "Settle %d ns\n", dphy->lp_time); + + return strlcpy(buf, buffer, PAGE_SIZE); +} + +static DEVICE_ATTR_RO(dphy_reset); +static DEVICE_ATTR_RW(dphy_freq); +static DEVICE_ATTR_RW(dphy_addr); +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +//static DEVICE_ATTR_RW(idelay); +#endif +static DEVICE_ATTR_RW(len_config); +static DEVICE_ATTR_RW(dw_dphy_g118_settle); + +int dw_dphy_create_capabilities_sysfs(struct platform_device *pdev) +{ + device_create_file(&pdev->dev, &dev_attr_dphy_reset); + device_create_file(&pdev->dev, &dev_attr_dphy_freq); + device_create_file(&pdev->dev, &dev_attr_dphy_addr); +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +// device_create_file(&pdev->dev, &dev_attr_idelay); +#endif + device_create_file(&pdev->dev, &dev_attr_len_config); + device_create_file(&pdev->dev, &dev_attr_dw_dphy_g118_settle); + return 0; +} + +int dw_dphy_remove_capabilities_sysfs(struct platform_device *pdev) +{ + device_remove_file(&pdev->dev, &dev_attr_dphy_reset); + device_remove_file(&pdev->dev, &dev_attr_dphy_freq); + device_remove_file(&pdev->dev, &dev_attr_dphy_addr); +#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +// device_create_file(&pdev->dev, &dev_attr_idelay); +#endif + device_remove_file(&pdev->dev, &dev_attr_len_config); + device_remove_file(&pdev->dev, &dev_attr_dw_dphy_g118_settle); + return 0; +} diff --git a/driver/csi/dw-mipi-csi-pltfrm.h b/driver/csi/dw-mipi-csi-pltfrm.h new file mode 100644 index 0000000..948db4e --- /dev/null +++ b/driver/csi/dw-mipi-csi-pltfrm.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI CSI-2 Host media entities + * + * Author: Luis Oliveira + */ + +#ifndef __DW_MIPI_CSI_PLTFRM_INCLUDES_H_ +#define __DW_MIPI_CSI_PLTFRM_INCLUDES_H_ + +#include +#include +#include +#include + +#define MAX_WIDTH 3280 +#define MAX_HEIGHT 1852 + +/* The subdevices' group IDs. */ +#define GRP_ID_SENSOR (10) +#define GRP_ID_CSI (20) +#define GRP_ID_VIF (30) +#define GRP_ID_VIDEODEV (40) + +#define CSI_MAX_ENTITIES (2) +#define VIF_MAX_ENTITIES (2) +#define PLAT_MAX_SENSORS (2) + +struct pdata_names { + char *name; +}; + +enum video_dev_pads { + VIDEO_DEV_SD_PAD_SINK_VIF1, + VIDEO_DEV_SD_PAD_SINK_VIF2, + VIDEO_DEV_SD_PAD_SOURCE_DMA, + VIDEO_DEV_SD_PADS_NUM, +}; + +enum vif_pads { + VIF_PAD_SINK_CSI, + VIF_PAD_SOURCE_DMA, + VIF_PADS_NUM, +}; + +enum mipi_csi_pads { + CSI_PAD_SINK, + CSI_PAD_SOURCE, + CSI_PADS_NUM, +}; + +struct plat_csi_source_info { + u16 flags; + u16 mux_id; +}; + +struct plat_csi_fmt { + char *name; + u32 mbus_code; + u32 fourcc; + u8 depth; +}; + +struct plat_csi_media_pipeline; + +/* + * Media pipeline operations to be called from within a video node, i.e. the + * last entity within the pipeline. Implemented by related media device driver. + */ +struct plat_csi_media_pipeline_ops { + int (*prepare)(struct plat_csi_media_pipeline *p, + struct media_entity *me); + int (*unprepare)(struct plat_csi_media_pipeline *p); + int (*open)(struct plat_csi_media_pipeline *p, struct media_entity *me, + bool resume); + int (*close)(struct plat_csi_media_pipeline *p); + int (*set_stream)(struct plat_csi_media_pipeline *p, bool state); + int (*set_format)(struct plat_csi_media_pipeline *p, + struct v4l2_subdev_format *fmt); +}; + +struct plat_csi_video_entity { + struct video_device vdev; + struct plat_csi_media_pipeline *pipe; +}; + +struct plat_csi_media_pipeline { + struct media_pipeline mp; + const struct plat_csi_media_pipeline_ops *ops; +}; + +static inline struct plat_csi_video_entity +*vdev_to_plat_csi_video_entity(struct video_device *vdev) +{ + return container_of(vdev, struct plat_csi_video_entity, vdev); +} + +#define plat_csi_pipeline_call(ent, op, args...) \ + (!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \ + (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD)) \ + +#endif /* __DW_MIPI_CSI_PLTFRM_INCLUDES_H_ */ diff --git a/driver/csi/dw-mipi-csi.c b/driver/csi/dw-mipi-csi.c new file mode 100644 index 0000000..f70b8a2 --- /dev/null +++ b/driver/csi/dw-mipi-csi.c @@ -0,0 +1,757 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI CSI-2 Host controller driver + * Core MIPI CSI-2 functions + * + * Author: Luis Oliveira + */ + +#include "dw-mipi-csi.h" + +static struct R_CSI2 reg = { + .VERSION = 0x00, + .N_LANES = 0x04, + .CTRL_RESETN = 0x08, + .INTERRUPT = 0x0C, + .DATA_IDS_1 = 0x10, + .DATA_IDS_2 = 0x14, + .IPI_MODE = 0x80, + .IPI_VCID = 0x84, + .IPI_DATA_TYPE = 0x88, + .IPI_MEM_FLUSH = 0x8C, + .IPI_HSA_TIME = 0x90, + .IPI_HBP_TIME = 0x94, + .IPI_HSD_TIME = 0x98, + .IPI_HLINE_TIME = 0x9C, + .IPI_SOFTRSTN = 0xA0, + .IPI_ADV_FEATURES = 0xAC, + .IPI_VSA_LINES = 0xB0, + .IPI_VBP_LINES = 0xB4, + .IPI_VFP_LINES = 0xB8, + .IPI_VACTIVE_LINES = 0xBC, + .INT_PHY_FATAL = 0xe0, + .MASK_INT_PHY_FATAL = 0xe4, + .FORCE_INT_PHY_FATAL = 0xe8, + .INT_PKT_FATAL = 0xf0, + .MASK_INT_PKT_FATAL = 0xf4, + .FORCE_INT_PKT_FATAL = 0xf8, + .INT_PHY = 0x110, + .MASK_INT_PHY = 0x114, + .FORCE_INT_PHY = 0x118, + .INT_LINE = 0x130, + .MASK_INT_LINE = 0x134, + .FORCE_INT_LINE = 0x138, + .INT_IPI = 0x140, + .MASK_INT_IPI = 0x144, + .FORCE_INT_IPI = 0x148, + .IPI2_MODE = 0x200, + .IPI3_MODE = 0x220, + .IPI2_VCID = 0x204, + .IPI3_VCID = 0x224, + .IPI2_DATA_TYPE = 0x208, + .IPI3_DATA_TYPE = 0x228, + .IPI2_MEM_FLUSH = 0x20c, + .IPI3_MEM_FLUSH = 0x22c, + .IPI2_HSA_TIME = 0x210, + .IPI2_HBP_TIME = 0x214, + .IPI2_HSD_TIME = 0x218, + .IPI3_HSA_TIME = 0x230, + .IPI3_HBP_TIME = 0x234, + .IPI3_HSD_TIME = 0x238, + .IPI2_ADV_FEATURES = 0x21c, + .IPI3_ADV_FEATURES = 0x23c, + .IPI2_INT_PHY_FATAL = 0x150, + .IPI3_INT_PHY_FATAL = 0x160, + .IPI2_MASK_INT_PHY_FATAL = 0x154, + .IPI3_MASK_INT_PHY_FATAL = 0x164, +}; + +struct interrupt_type csi_int = { + .PHY_FATAL = BIT(0), + .PKT_FATAL = BIT(1), + .PHY = BIT(16), +}; + +#define dw_print(VAR) \ + dev_info(csi_dev->dev, "%s: 0x%x: %X\n", "##VAR##",\ + VAR, dw_mipi_csi_read(csi_dev, VAR)) + +void dw_mipi_csi_write_part(struct dw_csi *dev, u32 address, u32 data, + u8 shift, u8 width) +{ + u32 mask = (1 << width) - 1; + u32 temp = dw_mipi_csi_read(dev, address); + + temp &= ~(mask << shift); + temp |= (data & mask) << shift; + dw_mipi_csi_write(dev, address, temp); +} + +void dw_mipi_csi_reset(struct dw_csi *csi_dev) +{ + dw_mipi_csi_write(csi_dev, reg.CTRL_RESETN, 0); + usleep_range(100, 200); + dw_mipi_csi_write(csi_dev, reg.CTRL_RESETN, 1); +} + +int dw_mipi_csi_mask_irq_power_off(struct dw_csi *csi_dev) +{ + if (csi_dev->hw_version_major == 1) { + /* set only one lane (lane 0) as active (ON) */ + dw_mipi_csi_write(csi_dev, reg.N_LANES, 0); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY_FATAL, 0); + dw_mipi_csi_write(csi_dev, reg.IPI2_MASK_INT_PHY_FATAL, 0); + dw_mipi_csi_write(csi_dev, reg.IPI3_MASK_INT_PHY_FATAL, 0); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_PKT_FATAL, 0); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY, 0); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_LINE, 0); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_IPI, 0); + + /* only for version 1.30 */ + if (csi_dev->hw_version_minor == 30) + dw_mipi_csi_write(csi_dev, + reg.MASK_INT_FRAME_FATAL, 0); + + dw_mipi_csi_write(csi_dev, reg.CTRL_RESETN, 0); + + /* only for version 1.40 */ + if (csi_dev->hw_version_minor == 40) { + dw_mipi_csi_write(csi_dev, + reg.MSK_BNDRY_FRAME_FATAL, 0); + dw_mipi_csi_write(csi_dev, + reg.MSK_SEQ_FRAME_FATAL, 0); + dw_mipi_csi_write(csi_dev, + reg.MSK_CRC_FRAME_FATAL, 0); + dw_mipi_csi_write(csi_dev, reg.MSK_PLD_CRC_FATAL, 0); + dw_mipi_csi_write(csi_dev, reg.MSK_DATA_ID, 0); + dw_mipi_csi_write(csi_dev, reg.MSK_ECC_CORRECT, 0); + } + } + + return 0; +} + +int dw_mipi_csi_hw_stdby(struct dw_csi *csi_dev) +{ + if (csi_dev->hw_version_major == 1) { + /* set only one lane (lane 0) as active (ON) */ + dw_mipi_csi_reset(csi_dev); + dw_mipi_csi_write(csi_dev, reg.N_LANES, 0); + phy_init(csi_dev->phy); + + /* only for version 1.30 */ + if (csi_dev->hw_version_minor == 30) + dw_mipi_csi_write(csi_dev, + reg.MASK_INT_FRAME_FATAL, + GENMASK(31, 0)); + + /* common */ + dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY_FATAL, + GENMASK(8, 0)); + + dw_mipi_csi_write(csi_dev, reg.IPI2_MASK_INT_PHY_FATAL, + GENMASK(8, 0)); + + dw_mipi_csi_write(csi_dev, reg.IPI3_MASK_INT_PHY_FATAL, + GENMASK(8, 0)); + + dw_mipi_csi_write(csi_dev, reg.MASK_INT_PKT_FATAL, + GENMASK(1, 0)); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY, GENMASK(23, 0)); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_LINE, GENMASK(23, 0)); + dw_mipi_csi_write(csi_dev, reg.MASK_INT_IPI, GENMASK(5, 0)); + + /* only for version 1.40 */ + if (csi_dev->hw_version_minor == 40) { + dw_mipi_csi_write(csi_dev, + reg.MSK_BNDRY_FRAME_FATAL, + GENMASK(31, 0)); + dw_mipi_csi_write(csi_dev, + reg.MSK_SEQ_FRAME_FATAL, + GENMASK(31, 0)); + dw_mipi_csi_write(csi_dev, + reg.MSK_CRC_FRAME_FATAL, + GENMASK(31, 0)); + dw_mipi_csi_write(csi_dev, + reg.MSK_PLD_CRC_FATAL, + GENMASK(31, 0)); + dw_mipi_csi_write(csi_dev, + reg.MSK_DATA_ID, GENMASK(31, 0)); + dw_mipi_csi_write(csi_dev, + reg.MSK_ECC_CORRECT, GENMASK(31, 0)); + } + } + return 0; +} + +void dw_mipi_csi_set_ipi_fmt(struct dw_csi *csi_dev) +{ + struct device *dev = csi_dev->dev; + + if (csi_dev->ipi_dt) { + dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt); + dw_mipi_csi_write(csi_dev, reg.IPI2_DATA_TYPE, csi_dev->ipi_dt); + dw_mipi_csi_write(csi_dev, reg.IPI3_DATA_TYPE, csi_dev->ipi_dt); + + /*switch (csi_dev->ipi_dt) { + case CSI_2_YUV420_8: + //case CSI_2_YUV420_8_LEG: + case CSI_2_YUV420_8_SHIFT: + break; + case CSI_2_YUV420_10: + case CSI_2_YUV420_10_SHIFT: + break; + }*/ + } else { + switch (csi_dev->fmt->mbus_code) { + + case MEDIA_BUS_FMT_RGB666_1X18: + csi_dev->ipi_dt = CSI_2_RGB666; + break; + + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + csi_dev->ipi_dt = CSI_2_RGB565; + break; + + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: + csi_dev->ipi_dt = CSI_2_RGB555; + break; + + case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE: + csi_dev->ipi_dt = CSI_2_RGB444; + break; + + break; + case MEDIA_BUS_FMT_RGB888_2X12_LE: + case MEDIA_BUS_FMT_RGB888_2X12_BE: + csi_dev->ipi_dt = CSI_2_RGB888; + break; + + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE: + csi_dev->ipi_dt = CSI_2_RAW10; + break; + + case MEDIA_BUS_FMT_SBGGR12_1X12: + csi_dev->ipi_dt = CSI_2_RAW12; + break; + + case MEDIA_BUS_FMT_SBGGR14_1X14: + csi_dev->ipi_dt = CSI_2_RAW14; + break; + + case MEDIA_BUS_FMT_SBGGR16_1X16: + csi_dev->ipi_dt = CSI_2_RAW16; + break; + + case MEDIA_BUS_FMT_SBGGR8_1X8: + csi_dev->ipi_dt = CSI_2_RAW8; + break; + + case MEDIA_BUS_FMT_YVYU8_1X16: + csi_dev->ipi_dt = CSI_2_YUV422_8; + break; + + case MEDIA_BUS_FMT_VYUY8_1X16: + csi_dev->ipi_dt = CSI_2_YUV422_8; + break; + + case MEDIA_BUS_FMT_UYVY10_1X20: + csi_dev->ipi_dt = CSI_2_YUV422_10; + break; + + case MEDIA_BUS_FMT_YUYV8_1X16: + csi_dev->ipi_dt = CSI_2_YUV420_8_LEG; + break; + + case MEDIA_BUS_FMT_UYVY8_1X16: + csi_dev->ipi_dt = CSI_2_YUV420_8; + break; + + case MEDIA_BUS_FMT_VUY8_1X24: + csi_dev->ipi_dt = CSI_2_YUV420_10; + break; + + case MEDIA_BUS_FMT_Y8_1X8: + csi_dev->ipi_dt = CSI_2_RAW8; + break; + + case MEDIA_BUS_FMT_Y10_1X10: + csi_dev->ipi_dt = CSI_2_RAW8; + break; +#if 0/*modify by wuyi*/ + case MEDIA_BUS_FMT_SBGGR6_1X8: + csi_dev->ipi_dt = CSI_2_RAW6; + break; + + case MEDIA_BUS_FMT_SBGGR7_1X8: + csi_dev->ipi_dt = CSI_2_RAW7; + break; +#endif + default: + break; + } + dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt); + dw_mipi_csi_write(csi_dev, reg.IPI2_DATA_TYPE, csi_dev->ipi_dt); + dw_mipi_csi_write(csi_dev, reg.IPI3_DATA_TYPE, csi_dev->ipi_dt); + } + dev_info(dev, "Selected IPI Data Type 0x%X\n", csi_dev->ipi_dt); +} + +void dw_mipi_csi_fill_timings(struct dw_csi *dev, uint32_t width, uint32_t height) +{ + dev->hw.virtual_ch = 0; + dev->hw.ipi_color_mode = COLOR48; + dev->hw.ipi_auto_flush = 1; + dev->hw.ipi_mode = CAMERA_TIMING; + dev->hw.ipi_cut_through = CTINACTIVE; + dev->hw.ipi_adv_features = LINE_EVENT_SELECTION(EVSELAUTO); + dev->hw.htotal = width + dev->hw.hsa + + dev->hw.hbp + dev->hw.hsd; + dev->hw.vactive = height; + dev->hw.output = 2; + dev->hw.ipi1_en = false; + + dev_dbg(dev->dev, "*********** timings *********\n"); + dev_dbg(dev->dev, "Horizontal Sync Active: %d\n", dev->hw.hsa); + dev_dbg(dev->dev, "Horizontal Back Porch: %d\n", dev->hw.hbp); + dev_dbg(dev->dev, "Horizontal Width: %d\n", width); + dev_dbg(dev->dev, "Horizontal Total: %d\n", dev->hw.htotal); + dev_dbg(dev->dev, "Vertical Sync Active: %d\n", dev->hw.vsa); + dev_dbg(dev->dev, "Vertical Back Porch: %d\n", dev->hw.vbp); + dev_dbg(dev->dev, "Vertical Front Porch: %d\n", dev->hw.vfp); + dev_dbg(dev->dev, "Vertical Active: %d\n", dev->hw.vactive); +} + +void dw_mipi_csi_stop(struct dw_csi *csi_dev) +{ + /* address | data, | shift | width */ + if (csi_dev->hw.ipi1_en == 0) { + dw_mipi_csi_write_part(csi_dev, reg.IPI_MODE, 0, 24, 1); + } + + if (csi_dev->hw.ipi2_en == 0) { + dw_mipi_csi_write_part(csi_dev, reg.IPI2_MODE, 0, 24, 1); + } + + if (csi_dev->hw.ipi3_en == 0) { + dw_mipi_csi_write_part(csi_dev, reg.IPI3_MODE, 0, 24, 1); + } +} + +void dw_mipi_csi_start(struct dw_csi *csi_dev) +{ + struct device *dev = csi_dev->dev; + + dw_mipi_csi_write(csi_dev, reg.N_LANES, (csi_dev->hw.num_lanes - 1)); + dev_info(dev, "number of lanes: %d\n", csi_dev->hw.num_lanes); + + /* IPI Related Configuration */ + if (csi_dev->hw.output == IPI_OUT || csi_dev->hw.output == BOTH_OUT) { + if (csi_dev->hw_version_major >= 1) { + if (csi_dev->hw_version_minor >= 21) { + dw_mipi_csi_write(csi_dev, + reg.IPI_ADV_FEATURES, + csi_dev->hw.ipi_adv_features); + dw_mipi_csi_write(csi_dev, + reg.IPI2_ADV_FEATURES, + csi_dev->hw.ipi_adv_features); + dw_mipi_csi_write(csi_dev, + reg.IPI3_ADV_FEATURES, + csi_dev->hw.ipi_adv_features); + + } + + if (csi_dev->hw_version_minor >= 30) { + dw_mipi_csi_write(csi_dev, + reg.IPI_SOFTRSTN, 0x1 | (0x1 << 4) | (0x1 << 8)); + } + } + /* address | data, | shift | width */ + if (csi_dev->hw.ipi1_en) { + dw_mipi_csi_write_part(csi_dev, reg.IPI_MODE, 1, 24, 1); + } + + if (csi_dev->hw.ipi2_en) { + dw_mipi_csi_write_part(csi_dev, reg.IPI2_MODE, 1, 24, 1); + } + + if (csi_dev->hw.ipi3_en) { + dw_mipi_csi_write_part(csi_dev, reg.IPI3_MODE, 1, 24, 1); + } + + dw_mipi_csi_write_part(csi_dev, + reg.IPI_MODE, + csi_dev->hw.ipi_mode, + 0, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI2_MODE, + csi_dev->hw.ipi_mode, + 0, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI3_MODE, + csi_dev->hw.ipi_mode, + 0, 1); + + if (csi_dev->hw.ipi_mode == CAMERA_TIMING) { + dw_mipi_csi_write(csi_dev, + reg.IPI_ADV_FEATURES, + LINE_EVENT_SELECTION(EVSELPROG) | + EN_VIDEO); + /* + EN_VIDEO | + EN_LINE_START | + EN_NULL | + EN_BLANKING | + EN_EMBEDDED); + */ + + dw_mipi_csi_write(csi_dev, + reg.IPI2_ADV_FEATURES, + LINE_EVENT_SELECTION(EVSELPROG) | + EN_VIDEO | + EN_LINE_START | + EN_NULL | + EN_BLANKING | + EN_EMBEDDED); + + dw_mipi_csi_write(csi_dev, + reg.IPI3_ADV_FEATURES, + LINE_EVENT_SELECTION(EVSELPROG) | + EN_VIDEO | + EN_LINE_START | + EN_NULL | + EN_BLANKING | + EN_EMBEDDED); + } + + dw_mipi_csi_write_part(csi_dev, + reg.IPI_MODE, + csi_dev->hw.ipi_color_mode, + 8, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI_MODE, + csi_dev->hw.ipi_cut_through, + 16, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI2_MODE, + csi_dev->hw.ipi_color_mode, + 8, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI2_MODE, + csi_dev->hw.ipi_cut_through, + 16, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI3_MODE, + csi_dev->hw.ipi_color_mode, + 8, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI3_MODE, + csi_dev->hw.ipi_cut_through, + 16, 1); + + + dw_mipi_csi_write_part(csi_dev, + reg.IPI_VCID, + csi_dev->hw.virtual_ch, + 0, 2); + dw_mipi_csi_write_part(csi_dev, + reg.IPI2_VCID, + csi_dev->hw.ipi2_virtual_ch, + 0, 2); + dw_mipi_csi_write_part(csi_dev, + reg.IPI3_VCID, + csi_dev->hw.ipi3_virtual_ch, + 0, 2); + + dw_mipi_csi_write_part(csi_dev, + reg.IPI_MEM_FLUSH, + csi_dev->hw.ipi_auto_flush, + 8, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI2_MEM_FLUSH, + csi_dev->hw.ipi_auto_flush, + 8, 1); + dw_mipi_csi_write_part(csi_dev, + reg.IPI3_MEM_FLUSH, + csi_dev->hw.ipi_auto_flush, + 8, 1); + + dev_vdbg(dev, "*********** config *********\n"); + dev_vdbg(dev, "IPI enable: %s\n", + csi_dev->hw.output ? "YES" : "NO"); + dev_vdbg(dev, "video mode transmission type: %s timming\n", + csi_dev->hw.ipi_mode ? "controller" : "camera"); + dev_vdbg(dev, "Color Mode: %s\n", + csi_dev->hw.ipi_color_mode ? "16 bits" : "48 bits"); + dev_vdbg(dev, "Cut Through Mode: %s\n", + csi_dev->hw.ipi_cut_through ? "enable" : "disable"); + dev_vdbg(dev, "IPI1 Virtual Channel: %d\n", + csi_dev->hw.virtual_ch); + dev_vdbg(dev, "IPI2 Virtual Channel: %d\n", + csi_dev->hw.ipi2_virtual_ch); + dev_vdbg(dev, "IPI3 Virtual Channel: %d\n", + csi_dev->hw.ipi3_virtual_ch); + + dev_vdbg(dev, "Auto-flush: %d\n", + csi_dev->hw.ipi_auto_flush); + dw_mipi_csi_write(csi_dev, reg.IPI_SOFTRSTN, 0x1 | (0x1 << 4) | (0x1 << 8)); + + if (csi_dev->hw.ipi_mode == AUTO_TIMING) + phy_power_on(csi_dev->phy); + + dw_mipi_csi_write(csi_dev, + reg.IPI_HSA_TIME, csi_dev->hw.hsa); + dw_mipi_csi_write(csi_dev, + reg.IPI_HBP_TIME, csi_dev->hw.hbp); + dw_mipi_csi_write(csi_dev, + reg.IPI_HSD_TIME, csi_dev->hw.hsd); + + dw_mipi_csi_write(csi_dev, + reg.IPI2_HSA_TIME, csi_dev->hw.ipi2_hsa); + dw_mipi_csi_write(csi_dev, + reg.IPI2_HBP_TIME, csi_dev->hw.ipi2_hbp); + dw_mipi_csi_write(csi_dev, + reg.IPI2_HSD_TIME, csi_dev->hw.ipi2_hsd); + + dw_mipi_csi_write(csi_dev, + reg.IPI3_HSA_TIME, csi_dev->hw.ipi3_hsa); + dw_mipi_csi_write(csi_dev, + reg.IPI3_HBP_TIME, csi_dev->hw.ipi3_hbp); + dw_mipi_csi_write(csi_dev, + reg.IPI3_HSD_TIME, csi_dev->hw.ipi3_hsd); + + dw_mipi_csi_write(csi_dev, + reg.IPI_HLINE_TIME, csi_dev->hw.htotal); + dw_mipi_csi_write(csi_dev, + reg.IPI_VSA_LINES, csi_dev->hw.vsa); + dw_mipi_csi_write(csi_dev, + reg.IPI_VBP_LINES, csi_dev->hw.vbp); + dw_mipi_csi_write(csi_dev, + reg.IPI_VFP_LINES, csi_dev->hw.vfp); + dw_mipi_csi_write(csi_dev, + reg.IPI_VACTIVE_LINES, csi_dev->hw.vactive); + } + phy_power_on(csi_dev->phy); +} + +int dw_mipi_csi_irq_handler(struct dw_csi *csi_dev) +{ + struct device *dev = csi_dev->dev; + u32 global_int_status, i_sts; + unsigned long flags; + + spin_lock_irqsave(&csi_dev->slock, flags); + global_int_status = dw_mipi_csi_read(csi_dev, reg.INTERRUPT); + + if (global_int_status & csi_int.PHY_FATAL) { + i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PHY_FATAL); + dev_err_ratelimited(dev, "int %08X: PHY FATAL: %08X\n", + reg.INT_PHY_FATAL, i_sts); + + i_sts = dw_mipi_csi_read(csi_dev, reg.IPI2_INT_PHY_FATAL); + dev_err_ratelimited(dev, "int %08X: IPI2 PHY FATAL: %08X\n", + reg.IPI2_INT_PHY_FATAL, i_sts); + + i_sts = dw_mipi_csi_read(csi_dev, reg.IPI3_INT_PHY_FATAL); + dev_err_ratelimited(dev, "int %08X: IPI2 PHY FATAL: %08X\n", + reg.IPI3_INT_PHY_FATAL, i_sts); + + } + + if (global_int_status & csi_int.PKT_FATAL) { + i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PKT_FATAL); + dev_err_ratelimited(dev, "int %08X: PKT FATAL: %08X\n", + reg.INT_PKT_FATAL, i_sts); + } + + if (global_int_status & csi_int.FRAME_FATAL && + csi_dev->hw_version_major == 1 && + csi_dev->hw_version_minor == 30) { + i_sts = dw_mipi_csi_read(csi_dev, reg.INT_FRAME_FATAL); + dev_err_ratelimited(dev, "int %08X: FRAME FATAL: %08X\n", + reg.INT_FRAME_FATAL, i_sts); + } + + if (global_int_status & csi_int.PHY) { + i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PHY); + dev_err_ratelimited(dev, "int %08X: PHY: %08X\n", + reg.INT_PHY, i_sts); + } + + if (global_int_status & csi_int.PKT && + csi_dev->hw_version_major == 1 && + csi_dev->hw_version_minor <= 30) { + i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PKT); + dev_err_ratelimited(dev, "int %08X: PKT: %08X\n", + reg.INT_PKT, i_sts); + } + + if (global_int_status & csi_int.LINE) { + i_sts = dw_mipi_csi_read(csi_dev, reg.INT_LINE); + dev_err_ratelimited(dev, "int %08X: LINE: %08X\n", + reg.INT_LINE, i_sts); + } + + if (global_int_status & csi_int.IPI) { + i_sts = dw_mipi_csi_read(csi_dev, reg.INT_IPI); + dev_err_ratelimited(dev, "int %08X: IPI: %08X\n", + reg.INT_IPI, i_sts); + } + + if (global_int_status & csi_int.BNDRY_FRAME_FATAL) { + i_sts = dw_mipi_csi_read(csi_dev, reg.ST_BNDRY_FRAME_FATAL); + dev_err_ratelimited(dev, + "int %08X: ST_BNDRY_FRAME_FATAL: %08X\n", + reg.ST_BNDRY_FRAME_FATAL, i_sts); + } + + if (global_int_status & csi_int.SEQ_FRAME_FATAL) { + i_sts = dw_mipi_csi_read(csi_dev, reg.ST_SEQ_FRAME_FATAL); + dev_err_ratelimited(dev, + "int %08X: ST_SEQ_FRAME_FATAL: %08X\n", + reg.ST_SEQ_FRAME_FATAL, i_sts); + } + + if (global_int_status & csi_int.CRC_FRAME_FATAL) { + i_sts = dw_mipi_csi_read(csi_dev, reg.ST_CRC_FRAME_FATAL); + dev_err_ratelimited(dev, + "int %08X: ST_CRC_FRAME_FATAL: %08X\n", + reg.ST_CRC_FRAME_FATAL, i_sts); + } + + if (global_int_status & csi_int.PLD_CRC_FATAL) { + i_sts = dw_mipi_csi_read(csi_dev, reg.ST_PLD_CRC_FATAL); + dev_err_ratelimited(dev, + "int %08X: ST_PLD_CRC_FATAL: %08X\n", + reg.ST_PLD_CRC_FATAL, i_sts); + } + + if (global_int_status & csi_int.DATA_ID) { + i_sts = dw_mipi_csi_read(csi_dev, reg.ST_DATA_ID); + dev_err_ratelimited(dev, "int %08X: ST_DATA_ID: %08X\n", + reg.ST_DATA_ID, i_sts); + } + + if (global_int_status & csi_int.ECC_CORRECTED) { + i_sts = dw_mipi_csi_read(csi_dev, reg.ST_ECC_CORRECT); + dev_err_ratelimited(dev, "int %08X: ST_ECC_CORRECT: %08X\n", + reg.ST_ECC_CORRECT, i_sts); + } + + spin_unlock_irqrestore(&csi_dev->slock, flags); + + return 1; +} + +void dw_mipi_csi_get_version(struct dw_csi *csi_dev) +{ + u32 hw_version; + + hw_version = dw_mipi_csi_read(csi_dev, reg.VERSION); + csi_dev->hw_version_major = (u8)((hw_version >> 24) - '0'); + csi_dev->hw_version_minor = (u8)((hw_version >> 16) - '0'); + csi_dev->hw_version_minor = csi_dev->hw_version_minor * 10; + csi_dev->hw_version_minor += (u8)((hw_version >> 8) - '0'); +} + +int dw_mipi_csi_specific_mappings(struct dw_csi *csi_dev) +{ + struct device *dev = csi_dev->dev; + + if (csi_dev->hw_version_major == 1) { + if (csi_dev->hw_version_minor == 30) { + /* + * Hardware registers that were + * exclusive to version < 1.40 + */ + reg.INT_FRAME_FATAL = 0x100; + reg.MASK_INT_FRAME_FATAL = 0x104; + reg.FORCE_INT_FRAME_FATAL = 0x108; + reg.INT_PKT = 0x120; + reg.MASK_INT_PKT = 0x124; + reg.FORCE_INT_PKT = 0x128; + + /* interrupt source present until this release */ + csi_int.PKT = BIT(17); + csi_int.LINE = BIT(18); + csi_int.IPI = BIT(19); + csi_int.FRAME_FATAL = BIT(2); + + } else if (csi_dev->hw_version_minor == 40) { + /* + * HW registers that were added + * to version 1.40 + */ + reg.ST_BNDRY_FRAME_FATAL = 0x280; + reg.MSK_BNDRY_FRAME_FATAL = 0x284; + reg.FORCE_BNDRY_FRAME_FATAL = 0x288; + reg.ST_SEQ_FRAME_FATAL = 0x290; + reg.MSK_SEQ_FRAME_FATAL = 0x294; + reg.FORCE_SEQ_FRAME_FATAL = 0x298; + reg.ST_CRC_FRAME_FATAL = 0x2a0; + reg.MSK_CRC_FRAME_FATAL = 0x2a4; + reg.FORCE_CRC_FRAME_FATAL = 0x2a8; + reg.ST_PLD_CRC_FATAL = 0x2b0; + reg.MSK_PLD_CRC_FATAL = 0x2b4; + reg.FORCE_PLD_CRC_FATAL = 0x2b8; + reg.ST_DATA_ID = 0x2c0; + reg.MSK_DATA_ID = 0x2c4; + reg.FORCE_DATA_ID = 0x2c8; + reg.ST_ECC_CORRECT = 0x2d0; + reg.MSK_ECC_CORRECT = 0x2d4; + reg.FORCE_ECC_CORRECT = 0x2d8; + reg.DATA_IDS_VC_1 = 0x0; + reg.DATA_IDS_VC_2 = 0x0; + reg.VC_EXTENSION = 0x0; + + /* interrupts map were changed */ + csi_int.LINE = BIT(17); + csi_int.IPI = BIT(18); + csi_int.BNDRY_FRAME_FATAL = BIT(2); + csi_int.SEQ_FRAME_FATAL = BIT(3); + csi_int.CRC_FRAME_FATAL = BIT(4); + csi_int.PLD_CRC_FATAL = BIT(5); + csi_int.DATA_ID = BIT(6); + csi_int.ECC_CORRECTED = BIT(7); + + } else { + dev_info(dev, "Version minor not supported."); + } + } else { + dev_info(dev, "Version major not supported."); + } + return 0; +} + +void dw_mipi_csi_dump(struct dw_csi *csi_dev) +{ + dw_print(reg.VERSION); + dw_print(reg.N_LANES); + dw_print(reg.CTRL_RESETN); + dw_print(reg.INTERRUPT); + dw_print(reg.DATA_IDS_1); + dw_print(reg.DATA_IDS_2); + dw_print(reg.IPI_MODE); + dw_print(reg.IPI_VCID); + dw_print(reg.IPI_DATA_TYPE); + dw_print(reg.IPI_MEM_FLUSH); + dw_print(reg.IPI_HSA_TIME); + dw_print(reg.IPI_HBP_TIME); + dw_print(reg.IPI_HSD_TIME); + dw_print(reg.IPI_HLINE_TIME); + dw_print(reg.IPI_SOFTRSTN); + dw_print(reg.IPI_ADV_FEATURES); + dw_print(reg.IPI_VSA_LINES); + dw_print(reg.IPI_VBP_LINES); + dw_print(reg.IPI_VFP_LINES); + dw_print(reg.IPI_VACTIVE_LINES); + dw_print(reg.IPI_DATA_TYPE); + dw_print(reg.VERSION); + dw_print(reg.IPI_ADV_FEATURES); +} diff --git a/driver/csi/dw-mipi-csi.h b/driver/csi/dw-mipi-csi.h new file mode 100644 index 0000000..be7e503 --- /dev/null +++ b/driver/csi/dw-mipi-csi.h @@ -0,0 +1,317 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates. + * + * Synopsys DesignWare MIPI CSI-2 Host controller driver + * + * Author: Luis Oliveira + */ + +#ifndef _DW_MIPI_CSI_H__ +#define _DW_MIPI_CSI_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Advanced features */ +#define IPI_DT_OVERWRITE BIT(0) +#define DATA_TYPE_OVERWRITE(dt) (((dt) & GENMASK(5, 0)) << 8) +#define LINE_EVENT_SELECTION(n) ((n) << 16) + +enum line_event { + EVSELAUTO = 0, + EVSELPROG = 1, +}; + +#define EN_VIDEO BIT(17) +#define EN_LINE_START BIT(18) +#define EN_NULL BIT(19) +#define EN_BLANKING BIT(20) +#define EN_EMBEDDED BIT(21) +#define IPI_SYNC_EVENT_MODE(n) ((n) << 24) + +enum sync_event { + SYNCEVFSN = 0, + SYNCEVFS = 1, +}; + +/* DW MIPI CSI-2 register addresses*/ + +struct R_CSI2 { + u16 VERSION; + u16 N_LANES; + u16 CTRL_RESETN; + u16 INTERRUPT; + u16 DATA_IDS_1; + u16 DATA_IDS_2; + u16 DATA_IDS_VC_1; + u16 DATA_IDS_VC_2; + u16 IPI_MODE; + u16 IPI_VCID; + u16 IPI_DATA_TYPE; + u16 IPI_MEM_FLUSH; + u16 IPI_HSA_TIME; + u16 IPI_HBP_TIME; + u16 IPI_HSD_TIME; + u16 IPI_HLINE_TIME; + u16 IPI_SOFTRSTN; + u16 IPI_ADV_FEATURES; + u16 IPI_VSA_LINES; + u16 IPI_VBP_LINES; + u16 IPI_VFP_LINES; + u16 IPI_VACTIVE_LINES; + u16 VC_EXTENSION; + u16 INT_PHY_FATAL; + u16 MASK_INT_PHY_FATAL; + u16 FORCE_INT_PHY_FATAL; + u16 INT_PKT_FATAL; + u16 MASK_INT_PKT_FATAL; + u16 FORCE_INT_PKT_FATAL; + u16 INT_FRAME_FATAL; + u16 MASK_INT_FRAME_FATAL; + u16 FORCE_INT_FRAME_FATAL; + u16 INT_PHY; + u16 MASK_INT_PHY; + u16 FORCE_INT_PHY; + u16 INT_PKT; + u16 MASK_INT_PKT; + u16 FORCE_INT_PKT; + u16 INT_LINE; + u16 MASK_INT_LINE; + u16 FORCE_INT_LINE; + u16 INT_IPI; + u16 MASK_INT_IPI; + u16 FORCE_INT_IPI; + u16 ST_BNDRY_FRAME_FATAL; + u16 MSK_BNDRY_FRAME_FATAL; + u16 FORCE_BNDRY_FRAME_FATAL; + u16 ST_SEQ_FRAME_FATAL; + u16 MSK_SEQ_FRAME_FATAL; + u16 FORCE_SEQ_FRAME_FATAL; + u16 ST_CRC_FRAME_FATAL; + u16 MSK_CRC_FRAME_FATAL; + u16 FORCE_CRC_FRAME_FATAL; + u16 ST_PLD_CRC_FATAL; + u16 MSK_PLD_CRC_FATAL; + u16 FORCE_PLD_CRC_FATAL; + u16 ST_DATA_ID; + u16 MSK_DATA_ID; + u16 FORCE_DATA_ID; + u16 ST_ECC_CORRECT; + u16 MSK_ECC_CORRECT; + u16 FORCE_ECC_CORRECT; + u16 IPI2_MODE; + u16 IPI3_MODE; + u16 IPI2_VCID; + u16 IPI3_VCID; + u16 IPI2_DATA_TYPE; + u16 IPI3_DATA_TYPE; + u16 IPI2_MEM_FLUSH; + u16 IPI3_MEM_FLUSH; + u16 IPI2_HSA_TIME; + u16 IPI2_HBP_TIME; + u16 IPI2_HSD_TIME; + u16 IPI3_HSA_TIME; + u16 IPI3_HBP_TIME; + u16 IPI3_HSD_TIME; + u16 IPI2_ADV_FEATURES; + u16 IPI3_ADV_FEATURES; + u16 IPI2_INT_PHY_FATAL; + u16 IPI3_INT_PHY_FATAL; + u16 IPI2_MASK_INT_PHY_FATAL; + u16 IPI3_MASK_INT_PHY_FATAL; +}; + +/* Interrupt Masks */ +struct interrupt_type { + u32 PHY_FATAL; + u32 PKT_FATAL; + u32 FRAME_FATAL; + u32 PHY; + u32 PKT; + u32 LINE; + u32 IPI; + u32 BNDRY_FRAME_FATAL; + u32 SEQ_FRAME_FATAL; + u32 CRC_FRAME_FATAL; + u32 PLD_CRC_FATAL; + u32 DATA_ID; + u32 ECC_CORRECTED; +}; + +/* IPI Data Types */ +enum data_type { + CSI_2_YUV420_8 = 0x18, + CSI_2_YUV420_10 = 0x19, + CSI_2_YUV420_8_LEG = 0x1A, + CSI_2_YUV420_8_SHIFT = 0x1C, + CSI_2_YUV420_10_SHIFT = 0x1D, + CSI_2_YUV422_8 = 0x1E, + CSI_2_YUV422_10 = 0x1F, + CSI_2_RGB444 = 0x20, + CSI_2_RGB555 = 0x21, + CSI_2_RGB565 = 0x22, + CSI_2_RGB666 = 0x23, + CSI_2_RGB888 = 0x24, + CSI_2_RAW6 = 0x28, + CSI_2_RAW7 = 0x29, + CSI_2_RAW8 = 0x2A, + CSI_2_RAW10 = 0x2B, + CSI_2_RAW12 = 0x2C, + CSI_2_RAW14 = 0x2D, + CSI_2_RAW16 = 0x2E, + CSI_2_RAW20 = 0x2F, + USER_DEFINED_1 = 0x30, + USER_DEFINED_2 = 0x31, + USER_DEFINED_3 = 0x32, + USER_DEFINED_4 = 0x33, + USER_DEFINED_5 = 0x34, + USER_DEFINED_6 = 0x35, + USER_DEFINED_7 = 0x36, + USER_DEFINED_8 = 0x37, +}; + +/* DWC MIPI CSI-2 output types */ +enum output { + IPI_OUT = 0, + IDI_OUT = 1, + BOTH_OUT = 2 +}; + +/* IPI color components */ +enum color_mode { + COLOR48 = 0, + COLOR16 = 1 +}; + +/* IPI cut through */ +enum cut_through { + CTINACTIVE = 0, + CTACTIVE = 1 +}; + +/* IPI output types */ +enum ipi_output { + CAMERA_TIMING = 0, + AUTO_TIMING = 1 +}; + +/* Format template */ +struct mipi_fmt { + u32 mbus_code; + u8 depth; + u32 width; + u32 height; +}; + +struct mipi_dt { + u32 hex; + char *name; +}; + +/* CSI specific configuration */ +struct csi_data { + u32 num_lanes; + u32 dphy_freq; //MBPS + u32 pclk; + u32 fps; + u32 bpp; + u32 output; + bool ipi1_en; + bool ipi2_en; + bool ipi3_en; + u32 ipi_mode; + u32 ipi_adv_features; + u32 ipi_cut_through; + u32 ipi_color_mode; + u32 ipi_auto_flush; + u32 virtual_ch; + u32 ipi2_virtual_ch; + u32 ipi3_virtual_ch; + u32 hsa; + u32 hbp; + u32 hsd; + u32 ipi2_hsa; + u32 ipi2_hbp; + u32 ipi2_hsd; + u32 ipi3_hsa; + u32 ipi3_hbp; + u32 ipi3_hsd; + u32 htotal; + u32 vsa; + u32 vbp; + u32 vfp; + u32 vactive; +}; + +/* Structure to embed device driver information */ +struct dw_csi { + //struct v4l2_subdev sd; + //struct video_device vdev; + //struct v4l2_device v4l2_dev; + struct device *dev; + //struct media_pad pads[CSI_PADS_NUM]; + struct mipi_fmt *fmt; + //struct v4l2_mbus_framefmt format; + void __iomem *base_address; + void __iomem *demo; + void __iomem *csc; + int ctrl_irq_number; + int demosaic_irq; + struct csi_data hw; + struct reset_control *rst; + struct phy *phy; + struct dw_csih_pdata *config; + struct mutex lock; /* protect resources sharing */ + spinlock_t slock; /* interrupt handling lock */ + u8 ipi_dt; + u8 index; + u8 hw_version_major; + u16 hw_version_minor; +}; + +void dw_mipi_csi_reset(struct dw_csi *csi_dev); +int dw_mipi_csi_mask_irq_power_off(struct dw_csi *csi_dev); +int dw_mipi_csi_hw_stdby(struct dw_csi *csi_dev); +void dw_mipi_csi_set_ipi_fmt(struct dw_csi *csi_dev); +void dw_mipi_csi_start(struct dw_csi *csi_dev); +void dw_mipi_csi_stop(struct dw_csi *csi_dev); +int dw_mipi_csi_irq_handler(struct dw_csi *csi_dev); +void dw_mipi_csi_get_version(struct dw_csi *csi_dev); +int dw_mipi_csi_specific_mappings(struct dw_csi *csi_dev); +void dw_mipi_csi_fill_timings(struct dw_csi *dev, uint32_t width, uint32_t height); +void dw_mipi_csi_dump(struct dw_csi *csi_dev); + +//#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) +int dw_csi_create_capabilities_sysfs(struct platform_device *pdev); +int dw_csi_remove_capabilities_sysfs(struct platform_device *pdev); +//#endif + +int dw_mipi_csi_s_power(struct dw_csi *dev, int on); +int dw_mipi_csi_log_status(struct dw_csi *dev); + +static inline void dw_mipi_csi_write(struct dw_csi *dev, + u32 address, u32 data) +{ + writel(data, dev->base_address + address); +} + +static inline u32 dw_mipi_csi_read(struct dw_csi *dev, u32 address) +{ + return readl(dev->base_address + address); +} + +#endif /*_DW_MIPI_CSI_H__ */ diff --git a/driver/demo/Makefile b/driver/demo/Makefile new file mode 100644 index 0000000..a77ce2f --- /dev/null +++ b/driver/demo/Makefile @@ -0,0 +1,28 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +TARGET = bm_demo + +obj-m +=$(TARGET).o +$(TARGET)-objs += bm_demo_driver.o + +EXTRA_CFLAGS += -I$(PWD)/./ +EXTRA_CFLAGS += -I$(PWD)/../common/include + + +PWD :=$(shell pwd) + +all: + make -C $(KERNEL) M=$(PWD) modules +modules_install: + make -C $(KERNEL_SRC) M=$(SRC) modules_install +clean: + rm -rf $($(TARGET)-objs) + if [ -d "$(KERNEL)" ]; then \ + make -C $(KERNEL) M=`pwd` clean; \ + fi diff --git a/driver/demo/bm_demo_driver.c b/driver/demo/bm_demo_driver.c new file mode 100644 index 0000000..a49a9b4 --- /dev/null +++ b/driver/demo/bm_demo_driver.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define BM_DEMO_NAME "bm_demo" +#define BM_DRIVER_MAXCNT 2 + +struct bm_demo_driver_dev +{ + struct cdev cdev; + dev_t devt; + struct class *class; + struct mutex vvmutex; + unsigned int device_idx; + struct work_struct demo_wq; + wait_queue_head_t demo_wait; + int irq_num; + void *private; +}; + +#if 0 +struct work_struct* pWorkQueue = NULL; +static unsigned int bm_demo_major = 0; +static unsigned int bm_demo_minor = 0; +struct class *bm_demo_class; +static unsigned int devise_register_index = 0; +static bool bm_demo_irq = false; +#endif + +static unsigned int bm_demo_poll(struct file * filp, poll_table *wait) +{ + return 0; +} + +void bm_demo_work(struct work_struct *work) +{ +} + +irqreturn_t bm_demo_irq(int irq, void *dev_id) +{ + pr_info("enter %s\n", __func__); + return IRQ_HANDLED; +} + +static int bm_demo_open(struct inode * inode, struct file * file) +{ + pr_info("enter %s\n", __func__); + return 0; +}; + +static long bm_demo_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + pr_info("enter %s\n", __func__); + return 0; +}; + +static int bm_demo_release(struct inode * inode, struct file * file) +{ + pr_info("enter %s\n", __func__); + return 0; +}; + +static int bm_demo_mmap(struct file *pFile, struct vm_area_struct *vma) +{ + pr_info("enter %s\n", __func__); + return 0; +}; + +struct file_operations bm_demo_fops = { + .owner = THIS_MODULE, + .open = bm_demo_open, + .release = bm_demo_release, + .unlocked_ioctl = bm_demo_ioctl, + .mmap = bm_demo_mmap, + .poll = bm_demo_poll, +}; + +static int bm_demo_probe(struct platform_device *pdev) +{ + pr_info("enter %s\n", __func__); + return 0; +} + +static int bm_demo_remove(struct platform_device *pdev) +{ + pr_info("enter %s\n", __func__); + return 0; +} + +static const struct of_device_id bm_demo_of_match[] = { + { .compatible = "thead,bm-demo", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, bm_demo_of_match); + +static struct platform_driver bm_demo_driver = { + .probe = bm_demo_probe, + .remove = bm_demo_remove, + .driver = { + .name = BM_DEMO_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(bm_demo_of_match), + } +}; + +static int __init bm_demo_init_module(void) +{ + int ret = 0; + + pr_info("enter %s\n", __func__); + ret = platform_driver_register(&bm_demo_driver); + if (ret) { + pr_err("register platform driver failed.\n"); + return ret; + } + + return ret; +} + +static void __exit bm_demo_exit_module(void) +{ + pr_info("enter %s\n", __func__); + platform_driver_unregister(&bm_demo_driver); +} + +module_init(bm_demo_init_module); +module_exit(bm_demo_exit_module); + +MODULE_AUTHOR("Lu Chongzhi"); +MODULE_DESCRIPTION("BAREMETAL-DEMO"); +MODULE_LICENSE("GPL"); diff --git a/driver/isp/Makefile b/driver/isp/Makefile new file mode 100644 index 0000000..e93963a --- /dev/null +++ b/driver/isp/Makefile @@ -0,0 +1,32 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +TARGET = bm_isp + + +obj-m +=$(TARGET).o +$(TARGET)-objs += bm_isp_driver.o + +EXTRA_CFLAGS += -I$(PWD)/./ +EXTRA_CFLAGS += -I$(PWD)/../common +KBUILD_CFLAGS += -O0 +ifeq ($(BUILD_TYPE),DEBUG) + EXTRA_CFLAGS += -DDEBUG +endif + +PWD :=$(shell pwd) + +all: + make -C $(KERNEL) M=$(PWD) modules +modules_install: + make -C $(KERNEL_SRC) M=$(SRC) modules_install +clean: + rm -rf $($(TARGET)-objs) + if [ -d "$(KERNEL)" ]; then \ + make -C $(KERNEL) M=`pwd` clean; \ + fi diff --git a/driver/isp/bm_isp_driver.c b/driver/isp/bm_isp_driver.c new file mode 100644 index 0000000..9a44c95 --- /dev/null +++ b/driver/isp/bm_isp_driver.c @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "bm_printk.h" +#include "bm_isp_ioctl.h" + +#define BM_DRIVER_NAME "bm_isp" +#define BM_DRIVER_MAXCNT 3 + +struct bm_isp_drvdata { + struct cdev cdev; + dev_t devt; + struct class *class; + struct mutex mutex; + unsigned int device_idx; + void __iomem *base; + void __iomem *reset; + //int irq_num; + void *private; // can be bm_isp_drvdata_private, but not use now +}; + +struct bm_isp_drvdata_private { + int private_tmp; +}; + +static struct class *bm_driver_class; +static unsigned int bm_driver_major = 0; +static unsigned int bm_driver_minor = 0; +static unsigned int device_register_index = 0; + +#define check_retval(x)\ + do {\ + if ((x))\ + return -EIO;\ + } while (0) + +static unsigned int bm_isp_poll(struct file * filp, poll_table *wait) +{ + return 0; +} + +void bm_isp_work(struct work_struct *work) +{ +} + +irqreturn_t bm_isp_irq(int irq, void *dev_id) +{ + bm_info("enter %s\n", __func__); + return IRQ_HANDLED; +} + +static int bm_isp_open(struct inode * inode, struct file * file) +{ + struct bm_isp_drvdata *drvdata; + + bm_info("enter %s\n", __func__); + + drvdata = container_of(inode->i_cdev, struct bm_isp_drvdata, cdev); + file->private_data = drvdata; + + return 0; +}; + +static int bm_isp_write_reg(struct bm_isp_drvdata *drvdata, void *__user args) +{ + struct bm_isp_reg_t reg; + check_retval(copy_from_user(®, args, sizeof(reg))); + writel(reg.value, drvdata->base + reg.offset); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, reg.offset, reg.value); + return 0; +} + +static int bm_isp_read_reg(struct bm_isp_drvdata *drvdata, void *__user args) +{ + struct bm_isp_reg_t reg; + check_retval(copy_from_user(®, args, sizeof(reg))); + reg.value = readl(drvdata->base + reg.offset); + check_retval(copy_to_user(args, ®, sizeof(reg))); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, reg.offset, reg.value); + return 0; +} + +static long bm_isp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + struct bm_isp_drvdata *drvdata; + bm_info("enter %s\n", __func__); + + drvdata = file->private_data; + if (drvdata == NULL) { + bm_err("%s:file private is null point error\n", __func__); + return -ENOMEM; + } + + mutex_lock(&drvdata->mutex); + switch (cmd) { + case BMISPIOC_WRITE_REG: + ret = bm_isp_write_reg(drvdata, (void *)arg); + break; + case BMISPIOC_READ_REG: + ret = bm_isp_read_reg(drvdata, (void *)arg); + break; + default: + ret = -EPERM; + bm_err("%s: unsupported command %d", __func__, cmd); + break; + } + mutex_unlock(&drvdata->mutex); + return ret; +}; + +static int bm_isp_release(struct inode * inode, struct file * file) +{ + bm_info("enter %s\n", __func__); + return 0; +}; + +static int bm_isp_mmap(struct file *pFile, struct vm_area_struct *vma) +{ + bm_info("enter %s\n", __func__); + return 0; +}; + +struct file_operations bm_isp_fops = { + .owner = THIS_MODULE, + .open = bm_isp_open, + .release = bm_isp_release, + .unlocked_ioctl = bm_isp_ioctl, + .mmap = bm_isp_mmap, + .poll = bm_isp_poll, +}; + +static int bm_isp_probe(struct platform_device *pdev) +{ + int ret = 0; + struct bm_isp_drvdata *drvdata; + struct resource *iores_mem; + u32 value; + + bm_info("enter %s\n", __func__); + pdev->id = device_register_index; + if (pdev->id >= BM_DRIVER_MAXCNT) { + bm_err("%s:pdev id is %d error\n", __func__, pdev->id); + return -EINVAL; + } + + drvdata = devm_kzalloc(&pdev->dev,sizeof(struct bm_isp_drvdata), GFP_KERNEL); + if (drvdata == NULL) { + bm_err("%s:alloc struct drvdata error\n", __func__); + return -ENOMEM; + } + + iores_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + drvdata->base = devm_ioremap_resource(&pdev->dev, iores_mem); + bm_info("%s: [%s%d]: drvdata->base=0x%px, phy_addr base=0x%llx\n", __func__, + BM_DRIVER_NAME, pdev->id, drvdata->base, iores_mem->start); + drvdata->reset = NULL; + drvdata->device_idx = pdev->id; + mutex_init(&drvdata->mutex); + //drvdata->irq_num = platform_get_irq(pdev, 0); + //bm_info("%s:[%s%d]: pdriver_dev->irq_num=%d\n", __func__, + // BM_ISP_NAME, pdev->id, drvdata->irq_num); + + platform_set_drvdata(pdev, drvdata); + + if (pdev->id == 0) { + if (bm_driver_major == 0) { + ret = alloc_chrdev_region(&drvdata->devt, 0, BM_DRIVER_MAXCNT, BM_DRIVER_NAME); + if (ret != 0) { + bm_err("%s:alloc_chrdev_region error\n", __func__); + return ret; + } + bm_driver_major = MAJOR(drvdata->devt); + bm_driver_minor = MINOR(drvdata->devt); + } else { + drvdata->devt = MKDEV(bm_driver_major, bm_driver_minor); + ret = register_chrdev_region(drvdata->devt, BM_DRIVER_MAXCNT, BM_DRIVER_NAME); + if (ret) { + bm_err("%s:register_chrdev_region error\n", __func__); + return ret; + } + } + + bm_driver_class = class_create(THIS_MODULE, BM_DRIVER_NAME); + if (IS_ERR(bm_driver_class)) { + bm_err("%s[%d]:class_create error!\n", __func__, __LINE__); + return -EINVAL; + } + } + + drvdata->devt = MKDEV(bm_driver_major, bm_driver_minor + pdev->id); + cdev_init(&drvdata->cdev, &bm_isp_fops); + ret = cdev_add(&drvdata->cdev, drvdata->devt, 1); + if ( ret ) { + bm_err("%s[%d]:cdev_add error!\n", __func__, __LINE__); + return ret; + } else { + bm_info("%s[%d]:cdev_add OK, major=%d, minor=%d\n", __func__, __LINE__, + bm_driver_major, bm_driver_minor + pdev->id); + } + drvdata->class = bm_driver_class; + device_create(drvdata->class, NULL, drvdata->devt, + drvdata, "%s%d", BM_DRIVER_NAME, pdev->id); + + value = readl(drvdata->base+0x4); + bm_info("offset=04, value is:0x%08x\n", value); + + device_register_index++; + bm_info("exit %s:[%s%d]\n", __func__, BM_DRIVER_NAME, pdev->id); + + return 0; + +//err_register: + // When error occore, should free memory, destory device, unregister ... + // but now, ignore it +// return ret; +} + +static int bm_isp_remove(struct platform_device *pdev) +{ + struct bm_isp_drvdata *drvdata; + + bm_info("enter %s\n", __func__); + device_register_index--; + + drvdata = platform_get_drvdata(pdev); + //free_irq(drvdata->irq_num, drvdata); + cdev_del(&drvdata->cdev); + device_destroy(drvdata->class, drvdata->devt); + unregister_chrdev_region(drvdata->devt, BM_DRIVER_MAXCNT); + mutex_destroy(&drvdata->mutex); + if (device_register_index == 0) { + class_destroy(drvdata->class); + } + devm_kfree(&pdev->dev, drvdata); + + bm_info("exit %s\n", __func__); + return 0; +} + +static const struct of_device_id bm_isp_of_match[] = { + { .compatible = "thead,light-bm-isp", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, bm_isp_of_match); + +static struct platform_driver bm_isp_driver = { + .probe = bm_isp_probe, + .remove = bm_isp_remove, + .driver = { + .name = BM_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(bm_isp_of_match), + } +}; + +static int __init bm_isp_init_module(void) +{ + int ret = 0; + + bm_info("enter %s\n", __func__); + ret = platform_driver_register(&bm_isp_driver); + if (ret) { + bm_err("register platform driver failed.\n"); + return ret; + } + + return ret; +} + +static void __exit bm_isp_exit_module(void) +{ + bm_info("enter %s\n", __func__); + platform_driver_unregister(&bm_isp_driver); +} + +module_init(bm_isp_init_module); +module_exit(bm_isp_exit_module); + +MODULE_AUTHOR("Lu Chongzhi"); +MODULE_DESCRIPTION("BAREMETAL-ISP"); +MODULE_LICENSE("GPL"); diff --git a/driver/isp/bm_isp_ioctl.h b/driver/isp/bm_isp_ioctl.h new file mode 100644 index 0000000..57a4023 --- /dev/null +++ b/driver/isp/bm_isp_ioctl.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 _BM_ISP_IOCTL_H_ +#define _BM_ISP_IOCTL_H_ + +#include + +enum { + BMISPIOC_WRITE_REG = 0x100, + BMISPIOC_READ_REG, +}; + +struct bm_isp_reg_t { + unsigned int offset; + unsigned int value; +}; + +#endif /* _BM_ISP_IOCTL_H_ */ diff --git a/driver/visys/Makefile b/driver/visys/Makefile new file mode 100644 index 0000000..5bbe89e --- /dev/null +++ b/driver/visys/Makefile @@ -0,0 +1,31 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +TARGET = bm_visys + + +obj-m +=$(TARGET).o +$(TARGET)-objs += bm_visys_driver.o + +EXTRA_CFLAGS += -I$(PWD)/./ +EXTRA_CFLAGS += -I$(PWD)/../common +ifeq ($(BUILD_TYPE),DEBUG) + EXTRA_CFLAGS += -DDEBUG +endif + +PWD :=$(shell pwd) + +all: + make -C $(KERNEL) M=$(PWD) modules +modules_install: + make -C $(KERNEL_SRC) M=$(SRC) modules_install +clean: + rm -rf $($(TARGET)-objs) + if [ -d "$(KERNEL)" ]; then \ + make -C $(KERNEL) M=`pwd` clean; \ + fi diff --git a/driver/visys/bm_visys_driver.c b/driver/visys/bm_visys_driver.c new file mode 100644 index 0000000..c55c439 --- /dev/null +++ b/driver/visys/bm_visys_driver.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "bm_printk.h" +#include "bm_visys_ioctl.h" + +#define BM_DRIVER_NAME "bm_visys" +#define BM_DRIVER_MAXCNT 1 + +struct bm_visys_drvdata { + struct cdev cdev; + dev_t devt; + struct class *class; + struct mutex mutex; + unsigned int device_idx; + void __iomem *base; + void __iomem *reset; + //int irq_num; + void *private; // can be bm_visys_drvdata_private, but not use now +}; + +struct bm_visys_drvdata_private { + int private_tmp; +}; + +static struct class *bm_driver_class; +static unsigned int bm_driver_major = 0; +static unsigned int bm_driver_minor = 0; +static unsigned int device_register_index = 0; + +static struct bm_visys_drvdata *g_pdrvdata; + +#define check_retval(x)\ + do {\ + if ((x))\ + return -EIO;\ + } while (0) + +static unsigned int bm_visys_poll(struct file * filp, poll_table *wait) +{ + return 0; +} + +void bm_visys_work(struct work_struct *work) +{ +} + +irqreturn_t bm_visys_irq(int irq, void *dev_id) +{ + bm_info("enter %s\n", __func__); + return IRQ_HANDLED; +} + +static int bm_visys_open(struct inode * inode, struct file * file) +{ + struct bm_visys_drvdata *drvdata; + + bm_info("enter %s\n", __func__); + + drvdata = container_of(inode->i_cdev, struct bm_visys_drvdata, cdev); + file->private_data = drvdata; + + return 0; +}; + +int k_bm_visys_write_reg(uint32_t offset, uint32_t value) +{ + writel(value, g_pdrvdata->base + offset); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, offset, value); + return 0; +} + +int k_bm_visys_read_reg(uint32_t offset, uint32_t *value) +{ + *value = readl(g_pdrvdata->base + offset); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, offset, *value); + return 0; +} + +EXPORT_SYMBOL(k_bm_visys_write_reg); +EXPORT_SYMBOL(k_bm_visys_read_reg); + +static int bm_visys_write_reg(struct bm_visys_drvdata *drvdata, void *__user args) +{ + struct bm_visys_reg_t reg; + check_retval(copy_from_user(®, args, sizeof(reg))); + writel(reg.value, drvdata->base + reg.offset); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, reg.offset, reg.value); + return 0; +} + +static int bm_visys_read_reg(struct bm_visys_drvdata *drvdata, void *__user args) +{ + struct bm_visys_reg_t reg; + check_retval(copy_from_user(®, args, sizeof(reg))); + reg.value = readl(drvdata->base + reg.offset); + check_retval(copy_to_user(args, ®, sizeof(reg))); + bm_info("%s addr 0x%08x val 0x%08x\n", __func__, reg.offset, reg.value); + return 0; +} + +static long bm_visys_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + struct bm_visys_drvdata *drvdata; + bm_info("enter %s\n", __func__); + + drvdata = file->private_data; + if (drvdata == NULL) { + bm_err("%s:file private is null point error\n", __func__); + return -ENOMEM; + } + + mutex_lock(&drvdata->mutex); + switch (cmd) { + case BMVISYSIOC_WRITE_REG: + ret = bm_visys_write_reg(drvdata, (void *)arg); + break; + case BMVISYSIOC_READ_REG: + ret = bm_visys_read_reg(drvdata, (void *)arg); + break; + default: + ret = -EPERM; + bm_err("%s: unsupported command %d", __func__, cmd); + break; + } + mutex_unlock(&drvdata->mutex); + return ret; +}; + +static int bm_visys_release(struct inode * inode, struct file * file) +{ + bm_info("enter %s\n", __func__); + return 0; +}; + +static int bm_visys_mmap(struct file *pFile, struct vm_area_struct *vma) +{ + bm_info("enter %s\n", __func__); + return 0; +}; + +struct file_operations bm_visys_fops = { + .owner = THIS_MODULE, + .open = bm_visys_open, + .release = bm_visys_release, + .unlocked_ioctl = bm_visys_ioctl, + .mmap = bm_visys_mmap, + .poll = bm_visys_poll, +}; + +static int bm_visys_probe(struct platform_device *pdev) +{ + int ret = 0; + struct bm_visys_drvdata *drvdata; + struct resource *iores_mem; + u32 value; + + bm_info("enter %s\n", __func__); + pdev->id = device_register_index; + if (pdev->id >= BM_DRIVER_MAXCNT) { + bm_err("%s:pdev id is %d error\n", __func__, pdev->id); + return -EINVAL; + } + + drvdata = devm_kzalloc(&pdev->dev,sizeof(struct bm_visys_drvdata), GFP_KERNEL); + if (drvdata == NULL) { + bm_err("%s:alloc struct drvdata error\n", __func__); + return -ENOMEM; + } + + g_pdrvdata = drvdata; + + iores_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + drvdata->base = devm_ioremap_resource(&pdev->dev, iores_mem); + bm_info("%s: [%s%d]: drvdata->base=0x%px, phy_addr base=0x%llx\n", __func__, + BM_DRIVER_NAME, pdev->id, drvdata->base, iores_mem->start); + drvdata->reset = NULL; + drvdata->device_idx = pdev->id; + mutex_init(&drvdata->mutex); + //drvdata->irq_num = platform_get_irq(pdev, 0); + //bm_info("%s:[%s%d]: pdriver_dev->irq_num=%d\n", __func__, + // BM_VISYS_NAME, pdev->id, drvdata->irq_num); + + platform_set_drvdata(pdev, drvdata); + + if (pdev->id == 0) { + if (bm_driver_major == 0) { + ret = alloc_chrdev_region(&drvdata->devt, 0, BM_DRIVER_MAXCNT, BM_DRIVER_NAME); + if (ret != 0) { + bm_err("%s:alloc_chrdev_region error\n", __func__); + return ret; + } + bm_driver_major = MAJOR(drvdata->devt); + bm_driver_minor = MINOR(drvdata->devt); + } else { + drvdata->devt = MKDEV(bm_driver_major, bm_driver_minor); + ret = register_chrdev_region(drvdata->devt, BM_DRIVER_MAXCNT, BM_DRIVER_NAME); + if (ret) { + bm_err("%s:register_chrdev_region error\n", __func__); + return ret; + } + } + + bm_driver_class = class_create(THIS_MODULE, BM_DRIVER_NAME); + if (IS_ERR(bm_driver_class)) { + bm_err("%s[%d]:class_create error!\n", __func__, __LINE__); + return -EINVAL; + } + } + + drvdata->devt = MKDEV(bm_driver_major, bm_driver_minor + pdev->id); + cdev_init(&drvdata->cdev, &bm_visys_fops); + ret = cdev_add(&drvdata->cdev, drvdata->devt, 1); + if ( ret ) { + bm_err("%s[%d]:cdev_add error!\n", __func__, __LINE__); + return ret; + } else { + bm_info("%s[%d]:cdev_add OK, major=%d, minor=%d\n", __func__, __LINE__, + bm_driver_major, bm_driver_minor + pdev->id); + } + drvdata->class = bm_driver_class; + device_create(drvdata->class, NULL, drvdata->devt, + drvdata, "%s%d", BM_DRIVER_NAME, pdev->id); + + value = readl(drvdata->base+0x4); + bm_info("offset=04, value is:0x%08x\n", value); + + device_register_index++; + bm_info("exit %s:[%s%d]\n", __func__, BM_DRIVER_NAME, pdev->id); + + return 0; + +//err_register: + // When error occore, should free memory, destory device, unregister ... + // but now, ignore it +// return ret; +} + +static int bm_visys_remove(struct platform_device *pdev) +{ + struct bm_visys_drvdata *drvdata; + + bm_info("enter %s\n", __func__); + device_register_index--; + + drvdata = platform_get_drvdata(pdev); + //free_irq(drvdata->irq_num, drvdata); + cdev_del(&drvdata->cdev); + device_destroy(drvdata->class, drvdata->devt); + unregister_chrdev_region(drvdata->devt, BM_DRIVER_MAXCNT); + mutex_destroy(&drvdata->mutex); + if (device_register_index == 0) { + class_destroy(drvdata->class); + } + devm_kfree(&pdev->dev, drvdata); + + bm_info("exit %s\n", __func__); + return 0; +} + +static const struct of_device_id bm_visys_of_match[] = { + { .compatible = "thead,light-bm-visys", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, bm_visys_of_match); + +static struct platform_driver bm_visys_driver = { + .probe = bm_visys_probe, + .remove = bm_visys_remove, + .driver = { + .name = BM_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(bm_visys_of_match), + } +}; + +static int __init bm_visys_init_module(void) +{ + int ret = 0; + + bm_info("enter %s\n", __func__); + ret = platform_driver_register(&bm_visys_driver); + if (ret) { + bm_err("register platform driver failed.\n"); + return ret; + } + + return ret; +} + +static void __exit bm_visys_exit_module(void) +{ + bm_info("enter %s\n", __func__); + platform_driver_unregister(&bm_visys_driver); +} + +module_init(bm_visys_init_module); +module_exit(bm_visys_exit_module); + +MODULE_AUTHOR("Lu Chongzhi"); +MODULE_DESCRIPTION("BAREMETAL-VISYS"); +MODULE_LICENSE("GPL"); diff --git a/driver/visys/bm_visys_ioctl.h b/driver/visys/bm_visys_ioctl.h new file mode 100644 index 0000000..739aef6 --- /dev/null +++ b/driver/visys/bm_visys_ioctl.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 _BM_VISYS_IOCTL_H_ +#define _BM_VISYS_IOCTL_H_ + +#include + +enum { + BMVISYSIOC_WRITE_REG = 0x100, + BMVISYSIOC_READ_REG, +}; + +struct bm_visys_reg_t { + unsigned int offset; + unsigned int value; +}; + +#endif /* _BM_VISYS_IOCTL_H_ */ diff --git a/test/csi/Makefile b/test/csi/Makefile new file mode 100644 index 0000000..0cfc6e3 --- /dev/null +++ b/test/csi/Makefile @@ -0,0 +1,30 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +SOURCES = test_csi.c +OBJECTS := $(SOURCES:.c=.o) +EXEC = output/test_csi +CFLAGS = -O0 -Wall -g -lm -I../../driver/csi + +all: $(EXEC) + +.c.o: + $(CC) -c $(CFLAGS) $(INCLUDES) $< + +$(EXEC): $(OBJECTS) + mkdir -p output + $(CC) $(CFLAGS) -o $(EXEC) $(OBJECTS) -pthread + +clean: + rm -f *.o $(EXEC) + rm -rf output + +install: + +.PHONY: clean all + diff --git a/test/csi/test_csi.c b/test/csi/test_csi.c new file mode 100644 index 0000000..76b4902 --- /dev/null +++ b/test/csi/test_csi.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include +#include +#include + +#include "bm_csi_ioctl.h" + +#define DEV_PATHNAME "/dev/bm_csi0" + +typedef struct _csi_ctx +{ + int dev_fd; +} csi_ctx_t; +static csi_ctx_t csi_ctx; + +static int csi_init(csi_ctx_t *ctx) +{ + int fd; + memset(&csi_ctx, 0, sizeof(csi_ctx)); + + fd = open(DEV_PATHNAME, O_RDWR | O_NONBLOCK); + if (fd < 0) { + printf("%s:Can't open %s: %d(%s)\n", __func__, + DEV_PATHNAME, errno, strerror(errno)); + return -1; + } + ctx->dev_fd = fd; + + return 0; +} + +static int csi_deinit(csi_ctx_t *ctx) +{ + if (ctx->dev_fd >= 0) { + close(ctx->dev_fd); + ctx->dev_fd = -1; + } + + return 0; +} + +static int csi_ioctl(csi_ctx_t *ctx, unsigned int cmd, void *args) +{ + int ret; + + if (ctx == NULL || ctx->dev_fd < 0) { + printf("%s:ctx is invalid\n", __func__); + return -1; + } + + ret = ioctl(ctx->dev_fd, cmd, args); + if (ret != 0) { + printf("%s:ioctl failed, ret=%d(%s)\n", __func__, + ret, strerror(ret * -1)); + return ret; + } + + return 0; +} + +int main(void) +{ + int ret; + struct bm_csi_reg_t reg; + reg.offset = 0; + + ret = csi_init(&csi_ctx); + if (ret != 0) + exit(ret); + int cmd = BMCSI_IOC_S_RESET; + while(cmd < BMCSI_IOC_MAX) { + ret = csi_ioctl(&csi_ctx, cmd, ®); + if (ret != 0) { + printf("!!!!!!!!!!!!!!!!!!!error\n"); + } + cmd++; + } + + ret = csi_deinit(&csi_ctx); + if (ret != 0) + exit(ret); + + exit(0); +} + diff --git a/test/isp/Makefile b/test/isp/Makefile new file mode 100644 index 0000000..928a7d0 --- /dev/null +++ b/test/isp/Makefile @@ -0,0 +1,47 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +# To support host build in current path +ifeq ($(CC),) + CC:=gcc +endif + +CFLAGS = -O0 -Wall -g -lm +INCLUDES = -I../../driver/isp -I../../common + +EXEC1 = output/isp_run_bm_script + + +all: $(EXEC1) + +.c.o: + $(CC) -c $(CFLAGS) $(INCLUDES) $< + +prepare: + mkdir -p output + +SOURCES_COMMON = ../../common/log_common.c +OBJECTS_COMMON = log_common.o +common: $(SOURCES_COMMON) + $(CC) $(CFLAGS) -c $< + +SOURCES1 = isp_run_bm_script.c +OBJECTS1 = $(SOURCES1:.c=.o) +$(EXEC1): prepare common $(OBJECTS1) + @echo OBJECTS1=$(OBJECTS1) + $(CC) $(CFLAGS) -o $(EXEC1) $(OBJECTS_COMMON) $(OBJECTS1) + cp -r isp_bm_scripts ./output/ + +clean: + rm -f *.o + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_16line.txt b/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_16line.txt new file mode 100644 index 0000000..4349a40 --- /dev/null +++ b/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_16line.txt @@ -0,0 +1,124 @@ +0 00002800 00000000 +0 00002904 00000003 +0 00002908 00000007 +0 0000290c 00001d1d +0 00002918 00000808 +0 0000291c 00000404 +0 00002920 00000403 +0 00002924 00000a0a +0 00002928 00002020 +0 00002910 00000707 +0 0000292c 0000100c +0 00002930 00001810 +0 00002934 00000403 +0 00002938 00000808 +0 0000293c 00000808 +0 00002914 00001f1f +0 00002940 00002020 +0 00002944 00000404 +0 00002948 00000403 +0 0000294c 00000806 +0 00002950 00000404 +0 00002954 00000afa +0 00002958 00000fff +0 00002900 00000004 +0 00001000 0000010f //global control, Vertical/Horizontal scale +0 00002308 00000000 //H offset of output window +0 0000230c 00000000 //V offset of output winodw +0 00002310 00000000 //H output size +0 00002314 00000000 //V output size +0 00003e44 00000000 +0 00002200 00000000 +0 00000408 00000000 //H input offset +0 0000040c 00000000 //V input offset +0 00000410 00000780 //H input size +0 00000414 00000438 //V input size +0 00000594 00000000 //H offset of output window +0 00000598 00000000 //V offset of output window +0 0000059c 00000780 //H output size +0 000005a0 00000438 //V output size +0 00002308 00000000 //H offset of output window +0 0000230c 00000000 //V offset of output window +0 00002310 00000780 //H output size +0 00002314 00000438 //V output size +0 00000400 00000486 //global control, cfg_upd +0 00000018 00001041 //data path, yuv out +0 00002800 00000000 +0 00000400 00000486 +0 000026a0 00000000 +0 000026a0 00000000 +0 00000014 00000100 +0 00000010 0001fe7b +0 00000200 00000010 +0 00000510 00000000 +0 0000052c 00000000 +0 00000528 00000000 +0 00000524 00000000 +0 00000514 00000000 +0 00000518 00000000 +0 0000051c 00000000 +0 00000520 00000000 +0 0000053c 01000100 +0 00000538 01000100 +0 00002f00 00000000 +0 000005bc 00000000 +0 00003e60 039c0780 //dummy pixels config +0 00003e00 00000000 +0 00003e64 00000000 +0 00002100 00000000 +0 00002600 00000000 +0 000005bc 00000000 +0 000026a0 00000000 +0 00000510 00000000 +0 000005bc 00000000 +0 00002000 00000000 +0 000005bc 00000000 +0 00002f00 00000000 +0 000005bc 00000000 +0 00001324 d0000000 //MP, Y base address +0 00001328 001fa400 //MP, Y size +0 0000132c 00000000 //MP, offset counter init value +0 00001340 d01fa400 //MP, CB base address +0 00001344 001fa400 //MP, CB size +0 00001348 00000000 //MP, CB offset counter init value +0 0000134c 00000000 //MP, CR base address +0 00001350 00000000 //MP, CR size +0 00001354 00000000 //MP, CR offset counter init value +0 0000160c 08000000 //MCM, AXI ID config +0 00000404 0000405d //ACQ prop +0 0000131c 02000100 //MP, AXI ID config +0 00001318 00000002 //MP, AXI config +0 00001608 00000002 //MCM, AXI config +0 00001314 00000004 //MP, format NV12 +0 00001300 00000001 +0 00001310 0000003a //MP control, cfg_upd +0 00000c6c 00000000 //forma conversion +0 000016c0 0007ff3f //interuupt mask +0 00001868 00000690 +0 0000187c 00000030 +0 00000680 00000010 +0 00000418 00000000 //number of frames to be captured, 0 for continuous +0 000005c8 ffffffff //interrupt clear +0 000005bc 00000023 //interrupt mask +0 00000400 00000697 +0 00005598 c0000000 //PP, Y start +0 0000559c 00000780 //PP, Y width +0 000055a0 00000780 //PP, Y llength +0 000055a4 001fa400 //PP, Y size +0 000055bc 00000780 //PP, Y pic lval +0 00005504 80000000 //PP, format RAW8 +0 000055c0 00000010 //PP, Y entry line number +0 000055c4 00000438 //PP, Y buf line number +0 000055c8 00000438 //PP, Y height +0 000055cc 00000780 //PP, Y lval +0 000016e8 00020000 //intr set +0 00005500 000000fa //pp control, cfg_upd +0 00001300 00000001 +0 00001300 00200001 //dma read trigger +0 00000400 00000697 +msleep 1000 // sleep 1000 +1 000016d0 00000301 // MI_MIS, should get 0x00000301 +1 000016f0 00000000 // MI_MIS2, should get 0x00000000 +1 000005c0 000000ff // ISP_RIS, Raw interrupt status, should get 0x000000ff +1 000005c4 00000023 // ISP_MIS, Raw interrupt status, should get 0x000000ff +1 00000400 00000096 // ISP_CTRL, should be 0x96 diff --git a/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_64line.txt b/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_64line.txt new file mode 100644 index 0000000..6129de5 --- /dev/null +++ b/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_64line.txt @@ -0,0 +1,124 @@ +0 00002800 00000000 +0 00002904 00000003 +0 00002908 00000007 +0 0000290c 00001d1d +0 00002918 00000808 +0 0000291c 00000404 +0 00002920 00000403 +0 00002924 00000a0a +0 00002928 00002020 +0 00002910 00000707 +0 0000292c 0000100c +0 00002930 00001810 +0 00002934 00000403 +0 00002938 00000808 +0 0000293c 00000808 +0 00002914 00001f1f +0 00002940 00002020 +0 00002944 00000404 +0 00002948 00000403 +0 0000294c 00000806 +0 00002950 00000404 +0 00002954 00000afa +0 00002958 00000fff +0 00002900 00000004 +0 00001000 0000010f //global control, Vertical/Horizontal scale +0 00002308 00000000 //H offset of output window +0 0000230c 00000000 //V offset of output winodw +0 00002310 00000000 //H output size +0 00002314 00000000 //V output size +0 00003e44 00000000 +0 00002200 00000000 +0 00000408 00000000 //H input offset +0 0000040c 00000000 //V input offset +0 00000410 00000780 //H input size +0 00000414 00000438 //V input size +0 00000594 00000000 //H offset of output window +0 00000598 00000000 //V offset of output window +0 0000059c 00000780 //H output size +0 000005a0 00000438 //V output size +0 00002308 00000000 //H offset of output window +0 0000230c 00000000 //V offset of output window +0 00002310 00000780 //H output size +0 00002314 00000438 //V output size +0 00000400 00000486 //global control, cfg_upd +0 00000018 00001041 //data path, yuv out +0 00002800 00000000 +0 00000400 00000486 +0 000026a0 00000000 +0 000026a0 00000000 +0 00000014 00000100 +0 00000010 0001fe7b +0 00000200 00000010 +0 00000510 00000000 +0 0000052c 00000000 +0 00000528 00000000 +0 00000524 00000000 +0 00000514 00000000 +0 00000518 00000000 +0 0000051c 00000000 +0 00000520 00000000 +0 0000053c 01000100 +0 00000538 01000100 +0 00002f00 00000000 +0 000005bc 00000000 +0 00003e60 039c0780 //dummy pixels config +0 00003e00 00000000 +0 00003e64 00000000 +0 00002100 00000000 +0 00002600 00000000 +0 000005bc 00000000 +0 000026a0 00000000 +0 00000510 00000000 +0 000005bc 00000000 +0 00002000 00000000 +0 000005bc 00000000 +0 00002f00 00000000 +0 000005bc 00000000 +0 00001324 d0000000 //MP, Y base address +0 00001328 001fa400 //MP, Y size +0 0000132c 00000000 //MP, offset counter init value +0 00001340 d01fa400 //MP, CB base address +0 00001344 001fa400 //MP, CB size +0 00001348 00000000 //MP, CB offset counter init value +0 0000134c 00000000 //MP, CR base address +0 00001350 00000000 //MP, CR size +0 00001354 00000000 //MP, CR offset counter init value +0 0000160c 08000000 //MCM, AXI ID config +0 00000404 0000405d //ACQ prop +0 0000131c 02000100 //MP, AXI ID config +0 00001318 00000002 //MP, AXI config +0 00001608 00000002 //MCM, AXI config +0 00001314 00000004 //MP, format NV12 +0 00001300 00000001 +0 00001310 0000003a //MP control, cfg_upd +0 00000c6c 00000000 //forma conversion +0 000016c0 0007ff3f //interuupt mask +0 00001868 00000690 +0 0000187c 00000030 +0 00000680 00000010 +0 00000418 00000000 //number of frames to be captured, 0 for continuous +0 000005c8 ffffffff //interrupt clear +0 000005bc 00000023 //interrupt mask +0 00000400 00000697 +0 00005598 c0000000 //PP, Y start +0 0000559c 00000780 //PP, Y width +0 000055a0 00000780 //PP, Y llength +0 000055a4 001fa400 //PP, Y size +0 000055bc 00000780 //PP, Y pic lval +0 00005504 80000000 //PP, format RAW8 +0 000055c0 00000040 //PP, Y entry line number +0 000055c4 00000438 //PP, Y buf line number +0 000055c8 00000438 //PP, Y height +0 000055cc 00000780 //PP, Y lval +0 000016e8 00020000 //intr set +0 00005500 000000fa //pp control, cfg_upd +0 00001300 00000001 +0 00001300 00200001 //dma read trigger +0 00000400 00000697 +msleep 1000 // sleep 1000 +1 000016d0 00000301 // MI_MIS, should get 0x00000301 +1 000016f0 00000000 // MI_MIS2, should get 0x00000000 +1 000005c0 000000ff // ISP_RIS, Raw interrupt status, should get 0x000000ff +1 000005c4 00000023 // ISP_MIS, Raw interrupt status, should get 0x000000ff +1 00000400 00000096 // ISP_CTRL, should be 0x96 diff --git a/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_frame.txt b/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_frame.txt new file mode 100644 index 0000000..e796be8 --- /dev/null +++ b/test/isp/isp_bm_scripts/2002_format.RAW8.YUV422.mp.00.regdump_frame.txt @@ -0,0 +1,177 @@ +0 00002800 00000000 +1 00002900 00000004 +0 00002904 00000003 +0 00002908 00000007 +0 0000290c 00001d1d +0 00002918 00000808 +0 0000291c 00000404 +0 00002920 00000403 +0 00002924 00000a0a +0 00002928 00002020 +0 00002910 00000707 +0 0000292c 0000100c +0 00002930 00001810 +0 00002934 00000403 +0 00002938 00000808 +0 0000293c 00000808 +0 00002914 00001f1f +0 00002940 00002020 +0 00002944 00000404 +0 00002948 00000403 +0 0000294c 00000806 +0 00002950 00000404 +0 00002954 00000afa +0 00002958 00000fff +0 00002900 00000004 +1 00000018 00000000 +0 00002308 00000000 +0 0000230c 00000000 +0 00002310 00000000 +0 00002314 00000000 +0 00003e44 00000000 +0 00002200 00000000 +1 00000400 00000080 +1 00000400 00000480 +1 00000404 0000c05d +0 00000408 00000000 +0 0000040c 00000000 +0 00000410 00000780 +0 00000414 00000438 +0 00000594 00000000 +0 00000598 00000000 +0 0000059c 00000780 +0 000005a0 00000438 +0 00002308 00000000 +0 0000230c 00000000 +0 00002310 00000780 +0 00002314 00000438 +0 00000400 00000486 +1 00000018 00000000 +0 00000018 00001041 +1 00002800 00000000 +0 00002800 00000000 +1 00000400 00000486 +0 00000400 00000486 +1 000026a0 00000000 +0 000026a0 00000000 +1 000026a0 00000000 +0 000026a0 00000000 +1 00000200 00000000 +1 00000010 0001ff7b +1 00000014 00000000 +1 0000021c 0000880c +1 00000204 00000000 +0 00000014 00000100 +0 00000010 0001fe7b +0 00000200 00000010 +1 00000510 00000000 +0 00000510 00000000 +0 0000052c 00000000 +0 00000528 00000000 +0 00000524 00000000 +0 00000514 00000000 +0 00000518 00000000 +0 0000051c 00000000 +0 00000520 00000000 +0 0000053c 01000100 +0 00000538 01000100 +1 00002f00 00000000 +1 000005bc 00000000 +0 00002f00 00000000 +0 000005bc 00000000 +0 00003e60 039c0780 +0 00003e00 00000000 +0 00003e64 00000000 +1 00002100 00000000 +1 000005bc 00000000 +0 00002100 00000000 +1 00002600 00000000 +1 000005bc 00000000 +0 00002600 00000000 +0 000005bc 00000000 +1 000026a0 00000000 +0 000026a0 00000000 +1 00000510 00000000 +1 000005bc 00000000 +0 00000510 00000000 +0 000005bc 00000000 +1 00002000 00000000 +1 000005bc 00000000 +0 00002000 00000000 +0 000005bc 00000000 +1 00002f00 00000000 +1 000005bc 00000000 +0 00002f00 00000000 +0 000005bc 00000000 +0 00001324 d0000000 +0 00001328 001fa400 +0 0000132c 00000000 +0 00001340 d01fa400 +0 00001344 001fa400 +0 00001348 00000000 +0 0000134c 00000000 +0 00001350 00000000 +0 00001354 00000000 +1 0000160c 00000000 +0 0000160c 08000000 +1 00001608 00000000 +1 00001300 00000000 +1 00001318 00000000 +1 00001314 00000000 +1 00000c6c 00000000 +1 00000404 0000c05d +0 00000404 0000405d +1 0000131c 00000000 +0 0000131c 02000100 +0 00001318 00000002 +0 00001608 00000002 +0 00001314 00000004 +0 00001300 00000001 +0 00001310 0000003a +0 00000c6c 00000000 +1 00001608 00000002 +1 00001608 00000002 +1 00001608 00000002 +1 000016c0 00000000 +0 000016c0 0007ff3f +1 00001868 00000000 +1 0000187c 00000000 +0 00001868 00000690 +0 0000187c 00000030 +0 00000680 00000010 +0 00000418 00000001 +1 000005bc 00000000 +0 000005c8 ffffffff +0 000005bc 00000023 +1 00000400 00000486 +0 00000400 00000497 +0 00000400 00000697 +1 00005504 00000000 +1 000016e8 00000000 +1 00001300 00000001 +1 00005500 00000000 +0 00005598 c0000000 +0 0000559c 00000780 +0 000055a0 00000780 +0 000055a4 001fa400 +0 000055bc 00000780 +0 00005504 80000000 +0 000055c0 00000438 +0 000055c4 00000438 +0 000055c8 00000438 +0 000055cc 00000780 +0 000016e8 00020000 +0 00005500 000000fa +0 00001300 00000001 +1 00001300 00000001 +0 00001300 00200001 +1 000016c0 0007ff3f +1 00003700 00000000 +1 00000400 00000697 +0 00000400 00000697 +msleep 1000 // sleep 1000 +1 000016d0 00000301 // MI_MIS, should get 0x00000301 +1 000016f0 00000000 // MI_MIS2, should get 0x00000000 +1 000005c0 000000ff // ISP_RIS, Raw interrupt status, should get 0x000000ff +1 000005c4 00000023 // ISP_MIS, Raw interrupt status, should get 0x000000ff +1 00000400 00000096 // ISP_CTRL, should be 0x96 diff --git a/test/isp/isp_bm_scripts/4005_scaling_640x480.512x512.txt b/test/isp/isp_bm_scripts/4005_scaling_640x480.512x512.txt new file mode 100644 index 0000000..12402b7 --- /dev/null +++ b/test/isp/isp_bm_scripts/4005_scaling_640x480.512x512.txt @@ -0,0 +1,67 @@ +0 00002800 00000000 // Default: disable De-noising +0 00002900 00000000 // Default: Disable DPCC +0 00000018 00000000 // Default: VI_DPCL (Data Path Control Register) +0 00000400 00000000 // Disable ISP_CTRL.disable_isp_clk +0 00001200 00000000 // Ensure ISP_MCM_CTRL.mcm_bypass_en=0, means data is coming from MCM read from DDR +0 00000408 00000000 // ISP_ACQ_H_OFFS = 0 +0 0000040c 00000000 // ISP_ACQ_V_OFFS = 0 +0 00000410 00000280 // ISP_ACQ_H_SIZE = 0x280 = 640 +0 00000414 000001e0 // ISP_ACQ_V_SIZE = 0x1e0 = 480 +0 00000594 00000000 // ISP_OUT_H_OFFS = 0 +0 00000598 00000000 // ISP_OUT_V_OFFS = 0 +0 0000059c 00000280 // ISP_OUT_H_SIZE = 0x280 = 640 +0 000005a0 000001e0 // ISP_OUT_V_SIZE = 0x1e0 = 480 +0 00002308 00000000 // ISP_IS_H_OFFS = 0 // can't remove +0 0000230c 00000000 // ISP_IS_V_OFFS = 0 // can't remove +0 00002310 00000280 // ISP_IS_H_SIZE = 0 // can't remove +0 00002314 000001e0 // ISP_IS_H_OFFS = 0 // can't remove +0 00000018 00001041 // VI_DPCL.vi_chan_mode=Enable MP, vi_dma_switch=path to ISP, vi_mp_mux=main resize to MI +0 00000014 00000100 // VI_IRCL, make sure ie to be reset mode +0 00000010 0001fe7b // VI_ICCL, make sure vi_mrsz_clk_enable (Main resize clock enable), disable ie +0 00003e60 039c0280 // ISP_DMSC_SIZE_CTRL, set img_hsize=0x280=640 +0 00003e00 00000000 // ISP_DMSC_CTRL, keep all Demosaic control to default +0 00001324 D0000000 // MI_MP_Y_BASE_AD_INIT, set Y output addr +0 00001328 00040000 // MI_MP_Y_SIZE_INIT, set Y output size +0 0000132c 00000000 // MI_MP_Y_OFFS_CNT_INIT, set Y output offset +0 00001340 D0040000 // MI_MP_CB_BASE_AD_INIT, set Cb output addr +0 00001344 00020000 // MI_MP_CB_SIZE_INIT, set Cb output size +0 00001348 00000000 // MI_MP_CB_OFFS_CNT_INIT, set Cb output offset +0 0000134c 00000000 // MI_MP_CR_BASE_AD_INIT, set Cr output addr, here it's semi-planar, it not needed +0 00001350 00000000 // MI_MP_CR_SIZE_INIT, set Cr output size +0 00001354 00000000 // MI_MP_CR_OFFS_CNT_INIT, set CR output offset +0 0000160c 08000000 // MI_MCM_BUS_ID.mcm_bus_sw_en=1, and set to 1’b1 before ISP works +0 00000c14 00008849 // MRSZ_SCALE_VC +0 00000c10 0000eff7 // MRSZ_SCALE_VY +0 00000c0c 0000cca4 // MRSZ_SCALE_HCR +0 00000c08 0000cca4 // MRSZ_SCALE_HCB +0 00000c04 0000ccb9 // MRSZ_SCALE_HY +0 00000c00 0000024f // MRSZ_CTRL, scale_XX_enable +0 00001330 00000200 // MI_MP_Y_LLENGTH, line stride=0x200=512 +0 00001334 00000200 // MI_MP_Y_PIC_WIDTH, line pixel=0x200=512 +0 00001338 00000200 // MI_MP_Y_PIC_HEIGHT, hight pixel=0x200=512 +0 0000133c 00040000 // MI_MP_Y_PIC_SIZE, Y picture size=0x40000=512*512 +0 00000404 00000058 // ISP_ACQ_PROP: conv_422, bayer_pat +0 0000131c 02000100 // MI_MP_BUS_ID: mp_bus_sw_en, mp_wr_id_en +0 00001314 00000000 // MI_MP_FMT, keep default: YUV420,Semi-Planar... +0 00001300 00000001 // MI_CTRL, mp_ycbcr_path_enable before next line +0 00001310 0000003a // MI_MP_CTRL, update immediately +0 00000c6c 00000000 // MRSZ_FORMAT_CONV_CTRL, it seems main format control moved to MI_MP_FMT(1314) +0 00000418 00000001 // ISP_ACQ_NR_FRAMES, acquire only 1 frame +0 000005c8 ffffffff // ISP_ICR, write clean all interrupt +0 000005bc 00000023 // ISP_IMSC, active interrupt: imsc_frame_in, imsc_frame, imsc_isp_off +0 00000400 00000697 // ISP_CTRL: isp_enable +0 0000166c C0000000 // MI_MCM_DMA_RAW_PIC_START_AD: input raw image address +0 00001670 00000280 // MI_MCM_DMA_RAW_PIC_WIDTH: RAW component image width +0 00001674 00000280 // MI_MCM_DMA_RAW_PIC_LLENGTH +0 00001678 0004b000 // MI_MCM_DMA_RAW_PIC_SIZE +0 00001690 00000280 // MI_MCM_DMA_RAW_PIC_LVAL +0 00001604 00000000 // MI_MCM_FMT +0 000016c0 0087ff3f // MI_IMSC, Interrupt Mask, enable most of interrupt +0 00001600 00000060 // MI_MCM_CTRL, mcm_rd_cfg_upd +0 00001300 0000c001 // MI_CTRL, mcm_raw_rdma_path_enable mcm_raw_rdma_start +msleep 1000 // sleep 1000 +1 000016d0 00000301 // MI_MIS, should get 0x00000301 +1 000016f0 00000000 // MI_MIS2, should get 0x00000000 +1 000005c0 000000ff // ISP_RIS, Raw interrupt status, should get 0x000000ff +1 000005c4 00000023 // ISP_MIS, Raw interrupt status, should get 0x000000ff +1 00000400 00000096 // ISP_CTRL, should be 0x96 diff --git a/test/isp/isp_bm_scripts/isp_mem_to_mem.txt b/test/isp/isp_bm_scripts/isp_mem_to_mem.txt new file mode 100644 index 0000000..3694dc9 --- /dev/null +++ b/test/isp/isp_bm_scripts/isp_mem_to_mem.txt @@ -0,0 +1,26 @@ +set 0x00000014 0xffffffff // reset isp -step1 +set 0x00000014 0x00000000 // reset isp -step2 +set 0x00000404 0x0000c05d // ISP_ACQ_PROP, set rgb_dma_sel, input_selection, conv_422, bayer_pat, vsync_pol, sample_edge +set 0x0000166c 0x00000000 // for "MI_MCM_DMA_RAW_PIC_START_AD", set mcm_dma_raw_pic_start_ad=0x60000000 +set 0x00001670 0x00000280 // for "MI_MCM_DMA_RAW_PIC_WIDTH", set mcm_dma_raw_pic_width=0x280=640 +set 0x00001674 0x00000280 // for "MI_MCM_DMA_RAW_PIC_LLENGTH", set mcm_dma_raw_pic_llength=0x280=640 +set 0x00001678 0x00096000 // for "MI_MCM_DMA_RAW_PIC_SIZE", mcm_dma_raw_pic_size=0x96000=614400=480*2*640 +set 0x00001690 0x00000500 // for "MI_MCM_DMA_RAW_PIC_LVAL", set mcm_dma_raw_width_bytes=0x500=1280=2*640 +set 0x00001604 0x00000004 // for "MI_MCM_FMT", set mcm_rd_raw_bit=b'100: RAW16 +set 0x000016c0 0x01800025 // for "MI_IMSC", enable interrupt masks +set 0x00001600 0x000000FA // for "MI_MCM_CTRL", set mcm_rd_cfg_upd=mcm_rd_auto_update=1 +set 0x00001300 0x0000c001 // for "MI_CTRL", set mcm_raw_rdma_start, mcm_raw_rdma_path_enable +set 0x00000400 0x00000219 // for "ISP_CTRL", inform_enable, set isp_mode, isp_enable +get 0x00000014 +get 0x000015e0 // Read MI_SP2_DMA_RAW_STATUS +get 0x0000168c // Read MI_MCM_DMA_STATUS +get 0x000016e0 // Read MI_RIS +get 0x000016e0 // Read MI_RIS +get 0x000016e0 // Read MI_RIS +get 0x000016e0 // Read MI_RIS +get 0x000016e0 // Read MI_RIS +get 0x000016e0 // Read MI_RIS +get 0x000016e0 // Read MI_RIS +get 0x00000400 // Read ISP_CTRL +get 0x000016e0 // Read MI_RIS +get 0x00000014 diff --git a/test/isp/isp_bm_scripts/isp_v4_mcm.txt b/test/isp/isp_bm_scripts/isp_v4_mcm.txt new file mode 100644 index 0000000..f66c50a --- /dev/null +++ b/test/isp/isp_bm_scripts/isp_v4_mcm.txt @@ -0,0 +1,113 @@ +0 00000010 0001ff7b +0 00000014 00020000 +0 00001204 04380780 +0 00001208 04380780 +0 00001280 00000003 +0 00001284 a667aba8 +0 00001288 8b34a6ce +0 0000128c 000b3658 +0 00001200 00000240 +0 00001600 00000018 +0 00001604 0002a222 +0 00001608 0000000a +0 0000160c 08028783 +0 00001620 00000f00 +0 00001624 00000780 +0 00001628 00000438 +0 0000162c 003f4800 +0 0000164c 00000f00 +0 00001650 00000780 +0 00001654 00000438 +0 00001658 003f4800 +0 00001614 80000000 +0 00001618 003f4800 +0 00001640 90000000 +0 00001644 003f4800 +0 00001600 0000005c +0 00001308 6ce60608 +0 00001310 00000030 +0 00001314 00000884 +0 00001318 00000001 +0 0000131c 03a2013b +0 00001320 00000000 +0 00001324 00000000 +0 00001328 001fa400 +0 0000132c 00000000 +0 00001330 00000780 +0 00001334 00000780 +0 00001338 00000438 +0 0000133c 001fa400 +0 00001340 001fa400 +0 00001344 001fa400 +0 00001348 00000000 +0 0000134c 003f4800 +0 00001350 0d050750 +0 00001354 00000000 +0 00001358 00000000 +0 0000135c 00000000 +0 00001360 00000000 +0 00001394 10000000 +0 00001398 003f4800 +0 0000139c 00000000 +0 000013a0 00000f00 +0 000013a4 00000780 +0 000013a8 00000438 +0 000013ac 003f4800 +0 000013c0 20000000 +0 000013c4 00001000 +0 000013c8 00000000 +0 000013cc 00001000 +0 000013d0 00000400 +0 000013d4 00000001 +0 000013d8 00001000 +0 000013ec 00000000 +0 000016c0 ffffffff +0 00000404 00d00018 +0 00000410 00000780 +0 00000414 00000438 +0 00000400 80186006 +0 00000538 01000100 +0 0000053c 02270220 +0 00000594 00000000 +0 00000598 00000000 +0 0000059c 00000780 +0 000005a0 00000438 +0 000005bc 001effff +0 00002310 00000780 +0 00002314 00000438 +0 00003e00 040128be +0 00003e04 00000000 +0 00003e08 00001f08 +0 00003e0c 200003ff +0 00003e10 0c968628 +0 00003e14 00008008 +0 00003e18 007d07d0 +0 00003e1c 301a3012 +0 00003e20 04010000 +0 00003e24 22018000 +0 00003e28 00020000 +0 00003e2c 0210210a +0 00003e30 00102102 +0 00003e34 0000388c +0 00003e38 00000000 +0 00003e3c 00000000 +0 00003e40 00000000 +0 00003e44 00000001 +0 00003e48 10001000 +0 00003e4c 00000000 +0 00003e50 00000000 +0 00003e54 00000000 +0 00003e58 00080010 +0 00003e5c 00080010 +0 00003e60 28310780 +0 000015bc 60000000 +0 00001568 60000000 +0 00000018 00001041 +0 00001200 00020241 +0 00001300 00004043 +0 00001310 0000003a +0 000014e4 0000023a +0 00001600 0000005d +0 00000400 80100697 + + diff --git a/test/isp/isp_run_bm_script.c b/test/isp/isp_run_bm_script.c new file mode 100644 index 0000000..241ca7a --- /dev/null +++ b/test/isp/isp_run_bm_script.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include +#include +#include +#include +#include + +#include "bm_isp_ioctl.h" +#include "log_common.h" + +#define DEV_PATHNAME "/dev/bm_isp0" +#define TOOL_NAME "isp_run_bm_script" +#define INVALID_MAGIC32 0xDEADBEEF + +typedef enum { + ISP_BM_SCRIPT_OP_REG_SET, + ISP_BM_SCRIPT_OP_REG_GET, + ISP_BM_SCRIPT_OP_MSLEEP, +} isp_bm_script_op; + +typedef struct _isp_ctx { + int dev_fd; +} isp_ctx_t; +static isp_ctx_t isp_ctx; + +typedef struct { + isp_bm_script_op op; + struct bm_isp_reg_t reg; + unsigned int expect; + unsigned int msleep; +} isp_bm_script_info; + +typedef struct { + uint32_t begin_line; // default:0 + uint32_t end_line; // default:-1, -1 means no limit + char device_name[256]; + char bm_script_name[256]; + uint32_t simulate; +} cmd_param_s; + +static int isp_init(isp_ctx_t *ctx, char *device_name) +{ + int fd; + + if (!device_name) { + printf("%s:device name is invalid\n", __func__); + return -1; + } + + memset(&isp_ctx, 0, sizeof(isp_ctx)); + + fd = open(device_name, O_RDWR | O_NONBLOCK); + if (fd < 0) { + printf("%s:Can't open %s: %d(%s)\n", __func__, + device_name, errno, strerror(errno)); + return -1; + } + ctx->dev_fd = fd; + + return 0; +} + +static int isp_deinit(isp_ctx_t *ctx) +{ + if (ctx->dev_fd >= 0) { + close(ctx->dev_fd); + ctx->dev_fd = -1; + } + + return 0; +} + +static int isp_ioctl(isp_ctx_t *ctx, unsigned int cmd, void *args) +{ + int ret; + + if (ctx == NULL || ctx->dev_fd < 0) { + printf("%s:ctx is invalid\n", __func__); + return -1; + } + + ret = ioctl(ctx->dev_fd, cmd, args); + if (ret != 0) { + printf("%s:ioctl failed, ret=%d(%s)\n", __func__, + ret, strerror(ret * -1)); + return ret; + } + + return 0; +} + +static int parse_script_line(isp_bm_script_info *script_info, char *script_line) +{ + int ret; + char op_str[64]=""; + //printf("script_line=%s", script_line); + ret = sscanf(script_line, "%s %x %x", op_str, &script_info->reg.offset, &script_info->reg.value); + if (ret == 3 && (strcmp(op_str, "set") == 0 || strcmp(op_str, "0") == 0)) { + script_info->op = ISP_BM_SCRIPT_OP_REG_SET; + return 0; + } else if (ret >= 2 && (strcmp(op_str, "get") == 0 || strcmp(op_str, "1") == 0)) { + script_info->op = ISP_BM_SCRIPT_OP_REG_GET; + if (ret == 2) + script_info->expect = INVALID_MAGIC32; + else + script_info->expect = script_info->reg.value; + return 0; + } else if (ret == 2 && strcmp(op_str, "msleep") == 0) { + ret = sscanf(script_line, "%s %d", op_str, &script_info->msleep); + script_info->op = ISP_BM_SCRIPT_OP_MSLEEP; + return 0; + } else { + printf_red("script_line invalid:'%s'\n", script_line); + return -1; + } +} + +static void help(void) +{ + printf("usage: %s [-d device] [-f script_file] [-s simulate]\n", TOOL_NAME); + printf(" example: %s -d /dev/isp0 -f isp_bm_scripts/isp_v4_mcm.txt -b 0 -e 9 -s 0\n", TOOL_NAME); +} + +static void _dump_cmd_param(cmd_param_s *cmd_param) +{ + printf("%s -d %s -f %s -b %d -e %d -s %d\n", + TOOL_NAME, + cmd_param->device_name, + cmd_param->bm_script_name, + cmd_param->begin_line, + cmd_param->end_line, + cmd_param->simulate); +} + +static int parse_cmd_params(int argc,char *argv[], cmd_param_s *cmd_param) +{ + int param_cnt = 1; + memset(cmd_param, 0, sizeof(*cmd_param)); + cmd_param->begin_line = 0; + cmd_param->end_line = -1; + + if (argc == 1) { + help(); + return -1; + } + + while (param_cnt < argc) { + if (0 == strncmp (argv[param_cnt], "-d", 2)) { + strncpy(cmd_param->device_name, argv[param_cnt+1], sizeof(cmd_param->bm_script_name)); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-f", 2)) { + strncpy(cmd_param->bm_script_name, argv[param_cnt+1], sizeof(cmd_param->bm_script_name)); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-b", 2)) { + cmd_param->begin_line = atoi(argv[param_cnt+1]); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-e", 2)) { + cmd_param->end_line = atoi(argv[param_cnt+1]); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-s", 2)) { + cmd_param->simulate = atoi(argv[param_cnt+1]); + param_cnt += 2; + } else { + printf("Invalid syntax.\n"); + _dump_cmd_param(cmd_param); + help(); + return -1; + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + int32_t ret = 0; + uint32_t current_line = 0; + uint32_t run_lines = 0; + FILE *stream; + char string[1024]; + + cmd_param_s cmd_param; + ret = parse_cmd_params(argc, argv, &cmd_param); + if (ret != 0) { + return ret; + } + _dump_cmd_param(&cmd_param); + + if (cmd_param.simulate == 0) { + ret = isp_init(&isp_ctx, &(cmd_param.device_name[0])); + if (ret != 0) { + printf("isp_init failed\n"); + exit(ret); + } + } + stream = fopen(cmd_param.bm_script_name, "r"); + if(stream == NULL) { + printf("Open script file:'%s' failed\n", cmd_param.bm_script_name); + return -1; + } + + printf(">>> Below result is run under %s:\n", + cmd_param.simulate ? "Simulation" : "Hardware"); + + fseek(stream, 0, SEEK_SET); + while (current_line <= cmd_param.end_line) { + if (fgets(string, sizeof(string), stream) == NULL) { + //printf("fgets script file:'%s' failed\n", cmd_param.bm_script_name); + break; + } + + if (current_line >= cmd_param.begin_line && + current_line <= cmd_param.end_line) { + //struct bm_isp_reg_t reg; + isp_bm_script_info script_info; + ret = parse_script_line(&script_info, string); + if (ret != 0) { + //printf_red("Line-%03d is invalid:%s", current_line+1, string); + current_line++; + continue; + } + + //printf("[line-%03d] offset=0x%08x, value=0x%08x\n", + // current_line, reg.offset, reg.value); + + if (cmd_param.simulate == 0) { + if (script_info.op == ISP_BM_SCRIPT_OP_REG_SET) { + ret = isp_ioctl(&isp_ctx, BMISPIOC_WRITE_REG, &script_info.reg); + if (ret == 0) { + printf("line%03d: Write reg OK, offset=0x%08x, value=0x%08x\n", + current_line+1, script_info.reg.offset, script_info.reg.value); + } else { + printf("line%03d: Write reg failed\n", current_line+1); + ret = -1; + break; + } + } else if (script_info.op == ISP_BM_SCRIPT_OP_REG_GET) { + ret = isp_ioctl(&isp_ctx, BMISPIOC_READ_REG, &script_info.reg); + if (ret == 0) { + printf("line%03d: Read reg OK, offset=0x%08x, value=0x%08x\n", + current_line+1, script_info.reg.offset, script_info.reg.value); + } else { + printf("line%03d: Read reg failed\n", current_line+1); + ret = -1; + break; + } + if (script_info.expect != INVALID_MAGIC32 && + script_info.reg.value != script_info.expect) { + printf_red(" Read value(0x%08x) != expect(0x%08x)\n", + script_info.reg.value, script_info.expect); + } + } else if (script_info.op == ISP_BM_SCRIPT_OP_MSLEEP) { + usleep(script_info.msleep * 1000); + printf("line%03d: sleep %ums finished\n", current_line+1, script_info.msleep); + } + } else { + if (script_info.op == ISP_BM_SCRIPT_OP_REG_SET) { + printf("line%03d: Write reg OK, offset=0x%08x, value=0x%08x\n", + current_line+1, script_info.reg.offset, script_info.reg.value); + } else if (script_info.op == ISP_BM_SCRIPT_OP_REG_GET) { + printf("line%03d: Read reg OK, offset=0x%08x, value=0x%08x\n", + current_line+1, script_info.reg.offset,script_info.reg.value); + if (script_info.expect != INVALID_MAGIC32 && + script_info.reg.value != script_info.expect) { + printf_red(" Read value(0x%08x) != expect(0x%08x)\n", + script_info.reg.value, script_info.expect); + } + } else if (script_info.op == ISP_BM_SCRIPT_OP_MSLEEP) { + usleep(script_info.msleep * 1000); + printf("line%03d: sleep %ums finished\n", current_line+1, script_info.msleep); + } + } + } + run_lines++; + current_line++; + } + printf("<<< %d script lines are run\n", run_lines); + + if (cmd_param.simulate == 0) { + isp_deinit(&isp_ctx); + } + fclose(stream); + return 0; +} diff --git a/test/isp/resource/RAW8_20100101_005155_1920x1080.raw b/test/isp/resource/RAW8_20100101_005155_1920x1080.raw new file mode 100644 index 0000000..37b5689 --- /dev/null +++ b/test/isp/resource/RAW8_20100101_005155_1920x1080.raw @@ -0,0 +1,147178 @@ ++H*H(H(G*P,K+K-N.S0K-R2R7M4V3S8W2T2X4R3U6_7W5\9[8[;dc;\;^8W8V5W5U2Z4U/S0L/I1F,H,G&=(=&A&7#;"8!9"5"/4.+$&      + +             +                    + +  + +          +       +     + +  +  +  + +   + + #(*',(("   + +   + + + + +        +  +   + +    +  + +     +  +     + + +                  +  +     +  +                  +   + +   + + +  + + + +  +  +  +         + + +             +         + + +  + +  +  + +  + +  +  +    +            +    +  +    +  + +    +  +     +  +  +   +  + + +  + + + +              + + + + +               +  +         +     +  + +  "#'       + + + + + +    + + + + + +  + + +  +  +   + + + + + + + +      +   + + + +    + +  +      + G-G/F3H0J/H3L2I1N8N7N5S7U7W3O7U9T8[=T7V?\<]<]7be;YEg@hDc>]@dCdBpCmElKgFvGiFsGqMtRtL{NrKzK{PxRL}TXUV[STY\^[YYZX`\[YRYTYXUN[}ORPvQuS~QvPrNmKnOkJjDiFc@hCfB]Hb<_=^:Y;Y5V9T7T6P6X6N6H3L5O2J.C)?)B(=&:(5(:#7%2$5$/.'%# " '  + +  +  +     +  +     +     +  +   + +  + +  +    +              + +  +  +   +             +    $(('**'" + +   + + +   +   + + +   +      + +        +      + +   +    + +       +   +     +  +   + +        +   +     +  +     +   +  + +  + +      +            +             + +     +     + + +       +    + + +           + +  +  +   +     +  + + +  +  +  + + +               +    +   +        + +         +  + + + + + + +  +  + +  +  !      +    +  +      + +       + +   +  +  + + +  + +    + +  + + + +  + + +   +      ,C-H-O*K,M-S1O.K0G-R-K5Y3T2S1U/R5[6Q6T2V7Y5]:X5^9Z9e9b=d;c?g7bk@mBj@iBqCs?pFvIwCwEtH|KuK{LtKLzPLOYPPRRLOPSRNMNQTWQWM~KONQPvLtJyJDzDqGvDnJm@p@pIj@l>e;g:c>d>`;g4^:Y:X4V4P2Q7S3T1N+R2[/J+G+A(?#9$5!<#4"77$7 3 1($$"#  %     +    + + + +  +             +      + + +  +  +         +   +  + +  +  +            +  #%&)'+*'&   +  +    + + +   + +  +      +  + +  +   +  + + + + +   + +  +    +        +       + +   +  + +        +          +    +  +    +  +      +  +   +   +  + +   +   + + +  +                             + + + +   + +   +      + +     +      +   +       +  + +   +  +  +  +  + +   + + +    +  + +  +  +             + +  + +   +               +   +  +  +    +   + + + + +  + +  + +     $#         + + + +    +  +  +  +  +   +  + +   + +   + +         +  + +  +  +      +   +      E.K,L3L/F3L2M5J4U2P3Q7O5S6U_:_AaA_@c@ea@_@f>c[=S9S:R6U6T0M6H6U=Z5J0A0@+>&9&8$5(:&9#4#84!,,### &   + +   + +     + + +        +           + + +  + +          + + + +   +   +   +        + + +  + +  #&*&(+',   +   +  + + +  +    + + + +   +   + +     +  +  +  +  +   + +   +      +  +  +         +  +  + + +  +       +  +        +     + +  +  + +    +  +   +   + + + +  + +  +  + +  +  +           +    + + +      + +     +  +             +          +      +    +   +          +   + +  + +   + +    + +      +         +  + +  + +      +     +  !!&            + + +   +    +    +  + + + + + +  + +          + +  +          +)F2I+G(G/N4R/L-N2J.K0R0U/P3R0S1W6Z8W3R;T3]3U2b6f:\7\:f7\;g>g@f;i?gq>mAsCkDvErHyDvErHrH~KHKJ~MKROVPQNPRUROPQORROM~NMMzOHOvKJL|H}D{HuIzDzIwEsDlBq?t>iFh8c:a;c5g>\8W8^7[3[/Q0S0M-G+K0Q5M1G*G-@*?&<%<$8 9!7#57$0'($     "   + +  + + +  +  +                 +    +  + + +         +         +            #"),))+)%  +  +     + + +  + +   + + +  +       + + + + + +  + + + +     +     +    +               +             + + +      + +   +     +  +    +    +  + +    +   +     +   + + + +    + +     +   + + +               +   + + +   +    +        +  +   +     +        +  + +  + +  +  + +  +    +    + +     +        + + +   + + +    +  + +  +       + +  +       +    +   +    +  + +  +     +  + + + +   +   ! ("      +      +  +  +  + +         +  + +  +            + + +    +   + +    +G2E0L2I4K2L0O8P8P6K5P4V6R:P8T8V5W;W[;`:_?_<\=bCh@fGiDeFgFjBhCgDrImHpJlKsKkIsMrQzP}RRRtR{UUUW[Z_V_[Z]U\]]XZXYU\SVTX}W~RNXONJ}QuLtMjEzKuKoDpKcFkDd@bB^B]@]>Z:X>_8R7R7R5O4M3M2F0O3M/F-D'=(8)7$=)6&6$8#1!2/*%&       +  +   + +      +     +               + + + + + +        +   + +                 +        ")+)%)&"%  + +   +  + +  + + +  +        +   + +   +    +   +  +  +  + + +       +   +     + + +    + +   +  + + +   +   +   +                 +      +    + +  + +  + + +         +  +         + +   +   +    + + + +   +  + +         +   + + +      +   +  + + +  + +   +   +  + + +    + + + +  +    +  +  + + +     +    +    +      +    +  +    + +       +   + +    " "#       +    + + + +      +  +   +    + + +     +  +    +       + +     -E(J'E/H-K.M0N/O0N1N*O.S4W.W3T5R2Z2U0Z6]6\4Z;V6^:Z9d9]>`rDnCoCpCuIrCoDrBqK}J{JtJ|HIOPLNNQXMUMNOPTNRQQQUNNzLJUOP~LGNHJyFG{MvDrBxHpBtCnAkc8e<]8Y8\5\9S7T7S2H/I0D0D1L-E/C->(=&:"<%=&:&6"52#0 -,('"            + +     +  +                  + +       +   +           !&&((*%+"   +  +     +   +    +      +  +  + +   +    +    + +    +       +   +  + +   +    + +   + + +   +   +      +   +        +  + + +  + +   + +  +  + +         +       +   +    + +       +           +             +       +          +           +     +     +   +  + +  + +  + + + +    +    +    + +     +  + +            + + +  +  +     +         + + + + +       +   +  +  +    +  +  + +    $!      + +  + +   +  +    + +     +   + + +     + +    + +  + +  +     + + + +  + +   +    @2I.M1N4K2N9L4M5I5O7V6O8K2R7X8T9P=W9O@Z>X>\X9g?h:gDcCaAbIdFmHjGoFwJjKqIsKtNvKwN~Q~RyPzS{V{W{\XWQaY\XaYZXTZZYa\YS\WQ_R}SWVzS~U~TP|SPtNvIkKoKuKpEmCkIl@aBdCd>a<]=\;[;Z4S5O5M1N-J1L2K.?.G#=)<(8(;%5)8!9"/$4#2*))$          +  + +  + +      + +   +                +    + +  +        +                  +    '&)+*,'#   + +  + + + + +    +        +    +  +                   + +    +   + +   +    +           + + +   +     +  +  + + +   + + + +                +     +       + + +   + + + +      +         +  +   +        + + +     +     +  + + +  + + +   + +     +  + + +          +    + +    + + +      + + + + +    +   + +   + + + +  + +  +  +      "      +          + + +  +    +   + + + +       + +  +    +   + + +  +      *F)G/H+K-I/F0O1P.L,P-U1Q0T3W1O0Y5U5^4X5Z5[4^6\<_:`9b;^7c=c?fU=ZAY@[>U9Y>ZY=eD\?gEpDeEiHiGgHlJlEnKsL|NoMzLsNxKyPP|UvVQSOYb__W_[X_Za^Z_\Y[RVYRTYWYU~QT}R}S~PtLtO}PtJxMoJoGlDhCfEfC^DfAb;U;^'<$>%9$:$:%5"1-1*&)%          +  +  + +     +  + +  +             +        + + + +        +         "*&)'( !   + +  +  +  +   +    +  + + +  +   +  + +  + + +  +     +              +    +  +   +  + +    + +  +    + +      +  +    +  +   +    +     +  +   +    +   +   +   +           +             + + +  +   +    +         +   +         + +    + +  +      +  +   +  +   +  +    +   +  + +     + +                + +    +        +     +   +      +     +  +  +   +     %%! +         +  + + + +    + +      +         +  +  + +  +  +   + + + G0G7I6H2M3P7J3M3O3M3R9S6O:U7Q9W=T8Y:R;\<^>^@`=_>[=]?]>^@aJjEgChGfAqAlHpIrJsLkEuLuPwJvNvV{OT{U~Y|XTSX|UTaXY``^\Z\X_b^\]XVYQzXTWU|W|O~URP{J{PyKwIwMqOmGmHfFnGe=e@bB^=Z=V>b;U:R^<[=Y?^;[@_DbDg:gBiAjGlBiJoHhHnInGjKoGxOxLtQsJuQ|WxT}RXT`WWxWY[[VaY^\`]XaZZ_[ZXZ~UU]~PSWY|R~QxJ~RuRwOyPqIqFlHnNlHeFeEeF^Fa:X9[@V:Z9V6O6T3M1M1J0>3G,?)C+>'<$<(:);(5$0&5"4.- ($   +          + + + +   + +  + + + + +   +        +           + + + +                  +  +   + +  + +  + $%'$%  +     +   +  + + + + + +     + +  +  +  +    +  + + +  + +  +  + +    +          + +  + +    + +  + +  +  + +        +  +     +   +    +  + +  + +  + +  + +  + +   +  +     +       +      +    +   +   +    +    +        +  + +            +     + + + +  + +  + +    + + + + + + + +        +  +    + +       +  +       + + + +   + + +  + +  + + + + +  + +  +  + + + +  !!#   +          +  +      + + +  + +    +        +  +     +   + + +  +  +  + + +    + .I+I/K,F3H,F1N/I,O1T1R0O4O1Q/[0X5Z7T5Y4^8Y:]6_7a9_7g9_9e9e9g=j9j?hg;l=e;c=_6\:Y;Y9Q1N3J.H-H(H-@)>)C(;)@(9#9$; 5 4$/ 2!.1(#     +      +  + + +     +      +               +    +   + + +                      ##+'&!   + +  +  +  +  +   +  +       +  +  +  + +      + + +    + + +   +       +    +  +  + + + + +  +  +  +    +    +    +        +   + +         +      + +  + + +  + +    +     +                  + +            + + +  +     +   + +  + +       +       +   + +  +   + +    +  +  +   +  + + +  + +  +  +   +  + +  + + +    +   +     + +          + + + + + + +    + + +    + +  +    +    + +    +   +   !               +    + + +  +           +    +    +    + +  + +   + +  +      H.I2R1M0L/K3Q1K8M4S9Q5S8O5S9P;T=[8U=]=]?]<[V*C+@)?%9)9'7&:$6"2/#-- %("   + +        + + +  +  + + +    +   +        + + +          +   + +  +                            + +      + "'#%    + +    + +           + + +            +     +    + +        +  + + + + +  +  +  + +    +         +    + +        + + + +  +  + + + + +     +  +    +  +     +               +  + + +   +   +             +        +  +  +  + +     +      + + +  + +  + +  + +  + + + +                  + +    + + + + + +  +  + +  + +     +   "    +        + + + + + + +     + + + +   +   + + +      + + +  + +           +   +E)A*J2F)J.L.L/N/Q0P1P5O1P1X/U3V4U7Z2W5Z:V8Y9d7_8_:^8^e>gBfAo?lDrDrBuCyJoFuJvEtKG}LzMKKQQNQOTPRMSSWSYNVXTWTRRRONNK|K~QGzJ{NyHwLJN~I}DqBlAmBmAg?f;i;]+H-D-G*C'C%A&;#;$8&="7"4.-", ))&!            +  +        + + +        + +  + + + +        + + +                       #"#" +   + +     +  +   +     +           + +        +   +           +     + + +  +    + +      +    +    +  +       + +    +  +         + + +   +        +         + +  + + +          + +  + + + + + +   + + + + +            +                  +  + +    + +    + +  +  + +  +   +   +   +   +   +  + +             +   +    + + +    +  + +     + + + +    +     #           +   +  + +   + +  + + + + +   + +   +          +  +  +  +   +    +   +D/?4G.O2K2P2R7O8M5P7M4Q7R7T=O8Tg>g@_BY=Y9W=W8Q7M4H0L0E-G.F/D'?+>(<(9&7'9#5$3!0 -"***&&     +         + + +  + +   + + +  +          + +     +  + + +  +  + +           + + +  + +      +              +         +      "!    + +   + +       +    + +    + + +            +       +     +         +  +  +     +   +     +  +    +       +             +  + +      + +    + + +    +              +           + +  +  + + + + +                              +  +   + + +  +   + +    + +  + + + +   +   +   +            +         +  +  + +     +                +      +   +  +    + +      +      +   +    + +  +   + +     +   +*F*H-N*N0K.O+L1N/N0M2Q4R.M-Q2U5T5Z5X5X8^5Z5Y;\7a8c?^6g<`@`iAi>lHi@oFmFlBnArGwCvLpEsFyGzH}GyJzGPSNSOSRUTQ[VSQOTRPQVWQSPRQ~L~MNK|JP{I}GvFzGwF|BKyEzB}FuAoBe?cAa:c:Z8Z;W2S5W1M1N2M+G-D)?&A*>)>%C$9%:%?%9 655!./*+"!!     + +          + +  +         +     + + +   +  + +  + + +          + +                       +          +  + +  + + +    +  + +      +     + +     + +     +     + +   +  +      + +  + +  +  +     + +   +   + +    + + +   + + +      +      +   +       + + + +  + + + +  +   +           +           +  +  + +  +     +   +                     +     + +   +    + +    +  +   + + +  +    + +   +    + +  + +  +  + +    +              + +       +  +  + +           +      !            +      + +  +  +  + + + +      +     +  + +   + +  +     +  +   +J0G.G1J5K/P6L5O6N5N3K4N;O9T4W8WZ9X:];W:\:\>d=f>dBfC]BgFeB_DeBjAgBqJjJoKoNsPpNsRsOvQuTtYsTTxPX~[XWY]W^Z\]\\b]ddYYYV\_UVYVZXTuQMR}NqKVwS~KrPNwPqMvPsLjFgDaCa>_A^?Z6X5U8S4M1K3K.J3E0F-B(>,;)8)8%:%7$4!2 6"..,'%!    +          + + +    +    +        + + + + +   +     +             +               +  +                 + + +  +    + +    + +   + +      +       +   +     +   +  +    + +                +   +  +     + +     +     +     +         +    + +  + + + + + + +    + + + + + +   +   +                    + +  +  +       +    +    +    + + +   +        +    +  +  +   +   + +     + + + + +     +  + +   +  +   + +  +  +   + + +  +          +   + +            !   +        +     + + +   + +     +  + + + + +   +  + + + +      + + + -H.I0M.J,J1J.H-N0R1P/S7S5L2M3Z/S5V6U;_6X:V9a:b8bF^>^;^6d;`9aY@`F`@hAfG_?bBgEoEgIlDgKlJmDlHoKnNvOsKtRzTSuNyR}NU{TXVWd[X]f`^_YZX[\d`c[]WV[XzZVRTU~QzSvTyMoOyM{HtNtPuOrOnGmJjCmIcEdB^;^?Z@]7V;P3S3I4E2K1D-G,>,?)<&>);&;%8$8%. 3#1.*&*#              +  +   +     +   +   +  +        + + + +  +             +    +                         +  +  +     + +  + +  +     + +    +   +        +   + + + + + +     + + + +   + + +             +    +   + + + + +  +   +    +  + + +          +       +    + +   + +  +  + + + + +  + + +        +    + +          +   +      +             +        +  + +    +   +       + +  + +   +  +   + +  +   +   + + +      +              + + +         +    + +   + + +    +     + + +      + + + +     +   + + 1G&D'K&M1M*O,K,M-Q1L2K5T3R5S3U2X1Xc;d@iAj=i=fAn?mBqDqDrFnBrC{NvI{IEyK~HwRINRLPSVTURQTVPTTVURVOTRRP~PURLOMOMJtH~FzLtLtCsGyCmDiAm=i?jAk>a=]>\;^;[7[1R1S.K-J*E,L+F(C'E':&>(6#7'4!9'1!6/,1(%#           + + + + + + + + +     + +  +   +  +    + +    + +       +  + +                      +    + +  + +      + + + + +  +  +  + +    +  + +  + + +  + +    +  + +   +  + +   +    +      +               + +   +  +  +    + + +  +  +    +       + +   + + +  +    +  +  +  + +  + +  +                     +       +  + + +     +    +     + + +       +    + + + +    +  + + + + +   +   +  + +   +    + +   + + +   + +           +               %    + +               +     +   +     + +  +       +     + + + + +  + +  +  + +      + A2M-J2I2J3L7N4E4Q6K6S4I8L2N:R9Y=V>T>V=W?^<]AU?]BZCdBgB_EdFdCjFfFhFiImGnLkItHjHpKvPxMxMuRQ|O|W~VY}_R]]U^\\_ba`\`[]^\^XZVZWX[UVS~TSQxQ|VtO|OyMpLtLoGoFhGlJjIkEe>aC]@g=Z=X>X8P5P4G2D+H0B2G,;,<.=);%=(:%4$< 9#3"14+*%#     +      +   +       +  + + +  +  + +     +  +               + +  + +    + +     + + +    +   +          +   +        + + +  +    +      + + +  + +         +    +  +  +       +     +   +  +    +   +   +  +   +     +   + +     +  + +  + + +   +   + + + + + +  +               +   +   + +    +  +          +          +  +   + + + + +  +    +  + +    + + + + +  +  +  +  +  +  +  + +    +  +      + + + +      +  +    +  +    + +  +     + + + +   + +  +   + + +  +   +-G.M-L.I1N-Q*O-S0N3T*T1R2S9Q2Q6Y0W7U4[7W7[8W6Z8`;\6^<_6lh:l9l@hAlApBuArBqApEvBsDC{IwMzJ~P}QKKKRNNQRQUQVPVSYZQRTRRURQVXMOJM|LQ|PzMxHxIrG|FpDw>j>rCnBjAb@n?d:a@a9c5W9Y;\7_8W.P.K,B.E+F*@'<$>":#;$9#4%51/4*/&(   +  + +      + +  + +         +  +      + + +            +  +                          +   +             +     + + + + +  +  +    + + +  +    +  +    + +       +   + + +    + +  +    + +        +      + +  + +                          +    + +  +   + + +          +  +     +   + +    +          +    +       +        +    +       + +     +  +  + + +   +   +  +           + + +    + +  + +  +      +   + +    + +         !    +       +      + +       + +        +   + +   + +  +            L4D0J1P5G3I4I1R4O5Q4S2Q7Q8T,:+B(7*9)7$7%5"5 33) ()%  + + +        +        + + + +  + +  + + +   +   +    +       + +  +              + + +      +    +    +   + +    "  + +  +  +   + +   + +  +    + +  +  +   + + +     +     +    +          + +   + + + +      +       +       +       +         + +   +  +    +  +      +       +        +   +          +               + +      +  +    +  +  + + +   + +    +   +   + +     +       + + +        + +   +  +     +      +  +     + +   + + +  +    +    +            +  + +,J-L+O-E/I1P.K.N2P0S0R0T0V.R7V4[6W2V6[3Y7Y8Y6f8X=^\c=c=n?eDiAsFvEqAqFrI{G~HtEyF}MGPJKKJNTPTTURSWRPUQSTQNM~RM|VOM|NNzP}K~P}N|MK{GyHsGyHsHlBkAr?gDf;h=d)<"<#9#6&6#6"2 0/),)%           +    +          +   + + + +  +     + +           +   + +                    + +     + + +  #"           +   +  +   +   +  +  +    +  + +        +    +   +         + +   +  +         +      +   + +      +  + + +   +  + + + +  +     + +  +  + + + + + +                           + +   + + + +  + +    +   +   +        +      +   +  + +  +   +   +  +  + + + + +   +   + + +       +        +  +    +  +   +            +             + +       +  + + +    +     + + +   + + +    +   + + +  D3F3G3K4J/N3H2P9S4P:I:T7O;U9Y5Y;T8XAX>Z>T=YAXBc=bCa>eDaFlAmIeFiIlCjIqFqKkNdKtJrLtO{R{KzRR|UTTQZVYZW]^a\a^Ud^bc][Z^QZ[ZYZW|SyTQRzOL~TvS|QyLvStHuMoKsNoHgIgGbBb;a<`BZ;Y6X9Z9X8]?[=c?c>V5H0E,C*:(:'7$5"5#1$/ 4 -0+&!          + + + + + +  + +      +  +  + +  + + + +        +             +   +  +  + +      + +  + + +  + +       +    + +      + + +  +    """!    +   +   +  + + +    +  +   + + +   +    +  + +    +      +     + +      +  +            + +     +    + +            +   +  +  + + + +  +                     +       +       + +            +    +           + + +   +  + + +  +     +  + +   +    + +   + +        + +          + +   + +    +      + +    + + + +   +   + +             +    +  + + + .K1L'L/O,L0J/O-R/S/R,O3S2R2V6R0W6Z3X5T:\oIpDqBoJuF}FtEtIzAuNJzJyK}OPPOUPURSVWUUROQMQTQRUZLUQRQ~KNROLG|CwGyGyExJqCrDoClEiDj@dT5SZ?aAh>c@bBdCeAeGhE_LkLxLnLnHpFsNuLzMvM{RoSvT{XzQSX]~YX[Y\^^]][]W[Y_^UZ[WcWWY~Y[SYV{V}OtTOwKxUsOuMqDtFsJhEiHnAbFgEcBh@aB^>V>R8P8M6T4N2R5V8Y;a;^4J*E'@+;&4%4!5'0 .* *++)    +          + +    +  +       + + + + +   +        +  + +  +        + + +  +  + + +        + +  + +      + +   +  + +    + +   + + +  !! ##$#  + +  + + +     + +    +  +   + + +    +  +  +   +         +   +  + +   +  +   +         + + + +  +         +  +  +  +          +           +    +        + + +       +    +   +    +   +   +  +   +  +   +   +  + + + + +  +   +   + + + +      +  + + + +   +      + + + + +           +   +  +  + +            + +    + + + +         +  +  +    +    +  +   +  +0G*N*I/E/R2M3O-L4P2Q0T5X3N2V5X6Y2W2[7\4Y7[5d9^>_;k8d:a6g?gV;[9X=^=];^a?c@_?aFiCdFmFiGoDkKmBmGpKyJqIwIuJtN{QxOS~Q}YW}W^ZWYd^c\e_]_dd^bZX]\[XYY\WZxVVSRT|O}X|SyOzQtKuKmEsJnJkFj@gHbBiA_A`@_>[;X4T4S4L0K.O3M2I4O/O1H-C(=(>$6"4#.#4#1,*.$&              +    +        + + + + +  +   +      +  +  + + + + + + +           +  + +  +  +      +     +   +   +   + +   +  + +   +   "&'# +  +      +      +   +    +  +  +    +     +     +      +  +  +       +  +    +    +    +       + + + +  + +  +    + + + + +  +   +   +                 + +   +    + + + +  + +         +       +             + +    + +  +  + +   +   + +  + +  +    +    +           + +                   + + + +  +  + + +   +        +  +    + +   +      +   +  + + + +  +       + +  + )C+H)H-P0O1N0P-O2P0Q1T1W1R3Q3W7Y/X4U7[4T6_7d9b6a;a?`=`nClBmCmJqEuJzL{GxFxKyOMPI}PKMMPOTSYPQUPWNO\RQSVQTONUPQzRJ{N~I|LyH|LzC}IuBqEpAtBkFpCg@fe:_=Z6X5U9O1Q1L,K*L.H-G0J*I*D,F'='9!7!7 11-, ..)'!      + +            + +  + + +   + +     +     +         + + +  + +  + + + + +         +   +               +   + + + + +     +  + +     $%'#  +  +      + +  +  +     +     + + + +    +       +         +   + + +   + + +  +  + +    +             +    +       +    +    +        +    +   + +                       +   + + +  +     +     +  + +   +             + + +   + +    + + +   +  +  +  + + +      + +  +    + +    +    +    + +      +  +  +   + +   +                    + + +     +  + + +      +  +     +      + +  + +    +  +        +  + +  +   +     +  +    G4H1G2O7M4K4N4L2O3L4N;X7X3T8U9X=U;_;_<]=`@\Bd;eBiA^D^CcCgDfFkGgEhJqGlEmKrOrNoJpPnVuOxTsR}T~S|TTU]___Z[\]`````X]`Z]Y[_Y_\`V\|UUSQ~T|VzO{U}QxL|LnLtIqInJlDgFeFe?gB]?Z6\8W:W5Q5L9O2M/H2L5L+F,D+@(@-=&9):$2!1!2#- ++!/%&        +         + + +              + +  + +   +    + +   +   + +  +   +             + +              +    +   +   + +   +    + + +   +  ""!!  +      +   +           +   +      + +   +   + + + +  + + +  +     + +   +       +    + +          +  +   + +      +   + +   + +    + +             +      +           +           +     +       +    +    +   +   + +   +    +  +  + + +      + +   +    + +   +     + + + + +    +                      +  + + +  + + +    +          +      +   + +    +     +  +  +  +  +  +  + + +    + +     +  *F-H.J*M/L.Q.O,S-M3S1T4Y3V1R4S6X2V4Y4\:[;Z4f9b;_6a8e^6g;j?`gAe@f?_9[:]:Z=U4R5N3O2N/G)G.E-E/G+C(A%=%;$:$:"453/-))'!!     +  +        + +  +  + + + + + +  +  + + + + + + +  + + +       +   + + +  +  +    + +       +    +          + +    +  + +     +  +  + +  %!'$#!  + + + + + +  + + +   +   +   + +  +   +  +       +   +  +   +  + + + +      + + +  + +   +       + +     + +                +  + + + + +  +    +    +  +       +                   + +    +  + + +    +  + + + + +     +  +  + + +     +  + +     +     +      + +  +   +     +     +  +      +   + + + +  +        +  +  +  +  +          +     +           +  +  +  +  + + +   +  + + +  + +    + +   + +  + +  + +    + +   + +     +    +   +  +    +  +        +  + N4J2H4O6H6P4J3Q5N8U9W6N7M:Y7W6X9TAYX9W7N8R1N2O2K2I0I,C0C*7+@);%9%4"4"52!,.,.' %    +         + + + +    + + + + +   +   +  + +  + + +      +   +    +    + + + +         +  +  +  +             + +    + +    +  + + + + +  + + +      %#(%&  + +   + +            +  +           +   + + +     +        + +   +   +  +  +  +   +  +  +  +  +     +  +  +   +     +    +   + +    + + + +           +    +    + +       +    +  + + + + +    +       +  +  +  +                 +   + + + + +  + +  +  + +     + +    +  + + + +        + + +  + +  +      +      +               +      + +   + + +  +  + +  + +   +        + +   + +   +   +    +       + +  +   +   +    +      + + + + -H+K-N,T,J*O0N3S2I0X4R0Q4U2T3Y8S6V0Y4X5[5]:[8^9^n@pCnFrCxGlDwEtD|JxL|NzL|JNMLTOURRRTUTTXUXTUXQVSQQTUPNOQRMN|FHzG{JBuJxJqBoGk=o;j@iC^AeC`9]>_9c6VR=R;Z9\>]<\=XAS:Z>b>b>a@eFcCbD]HiGjFjRoLiKrFqKvInHtMuMvMsU~PtVuRSYYYWZV]\Zabaac`bYZb^\[X\Z__Z_USVZU~SUQ|TxRvNvTqTsLtFnArIgChCbB^A`?Z>X8X;W7R4K4J3H/J2H.C/J/E->*>+B&5'8$9#2 1#.!)-(* ,-)   +            +   + +  +  + +   + + + + + +  +      +  +   +   +  + + +       +    +            +              + + + +  + + + +  +  + +  +     !$'&(" + +   + +    +         +      +       +  +   +   +  + +  +   +         +   +     +   +   +   +   + +  + +    +   +  + +    +    + +  +         +      + + + + +   +   +  +    +   +     +   +              + + + + +   + +      + +  + + +    + + + +    + + +   +     +   +    +  +  +   + +  +  + +  + + +  + + + +           + +  +  +   + + +  + + + +  +        + +   +  +  +  +   +   + +      +      +  +  +    +  +    + + +   + +  + +/J/I+K-N.I.M/R-K1O.P4M2\2T2S3V2]6X6W:Z8_7a7`5]8`h@o?qCpAnAsFsAwCrAxJuJtJ|H{MuPxF~L~INPRPROSWVU[S]RYUWTWPUSXSUONKNP~NLrAMtL}KxG~EuCtDqElDh@fAk?c?\:Y:];Y8V;S4Q5P/J.K1J-K(C,H+F,A%<%:$1$8#6"42,))('*+)%   + + + +   +   +   +   + + +            +  +  +  +   +   + +   + + + +   +          + +           +        + +    +  +  +   + +     +   +   + + + + + "$(!"!   + +      +            +      + +        + + +  + +    + + +  +  +   +   + +   +    +   +               +    +  +    + +   +   +   + + +   +  + + + +          +        +     + +  +   + + + +    +   +  + + +      + +   +           + +  +  + + +   +   +  +   +    + + +     + +    +    +     + +  +     +  +   +    + +   +       + + + + +  +      +  +   +  + +     +        +     + +  +  + + +  +      +  + +        + + +     +  +   +          F.F0F4L2I5J8T3L3L5P7P6R;U:V6T;V:Y9Y7[:^B^D_<[;b@`FdAgFd@kEpBhJkFkBoClEpGnKqRoMqOqLwQwPxT}P~SZUYVZ]^\b\b_Zd^\a]ba]^[Z\]_`_RYVVQ~P|PQ|SStNtNtMnKoFrJkEcCkGb@a@c@\qBoEkCkFsCwH{I|MwF|ItONyNJORSQOWUYTVURXVUKVT\RQTVONSNLLLLJI|JyI~IxKuEoCqDtDmHn@d=_?d>`=\:_9[8Y4U5S.U3J.K/F*K+E.A)F(@*<%8%; 7 8!-2,&,((&&'#     +    +        + + + +   +  + + +    +    + + +          + + + +  +               + + + +    +    +     + + +  +       +   +  +   +  +  + + +  !#"!    + +  +         + + +      +      +    +           + +  +  +              +   +  +    + +   +  +   +  + + +   +   + + +        +            +         +         +   +       + +   + +   +             + + +    +          + + +  + +             +    +      + + + +  +         +    +  + +   +  + +  +  + + + +    + +   +     + + +    +   +    +  + +    +      +  + +  +  +  +   + +       +     +  +  + + + +     + + +    + +    I.I1O5E4L3M,I1P6R5L8P;P:S=W8^7X:Z8T6Z>[D`A[G_B\B]AdHfCf@jAkEkAhIlJiHnErPpIuL~JpMvTyQQ|QzR~V~UWwX^[a]bXadeb`a`da`^[^]]YV^^ZZQZWY}S}RUxTyK~LxOnKtLmEnEgDdEgBhAcA^>[?X6X^>^>_@b9dBeEbD^BlDiCgEgJkEmEfHmLtLrNxNtKyLqV{L|S}SO|UW~XUU\^X[\^]aZfg`_f__]c\`bU\_^ZWZUTWVwWNxPxNtKuJsOpJsNnHjBlCmD\Dd<[@Y8]6W9X7M4P5G+G-G.G,F,E-C(:$;(:"6"92 6!,,'+&#$!#!!!     +     +    +       +     + +  + +  +  + +        + + + +      + + +    + + +    +     +  +            + + +  +  +     +  + + +  +  + +  + + + +   + +  +   +        $#     + +  +      +            +        +  +   + +    +  +   + +   +       +  +   +    +  +  +    + +  +    +   + +                          +     +   +  +    + +        +     +        +     +     + + + + +  +   +   + +  + + +   + + + +  +  +  +  +       +    +  +   +  +   +  +  + +    +   +  +       +   +  +   + + + +  + +  + +  +  +   +  + +  +  + +  + +  + + + +  +   +     +       + +  + +     + +  + +  + +   +  + + +  + +O.J(M-N+L0K0O/R/U2L2R1U/U6\1Y2T9Y9V8\6_7]9`6]=a9\>g;e9`l@cCpChAmBqClDxHvEvEuHz?|I|KM|RLPMNOUNMSTWSVTXYT[UVVNWVMWROSQOTJQ{JzKLI{TDtKtDwAnCsAi@f>gBeBg7bZ>Z8`<]B[@_=^@fC[?_EhCcAiBmEeFeDnHoFnOyNpIwLsLlTvOxTvRuX~XyVUP\X^W]]^ab`Xd\d`_c]b\\][aZZ_QXVZY}UWP{TM~UxKpJmLsIkIlJhDgChC^?b?c>Z9X?V;Y7P8Q2H2J2H0D,D-@)A)7(?'9%5)0$31!-, (*#$("      + +   + + + + +   +    + + + +   +            + +  + +  + + + +   +  +   + +   +   +  + + +      + +      + + + + +         +    +  + + + +   +    + + +   +  + +     +   +  ""&$#" +   + +  +  +    +  +   + + +      +  + +       +  + + + +  +    +    +  +       + + +   +      +    +      +  +   +                +   +   +   +     +   +  +        +    +        + + +   + +    + + +   + +  +     + +    +  +  +            +   + + +    +   +    +  + + + + +  +   +  +            + + + +  +   +   +   +  +  +        + + + + + +  +   +  + +    +  + +   +/K,K/I.S/M+N/Q2J.O3P2O8W1Q2Z6V7\4\6\5^6a7c9^9\;`=_:c9af9mBkBn@j>oFtDsEtEtDzJwH{HwCxHOE}M}NLIPRJTVRSOTUUVSRVUVXWWPPRWSSTNNSSIyJ{KJxFvHsGrErBlAnCj=j>a>f@a8`8c:V6V9P1U3N.N/K0I+C*?)A'9&=";#:$9 3"5-0(*)'"#                 + +  + +  +   + +    +   +        +  +   +    +   + + + +   +   +     +  +     +          + + +      + +     + +       +   + +   + +  + + + +  + +     !")&#" + +   +       + +    +  +  + +     + +             + +   +           + + +      +   +    +  +  + +  + +     +   +      + +   +   +                  +   +         +     +  +          + +                 +      + +   +   +  + + + +  +      + +    +  +   +  +  + +   +  +         +  +  +  +     + +    +   +   +  + + +    +  + +  +  +  + +  + +            +      + + +   +  +  +     +    +  +      + + + +       + + +  + + +  + + +  F2F5N6P9R6P7H4P:R6O5U5T4Yb=Y=Z@a=a=`E\BeEf@cDeEdBhHbIkCpLpInLpNuHtLoNzLvQxV|SzRW}V[Ra[Z^\\_cbb``cc`^[^_b[]^YYXYX]W\{SUOPQ~QxNzKlHoLgDjIpHgJfAc?_>b?\>\9Y:S:S6O0P4L-G-D,D*@*<)@&;#;(8%2#23/,)&%$       +   +      +  + + +     + + + +    + +   +     +   +  +   +  + +  + +      + +     +   +  +    +     +     + +      +    +  +         +  +        + +  +   +  +  + +   + + + +   +    #"($& " + + + + +       + +     +  +   + +   +   + +  +  + + +  +       +           + + +  +    + +  + +  + +  +  +  + +                + + + + + +   +       +  + +  +       +  +               +    +    +   +    +  +   +  + + + +  + +      + +       +  +  + + + +  +  +           +    +  + + +   + +  +     +     +   +    + +   +          +       +  +  + +  +     + +   + *J/G.L0J0M-P.G1M0Q5T2N1S2W2Y4R5Z7Z7Y7Z;[8^:]6el?nEmCvBoCqIpHxFtK}F{JINOyQ~OPMRUVPWW\SWPPXTM^XZTTVSURNQQNM}NMNIPzIK|HqCmJm?oCiBgBgCgAo=`>[:e5Z2]6W2U0Q1K1J1I1D.E)E(='>#:'9$6"1 02), ()*#!   + +   + +  +  +    +  + +   + + +     +   + +           + + +   +     + + + +   +   +     + +  +      +  + + +  +  +      + + + + +  +         + +  +     + +  +  +  +      +   + + +  +   "$& '%"!     +  + + +           +  +     + +   + +     +   + +     +     +  +         +  +   + +   + + + +      + + + +  +  +      +               + +  +    +   + +  + + + +   +     +  + +   +   +  +  +      + + +   +  +  + +   + +   +   + + +   + +     +                +     +   +  +  + + +  + +     +        +  + + +  +       +   +  + +   +   + + +  +         +              +   + + +  + +  +      +      +  + +  + G4N/H2I2M3L7M4Q[=U;S6S7U5N2I1G0H.H,@,B(6(>&6&:$8!/&1-*.&'!!    + + + + + +      + +  +  +   + +  +  +           +  + + +       +  +      + + +  +   + + +   + +    +     + + + +      +  +  + + + +  + +     +    +  +       + +  +  + +    +     + +  +   $$'#')$ +  +  + + + +  +  +     +                   +   +    +     + +  + +   +    + + +  + +  +     + +      +                    +   + +        +  +      +         +   +   +      + + + +  +    +  + + + + +  + +  +   +  +        + +  +  +  + +    +    +    + +  +  +   + + +   + + +        +         +   +    + + +    +        +       +    +  + +   + +    +.N0K.G+N.L.O1P2S/T2Q/V2R8U5P4W4V4Y7Z4^;[;X7b;c7_:f8d=i8h=g=l@lBiBiArDsBtFqCsExDyMwFuJyJJxLIONNMWMQYUQWWSYXSSXWP[]ZXV[XQVLMPQI}OJwLyLyNzGyKxFpEnDlFfFoBm?h>c:];\4V7W7X5Q5S4P+L-I,I+D*C(:'7(8#8%9#7"00/ *0(%$!     + + + + +  + 2+  + + + +  +   + + +   +           +  +  + +  + +  +    +  + +  +  +  + +  + +      +  + +        +  +  +   +   + +  +  +    +         +  + + + + + +  +   +  + +  + +   + +   +  + + + +   !$"*'!#   +   +  +  + +   +          +     +  + + + +      + +       + +        +  + + + + +  + + +   + + + +     +      + +   +                     + + + +   +    +  + + + +    +      + +     +    +    +    +     + + +   +  + +  +    +  +  +        +  +             +       +     +   +   +  +  +     +   + + +  + + +      + + +  + +  + +           + + +  +  +       +  +  +    + +   +     +   +   + +  + +   + +  +       + +    + I2O0N7N5M-O5Q;N8R8P?S9U6Z\<_DaB`?_BcHfF]BeDiEgEbLhHhGsLqKtOmOuK{MvLzPxPwN|QxV~[RXYYY\a^[a_ab^^cd_`c]fhZ[[dXVZW]V|WWOT}V|QvNxMQpIoGpHjHoGaBc?c@a=d?[9V

S:S5Q1I2F5N1E1>+B,A)9+;&3$6&2"32!2-*%%"!      +  +   + + +  &1)  + +    +    +  + + +     +      + + + +      +          +  +  +  +   + +  + +      +              +    +   +    +      + + +   +    +  + + +   + + + + +  + + +    + + + +  !"$"""!  +  + +   +    +       + +   + +                +       +        + +     +      + + + +   +   + +   + +  +  +                      +  +          + +   +     + + +     +   +      +     + +  +    +    + +   + + + +   + +   + +    + +         +  +  +     +   +           +  +  + + +             + +  + +     +     +     +   +  + + +        + +  +        + +     +  + +  +   +  + +  +    +    +   +   0M-N-O-J/J-T1R0J5P2W2V3W6R2S4[5[5[:]6[9b8a:c;b;^:cBe=f?i7j?jCe@iDnBwBlCsFxDp@uHrJDuLKNNMWOKUROPTVTWWYURT]WRTQS]RRWTOMPQQ~PNOK}O|NzL{JyIuLrDtAjCmEj]9Z9[<[=\@^=`?fAgBgGcFkEdKeFlIiJlJvIpKuKoOpOqQuSsN{P~QTWUR^XU^Z_]c_]eg`daiab_da]\`]bb\]WZRRzSZTU~MyT{Q|KwLtIvHlImHeIfDcDa?dB^@YBW8S5N7O6L7I4E3H)B*C+>);-;';%:$9!00*-*&"!      +    +  + + + +  #)+"  + +    +  +         + + +  +  +  +     +   +  + + +   +  +      +      + +  +    + + + +      +              + +  + + + + + +     + +   +  + + +     +      +    +  + +   +    "&%'  + +      + + +        +    +    +    + +    +     +    + +   +    + + +  + +      +    +   + + + + +          +  + +  + +   +   +         + + +   +  + + + +  + + +    +  + +  +            +  +  + +    + + + +    + + +   + +    +    + +   + + +      + +    +  +       + +  +  + +    +        + + + + + + + +  +       +   +  +  + +  +        +    +  + +      +    +        +   + +   +  +   +   + /D0P0S,K*N/V1L-L5Q1O1T0Y2T3Z7W7`6\:]9\9[:[;c=b8_=f:b;aGe>fGlAo?jDrHpBm@pBuCxHuBwBwLML~NQSJNPOTRQ\UWVXXWV\YYW[_]TLWPSNSLRPQLRL{SvHxLtJsFwGoCvCo?nBmGk@f9a8b=c5U2\4W4O5S0M1N1L/C.C,D)>)8&<'8#;$5"1 1,))$!"         +   + +   + +  + +  + ')    + +     +  + +  + +           +  +    + + +  + +      +  +     + +  + + + + +      +  +   +  +   +            +      +      +  +       +  + +         +   + + +   +  + + +    !$&$$    + +  +  +            +     +   +    +  +  +  +     + +   +        + + +   + + +   + + + +  +    +  +     +               + +           +     +     + +      + +        +     +      +  +    +   +    +  +  +  + + +  +  +     +      + +   + + +  + +  +  +   +        +    + +    +   +     +      +         + + +    +  + + +   + +  +         +       +      +   + + + + +       +   +   +    + +          + +   + + H1N7J2Q1O4M9K2R9T=O6P6W9U^<^A`H`B_CbD\HmKnIjClIpBkHlKlJrIpLqQsLsLyTzQXTTTWSV[`Y][Z]cdbgbgbbcc[^]gaaa`V[[X`WRYQ}Q{UORwQzPpIuMqKmMlKqHdHfHeCaA^9\8V7T:T6T7P9H2H+E,G,A+A'?(:'=%4%7$7,++'&#        +  +    +   (& +      + + + + +   +     +  +   + +  +             + + + + +  +  +  +   +       + +  +     +                   +   +   +    + +   +   +    +  +   +  +   +   +  + + +   + + + + +  + +    "###$ +   +        +    + +  + +    +  +    + +   +          +  +  +   +  + +   + + + +  +   + + +    +            +    +  +  +  +    +    +    +      +            +    + +   +  +    +  +     +       + + +  + +    + +     + + +  +  +  +  +     + + +       + +    + + + +         +   + +  +      +       +     +   + +  +     +    +  +     + + + + +   + + +  +    + +  + +  +  +   +    + 0C1I*Q.G2O2Q2P2P0T2S2V5W1W5Z5Y5W3Z8U7_<[6\7]9d9f7d=c:f:g:f>q?fAjDmCsBqDqDqEsHxGzHrHMuKJ{NP}PN[MQXUQ\UXZa\X[ZYTSTWYTUP[TTSPMOQMMMyI}H~AqIwMuHrAmFlDg;j9g;b;e@b;c5Z8U5R4T1S1N.J/A/J,C(?'@#<%8 9#5#."2(+-%$"!      + + +    + +  + +  +      + +  +  +   +         + +    +  +  + + +   +   + +  +   + + +  +     +   + + +  +     +  +                      +  +          + + +  +      +    +  + + + + +   +  + + +  +  !'#%!       +      +    +     +    +  + +            +         + + + +  + + + +     +   +  + + + + +  +                                      +         +  +    + +        +       +       +     + + +       + + +   +    +     +        +           + + + +        + +  +      +  +   + +  +     +   +     + + + + + +      +   +  + + +    +        + + + +      +      + +             + + + +  +   + +   + +  + + +K3J1H5O6R8N7Q8V6T>Q[;]Zj=g@eCl?q=oAoAsBsByFrG{IvLyHwHxL{F{JDLSMMMTUVMZ[YUWTUWUTXRRYYTZZTQSVRQUPORG~MzK}LvH{O{EnGrDkEmClBjAh?e>`?]9[:V9Y6T4Q4P2N3K,N-H*F(?'<&;!7"7%3 1 /1)+)$"   +  +   +    +  + + +   + + + +  +    +   +  + + +   + + +    +   +    + +   +      +    +  + +       + + +     + +   +                      +    +  + + +          +            +  +  + +       +   +!#&"$!  +         + +        + +   +  + + +   +  +          +      +     + +  + + +    + + + +   +  +  +   +   +     +              +        +    +   + +     + + +         +     +  + + + + +   +   + + +     + +  + +  +     +  +     + +     +    +       +              + +         + +    + + + % +   +     + +  +   + + +    +           + +  +             + +      +  +            + +  +    +  + + + +  +  +     + + Q5M4P2N6J8Y7N:P8S6U5S:\@W=V=[=X(<&5+>#5'//!3 / +)$#      + + +  +  + +  + +   +  +  + + +  + + + +  +  + + +      + +   + +      + +  +       +  +    +   +  +  +  +   +          +  +   + +       +   +        +   +   + +      + +  +  +  + + +    +  +      + + +   +  + +   + +  "$"  +          +  +    +  +  +  +           +  +  +   +    +   + +  +  +   + +    + +  +                 +    + + +  +   + +  + +    +   +  +        +  +    +   +   +  + +   + +  +  +     + +    + + +       + + + + + +  + + + + + +       + + + +  +   + +   !  +    + +       +    + + +            + + +  +   +   +         + +  +        +  +  +  + + +  + + + + + +   + +   +   + + ,I,P2J0O.S1S0N2V1X/N3Z1T5T5Q6Z3S4Y7\4Z8g8`3a<\d?v?rAuDoFpIqFyLzLsKyKzDI}O~NLSOSQSUYTXZXW]XX^YXTXW[SUYTUQYVNRUROQQNJ|GxL}EqJrNqFoCjCe=b>b=d4[<\>^;[3Z4U0N0N2I*J*E*E(A*;%9&7&2#51",0+))'#    + +  + + + + + + +  + +  + +       + + + + + + + +   +    +     +   + +  + +   + +            + + + +  +  +   +      + +  +  +   + +  +      +  + +       +           + +   + +  +     +  +  +     +  + +   +   +     +  +    +  +   "!#%!  + +     + +   +          + +  +   +      +          + + +  + + + + +  + +  + + +  + + +  +  + + + + + + +   +   +      +            + +   +        +        +  + +        + +             +            + +   +   + + +   +   + + +   +    + +     +   +    +   +     + +   +      +   + + +  + +  +            +       + + + +       + +   + + +    + +          +    +   +  + +       +        +    +  +               + J6H3J4L7R9S4R4M6M9P:U5O;Z:Z:_>]>U:\`;aCdCfg8d>e=b;m=eAjAg:fj@dC`?j:cA\6V8Y2Q4P3P1O3E)E(E(F'>)A'79$:#6 /.*(&&"   + +     + +  +  + +  +   +       + + + +   + +   +          +  +       +   + +  +  +   + +    +  +    + + +    +   + + +  + +        +             + +   + +         +      +   +  +  +  + +  +    + +    +   !#!##!     + + + +     + +      +   +  +      +    +  +     + +   + +  +  +  + +  + + +       +  + +  +  +   + +          +    +          + +  +   + +  + +   + +        + +  +         +    +   +   +  +        +   +   + + +     +     +  + +    + + +  +   + + +     +  +  +  +       + +   +  +      +   +   + + + +  +   +      +   +      + +       +  +   +   +   +  +  + +              +  + + + +     + +   + +   + +   +   I5N4R4M5Q7Q5Q7M2Q3V9S:T=X9Y7Y>W<[C[@_Ba>b=\Fb?dEg?gFgGcHjHsJjGqLrJjLuNoJqPwRzTtU{J|TS|VUXW[X\Y]_bb[fa`lbkecibhd`_bbc\[]X^]UWXMU|O|Q~J|OtPyLkIrMmKnHkEgDkC^B]>c?Z;[9U:U4L8S6L3G1E.E-B(>+8(7)9 4%2"/. )(%#!        + + + + + +   + + + +    + + +  +     + + + + +    +     +  + +   +      +  +  + + + +  +  + +        + +  + +   + + +      + +   +  +     + +                       +   +  + + + +  + +  +        + + + + +   + + +   + +  +   +    + +     #""#  +  +  +      +      +  + +         +    +    +  +  +     +   + + + +  +   +  + +   +       +                   + +      + +  + +   + + +  +    +        +      +     + +     +        +    + +   + + + + + +    +      +       +   +    +  +   +  +      +    + +  + +   +    +     + + + +  +          + +   + +   + +   +  +    +    +       + +  +  +    +       +   +   +  + +   + +    +   + + + + +   ,I.H0S0I,P4K/S.N4T0[3W2U5Z3X0[2]7]8a;Z5b6c8a>^8h7c9j@d?h>jCq?kCmBwAxBmGsIrErI|IIzJGzRxL{MLNQULWVQPWR^VY]XWX][X\YYZWSVUWSVKOZTYNOwKNKyIuFzAoFwCoFk@g?o@g=d7_9a9X8Y8U5T4K0N,F+L/H-G+@'<#4#8"5!43.0**#"  +  + +  + + + +  + +     +  + +   + + +  + + + + + +  +    +                       + + +  + + +   + +  +  +   + + + +  +        + +     +   +                  + +  + +        + +  + + +  +  + +   + + +  + + + + + +  +   + + + + +   $"!%     +        + +    +  +     +     + +       +  +  +  +  + +   + +  + +   +  +  + + + +    +      +      +        +  +    +    +    +  +    +  +  +   + + + +      +  +     + + +    + +     +  + +  +        +   +  + + +  + + +  +  + + + +    + + + +     +        +  +  +  + +         +         +      +  + +     + + + +  +       +           +  +    +       + +  + +      + + +    +   +     + +          +   +   + + +  +  J2M2P8L3N7X3O3S9S4S:O9V;T9T9Y:^=WAZ?Z=aA`?`=\BgEhEjGeKeClDmGlJsGkHuIsO|KyMuQwK{RV}NOWTWW^Wb]V`\bdc^docibge__hd[_^`]Z_XYX^TX]TS}X{MwKMMsFrMlKnIgBeAbBe@bBg?XjAvDpItHwFyBnGrCtNxFxKRySPNMKOTQWUQ[WS^\b\\^W]ZW^XZXZ[TVUVRSVVJNQOLLyJyIyFxEzFnDpAoBkCg=d@f;Z8b6V8Y7U3X3N2R,I-H.E(A*A*@&>'<"5!3!- ,,,(%#$  +     +  + +  + +   + + +    +  + + + + + + + + + +   "  +  + +  +    + +             + +  + + +    + + + + + +    +   + +   +  + + + + +   + +   +     + +  +                          +  +       + + + + + + + +  + + +    + + +   + +  +   +    +  +  +   !"#$       +  +   + +  +   +  +    + +    +              + +       + + + +    + +  +     + +  +     + + + +  + +        +     +        +   + +  +  +  +   + + + + + + + +         +       +            + + +   +     +   + +   +       +  +          + +  +   +   + +  + +     +     + +           +  +   +         +  + + +  + +  +    + +   +   + +  +   +  + + + +       + +      +       +     +    +  +   +    + +   +   +  +   +       + + + +   +   + +   + J.Q2O8L9P4R7O6Q:T9T7W6Y:U6[>W>X?W+A$=$:#8 6"52/-&%#!  + + + +   + +    +     + + +    +  +   +  + + + + +  +   + +     +  + +  +                  + +   + +  +  +   + + + + +  + + + +  +  + +     +                      +  + +          + + + + + +       +  + +   + + +  + + +   "#    + + +      + +         +      +    +       +  +  + + +  + + +   +            +    + +  +  +                + +  + +       + +        +  +  + +  + + +  +       +  +    +  +  +      + +   +   + +   + +       + +   +    +  +    +    +   + +      +      +     +  + + +  + + + +  + + + +          + + +  +  + + +    +       +        +     +      + +  +     +   + +    +   + + +  +       +   +     +         +    + + +   +   + L5K3J4N4S8O6S9V:W9U9V6WbGe?gDgIhLiGoChKrNrKuIsRxKtJxPyJ|PwVRxQ}O}\YZZ]U\bZ`defeagbfccd`gca^bd`c_\[Z^]VXUZYZ~M|TzQ{NoMhIqMkLnEmCe?dB\=e9[?X,9':$2&5#3!0.(*$ "   + +      +      +   + +  +     + +   +    + + + +  +   +  + +    + + +   +  +   + +    +  +   + + +   +     +    +  + +    + + +  + + + +   +   +      +   +    +  +    +         +        + +  + + +       +  +        +          + +   !   + +  + +  + +    + +  +       +   +    +   +        +  + + +    +   + +  + +  +   +  + +     +            +  +      +      + + +  +   + + +  + +    +  +       +  + +    +    +   + +     +  +   + +  +  +   +     +   +      + +    +     + +   +      +  + + +        +   +        +    +  +      + +   +     + +  +             +      +   +    +  +    +        + +  + + +    + + +      + +    + + + + +  +-I,R2L,N,P,P5U1U3T4W5W1U2U4Z5Z:\9]9`8\@d;i=j8cq?rEoCrD{DtDuGuIH|KvNxK~L~KKPNSYNQXVZTW[]Y[Z_Z]\YZYX]TYWX^UWXXWRQRSP~MH}JKzH{GuIpCpDqBhDjAd?j9[:c8Y7W;Y5T4N,O0K)E.E)B+E(?#=%8%6$4"1#1.+''"  + +   +   +  +    + + +  +      + +  + +   + + + + +  + + +    + +  + +    +           +  +   +  + +    + +  +   + +  +  +    +   + +   +  + +   + + +  + +  +                   +          + +          +  + +  +  + +  +    !       +      +     +   +  +     +      +         +     +  +     + + + + +  +   +    +  +  + +    + +  + + +      +    +        + +  +  +     +      +       +  + + + +  + +    +     + +    + +  +  +  +     +  + +   +  + + + +   +      +   +    +     +  + + + +  +  + +     + +   +     +  +    + +     + + +  + +  +      + +   +   +  + +   +    +  +    +      + + + +     +            +     +     + +  +    +   + + +    + + +     +  + +  +     + +    + + + K3N0P4R:R4S3S4T;X6W;R9U;V<[8Z>Y:]<]\FaBaCgBaAlAkEaDfJeDjNoKnQuJqLqJzKwMySRvQ{OvYUW\~X\\_b\`\\dc]`hhgh^]mdjcf]_`_b^aX\\X]Z\TRWXV}RzSxOwJqLnDmFnFlEdEd@]:V>X&@'3$8"6$01!-+(%!!   + +          + + +           +     + +     +  +         + + +     +     + +    +    + + +  + +   +    + + +  +      +  + +   + + + +   + + +                                  + +       +  +   +   + +  +    + + +    +    !  " + +        + + + + +  +        + + +       +   +  +     + +  + +      +  +      +  + +       + +          +  + +   +         + + + +  +  +        + +  + +    + +     +     + + +   +  +      + +  +  + + +      +      +   +  + +    + +   +  +  +  +         +       +  +     +     +  + + + + +  + +  +    +  +  + + + +             +      +   + +   +  + +        + +    + + +  +   +  +    + +  +  + +  + +  + + +  + + +1P1Q0P3O8N:P4N3S2U2S3Y0\6T8W:^5\6W8f:e:]8`d@eAf?hCkFlCoCpGrGnCvHvHtHsK{K|JKN|GRQURNVQ\TZZWaZZY^]^]YaYY\W\YZV`ZXQPSQNSRHPO}MGyFyJzGwCsCoBnBk>iBe?`<\:_9[4Q2S4R0O.J.I+B'C*8*=%=&=!5"9$2*,-/%$ $   +    +  +   + +    +  +     + +       +   + + + +    + + + +  +   +              +  +      + +  +   + + + + +      +  + +    +  +   + +  +  +                              + +  + +    +     +   +   + + +  + + + + + + +  +  "!  +  +       +   + +  +   +  +       +     +      +       + +  + + +    + +  +  + + +    + +  +   + + +   +  +       + +         +      +   +        +   + +  +    +     +       +   + + +    + + +  +      +    +           + + +  + +      + +  + +   + +   + +   +   +     + + +         +   +       +      + + +   + +           + + +  +    +             +   + +    +  + +   +   + +  +   +  +      +  +    + + +        + + + R4M3M5Q1V2Z:Q8S7X8ZbCgBdFeEgAeEcCjIgIlMlHqKsKpPqKlNyPxKvNuUyXRR|V]\VXZYXa\[abdegeefidgecmcefdecb]f\b`\^ZXZYS|PVuL{R|SsQyOoMoDmDnCcA^9c)='?(9+5%6#1 )-+(&$"   +     +      + +      +  +     +    +   + + +  + +   + + +    +   + +  +   +   + +   + + + +      + + +   +    +  + +         + + + +    +      +                        + +  +  + +     + + +  + +     +   +       + + +    "  +     + +     +                 + + + +  +  +  +   + + + +  + + + + + +  +  + +  +       +        +           +  +       + +  + + + +       +    + +     +  +  + + +    +    +   +    + +  +  + +    + + +    + + + +  + +  + +    +    + + + +    + +     + +     +   +    + + + +  +   +  +    +     +    + + + + +    +            +              +   +  +     + +  +    +  + +  +  +  +  + +        +   + + + 1K1L3N2N3L2X0X4Q3Y4Q4R5Q6`4Z\:g@j:iAeZ<]>g>[@\@_BhBfCf@fEjBjGiFfCkGlFpJtIpNsNzOyR{RxU{UyV~W{USS\RT\Y[]^_ffkiabbfcefcfcfge`a]`\a]ZZ^[_ZW[P~UR~SzQzLtMpIrGlHfHg>fCiChC`A[;\?\4P5O6H1R4F.D+D)>'E%;)9$4$4#4,!/)&%'   +        +  +       +  +  +  + +  + + +  +  +    +  +  + +    +   + + + +  + + +   + +   + + +      +   + + +  + +   +   +   +    +  +  +   +  +      +      + +            +        +  +        +       +  +   +  + + +  + + + + + +                   +     + +  +   +  +   +   + +  +   +  + +   +  + +   + +      +  + + +      +                   +     +       +    +    +       +  +      + +      +  + +  +   + + +  +    +  +  +  + +    + + +  +        +  +    + + + +        +         +        +     +   +   +   + +        + +                      +    + +  + + + + +       + +  +  +    +  + +  +      + + ,L/O)N1N3Y3M0M2Z4[3Q1Y5^4T9Y:\8]7Z8a;_5dAg;^;g=kAf>m?s=k?qGpBsHrCoF}GrFyHxKzBwMNHzKPNSMVRPUVYPUWXXZ``Va^VZ_WR]V[[Y]TWPWTRZUQOMQKvLyJzNwKxJoCtCc>l@l@hBc?a=b9Z:W;T2T1N5G/M1G)C*A)@$C%9!:&62 5-,'&$#  + +  + + + + +       +  +      +   +    +   +    +  +      + +    + +            +   + +      +      + +  + + +   +   +   + +    + +    +           +             + +  +         + + + + +  +  +  + +  +   +  +  +   + + + +    # +      +   +      +       +  + + +   +       +    +     + + +   + +  + + +  + +  +  + +  +   + + +  +  + +              +                +    + +  +   + + +  + +   +  + +   + +       +   +  +  +   +   +     +     +   +  +     + +   + + +         +   +   +  + +   + + +      +                    +    + +    +    +   + + +  +              + + +        +        + +      +     +    + +   +   + + +  + +  + +  +   +    + +   +  O7L7Q8Q4Q7R6K7Z7T9U7Z=]AY9TA[=`?`>]B_?^>j;gBjGgFmGjCiKlLkJpHrLqLqMyNsIrSsT}QxO}ONVL\Y`X\^^\a^`bbeffhdehggjbdccfacg_h_bcZ`ZWYXTSP~PvRzOxLpLqMiFrBhHcBdCi>b?b#=&8&4"/!-.,((%   +  +  + +  +  + +   +   +     + + + + +  +   + + + +      +  +   + + + +    + +   + +  +   + +      +   + +  +    +  +     +  +  +    +  +   + +    +  +     + +                    +    + + + + + +  + + + +  + + + + + + +  + + +        +     +  +  +      + +   +      + + +       + + +     +      +  +   + +   +   +  +  + + +   + +  + +    +        +                 + + +   + +   + + +   +     +  +  +  +          +  + +    + +  + + +    +  + +  + + + + +         +   + +    +  + + + + +  +    + +  + +  + +  + +         +  +  + +  + +        +  +  +  +    +  +     +    +         + +  +   +  + + + +     +  +      + +   +   + +   +  + + + +     + + + +  + +  + + + +        +   +  +  P4R6H3Q>P6SZ:^:\4e;_8a9b:d=elBjAo?qFoAjCnHtBsExH{FzL|O{H|H|MMNUOMUTTXWXVWYX^cX\^Y\ZW^T\WRZXWU]UUQSUSMPRPP}LzLOtEtIoAnCmFh?a<`?b9\8Z:Y4W2U2W4J1P-M.B*B+?'A$?#7#1#4-40-&#    + +      + +           +    +  +  +        + +  +  +  +  ""# +   +  +  +   +  + +  +     +   +   +   + +  +  +      +  + + + +  + +   +  + +   + + +   + + + + +  + + + + +  +   + +            + + + + + +        + +  +  + +  +  +   +  +   + +       + +         +   +         +    + + + +  + + +    +      +     + + +    + +  +  +     +  + +   +    +  + +          +    +   +   +   +             + +  +    +      +   + +         +  +         + + +    +            +  +   + +  +  +  + +   +    +    +     +   + +   + +   + +         +  +   +  +  + +    +  +   + + + + +  +  +  +  + + + + +       +  + +  +   +  +         +  +       + +              + + + +      + +         + +     + +  +   + + +  + N/G4M5N5Q8N8T7R8V:V8W6V>U?[;^=UBY?[Ba>aDbAhDeAcIhCmDhEgImGlMmFsGsPyPySxJtPtT{N{S{R}U}UWYUVY[c]`[ajgcfdbcjgefjgeakgdca`h^_a^\ZU\RV~VP{SOySxNnOsNnMiGlDgHeEb@\>\C\:T:Q6O8O7R2G1L*K,A,B&A*7)7"3#1. 0()$&!     +   +  +         + +       + + +  + +  + +   &    + + + + +  +  +  + +  +  +    +    +      +     + + + +   +     +   + + + + +  + + + + + +  +  +    + + +   +       + + +  +                    +  + + + +   +    + +  +  + +  +   +       + +       + +                  +    + +  + +    + +   +   + + +  +  + +  + +   +  + +  + + +  +        +     +  + +      +    + +  + + +  + +    +          +             + +       + + +    +  + +  + + + +  +    +    +     +  + +    + +  +  +  +       +  +   +  +     +   +  +      +   + +  +     + + +     + +  +              + +    + +    +  +  +    +  +  + +  +     +  +  +   + +  +   + +   + + + + + +  +/K.S/N.O0P4U3U3T2Q3S5V6Y5V:`8V>[:V5[5a2_<^5gh]7X3Z6Y6S1M4M2R1H1I-E)B)>);$8'15&42,&'"           +             +          + + + +  + +  + +  +   + +     + + +  +             +     +     +    +  +   +  + + +    + +  +  + +  + +   +  + + +   +  +    + +         +    +   + +     +   +  + +  + + + +   + +    + + + +   +  +       +  + + +    +        +   +  +       + + + +        + + + +  + + +   + +  + + +    + + +     +  +          + +   +    + +  +      +  + +   +    + + +   +  +  + +   + +  +      + + +   +   +  +     +  + + +     +    +   +        + +   +   + +   +  + + +         + + +  +  +     + + +   + +  +   + +   +      + +        +     +   + +   +        + +     + +  + +  +  +               +      +  + +  + +  + +    +        +      +   + +  +   J5T4N7J9S8S6Q;Ub@_=a<\?f=dCeAeBdFkFnInLoFjJtHnKoNyPoJvLnOtSyPxQ|Q}Q|QxSSS]ZY^^]ddabakhboddfhnbjl`o]kb`dda`Z^]c\YSWV[VT{OxMpKvJrGoKrFnEfAf@]Ca`7\<^:m>d@m@iFcBkBkAsCvHwCtBpFwIuFvDxBzH~PKM}TO{MSLSRV\WVWXY]Z\\Y[][]\`^ZZW`YR\R[Q^TSXORJLNzH|LyNyHzGsDoDqIpBm>g=[?c=]:a8Z2S0T5O/L.L0J-H*B*D+>)A';*7"5 30-&$%"!  +   +         +   +   + +   +    +   + +  + +  + +  + + +  +  +   +      +  +   + + + +    + +  +        + + + +    +    +   +   + + + + +  +  + + +   + + +     +            +   + +  +     +    +   + +   + + +  + +   +         +  +   +  +     +     +      +   +    +    +   +  + + + + +   +  + +   +                                 +         + +  + +     +     + + + +  +    + +  +  +  +  +    +        + + +     +   +              + +    +  + +     + + +  +  +  + +   +  + + + +  + +  +         + +  +   +     +   + +  +    + +   +  +  +      +  +     +    +    +    +    +       +   + +  +   +  + +  +   + + +        + + +  + +    + +  + + +    M2R4Q3Q:P9R7M4V;U9Y9V7Z=T;]:[a=^>bAfEaHaHmIhChInLpHlLuJtMlKuOxJvN}OwQyO|Vz[TUZ^\Z\Wb^ca^kmdaaghliejggdgheadhd`f]]]]ZV\VTYSQ{UqOKrJtMlMkDh=fIgDeB_@_@Yd?h@k@mGhFnEkFbLmNgGwLzInJsMqSuJsN{P}P|RRyXU[\WW[X\Wa`]bbgglgmceejgdafghcc`fec``Z^^Ya^YXVS{PRvOOuPsNvNnFdCiKgEge9f:eoDsFtCuFwJrGwLxK~LM|Q|PNJRWTMVUXTZaXWX_[]a]^[`eW]XZW\\RZWYVUTNOUSPVTIFtJqGpJwEh?tClBj@f;a:`*?(;%4!45 3/,*(!"      +     +      +        + + + +  +    + +     +  %.#  + +      + + +   +        +  +  +  + +     +   +   + + +  + +    + + +   + + +  + +  + +  + +    + + +  + + +                       + + +  +    +    + +    + +     + +  +  +  +    +  +      +    +   +     + +    +  +                  +  +  +  +   +  +   + +    +     + +     +      + +                +         +  +      +  + +  +  +    +            +    +    +    + +  + +     +  +   +  +   +   +                 + + + +    + +     +  + + +  +     + + +   +    + + + +       + +          + + + +   + +   + + +  + +   +     +  +      +    +  + +   +  +     +    +  + + + + + + + + + +  +       +   +  +  + + + +  + + +   + +  + N3R4Q5M8R7T:R5W5Y8O8Z`?Y=_B[?cAgG]FfIkFgCoHmDmKlFoLpFhJsPyLuOrL{QtSuS|RRTTYV\UXY`Z`ba_efdgjjlfgjkfihfc]cfcac_b`\\YWZ[XQR~NwNwKtJuLsGqHlHkH_C_D`AZ?[9W8R;U8T4O3L0L,F.E'C&;'?(<#8'5#7$1.-)%#   +   +         +        +    + +   + + + + +  + +    +    &(/        +   +  + +  +  +    + +    +  + + + + + + + + +  + + +   +     + + + +  + + +   + +     + + +      + + + +    +               +    + + +  +  +  + +   + + + +   +  +    +   +    + + + + +   +     +    +          + +     +   +  + + + +       + + +   + +  +    +      + + +        +    + + +  + + +    + +      +      + +  +   + + +    + + + +        +    +    + + +  + +             +    +    +       +    +   + +  + + +              + +   +     +       + +           +   +    + +    + +      +             +  +        +  +        +  + + + +   +     +     1P3P1P2P0T3T2U8V4Q5V2X5U:]5X<^5^8c9a=d8d:c@hbBp=l=m>kBh?lBrCmEvKwC{I{IwMsJQNKOLUVOPXR\XW[][a^a_]Z`\V[XY`X]YVX^TWZURWZLPNUMKF{IJvGn?vHqBiFh:hAj;W7`4^:Z=Z7R5S5N3M0P,C+C+C)<#9%<'5#1 26..,)% #   +  +  +  +      +       +     + +    +      +  +   +  + +  02   +   +   + +  +   +  +  +   +  + + +   +   + +   +    +   + + +     +  +   +  + + + + +      +      +      +          + + + +      + +  +  + + +   +  +  + + +      +   +  +  +  + + +     + +    + +   + +   + +   +  +      +  +  + +     + +    +  + +  +   + +  + +  +    + +        +    +     +          + + +  +  +   +      + + + + +     +  +     +     +  +     +    + +   + + +      +  + + + +   + +             +  +      +       +       +  + +       + +   +     +    +       +   +  +          + +  + +  + + + +       +   + +    + +  +  +  +      +    + +  + +      +  + +     +    +      + +   +   L4P5O5R2Y7R9S3S9Y6Q;X=[>\;[@Z@WE\>Z<\Be@gDe?bEbFhDeJoFkDlDmKoSsJpKuQwOwKxP{O{W{V~UUVdX\^ZW^bZaddhhedlpiblgdebebead`f^\eX[]Y_W][VYR}NySNqNiKmJkLlEpGdHf=bG^@Z6^:T7Q6O6O6H6M4B-B/A*@'?);"6#2"2 2 + *($#$   +          +        +     +   + +     + +  +  + + + + +   "3 +  +   +    + + + + +    + +   + +   + +    + +     + +  + + + +  + +   + + + +     + +  + + +   +  +    +    +         +   +        + +   +   +  + +    + + +  + + +     +  +        +   + +       +     +    + + +     + +  +    +   + + + +   +    + + +  + + + +   +   +  + + +  +        +             + + +      +   +   + +  + + + + +     +       +    +         +    + +  +       + +        +   +    + +  + +   + +  +  + + +   + +    + +    + + + + + + + + +    + +    + +   + + + + + +  +       + + +      + + +     +  +    + +      +       +       +  +   + + +    +       +  + + +   +     +       +   +  +  +.N1S0N7L/S0S2W4V3\2W3X8\3W7]7[8b;`8d:]8\:b:b=dBe?j?q;nDj@kBoCoFs@tBpHuIsIwG{K|K~LOM~RNPMSQVNZXU[X^c\Y``]b__\V[_W_[[]TWX_\QXRPORQJNDPxGuJtHvGrAjBlAh>eb8_6Y7]3P8Z-L0S-H-K,A.D'@';$<#5"730-*)(#&!"    + + +       +   +      +  +   +    + +  +  +  +    + +  +  + + +  + + + + +   +  + +  + +   + + +  +   + + +     +     + + + +      + +    +  + + +  +      +  +  +                           +     +   +   +  +   +  + +  +  +  +    +  + + +  + + +    +             +  +      +  +    +  + +   +  + + + +  +   +   + +  + +     +    +                 +        +      + +       +  +  +    +     +  +  +  +  + +      +      + +   + +        +     + +  +    +  +   +     + +     +     +  + + + +          +  +   + +   +    +      + +      + +      +       +      + +        +   +               +   +    + +   +   + +   + +   + +  +   + + + + + +     +  + + + + +    + +  + J4O3O8N8O3QfAp@mBoDsGoFsCuJvJ~EzK}M{OuNzI{KN|PMSPRVSXWXV]_]\`\\_^]^_X[XYXW\ZZ_WYYUVSPWVNOKKJJ}DtAsAoBh?gBe>g=bfBg@nFgAqAlHhHiHnHsJnMpIsLyQsMwMwRVzQU{XVRVU[^`]`Xb`fafihifieokheidhacfec`a^bbb]\]Z^XXUPWwQKtMrGtFpJmHp@k?b=g@U=^=^>Y7V8O7O4I1H0D/G+<*C,=*:)6&400)'(&%   +    +              +  +     +  + +   + +   + + +     +  +  +  +  + + +  +    +  +    + + +  +   +  +  + + + + + + + + + +            +   + + + + +   +    +       + +    + + +  +   + +     + + +      + + +  +    +  + + + + +    + +    +  +   + +  + +               + +  +    +     + +  +  + + + +  + +    +   +         +          +                 +  +  +     + +   +    +   +   +  + + +   +      +    + + + +  +    + +  +    +    + + +  + + +      +      + +   +  + + + +  +   +  + +      +   +   + +    +  +  + +  +  +    + +    +   + +    + + +  +   + +             +      +   + +  +  + +     + + + + +    +    +   +  + + +   +   0O+O/S.T5W4S1\1U5]8T.Y4a3Y5]6_;_:f8_:_8_:i:b=e:g=kAlAp:i?l>lEoAsFpFtHyKwFFwKIL{KKTLLLRWWRSWVUX^[U_[Y`WW`^[Z`Y]Y]R[UXWZR[RTXXOMKM|IsK|EvJt@kEpDh>hY(3#9#2 1 -)&#!    +   +  +  +  +       +  +  +   + + + + + + + +  +  $(  +  +  +  + +  + + +   +      +   + + +  + +    +  + +   + + + + + + +  + + +  +  + +  + +   + +       +     +    +  + +  +    +           + + +  +   +  + +  +   +           + +     +  + +  +   +   +    +  +  + +         + +     +  +  + + + + +   + + + + +    + + +                         + + +  +  + + + + + +    +  + +         +  + +  + +    +    + +      +   +    +    + + + +      +  +   +   + + + + +    + + + +     + +    + + +            +  +   + +  +     + + +     + + +      +  +   +     + +  +  +   + +    +  +     +             + +      + + +    + +   + +  +   + +  + +   + +  + + + +  +      /K,P0L3T4N1W,Q3V5P2\1Z9_5^5^7\6Z9]<^9]9a=a@f:j@d:g=m@oEnDmCpBqEuGmBvCyF~AuGyM}O}N{NINRWQPWSVVUVW[ZY][W[`^]YW]\\aY^[ZVT_WSVOWZUNRPOQ{I|GzItEpArBkDn>g?fb6]:W8X6Q8W2Q0O2J1B0E*D(C(>*7)7#3$3 1".+-&$     + +       +   +     +     +      +    +   +   +  +    + +     '-     + +    + +  +  +     +   +  + + +     +    +      + + +  +   +   +    +     +  + + +      +    +                       + +           + +  + +    +       +   +    + +  +   +    +          +   + + +    +  + +   +  +      +    + +  + +  + + +  +                      +         +   +      +   +  +  +              +   +   +   +    +        + +  +  + +  +     + +   +       +  + +    + + +  +   + +       +     +                 +  +      +   + + +  +      +    +    +                + +  +  + +     +     +            + +  +   +  +  +   +  + +  + + +  +    + +  + +  +   +   +   +  +    +   + + + P4K8R8W4T7P6U;V:Z9R;W=X=^?\?[@^>\>a@\CnDhEdGbCgHpGmJnDfHoNtKnOqLpRuRxR{KsQ|V{TyR[}NZX}WYZZbc[_edc^hkgooej^ikmdiadbgdbo[fh[YcXW^b}UQzSXQvPtKwLtOnIlGeEhDd?dCaY;b;c9fmDmErArFqBtBsHvHzKHIzHJK|MMHMNRTUWWQ[Z^[\[\V[YdYbb`][\aYX^^WYWSSRVOV}RJNOL}NzIwNxHvFnEqBnAg:g?`;`,6%9"3$4 -2&'    +   + +  + +    + + +  + + +  +   +      +     +    +     + +  +     +  !!+,     +  +  + + +  +  + +  +     +  + +  + + +   +  +    + +      +   +  + +  + + + + +    + + + +    +  +    + + +     +  +            + +   + +     +  + + +  +  +   + + +  + + +   + +     + +   +       + +       + +   + + +  +   +  + +  + + + + +     + +   + +  +           +  +    +   +             +    +     +  + + + +       +       +         +       + +   + +    +  + + +   +    + + +  +   +   +  + + + + +     + +  +    + + +  +  + +  +   +   +    + +     +           + +  +         + + + + + +        +  + +  +   + + + + +             +   + +   +    +   +  +  + +  +  + + + +  + + + +     +   +   + +    Q9S5Lb?X;X>b;a>b@_:bCb@fEfJgFkGlHiIgImIkLuLpMuMwOpLLvN~O|\yVVT}VRXZ~WY\ZTd^]bgabjhfiikkgjjeilh_fjidcd`[_Z^^_ZSZVTQPtT}JtKuKxEiFeAdEbAZC\@W:[8Y8O7L2J3O4F0@-B-=,C&;)7$1#4"/+",($     +  +      +   +  +  +   +  +   + + +   +    + +   + +  +  + + +   '1 1 + + + + + +  + +     +    + +  +  +   +    +  + +  +   +      +  + + + + + + +  +    +  +       +      +    +     +  + +  + +  +  +       + +   + +    + + +         +   +  + + +       +        + +   +  +   +     +            +   +    + +  + +  +   +  +        +       +    + +  + +  + +   + + +     + + + +     +     +                 +   +        + +  +  + +   + +  + +  +  + + + + + +  +  + +  +  + +  +     +  +     + + + +        +  +        +      +   +      +       + +     +    + +    +         +  +       + +  + + +  + + +  +  +  + + +   +    + + + + +  1K4P/N,N5P3[2R3\1T4W4\5W5]4Y8[>a<^;e=h7a:f>`9k:l@i;jBrChBkDwDkEzGpCtMwJtJ}LP|LN~OOOQOSTURWSPXX^Y][WbgYY`Y\\]Z_^\[S_XMY[T_QNRLVRPKJ~J~IoCnEsJqCn>e@b?d=_=[9[8V4O7Q2R-Q2J,J/E-G,>&<'>%8&9!65 ,**("$   +     +   + + + + +  +        +  +  +        +    +     +    +   $%   +  + + +    +   + +  + +  +  +    +         + + + + + + + + + + + +  + + + +   + +   +     + + +  +      +   + +   + +    +     +          +  + +  +      +    +   +  +            +         + + +       +    + +   + + +   + + + +    + + +      + +          +       +  +   +              +   +  + +  + +  +  + +  +  +  +           +     +      + +         + +   +    +      + + + +    + +  +  +   +   + +   +  +   +  +   +  +    + + +  + + + +       + + + +   + + +       + + +    + +  +    +   + + +   + +  +    +   + +    +      + +  + +          +    +   +  +     +    +    + +  + + + + + + +  + + + + + O8K2O8P8P3Q9Y3Y^A^D^=aAe?e?cHiCl@gGfMjEpJoJnGpJnLmKmOpNzS{PtU}RzWzTWWXW^[`^Z__aaghgbkilqbdlpdmjkahfg`bd_`[[]W`]\XWYU~Q~UHvLtKtGpGeBjDfB_AeB`?[>U7X7Q8T3O2K0E-H)A,?/>'A%8$9!3&2/+(!#   +  +  + +   + +       + + +   + + +        + +          +       + + + +   + + + + +     +  +   + +    +     + + +    +  + + +      + +  +  + +  +     +  + + + + + + +    + + + +  + + + +   + + +  + + +     +    + + +   +   +  +     +   + +  +       + + + + + +    + +      +  +  +    + +  +  +    +   +   + +    +    +  + +   + + + + + +    + + +    +             +   + + +         +     +     + + + + + +      +     + +    +    +        + +  +    + + +  +   + +  +    + +   +  + +  + +       + + + + +       +  +     +  +      + +   +  +    + + + +   +  +        + +         +    +          + +    +         + +  + + + + + +   +  + +  +  + + +   +  +     + 1P2R/T/Q2Y1^4T4\7P6V8W5X5[4c6\;^7a:d9d9i;k>^9j@hBl@m;pBjc9^<`7_:[6U4S4M/K3L2L,I-D,?,<$;&7(;"6!-!-1-&&""  + +   +  + +  +  +  + + +   + + + + +  +    +    +   +    +   +     +     + + +       + + +    + +   + + +    + +   + + + + + +  +      + + + + + +   +      +  + + +       +         + +      +          +    + +  + +        + +   + + + +     + +   +  +    +     +  +   +     +      + +  +          + +  +   + + + + + + + +  + + + + +  +  +  +     +          + +     +    + +   +     +      +  +   +  +  +          +  +    + +  +  + + +       +  +      +     + + +  + + + + +   +    +               +  +  +  + + +  +   +       + + + +    +         +  +   +         + +  +    +  +    + +      +         +   +     + +    +    + + +   + +     + +   +   +   + + +  + +  + +  N8T8P9Q9S9W=S8Z9T;W`CXE`DbCeIiKlIbGmFhKnNoGqKnIvNuJsRvP{RxTVxRXUSV[[]\^\^be_^dfehekehfijjigdfg_hf`fc`^ccb]``XWSSTVV{VtP}MuJgJuDjA`Ad>aCb>a.>'9$8"64 .+,& " +     +   + + +   + + + +  +      +    +   +      +    + +      +   +   + + +  +       +    + +     +   + + + +  +  +  +  + + +  +  + + +  + + +    +    +  + + + +  +     + +  + +  +   + +   + +  +  + +  +  +     +    + + + +     +   + + + +     + +   +     +  +  + + + +  + + +     +       +     + +     +      +   + + + +   +    +        +          +  +  +     +        +   +    + + +   +       +  +    + +    +  +      +   +      + +     +     + +    + +       +  +    +  +     +  + + +  +  + + +      +     +           +   + +         +      +  +   +     +   + + +  +           + +   + +  +   +  + +  + +  +   +       + +   +  +  + +  +  +  +  + + 2S0M2Q3P5R3Y5V.W6U6Y4[=_7Y:]8Z:b9^5\#: 4"5"6!..)%$#   +  + + +      +   + + + + + +       +  + + + +  +  +   +  +   + + +  +  + + + +  + + +   + + + + +     +  +   + + + + +   +  +  + +  +   +  +      +         + + +   +           + + + +   +  + +   + +      +         +   +      + +  + + +     +        + + +       + + +     +   +           +  +      +  +    + +       +  + +  + +            +     +         +      +    +    +   + +      + +     +  +  + +   + +               +  +            + +   +   +  +      +     +     + + + +       + + +    + + +    +  + + + +    + +    + +   + +     +  +  +      +   + +   +  +   +   + + +  + +   + +  + +    +       + +      +    + + + +   + + +       +   + + + +  + + + +   + +S4S4S4R;S;WU>ZZDXA_Ac?^Jd=bFcCfCnDnKjGjHpLuMgQkExOxJvOuOQ}VzV|UW[ZTZ^a`cYd]bcijbjimlsmjkihglokeied]be^eac`Z^ZYT\|VRxP~RtPuMxHoGuHoHgBgF_?_=_;V9X8Q8P8L0J3I,D1A-?)=*@%<%6 5#2".*)&##  + + + + +    + +   + +     + +   +   + +      +    + + + +     + + +  +       + + +  + + + + + + + +  + +   + +  +  + +  + +  +   +   +         + +    + +  +     +  +  + + + + + +  + +  + + + + +   + +        + + + + + + +  +   + +  +  +   + + + +  +  +   + + +  +  +  +  + + +  +  +       + + + +      +  +  +    +       +  + + +    + + +  + +  +  + + +     +   +                     +    +    +  +      +  +         +   +        +  + + +  + +  +   + +   + + + + + +     +  + + + + + +   +  +   +  + +  +   +        +    +   + + + +    +            +   +     +  +  + +   +  + +   +  + +   + +                +  +      + +  + + + + +   +        +     + + + +  + + + + + +0P,W-Q0Q2O2R5U4T1[3_9]9`;Y4`9]8`6e7c>eBc>f@k?dd;^>a;];S9[6X4Q2M3G,M,C+B)>(?%<(7$47!1$0++*&##!    +     +  + + + + + + + +     +      + + + +    +  +  +  + +   + + + + +  +     +  +  +    + +   +  + + + + + +  +    +    +    +   + +  +       +         + +       +      +    + + +  +    +  +  +            +    + +   +      +  + +   +   +  +    + + +    +    +  +          +   +  +    + + +   +  + +     +    +    + +  +                +     +   +       +   +  +   + +  + +   +       + +        +   +  + + +  +  + + + +  +    +  +  + +      +   + + + + + + + +   +  +         + +  +   +  +  +     +    +        +    + + +     + + + +  +   + +           +  + +  +   + +                  + +         + +        +    +    +  +    + + + + +  +    + + P5O6O:R6S;W9T7^;\9V8[;[=[E]?aAb@_AkCeIjDdHcEgDkIjHiFqInDmLpOvLtK}OtNT|PxRvO{VUO[W~VYY\hXddeaffcjelmhjoilkeilkindeehaffc_^aa_X\ZVY}PyLOyPzNsImKrJjDfBgB`D]C[c;`8d?h>eAnAmApAnAhBmDtElFrIrDzFwH{PxFzLJ{NJRTQQSWVQR\UZW]W_[d_abe\bb[b\ZYY[][VaR]YY\TRVOQUNQ{LzIyN{Fq@rDpEkCj=d?c=e9d8Y=\6Q1R.N1L1H.I+D&C(?&@"<#7"3 3 2$*()('!    +  +    +      + +    + + +   + +   + +  +      + +  + + + +        + + +  + +     +  + + +      + +   +   + + +  +  +  +   +  + +          +      +  +   +   +  + +     +  +      + + +    +   + + +   +  + + +  +  +   + + +   +  +   + +     +    + +    +   + + + +    +      +      +  +   +   +    + +  + + + +   +  +  + +  +  + + +   + + +     +  +   + +           +   + +        +    +      +     +  +            +     +         +   +        +   +       +   + +   +  +       +       +   + +   +   + +     +  +  + +    + +  +    + +  +    +    +    + +     +   + +   +  + +          + +    +  +           +  + +  +   + + + + + + +  +   +  +        J8R:P9W8S9V?ZU9_<^:\>`>^>XA`@`BbBgFlBfBjFgBbKlHjGkLeMuOqGhN|QrM}QsQ{OsRSzW{W}UR[V[\`][\efhgceeijgjisenhlhgiefcff`cd_ag^b^X]Y[RNT~RxRxStRuNtOp@pFb?^C`>d:_Y3R8M5M2G0G,C-@+;)=*9#4"3#0!0(&,%$"!   + + + + + + +   + +     + + +      +         + +   +  +   +   + + + +    + + + +  +  + + + +      + +       +   +  +  + +    + +   +        + + +       +   +  +       +  +  + + +  +  +    +  + + +  + +  +    + +   + +   + +   + + + + + +    + + +     +   + +    +  +                + + +    + +   +   + +  + + +   + + +           +             + + +    + +   + + + +  +         +     + +  +   + +      + + +        + +   +        + +  + + +    +       + +  + + + +  +        +   + +   +   +    +        +     +    +  +   + +        +   +   + +  + +          +            +  +  + + + +    + + +  +   +  +   +  +   +   + +   + ,O3Q2L5Y2Q1S4S7S4[6V5U3a1b9\8\8f=d9f;]:d8g>h@i>fBhClFoBgBn@o@oJvGsJsIxM}N|KvJILNMOJTUSQXVTRVS_XYZYbcacX^a]^^_]Y\[_`ZYYU[XYYPQQNQM|FHyJ{JxKpFlDjBbDn=_`?Y:V6_8X2U2I2O-F-G)B(<&;#8;#4!-/1)%*%#   + +    +   +   + + + + + + + + + + + +   +            + +   +    + + + +   + +  + + + +  +  +    +   +   +  +   + +  + +  + + +     + + +    + + + +  +   + + + +  +    +    +  +   +  +  + + +    +    +  + +  + +  + +             +    + + +     + + +    + + +  +  +  +     +  +            +     + +  +     +    + +  +   + + +   +  +  + +  +     +      +         +         +        + + + + +  + +       +  +   +      +       + +  +         +   +   +      +  + +     + + + +  + +     + + +   +    +  +       +  + +        +  +     +      +   +          +    + +          +  + + +     +  + +    +  + +   +    + + +    +   + +  + + + + M7R;N9R;S9Y;T;X:V?Z9^>`AY?_?[?_@`CeBaBgBfCfCjFkGjGoGlOlLnJtPmLqIyPsWtQ}MzY~X{SOXVW_Rb[Y\]aijfdbefhijkqhdehdikjljgdmabba`fcb^YZVYVRU}[|S{PsInHzKiFoKgBdGb?Z<[;]5X8U5P5T/D0F2E*E)?&@&<&3'0"0"1*)(*"!"   + +   +          + +  +  + + + + + + + +         + +    +  + +  +    +   + +  +   + + + + + +   +    + + +    + +  +   +   + +  +  +   + + + + + +   +  +   + +     +             + + + +    +      + +  + +  + +      +  + + +  + + +   + + + +    +  +  +   + + +    +      +    +  +   +    + + + + +  + +   +  + +  +  +   + + + + + +  +     +       +    +      +    + +     + +   + +     +     +   +             +   +   +  +       + + +  +  + + +  + +   +    +  +      +  +    + + +   + +     + +  +    + +    +                +    + +    + + + +      + + + + + +     +    +   +   +    + +  +    +   +  + +    + +  + + + 3T2P3X3N-R2T4T1\5]:X7\7]:_=X8_2c8d9c5]>jh@iBm=gAjDt=o=qCtDuFuCsMzHtGxIOKKMP~TTUMQQYTVVWY_Y_`b``^\cg```_`^``ZZ_[Z[VZWZWRSWKL~P}M}GLxFrJuDt?kBfBj;j=b9d:]:Z4X:L1U0M2E/I0F,D+G'8(:"7!430!/,&%&   +  + +     +  +   +   + + + + + +   +    +  +   + + + + + +  +    + + + +  +  + +   + + + +  +  +     + + +   + +     +      + + + +   +   +   +       + + + +  +  + + + +      + +  +      + +  + +  + + + + + + +  + +         + +   + + + +   +     +  +   +     +    +      +       +    +  + + + + + + + +  + + +   + + + + +    +                     +         + +  + +     +     +  + +   +     +   +     +     +    + +    +       +  +   +     + +   +       +   + + +  +  + +  +   +        +  +              + +  +    + + +    + + + +    +    +                  + + +   + + + +  +     +     +  +  + + + +  +  +  + +  + +     + + +   +  +      +  + + + +   +  + + +  + N;S7R5R7T6[7W;\>Z9[6]9^=Y=]B_;bA`BfDaAd@d>gEhDgKhEkImFpPnJvMpKvOvKsSzKwRtTROPR|V~Va[\Z^]`]^abicfljoikmehoichkjieefhge]a^ea_^Y\ZVWTUxPOzNyKqIrNpIhEhBdH[:`@U9Z9\9V1L3M1I1H.H.@/;*?&4(4%4!6-*(('&"   + +    +          +   + +  + +   +        +    +   +  + + +   + + +  +  +   +   "#9)  +  + +  +    +   +   + +  +    + + +       +        +      +     + + +    + +          +    +   + + +  +  +       +     +  +   +       +   +      +  +  +   + +  +  +  + + + +          +    +  + + +     +        +       + +    +       +      +  + + +    +  + +  +        +    +        +   +  +        +    + +     +    +  + + + + +    + + +      +  +      + +         +         +      +  + +     +     +    +     +      + + + +    + + + +   +  +  +   +  + + +    +  +0R0S0U1T3T3W2V7S4Z4X5Z4^8]:\<_6b;^=f=e:g>cBhGi@k=mCm?oAoBn>pFyD~HqFxJ}HxIyNH~NJNNOPQZSPUVRV]Xa_\a__fd^`]_``_d^_aZWS[VVZYXZRWXVORPyN~LzK~BuG~GpJkBgAh@e;a9Z;^;Z8Z6R:O/Q2I/L/H*G$A%>&6#;!1!. ,.*+&&$#    + + +  + + +    +    + + + + + + + + + + + + + +  + +  +   +        + + +        + +   + + + +       27&0.&  +  + +   +      + +  +  +   + +  +  +   +  +  + + + +  +    +     + + +  + + + +    + +       + +    + +   + + +    + + + +      +     + +    + +   +    +         +   +   +      +     + +  + + +    + +  + +    + +     + + + +  + +  + +    +               +      +              + +   +     +  + +         +     +         +  +        +  +  +     +     +     +          + + +       + +  + + +  +  + +  +   +    +  +     +  +    +   + +   + +   +  +      +                +  +    + +  +       +  +  + +  +  + +            +    + + R9S9R;U;R5X=Y=\;T:[9W@Y>]=`B`BaB\>aCaDiCgEf@iCjJnGoIkIlFwIwPpSqPxMwOM|UwWyTO}YXW[YbZZbfbc^hbhicfhjnfjtpnilnmqdhekhgib`dc\b`ZZUUPN{RvZwPvJrKiOqHnEoJiAfCaDc?];Z3S8V:R5O4H1F0F.F-C(B,;)4%7$/#7.+)&$!    +  +   + +   +   +   +   +  +   +       +       +  +  + + +   +     + + + + +  + +  +  +  +   +."   + + +  + + + + +   +  + + +    +  +  +      + +   +  +   +  +    + + + + + +        +    +    +  + + +    +  +  +  + + + + +  +      + + + + + +  +   + +    + +  +            +    +   +     +  + + + +    +   +   +  + + + +  +  + +  +   +      +  +      +     +    +              +     +    + +   + +        +     +      +  +     + +   +   + + +  +    +    +  + + +    + +         + + +  + +  +   + +  +  + +    + +    + +  + + +   +  +         +   + +  + + +  + +     + + +  +  + +     +   +      + + + +        +    +  + + +   + +  + + +2Q1T3S3S5U3`4P3]7W8W4^9_4[<\8e5c;b;[=d?gj@sAiCm?j@rAzKxGzCrG|DzKwOL}OQQIRORUUWTW[[ZZZX_`e_aYb]b[d_]]^][Y`^_[[VSZZZYWPPOORM}JxK~IqCnGqBn?j=hAhA`:];Y8Y:U7X2R1H,F-J)E+B)?">&7&51,,,)&#!  + +  +     +    + + +   + +  + +  + + +        + +   +  + +   +  + +   + + +  + + +  +      $#    +  + + +  + +   +    +  + +   + +    + + +      + + + +      +  +  +    +  +     +   +    +     + + +  + + +    +     + +  +  +  +    + +  +  + + + + +  +  +     + +   +  +      +       +   + +  +   +  +  + +  +   +  + +   + + +  +  + + + + +          +           + +   +  + +           + +  +  +  +     +  + +    +   +   +  +  +    +     + +    +  +      +   + +    +  +   + + + +  + +    +  +  + +     +     +   + +  + +      +     + + +   + +   +   +  +  + + +    +  +  +    +    +  + + + + +    +         +   +     + + +  +   +    + + +  + +   +  +  +    + +   T;O7W6S7R@W;T*:&8!3$2!0-)&&#"   +     +  +    +           + + + + +   +  +  +      +       +    +   + + +        +   + +  +  +  +  + +    + +  +     + +   +   +    +   +  + +  + + + + +    +  +    + +  +      + +        +                      +         +   +   +  +     +  + +   + +    + +   +  + + +  + + +   +    + + +   + + +       +       +   +   +    + +  +    +   + + + +    +   + +   +   +                   +      +    +     +   + +  +      +      +    + + +  + + + + + + + +   +  + +  +    +  +   +    + + +  +         + + +  + + + +   +  +   +  +  +    + + +  +       +  +  +  +          +   +   + + +   + +  +     +2Q/P0M2T2Y1Y0T2Y4Q9[9]7b6a6^8]?c:^>a9d9c:f6gAem>nCnBs?qGtE{IvItIIrMyMNzPPQNRQQSVYWZaWd]_Za]^Za]ged]d__b^`a__bYa]ZW[SYWUQNRMI}MyLxFvCtJrDuErFi@l=d*A*<&63"6,0,'#" "  + +        +  +  +    +    +     + +     +         +      + +      +  +     + + + +   +   + + +  +       + +   +   +      +   + +    +  + +  + +  +  +     + +   + + +    +   +   + + +  +   +  +            + +  + +     +    +  +   + +   + +  +  +  +                 + + +    + +  +   +    +  +  +  +      +  +  + +        +                  +   +  +    + +    + +  + +   + + +            +       +    + + + + + + + + +  +    + + + +   + +  +  + +    + + + +     +   + +  + + + + +       +  +          + + +  + + + + +  +     + +  + + +   +   + +  +   +      + +  +  + +           + + + + + + + + +  + + +  + + + + + +  +  5Q3Q0T5V9V4W3X7Z5U5Z6X:`<_:_:`6`=b;edZ9Z>V=\?W>[B_?a@e@dAg@eEdCgFgHgGkCpHqLrOlJsIyMsP{NsLyM|SzP|T~NTX[YW\Z`]cca^aiciflkkppnpkmngrnholfekkghgdlc^``b_][[RX~T}P{UuHnIsJqFiElDhCdD_C\@Z9U:S;W8O3O1I,F.A-?+<*A$8%7#3#.!++)$"  + + + + +     +      +         +    +  +  + +     + + +  +       + +     +  +       + +  +  + + + + + +   + +   + +   + +   + + + + +  +    + +  +  + +   +  + +  + +  + + +  +   +  +   +    +  + +  + + +  + +      + +   + + +    + + +  +    +  +   + +  + +   +         + +   +  + +  +  + + +    +  +  +  + +  +    + +  + + + +                      +  +        +   + +  +   +       +          +       +         +      +         +      + +   + +  +   + + + + + + + +   +  +   +   +         +  + + + +   +     + + +   + + +   + +  +  + + + +      +  +   +  +  +    +  +   + +  +    +        + + +  +      4T/P1P2T/Z3T7X1V2X9Z9\:\;_6^h?p>o=nDoAqBoBpEyF{DzH}DvFxG|JzLN}QOSNORMW[WV]UYW]YX^cd`d`ledida``b_`bcb][YX][V\YRUURQOOEJ{EzJoFrIpGr=f@e?[?[=`8U6P6W3K/N4M-H-H,B&;&='8&1 2!2/,()$$    + + +  + + + +   +       + + + + +   +  +   +    +   +  +   +    +      +  +      +  +  +   + + +   +  +  + +   + +      +    + +  + + +   +   + +    +      + +  + +   +  +   +  + + +       +    + + + + + +  + + + + + + + +  +    + +  +  +  + +  +   +   +     +  +   +  +     +  +  +      +  +  + + + +  +   + +  +      +  +      +     +           +    +        + +     +     +     +   + +     + +   +     +   +        + +   +        +  +  +     +   +   +     +   +     +  +  +    +  +  + + +   + +  + +  + +                  +  +       + + + +         +    + +        + +   +         + +         +  + + +  +        + +  +  +  + +  + + V8VW;Y=_;aAbY>^:Z:[6R7L7N4K4I/C+E+B*<';"3#3&.) )/%$#   +    +   +     +    + +   +  +    +      +   + +  +  +     +   +  + +   +  +     +   + +   + + +    + + +  + + +   + +   +  +      +   +    + +      + +       +  + + +           + + + +    + +    + +  +   +  + + +   +      +  +  +  + + +  + +  +     +    + +    + + +     +   +   + + + + + + + +             +     +    +        +     +       +    + + +  + + +  + +              + +  + +  + +     +   + +  +  +    +    +      +    + +  +   + +     +      +  +     +      + +  +     + +     + +   + + + +  +   +    + +            +  +     +  +  +  +       + + + +    +      + 2T/T5S2Y1O2R9Uk?k?qBnAvBrExFvFxLsLyIN{JyN{JIPPTONVOTXTV[Z]^\aa_bgZk_fb`^]bbaXb^fa]^_^[W]^XYOTQYUJQPGxNxHtIzFk@cAlAh@_;_;^9Z7T8U6R5R3L1I/F,D*>&;(B&7"1-#0,&'$!   +  + + + +       + + + + + +   +    + + +  +  +  + +    + +   +    + +    +    + +     + +     + +      +    + +   + + + +  + +  + +   +   +   +   +   + +      + +    + +    + +  +     +  + +      + +    + + +  + + +     + + +   + +   + +     +      +  +    + + + +  +    +  +  +  + + +  +  + + +  + +    + +  +  +   +  +   +       + +    +         +   +        +    +  +   +     + +  +   + + + + +    +         +  +  +     + + + +  +    +   +    + +     +  +   + + + +  +  + + +  +    + + + +     +  +  +    + +  + + +   + +              +    +   + +  +     +  +  + + +  +   +       +        +  +  +   + + +    +   +        +  + + + +  +  + + +  + + X7R3P>Q\>V;^@_AZ@e@`@_@[BfGfBlFjG^GgCpJkHtGoPpLnQpTyMwQxQxS|S}Q~VUWVYTZ\`d\dbad^elbjojmlqjhisqgutikmmjmkehpjede`e`b]YVPQQRzMwVwLxNsKpHlHeEaAb?eA[@[:Y>Q5S4Q2M2J/F+?+D*7.:%3 0$0!/!**'""           + + + + + + +       +   +    + +  +   +     +  +         + +   +  + +      +   +    +    + + "  +  + + + + +  + + +  +   + +  + +    +           + +    + +  +   +   +    +  +  + +     +  +  + + + + +       + +        +  + +  +  +  +   +      + +  + + +  + +  +     + +  + + + +  + + +    +                  +              + +  +    +         +       + + + +  +  +              +   +        +  +   +   +  + +       +   +  +  +       +   + + +  +        +        +   +    + +  +   +  +       + + + +    + + + +    +    +       +   + + +  + + +        +  +  +  + + +   +  0Q0R2W4S7U4W4^5[5];^9^7a7c7\9^9Zj?iAmCk>lBsBqCvErBxEsF}JHG}KPQMTNQLTPUXVP]W[ZZ``_e[e`begccbk^_e`e]d_c\^b^ZYY]ZRQQWSPO{J~MzLsFoKzHp=h@i>dAe>]8\:^8X2R9Y4P0P5E/@,E-=(='<"7$3 34.(%&!!        + + + + +  +    + + +  + + +  +     + +    +   + +     +          +   +        + +  + +  +   %  +      + +    +     +  + + + +  +    + +          + + +  +  +  +      +    + +  +  +   +  +   + +  + +  +  +  +  +          + +  + +   +    + +      + + +  +  +     +    + + +  +   +   +   +    +  +    +         +  +  +        +           + + + + +  + +  +  +  +               + + +      +    +  +  +     +   +   +          +     + +        +  +     + +  + + + + + + +       +   + +  + +   +      +        +            + + +  +  + +   +           + + + +  +   +   + +   + + +     + +     + + +   + + +  +     + +   Q;U7T6YAS:X>[:V:[@]@_<\?`j$='8&7 3,+ ))'$"   +   + + +  + +  +    +  +  + + + +       + +  +   +         +   +   +    +   + +  +    + + +  + + +   *! +  + + +   +  +  + +     + + + + + +   +      +    + +          +   +  + +    + +      +    +  + + +      +  +  +   + + +   +   + + + +       +   +  +     +  +  +     +  + + +   + +          + +   +             +     +     +      +        +     +  +     +   +     +       + +  +  +          +      +        + + + + +  +  + +  + +    +  + +     +         +      +   + +     + +            +   +  +          +      +         +   + +       +   +       +   +      +  + +  +    +     +    + +   +   + S8U9X=S3UX?W;]:_DdB^=f>c@aC_ChEjHdIhHkGbIqFlLjHmKtNnKsO{M}TyT{P~R|Q}TWQZ]X`\]\a_^]egdldcmrnhrmrnoovnqpllkrhshnhdc`cdcb_^^^_UPQxV}PxSsSxHpCoGfC_Bd@[>[DO?[8\7T6P3N7I,J/D0F+@'5'9%;"/1*)##"  +     +    +  +   +  +  +    + +          + +  +          +   +  + + +   + +     + +     +    + +  + + +     +  +  +  +  +  +  +   + +         +    +     + +  + +     + +  +  + +         + +      +  + + +         +     +   + +    +  +     + +  +     + + +    + + +   + +  + +        +  +  +  + + +  + +    +   + + +      +     +   +  + +  +        +   +  +  +   +  +    +     +  +  +  +   +               +  + +   +   +     +   +   +   + +     +   + +  + +  + +          +  +   +   +  + +     +  + +  + +  + + + +   + + +      +   + +  +       + + + + + + + +    + + +  + +  + +    + + + + + +1Y0Q/S8O4W6V9W8X5[8`9`2f8[6X:a>c;`:i=gBkfCa:_?_9a6S5V4S8O2V0K+E)D*E(<)?(=$7$/ /).(%!   +  + + +   +   +  +   + + + + + +           +   +  +   +        +  +    + +     +  + +   +     + +  + +        + +  +  + +   +  +   +  + + +  + + + +    + +               +  + + +     +  + + + +      +   + +  + + +   + + +   +  +   +     + + +  + + +      +    +  + +  + + +  + + +      +   + +   +  +   +  +   + + + + + +           +   +     +    +                 +  + + +  + + + +  + +  +    +  + +         +           +                   + +  +  + + +   + +       +          +   + +    +    +   +  +  + +     +    +    +  +  +     +             +   + + +  +   + +  +    +     +   +    +       + +  +     +   +  + + +    + +  +  +  + + +T6R6R8S9T;T8YaB\>U5X7O4M2N7G.H,G-@*B)B*4+92!.-+ $      + +   +    +   +  +    + +      + +     +         +   +         + + +   +   +     + + +     + +   + +  +  +    + + + +          +    +  + + + + +     +   + +     + +    +    +  +  +   +    +    +     + + + +          +   +    +        + + +   + +  + +  +       + + +  +  +             +     +       +           +  + +    +   +  + + +  +  + +  + +          +        + +     +   +    +  + + +            +   + +  + +   +  + +           +      +  +     +  +  + +   +   +   +  +  +  + + +    +     +                 + +    +     + +      + +  +   +     +  1T3X3U5T0Q7_3[4T4V4_6[9^;b;Z6_;ap?nDiCvDwBp@xC|DyH~MOMHwHOQPSOWTYSUQTXZ]]\_c^bgbdbdl_`g^kbh[cbea^\^\][_[YXT[[RXNHOzK{KxGuJuDl?kAk>a>a;b:a8[8S3P4O1H/G0E-G,C*B*=(<$8"8"0-)(%"   + +  + + + + + + + +   + + + +   + + + + +  +  + +   +   +      +         +  + +  + + + +   +     + + +   + +   + +      + +     +  +  +      + +        + + +  +  +  +    +  +     + +     +    + +   + +   +     +  +      + +     +  + + +  +      +    +     +   +  +   + +  + +    + +  + +  + + +  + +  +   +  + +       +                + +   +    + +    +          +     +   +  +   +   +  +          + +     +         +    + +          + + + +    +   + +  +      +  +   + +     +       + +       + +    +      +    + +   +     +      + +   +   + + + +  +   +      +  + + +  + +   + +   + + +     + + +       + + + + +  +   + + +   +   +  + +  + + + + P;Q6U>T;_;T=Z^=Y@_=aD`GeFhGdFkHgGlBrHlDnNqLgLpJxHtJqSxW}RT~VyT~UZVUV^^[]fXc`fdedebmkmiqnriptikqoopsipilshglbfc_ecb\Z][ZUZWU{POsMpPrGlHgGe@];U<[9Y7S4T4N/J1G3C,D2@,C'?(7)6!4!4!.%%#!   +   +      + + + +     +        + +     +  +       + +   + +  + +  +  +    +    +    +   +  +     + + +    + + +    +    +  +  +  +   +   + +   + + +   +    +   +  +  + + + +  +  +  +   + +  +   +   + +      +   +  +         +    +   +   + +  + +    +  + +   +    +  +    +  + + + +       +          +      +          +    + +   + +    +  +    +  +                +  +   +  +     + +   +  +   + +  +    + +   +  +   + +   +   + + +       + + +      + + +      +  + +  + +  +      +  + + +  +   +    +  +   +  + + + + +  +  +   +   + +  +  +  +  +   + +1V7W3T6Y5S6[6W6Z4_5]9Z9a9b:c7a8fnBrDmDtGmAqBxEwK|IHzGxH}KLHPSJRROMSNV^Y^W`[^^]gi]dcdfibhidcabafc[_^ba]daZWWWW[YYMMPMKKzLwJqGv?m@f^;V8[9U3T4O0S2I/O+E,@*@*=(7'7#:!/.0'&!     + +   + + +  +  +  +      + + + + + +             + + +  +   +   +  + +         + +       + +   +    + +   + +   + +        +      +   + + + +   +    + + +    +    +    +           +     +    + +   +    +   + +   +  +    +    +   +      +    +  +   +    +  +  +  +  + + + + + + +  +  +   + + +     +    + +    +       +         +       +  +          + +     +     + +  +  + +     + +   + + + + +     +    + + +  +           + + +   +    + + +     + + +   +  +     +   +       +  + + + +    + +   +     +   +  +    + +     +  + + +    +   +    + +   +         + + +   + + +         +   +      + +  + + +  +       +  R6V7X:\6Q9W`>Z;W:R5S4P5U5H2F1G+B'A)?'<(5$8"/-(*"#!   + +         +  +    +   +    + + +    +      + +     + + +          +   +   +   + +  +        +    + +     + + + + + +  +  + +   +   +  + +     + +  +  +   +       +    +            +  +    +   +     + +  + +   +   + +     + +    + +     +   +  +    + +   + + + + + +  +    + + +  +    + +     +                 +                +   +  +   +   +    +   + +       +  + +           +    +  +  +  + + + +     + +   +    +   +  +  +  +  + +  +    +    +    +     + +  +  +      +  + + +  + + +   + +     + +  + +  + +       +  + + +    + + + +  + + + +  + + + +    + +4Q7W2S9Y1Z6Z4^6_7a8`8Z<`8a7m@e:aAf8gAjBoW9TAU7R7Q1L2M/K.A,>-?&<(9#8&5#43%-&"     + +  +      +  + +   + +     +    +  +  + + +         +          +   +     + + +   + +  +   +         + + +  +   +    + + +  +   + + + + +    +               +           +    +   +  + + +    + + +           +      +  + + + + + +        +   +       + + + +   +   + +     +  + + +   + + +        +      +         +      +    +       +   + +  +   +      +   +      +        +  +  +  +   +     +    +     +   +  +   + +    +     +     +  + +  + + + +      +             +     + + + + +       + + + + + +  +  + +  +   +  +  +      + +     + +    + + +    +  + +  + + +   + +    + +  + + + + + + 2P1U3X5[8Y6U5T8S9Z5\9X8e8^e;Z>a9R5[5X5R2R3L.G*F)D'>$?$;$;&4#/ 5/,)(    +  + + + + +  + + + + + +       +   +  +           +    + + +    +   +    +        + + + +  + +  +  +  +   + + +   + + +                   +  +        +     +   + +  +     + + + + + +          +      +    + + +    +  +     +             + +    + + + +     +           + +   +  + +     +    +                       +            +    +  +    + + +  +  +     +    + +  +          +            + + +    +   + +   +   +         +    +  +   +     +      +    +       +    + +  + +  + + + + +  + +   + +       + +        +   +  +     +    +   +   +   +  + + +  +      + +    + +    + + +    + +X1V[>^F`C\C`@bGgDhCeBkGnBkJkImFnKoIrLnMoVoS}POxXO|V}P}UXXY[ZY]Yadc`[e^gfbjimmkrnpsnuvpohtnkqqouogllildfjeba]XXZPUPX}Y{S{NwMqKtDoHjBaCcAb?X?Z6XwDqHrGuHyJIxIJJ~KONKMNIQOWSZZ[\\\]d_bbbbcgadegdgebdaghagf__d`_V_Y`TYUSYTQNPKH}JwKsExIw>nAj>c>d9b8Y<^4T3N4N1N+L*?*B*@(<)9$0'7 22 0-$$   + +   +  + +  + +  +  + + + + +     + + + +   +    +   + +  +  + +  + +   +   + +   + +  +  +  + +  +  +  + + +      + + +  +     +  +  + + + +    + +   + +   +        + + +      +  +  + +   + +     +  +    + + +       +       + +            +     +   +       +   + +    + +  + + + +  +                 +   +  +    +  +    + + +    + +  + + +  + + +    +      +    +   +      + +  + +       +  +  + + +         + + +  +        +         +               + +    +    + + + +     +    +  +  + +      +    +   + + +     + +  +    +    +   + + +  + +  +   + +     + + +  +  + +  T8Y8U9S7V8[=]=\9UAa?\?[DaDbD`D[FjBhBfFnEoGmGlJpKpIIqMxRsQzPuS{NzSyPMxPYS{]VX[Y`\a__fc\jfllhnronruxooookonougrqnokgmhlff]`b^]\X[WXTyY~STxLsPhMqKdGkFjFkBY;d;[b?a;W8Z7S2U1V-M0E/A$A$9'='9"5!1!4 /**%  + + +   + +  + + + + + + +  +      + + + +     +  +  +       + +  + +      +          +  +      + + + +  +  + +     + +  +   +    + +     +  + +   +   +  +    +    +  +  +  +  +  + +  +   + + + +  +  +  + + +     +  +  +     +  + + +  +    +   +  +  +      +    + +   + + +   + +  +   +   +  + +   +  + +        +            + +          +    + +  +     + +    + +        + +        +  +  +        +   +   +   + +  + +  +  + + +  +  + + +        + +    +  + + +    +     +  +   +     +  +             +    +  + +  + +  +  + + +  + +  + +    + +       + + + +     + + +     + + +   +  +   +  +  + +     + + + +  Y3S:W;\9U9`*=(5"3%5"5!/.(%"       +  + +  +        + +  +  +   + +    + +       +   +   +  +   +  +   + +  +  +  +      + + + + +  +   +  +   +   + +  + + + + +   +  + +   + +     +   +   +   +  +   +     + +    +    + + +   +  +  +   +   + +    +   + +  +  +   +   + + + + +   +   + + + + +  + +  +  + + +   +  +   +       +        + +  +  +  +     +   +   + + + +   +          +    +  +  +  +          + +   +      + + + +    + +       + +  +  + +  +  +    +  +       +         +  +  + + + +     +    +   +       + + +      +    +    + +  +  + +      +    +  +   +    + + + +   +2S4U2X4[7X4]8\9a:[8Z:[6]=c8c8i9b9e@eDl>m@jAiCtEmAlGsHvEmJrFxGxG|KuNxKORMQJUWPUUWU\YWVY\d`e_fdcbnijecacekehfgddbdf]`^_[V[XSVW\VUQSF~L}EH{FrEoErBmAu:dc;_;\2V3Q0T1G0I*E'>+?%<&5#4 0 0--&'!!  +      + + + +   + +  + + +   +  + + + + + + +  +   + +  + + +  +  +   +   +  +  +   +          +        +  + +     +       +       +    + +    +  + +      + +   + + + + + + + +    +     + + +   +  + +      +  +    + +   +  + + + +  + + + +   +   +   +         +     +    +    + +     + +  +   + +  +    +    + + + +          +      +    +         +  +  + +  + + +  +  + + + +   + +  +      +  + +        +               +   + + + +         +   + + +  +    +    +   + + + + + +  + +  +    + + +           +      +   +     +      +           + +       + +  +  + +   +       +   +   +  + + + +  + +   +    +    + + Q8Y;T8U8T@\=S@a>_=_A[=c=dAcB^AkCnGgFfEjHhKjAkGiDuLuKtW{PrL|Q~QtVyP}UQR}RZVVYZ\^]c^_gifgjpfeljldsmlxrqrrnuspjsmqdnnfigklgf_c\\_ZYXR{X{R~UyLxOpJyKkKpAjHlAeEbA[AY;U5[9M4J3L/D+E+@);%;%1!2!1- +&#!  + + + +    +    +          + + +   +   +  +    + +   +  +    + + +    +  + +    +      +  +  + +  +  +  +   + +  +    + +   + +  +  +              + + +  +        + + + +     +  +   +  + +  +  + +  +  +          + +      +        +  +  + + + +  +  + +   + + + + + +   +             + +   +     +     +    +        + +              +      + + +     +                + +  + +  + + +    + +  + +  +  + + + +  +  +    +     +   +              +    +  +  + + +      +       +  + + +  + +       +    +  +  + +  +   +  + + + +         +  +  + + +   +      + 3X5Y5X0X8U5Y1Y:[9_8]9];a:[7a8g?c;e>mAbDpHjApBoAqDnAy@qEuJrH|HwJwK|L{HzIMKORKUQRUXVU_YZ[\_^]a[efdfjdhbbgcbdfebdd]i_`c_f\[ZS[X\VRSVG}KyKzItGoIpCoAo@mAm@kAa<`:_8^7[-Y0S2L-O,I)H)C%>$9"4 2#1")')&!    +  +      +  + + +  + + +  +   +   + +      +   +    + +  +  +  + + + +     + +  + +    +   +       +   +       + +  +         + +       +  +   +  +       + +   + + + +  + +  +   +       + +  +  +    + +  +  +           +    + + +        + +     +   + + + +   + +  + +   + +  + +    +   + + +       +        +        +   +      + +   + +     +   +      +  +   + + + +  + + +         +   + + +  +  +    +        +  +     +  +   + + +  +  + +           + +   + + + +   +  + + + + +     +            + +    +    +       + +     + +  + +        +  + +   +  +   +     +    +  +   +  +  +  +   + + +     +  +   + + + +   + +  +     V;S;Z;X?U<_@Y@a>Y;]@YAc?e@c?aEcAaEmHfEeFgHjGpGsNpIoNmKrJtMxPzMvVW{Z{WU\UWVT_X^bc[fbfbeklitkokplsstswtuqqjypntjffjliigfbde_\`^]_SX}VzQyKvOtNuJtLnClCjHkCdCaC^>WAX;U;O1R5J4H0E-A,?*>&5 6".-+"""  +  + +  +     +          +    +  +     + +    +  +        +    +    + +  +         +      + +   +     +       +    +    +   + + + + +   +   +  + +    +      + +  +    +  +      +  +  +  +  + +           + +  +      +     +  +    + +  + +  + +   +  + + + + +  + +   + + +  +  +      +      +           +         + +       + +  +  +    +       +     +         +   +   + +     + +     +        + +    +   + + + + + +  + +                     +   + +   + +  + + + +     +        +   +     +  +  + +      +  +  + +  +    +   + +         +    + + + + + +3S3U7X1U7\8\7W6_6U=Z;[:a:e>c:f@b?f>f=nAoBi>k@lCm'>%:#3 22*-$%! +  +   + +  + + + +  +     + +   +  + + +    +       + +   +    +  +   +      + +  + +    +     +    + +  + +         + +   + +   +  + + +  +   +        + + +   +      +       +  +     + + +  +    +    +    +      +   +   +  +       +  + +  + + + +   + + + + +   + + +  +  + + + +    + + + + + +             +  +      +                  + +  + +  + + +  + +  +         +       +     + +          +   +      +      +  +       +  +  +   +  +   +      + +      +    + +      +    +   +   + + +   +    +  +    +     +   + + +   + + + + +    +    +       +        + +    +   +  +  +  +   + +   +   +   +   +  P9U^BeA]@bC\F_GbAaGeHlDeEhGiDnLpJpHnMqMmNyRnMMwPvSyU}TyWSVX]Y]]XW][df]bihfgfkmnljn|tqpssptonowqpkoookhnfldbc`d^__[]VXQ~JzRtNpMsCwCiLgCcF]@hA[;X8^>Y=N6X6J0K4E1?,>,B);&3"10+$""  + + + + + + +   + + + +    +     + + +  +  + +      + + +    +    + + + +  + + +         + +  +  +   + + +  +     +   +      + +     +  +    +       +      + +  +  +  + +  +         +  +  + + +       +   + + +    +    + +      +   +  +  +     +  +  +   +  + + +  +     +  + +        + + +  +  +  + +  +           +     +           +  +  +  +     + + + + +     + +                 +   +      + + +  +  +       +      + +  + + + + + +  + +         +    +  +   +    +    +  + +     + +       +  +   + + + + +  +        +  + +     + +    + + +  + +  + + +  +  + +  +0Q4V3X5X5]7[4Z;`8a7^7Y7\8b=f;d?f=b=f@i>j>jCiCrHrCoEpEpFqMtE|JuLyFvLH~LK{OMOV~QSPRUV[VZZV]aZclca_ikeedalihfchfaagf_gbd_[WW\][T[VUSPP~MP}LrJ~KnCsDqAlBh@c 8#2-*''"!    +       + + +  +   + + +     + + + + +   +    +     + +   +          +   +    +       + + + + + + + +        +   + + +         + + +          + + + + + +  +  +          + +  +     + + +  + +  +  + +     +  +  + + +    +  +    +     +     + +  +  +        + +   +  +   +             + + + + + +       +      +                  +   + +  +  + +  + + + +   + + +  +     +    +    +         + + +             +       +    +     +  +   +    + +   +  +    +    +   +    +   + +    +     +  +     + +  +    +    +  + + +     + +     +     +  + +   +         +  + +  + + +   +  +  + +    + +  + +   +    +   + + +   + +  +  V8T<_9Y=^>Z?\;[;fBYC\DcBiBdEeDgDdAjEiDgDeIiJlJtL{KvPsKmPzSsMRWyR{X|QUU~VYSZYZ\bhcaikimlghrnpfsrorxusuuuwqnqurqhrhn`fhggece`hab_\ZX}QLwMzMoNqHiCmEfF_C\@`Aa<_>YBV:R9Y8R6O1K3E,?-?):&:&1!0 2(%"      +  +  + +  + + +    +   +   + +  +  +      + + + +   + + +   +       +     + +  +  + + + +     +  +  +  +  + + + +    + +         +      + + +    +    +  + +        + +       +  +  +  + +   + + + +   + +  +    +  +  + +   + +   +       +   +   +   +   +  + +  + + +  + + +    +                  +      + + + + + +   + + +  +                 +      +  + +   +   +      +  +   + + +  + + + +        + +  + + +  +   + +       + +  +   +  +    +  +  +   +      +  +  + + + +    +           +   + +  + + + +      +     +    + + +   + + +   + + + + +  +  +  + +  +   + + + +  + 2P2S6T3W4[6Z4_5\5c7U7d7e>d:c9f9b>g=pCg@m?lGi=uCkGkCxHoFwEsF{KuH}D|C~IxLOL~OJPSTSRQ[WYWV[\Vbe^_e`gidehiai^f_bkchf`^Ve`Z_\bWY[\YWWLQLOTzKJsCuJqAqCq@a;`>d=b:X;Z4Z5T4Q2R0X,O.N,F&C(>#>!5%5!21+##!  +  + +    + +  +   + + + + + + + + + +   +    + + + + + +   + +  +         +  + + +    +   +     +  +    +    +    +  +   + +  + + + + +   +      +      + + +  + + + + + + +   + +  +   + + +     +   +   + + +  + + +   + + +    +   + + +        + +    + +  + +         +  +  +   +       +  +    + +      + +  + + +   + + +     +            + +      +     +     + + +    +    +      +  +         +       +    +     + +  + +    +  + + +    +   + + +   +  +  +   +       +      +          + +     + +     + + + + + +        + +  +   + + +  + + +  +     +    + + +  + + +         +  + +    +   +   +     + + +  +  +  T:V:[@W=X:[=X8^<^@aBbA_?c?aCcDeH`GfJfFdKiPrLhQqJyFrJoNzMqMuMwNPzR~OZUW}VZX^[X\Yafeddggijhilllosltooywuxopposnpsqjqffjh^c_^ae^_^^V[VS|QzUuLrEjDpAcGa>iAcBXBU=`>V:P5P8R8L/H0E2A/?.A(6(9$5%2+&"   +      + + +  +          +    + +   + +  +  +   + +      +     + + +     +     +        + +    +      +         +    +        + + +    +      +     +  + + +  +   +   + + + + +     +      + +  +         +   +     +    +      +    +     + +  +  + +   +     +   + + +    + +         +   +    +  +          + + + + +        + +       +   +    +   +             +  +    +  +    + + + + + +      + +   + +  +  + + +    + +  + + + +  +     +     +   + + +         +    +  +   + +   +      +      +  +      + +   + +   + + + +  + +     + + +       +  +  + +  +       + +   + +:U5W4\5]5U5[5X7\=^:a;_;__9g=c>f;e@g?kBo?oGkFpBvGxIwDuE|HxH{NyMKIPUPNKQSM[WVV[[T^Ya[^`]dgb`cjfjhbififgffdfab^bbd_ZWWXYURQTROKL~IyIIsEqFsEka<];^,<)=#4)4$/ ,'    + + +     +   +  +  +    +    +      + + +        + + + +      +   + +  + +   + +  + +    +  + +  + + +   + + + +  +    +   +      + +  +  + +  +         +    +        +    + +  + "   +   +    +  +       +  + + + +   + +       + +  +  +  + + + +         + +  + +  + +   +   +     + + +   + +   +  +    + +  + +    +  + + +      +      + +  +     +      +    +   + + +   +    + +           +      +  +  +  +        +    +    +  + + + +  +  +  + + +  +    + + +  +  +    +      +  + +  +  + + + +       +  +      + +     + + +    + +     +          +      + +     +  + + + + + +  +  +   +  + +   + + + + + + +      + +    + +  +  + +    + + + + + + + 2W3W6Z7X6X7[6^2U;e9^9]BfhAgBpCl?h>q?tAp@mDnAuCxJyH}GuP{LK}QHQT}QNRURZSSRVXVZ]V\abdbelaegfmhhfedbeddaebdceY_]\]a[]WSUWSPKOJyMKL{KvEu@lBdAe=^6_>[7U:U1X6Q.P-L.M'G*K&I)B#=%A$9$7"9!6-%  + +  +  +   + +    + + + + + + + + +  +     + + + + +  + + +  +   +           +    + +   + +  +   + +      +   + + +    +  +     +  +  + + +  + +    + +  +    +    +   +  +  +  + +      +     + + +   +   +   +    + +     + + +  + + + + +   + +   +   + + + +   +     +    +  +   +   + + + +      +  + +   +  +  +   +    +  +  +   +         +   +         +     +    + + +  + +   +  +   + +   +   +         +  + +   +      + + + +           +  +  + +   + +    +  +    +   +   + +    + + + + +   +    + +     +  + +  +   +   + + +         +     + +   +         +    + +  + + + +         +     +   + +  +  + + +  + +    +  +  +  +  +    + +  +  +  +   T8Y9W:[?Y;b`C^?W;Z3S7R6P2O0I/F.C,@-A+;,8&;&<'3#/+'#!   + +    +      + + +   + + +     +  + +         +     + +  + + + +   +     +  + +    +     +  +   + + +  + + +   +   +   +     +        +   +   +   + +  + + +   +  +   +    + +  + +        +     + + + +  +  +  + +      + + + +   + + +     +   +    +  + +      +   +  +          + + + +  +    +     +      +       + + +      +     +   +     + +    + +   +   + +   + +             +     + +      +      + + + + +       +           + +   + +  + + + + +  +       +  +  +  +  +  +   + + + + +  +    +   +         + +   +      + + +       +  + + +  + + +    +      +  +  +  + + +   + + +  + + +3S3X5Z5T5a9Y;\8a6^7b9^9c5i5i?d@k@j_4V6]:Q4W4S4O0I-G0H(G(B)A&?$;$=!=!64/$$#  + + + +  +  +  +  +  + +  + + + + + + + +  +  +   + + + + + +  + +           + +  + +  +   + + +        +    +  +      + + +   + + + +     + +      +  +   + +  +  +  +    +  +    +  +   + + + +  +     + + +  +  +   +  + + + + +   +   +     +  +  +  + +     +  + + +   +  +      + + +     +   +       +   + + +  +  +   +     +  +  +   +   + +         +      +    + + + +  +        + +        + +          +        +  +   + +  +       + + +  +   +     +       +   + + +    +   +   + +     + +   + + +  +  +    + +              + + +  + +      + +  +   + +   +           +   +             + +   + + +   + +  +      +  +  +  + + +    + +  + + +       + +    +  +    +   + +   + +   +    +  +  U;P8R8\?[@eAZBX?]DZ?\A\>_D\BdJcBgCkFqIgHlJsKmIkImFtMrLsMzNtS|NRW~XVRY[W_^f_ca^_chighggnplmqvnpryssgnlnoixhonjnnoimgbcibe]c^]aYZVyUO{StLuJqJnNlFl?aCa?VAZ8S9R6T7Q3H5M1G.C.F-A(B):)7,:*3&: 1$-"((!   +  + +     +  +   + +      +    +  +      +        + + + + +  + +      + +  +   +   + + +  +  +    + + +   +  +  +       +   +   +    +     +     +    +                  +   + +   +  + + + + +  + + + + +   + +  + +  + + +  +   + + + +   +  +   +  +  + +     + +   +    +  +    +   + + +  +   +  +  + + +   +   +   +       + +  + +       +       +  + +  +   + +   +  +  +  +                 +   +         +  + +  + + + +    + +      +  +  + +   + +  +        +  + + +  + + + + + + + + +   + +   +    + +       +    + +  +         + +    +  +    +       +  +   + + + + +         + + +   +   +  +  +     +  2S4U2_7X7[5]:Y4]5^<_;]7a8ca@i?b?l?fCn?sCsGoBwHm?sHvAvDrBwJ|J{KyIO{KIMROWVTXRYVXV[Y]]\cdaf`afn`iihkhdhgkce`ibe`f]a]\^\[\WVPVUPQQzS|L{KwJxEqHtEsCm;c?b=j=[;Y6Y4W2R/I.N+C-C*D(C+A!>#>!; 6"500.'%"!   +  +   + + +   +   + + +   + + + + + + +  + +  +  + + + +  +    +           + +     +  +  +   +  +   + +  +  + +  +  +  + + +    +  + +          +  + + + +  + + + +     + + +  +  +     + +     +    +      + +  + + +     +  + + + + +  +     + + +  + + +     +    + + +    +   + +   + + +  +   +    +  +   + +  + + + +  +      +  + +               +   +       +         + + +  +     + +         + +   +      +   +  +   +    +  +       +  +   +  + + + +  + + +   +          +  + +    +       +  +      + + + +   +     +      +   + +  +     + +       +  + +         + +  +        + +  +     +    +    +   +   + +   +   + + + + + +     +  + + +   +  + +   + + Y;W;S9W;^>_@[;Z=`?W<^FXH`FcDcCeHiHkFgEkLiJiIoMmMxLwQwRrQrOzWvS|QzSVXM\ZY[X_\^\dfd^bgcplhgkptomwtuvzzytpvrunsmjrmpnqnhiffana`\\UTZVT{SRqOrHoLkFjGrCa?\;[<\@S4T5O8N0H4L0J,<&B,B+:-:'7&7(6$/#/#-+%!  +  +       +  +  +   + + + +    +  +  +               +  +   +   + +  + +  + + + +   +  +  +  +  +   + + +  +    + + + +    + +      +  +    +        + +     +                  + +      + +       +   + + +    + + +    + +  +  + +    +      +       +    + +   +     +  +    +  + +  +         + + + +        +   +   +      +  +  +  +  +   + + +    + + +   +     + + +    +                 + + +    +     + + +   +  +  +    + + + +  +       +  +         + + +  + + +  + +  + +  + + + + + + +  +          +     +    +         +      +      + + +  +  +  + +  +   +  +   +   + +   + + +   +  +    + + + +  +  +     + 1Y0V5W6\6`8]9U7c:^:a?^9g:f?_@`Ai=m;g@h;lAm@qCmBrBsIuEvHwEuL{EtJyL~ILLKOSQUUSSTXUVSU[__X\bfabgkagbimgoklgjgcgbace^c[^_a]`\WZPR[QQNMM|L{JvDpCtFpEe=c@h(;%=$9#9"8333,-+%   +  + +       +   +   +    + +  +   + + + +    + +  + + + +  + +  +  +  + + +   + +  +  + + + +  +   +      + +    + + +  + +     +  + +          +  +  +  + + +    + +    +  + +    +      +  +  +     +   +  +     +    + +           + + +    +  +  +  +          +  +  + +   +  +    + + +  + + + + +      + +   +          + +  +  +             +   +         + +     + +   + +  +           + +    + +  +   +  + +  +    +            +   +   +  +  +  + + + + +   +    +  + +  +   +  +     +  +  +   +  +   +     +  +   + +   + +  +  + +   +  +    +  + +         + +    +  +   + +         + +      +  + + +  + + + + +  + +   + +      +   +   +  + P7Z:V=Wd=f;b=eg@n>p=l?lCqDtGr@sDmDtIwL|K}KOKQHNMOSSOVXUZXVZXW\\_^b^djggdfqggmenliigcjj]ghd_Zbcb^Z`WVXUVPPQKzMyLHzIwKtCmEd@c=j<`:b:[:`4T1Q.O.K-C+E)B'@$=%8'<7!471/.)&("# !    + + + + +   +   + +  + +  + + + + + + + + + + +  + + + + + + +   + + + +  + +    +  +  +     +   +   + +   +   + +   + +  +   + + +        +        +  +     +     + + + +  + +       +        +      +  +    +   + +     + +   +   +    +      + + + +        +   +   + +     + + + +    + +     +  + +  +  +           +  +  +                  +    + + + +  +  +  +      +  +   + +  + +    + +       +  + +    + + + +         +  +  +  +        +  + + + + + +   + +           +         +    +       + +   +    +      +  + +  + +     + +    +   +        + +   +     + +  +       + +     +      + + + +      +  + + + +  + +  + + +   + + +   +  + + + T8T:T8S:W8WAY@Z?]C_EaAdAa?`GgEeIiFiIdCmJoHiKlKpOrJrHrIkMzW|T}TY{QWQ}SXZXZX\Xb[`fjnhohnelojvukottzsutyynxwjrmomnljkqofljb``f[]c]RY~PV|O}QyIwMrGrCiJdFb@bCW:V9R8Z5N2E2G.I2B*>+;)?&6)6'9$8#/ -. +++&#" +     +  +       + + +   +              +    + + +  + +     +   +     +        + + +   +     + +   +       +   +  +          + +  + +  +         +         +  +  +     + + +  + + +   +  +  + + +     +   +  + + +  + +   + +               + + +  +    +  +    +     + + + +   + + +   + +                                   +  +    +   + +  + +   + + +       + +           +  + +  +  +  + +   + +   +  +   + +  +  + + +  + +   +  + +       +  + +  +              +  + + + + +   +    + +    + + +  +  +  + + +    +   + +        +        +  +  +   +  + +    + +       + + +      + +   +    +  + +  + + +   + + + + +   + + + + + +  + +  + +  8S4Z3Y5U4Z:]6a6_=`7b;a>_<]=a>jc7Z7_7Y1T-P.K3K-I,F&B&@&8":$7$4"21--+-*#)#"   + + +  + + + +  + + + + + +  + + +  + + + + + + + +  +      + + +    + +  +     + +      +     + + +  +        +   + +  + +  +   + + + + + +  +    + +  +       + +    +  +   +  +       +    +   +     + +  +   +  + + +   + + + +    +     +  + +       +  +  +      +  +      +   +  + + +  +     +   +    + + +    +          +                +     + +  + + +  +   +     +   +   +        +   +      +  +        + +   +  +  +   +      +   +  + + +  + + +  + + +   + + +   +  +    +     + + +  +   +     +  +            +  +  + +   + + +   + +  +  +   + +    +      +    + + +     +   + +   + +           +     +         +  +  + +      +  + +  + +  +   + + + +R8Z?W`AaAb@W?_>`CaA_D_DaDgE]IdDmGiGlIsGmInIsQoLpOvPxWyMVzSQ}U}XYUZYX[^_\]Zdidhhedllllnxrptvvy{z}|yquvtosntrpljkjclaffb`fc[W]W~RvPxSwNrHsFrJkFk=g=_?X:S9R3U4O4N2G6D0G.=(=(@$:&72!2%0!/#.,&*%#"       +  +    + + +  +         +  +       + +     + + +  +  +  + +   + + +       + + +  + +     + + + +  +      +     + +  +   + + +                + + +  + +  +    + + + + +           +    + +  +  +     + + +   +         +           + + +   +    +   +    + +    +        +               +  +       +  +  + +     +      +     +            +   + + +   +     + +  +    +      + + +  +      +     +       + +  +  + +  + +  +  +   + + + +   + +        + +  +     + +       + +    + +    + +  + +  + + +      +    +  +  + +    + + +    +   + + +    + +       +  +    + + + + +7S3]4X4T4_6^;]6e7]7a7`6a;e=j:d:f:k=d>nBi@gBrAnEtGtHvEuFtJ{GF{K{N|K~JOIUTQQRUUS\YZ`X^_Waaeeahfdjdfhhokpjdhhdh][bbjeh`c_]^bY]TWTSQTMM|NvI}GqEnEmBk>j?b6^8`=^4X1P3O0M3M,I-D*B'@(>'8#: 7 0*+0)$&$$   + + +     + +    +   +  + +  + + + +  + +  +  +      +  +  +          + +     +   +     + +    +   +     +     + + + + + +              + +   +  + +  +    +   + +       +  +     + +    +       +  + + + +  +  + +   +    + +      +   +   +  +     +       + +    + +   +   +  +     +  +  + +    +      +  +      + +   +         +        + + +    +  +    + + +  +   + +    +  +     +       +     +         + + +  +        +  +     +  +  + +   + +     +  + +  +   +  +    +  + + + +         +     + +      + +    + + + + +  +  +   +       +   + + +  + +    + + + +  + + + +       + + +    + +     + +   + + +   +  + +        +    + +  + + W=U\=Z@[;a@a?`=[B_Bd=]BjD_FhEhDjGfMlJnFjHqDrKqJ{MuQyM|PtUuRSYTYUV|\_Y[aa`ccccfkdoennlmqtrnuv{vttpoulxpnnpxsolfmjlhbmhg`a^Y\[VOyTtSuOqKrKpEdHk@a?\@\=`?Y>S9K3O5I0G-B,<(?&<(9'7&/&4 /.$*)%"!!     +  + + +  + +  +   + + + +  +        + + + + +  + + +   + + +   +   + + +  +    +  +       + +  + + + + + + + +   +   + +    + +  + +   + +  +           +        +  + +   +    +   +     + +   + + +   + +      +  +     + + +    + + +    +  + +   + +  +  +  +  + + +    +   +  +   +        + +         + +         +  +         +      +  + +          + +              +             + + + +  + + + + + +  +  + +     +     + +  +  + +     +  + +      + + +   +   +  + + + + + + +   + + + + +   +  + +   +     +          +         +    +  +      + + + +       +   + +   + +  +  +  +   + +   + +  +    +  + + +  + + + 1M2Z7X2^5]6^8[;b8Y=`7b;i:f:c>e?h=i:jAiEiBlEnCyEmBrGtEuEsI|FzG{F~K~F~P|MNQOQRSSUW\W]Z[U]]`c\hicdfffinkpiqlkhhdafjdebaccd\Y^][YW\XXUSLPJvH|IsFoDmBmFh?a;b8`9[5^6[5Q.O2K*F.I*>'B&<&='<"8!21-,)%"!  + + +   + + +    +  +    + + +  + + +  +  +  + + +     +   +  +       + + + + +  + +     + +   + +   +   +  +  + + + +   + +   + +      +       +      + + + +  +  +   +   +    + + + +  + +       + + + +    + +  +  + +    +   +     + +  +     +   +   +  +   +      +   +      +      +  +   +   + + +  + + + + +    +  +     +    +    + +  +  +             +  +  +   +   + +  +  + +       +    +     +    +      +  +  +   +  +  +  +  + +      + + +  + + +        +    + + +  + + +   +  + +     + + + + + + + + +   + +        +     +        + +      +  +   +   +      + +     +   +  + +  +  + +   +  + +      +     + +      + +   + +   +  +  + +  +   +      +   + + + +    +   +SZ=]>^=]Z9fGYFcGcBfCaFkDdJiFnHfKmCqJmKqLjQxRvP{LyP|NyP}RVVP}ZWaY`]Z]aecggfgjqmtkpiqxqrtstxuyuuytptsqrolsrlgkojkhe`h]abaW_PRSwOyOuKlIkImCrKZ@aAZ>`=X:V7L5Q8M/I5B,=(B(9+<#8'2%5!1&-+((#!          + +  +      + + + +             + + + + + +  +  +    +   +     + +   +     +   +   + + + +  +         + + +       +    + +    +  +     + + +   +   +  +   + + + + +    +  + + +       +  +    +      +   +    +     +  + +     + + +   + +     + + +    +     +  + +   + +         +    +  +   + + +    + +       +  + + + + + +  +   +  + +   +                   +  +  +  + +    +        +       +  +   +   +    +   + +  +       +   +      +  +  + +  + + + + + + +  + + + +     +    + +      + +   + + +   +     + + +   +   +  +   + + +         + +     +     + + +  +  +  +   +    + +   1S1V3Z7\4^5_2`:\7\5d;_>f=c;e;e=hBjm@oEuCpEtEpDmCvItDzHxI{KKLzO~LJQPPPXTRYZUXZW_]^bgbcblcggjhiiaamtgkpepejchdifcg\b`ZX\\XVXYUSWSLM}JnGkGqDn?g]6[7S4T4L1I0I*E*B';)9 9$7"<3271*&!#     +      +  +       + + + +   + + +  + +   + + +       +  + + +  + +   + +   + +   + +  + + + +  +         + + +  + + + +   + +  + +  + +  +       +   +  +      + +     + + + + +  + +  +    + + + + + + +   + +   +  +   +  +  +  +    +    + +   +  + + + +  +   +  + +  +       +  +      + + +  + + + + + +   +  + +     + +  + + +  +     + +    +  +        +  + +              +     +  +  +  +  +     +    +   +  +                 +      +      +  +   +  +  +   +   +  + +   + +    +  + + + +  +               + +       +                     +    + +             + + +    +    + +   +      +   +     + +    +   + +  +  +  +   + +  +    + +   + + +  +  +    + + +      +Xb<\A^Aa>^9b>cChDdEjFcGiFlGjLhKgMpLuGrImPxOsJtMyL}TvTwUPVV~V|Wc\^Y][ccc^clgbsnhopqolkssoxysv{rvruvrxrmkpolknlplfd_be[b_\\WTVyP~RxIsJqFkHk@aD_@a=V@T5T9R3L/L0G1D,E*9(>%5(6"2$1"1"..+'#!!      +       + +    + + + + +   +     +  + +    +  + +        + + + + +  + +         +  + +  +          +      + +  +   + +   +   +   + +     +  +  +      +  + +  +  + +    + +  +     +  + + + +   + +   +  +   +     + +   +   +  +    +   + +        + + + +   +  +    + +  +  +                       +   + +  +   +  +  + + +  +  +        + +         + +    +  +  +  +      +  +   + + + +   + + + +   + +  +  + +   +            + +  + + + + + + + + +  +   +   +        +         +    +  +     +  + +   + + +       + +  + +       + +  + +  +   +  +   + +        + + +  5]2V0Z6Z;\5[6^:^;\=b8`>f;hYc>^<[E^@`C`@bC_>eGdHfDeEjKhHjLpJxIhNuMqM|SuNuM|RR}XT~]}WXZV]d`]_bcbdjfbcengcliunptxyvtp|wpwswu|nnyutkknkphnhibaf`ZY^YZ]UU{QtLrNoMpDdHfL]>]D]=S8Y6UV@Y=X>`=]:_@ZAg@jBe?fFaDhGdHkFrImHrIiGrKnMuOpJvMuJyKwJZyXyTTZUzZV\[\aa\_cddcihciimornxupvuswuxvxyzxrsvxnnqhpoqnomhklcdb^]\\^YXRxS~UzQ{MqMmBmA`@^<\E]9X6V:R5N3J3M5E0D'>,:&3&5#2%.+*&# ##            + +     +   + + + +   +    +  +     +  + +         + +  + + + +   +   +  + +       +      +        +   +  + +  +  + +  +    +         +  + + +  + +  +       +  +  +    +         + +   +  +  + + +  +          +      + +    +  + +     +  +    + +   +        +     +       + +  + +  +    +  +     + + +                  +  +  + +        +   + +      +  +  + +  + +      +  + + + +  + + + +  + +  + +  +  +  +    +  +      + +     + +            + +   +     +  + +         + +   + + +   + +   +  + + + +  +  +  + + + +  +     +   +3V2W:\4\:Z5_8\:d;ch:e>k@iiBsCoCyG{BxH}D}K{IF~HL{OMNN{NNVURTXWU^[^Yac^be_hhjhhiognllglfgmhfbnifdmegb`gai``_]UW[VQRzW~L|K|JzIxOtHlHfCdAd?b;b9T4U5R0P2O/J,C,B*A*>$:#;#3-1*)#! !!   +  +   +    + + + + +  +  +  +  + + + +  +   +    + +     +  +     + + + + + +   +  +  +    +       +       + + +        +   + + + + +  +  +  + + +    +  +     +     + + +  +        +       +      +  +      +   +  +  +  + + +   +   + + +     + +     +        +                        +      +     + +   + +                       +   +  +  + + +  + +           +   + + + +   +  + +  + + +  +     +   +  +   +   +                        +   +  + +  +  + +    + + +  +        + +   +       + +             + +   +   +       + + +  + + + + +    +     + +  +   W?S=U?[8UA\A]=`C^Ff>cDdAeAeCfAhDkHvFoDrJmHmHoIvMuHkQvPyQxT~Q}QNTW]WY[Z^`]]edf^albgfjqjrxtquut{srorz{|tyxuttrxtpnxkpiklfge_c[bZWZ~RX~N~LyNtMtKpDmLfDe>aB_@X6U6K3O6L/J.G-G.>)?*9%;$1 3!**%"        +       +    + + + +  +  +    +      +       +      + +           + +     + +     + +  +  +  +  +    + + +     + +  +         + +      + +  +   + +     +    +  +   + + + +     + + + + + +  +    +   + +            +                +     +  + +  +          +   +     +     +   +     + +  + +   +      +  +    + + +    + +   +  + +     + +  + +  +  +  + + +   + + + + +     + +   + +  +     +        +  + +  +    +       +     + +      +   +      +    +       + +   +   + + +    +  + +  + +   + 6W4Y6_6T9V6\mj>e);'5'3 11 ++'!     +   +       +   +   +   +     +  + +   +  + +    +      + +   + +    +        +    +   + +            +                    + +     +  + +      +    +  + + +   +    + + +       +     +     + +  +   +        + +   +   +     + + +    +        +          +                  +  +   + + +  +       +    +       +   +  +       +  +  +       +  +  +  +     +   + + +  +  + + +  +   +  +    +  +   +  +              +  +  +     +  +  + + +  +   +                 + +  + + +    +       +  + + +  +     +  +  +   + + + +    + +   +  +   + + +        + + Y9W@Z=_6]:aD`@fA[@bBh@_Gh?dFkKlHiHiFlGpFpKtLqIoPvQ{QwP{VySX|QU^ZZ\WZ^^Y_^ahggfjjgimuontqxvxvwwu{zwo{vzstrqpssmhmrpilsfjgch^Y\[VWVT{RuOrJqMjHpIhCeFb>bBe=S>[7V6R/L-D)C-=(=.;'9#23/, ('    + +              + +    +  + + +  +                 + +      +            +   +  +    + + +        + +   + + +  +   +    +              +  + +   +    +  +  +   + +  +  + +    +  +   +  + +     +           + +   + +           +        +  +        +            +      +            +     +  +  +  + +   +   +   + + +  + +   +   +   +  +  + + + +     + + + + +  + +  +   + + +   + + + +    + +     + +  +      +             + +     +           +  +  +   + +    + +  + +       + + +   + +     + +  +7a;Y6Y8[5]4c6\7^9_9a8a8geAp=l?q@oCtAsDxDyHrK|H}NyJI{OLNMNMSPUVXOZXZ[[c\b^]b^`c`hjjfnjjqnkpqjqhikqhgfljcchdkdd[^`__RRXPPONIyKvHoFp@gCmBp@m=b6b9[5Y4W7U4S/M+E+?(E&?%9$5"2.)(#   +       +  +  +  +     +  + +       +   + +  + +       +    +    + +  +  +  +        +      +   +   +  + +   +  +  +    +   + +  +  +   +       +     +     +       + +  +  +  + +     +  +  + +    + +   + + + + +  + +           + +    +       +  +   +         +  + +        +   +  + +   +       +             + + + +  +        + + +   + + + +   +  + +    + + +   +    + + + +   + +    +      +          +    + +     +    + + +                 + + +      + +   +  +    + + + + + + + +  + + +   +  + + +     + +      + + + + + +  + W;_9Z9X>Y>\B_D^>b?cFdBmEiBkHkCnPiJhGpOpHsJvRmRxOqPxOyPsRxX|S}Y|T{XzRWZY]]]_`[eb^b`kjckrjuottpyqtwvv|yz}zzzstxsvyqtrimpoljiakcbb[]XWXV~QUzPtLpMlMsFnEfAdCf=W=U;\%<'='41.+(#!   + +  +    +           +           +   +  +                        +  +    + +   + + +    + + +       +  +      +      +      +        +   +    + + + + +  + + +  + + + +     +        + +    +          +      +            +  +  +     +  + +   +   +    +  +    +      + + +   + +   + +  +  + +     + +     + +  + +            +  + +  + + + +  +     + + + +      +   + +  +         +  +  +             +     +        +      + + +        +   + +   + + +    +  +   + +   2X4Y6]:a8a;Y7`:b6fk_?^=[C_A^@dC^?cCbAgBgClDjGgEdJqIpHrGnHsMsMvM{NwQzOyT~PPyYW~XX]`S_\a`b`ah`hidkmoosrvvqrr~|ww~wy~~w{ywyvwvwvtropoiljgbjff`bdZ_^O~R{W~N{OzMrMkFjAf`GaJmFlGfBkDqNjHlJjLsKpJuQrP{NwLyO{UT~SSzSV}R|Z[WY[]V\c`de`fldpllmmruzsuwsr|}wvuyyytvt~w{usqsutolnibf`bb_cc`YVQwVOSyQwDsFuMqIgDdC\C^>`8R8R6M5H6H0H.C/:,A+@&;$7#5!3*'!!   +  + + +  + +     + +     +  + +            +    + +   +  + + +   +    +   +    +     +     +   +  + +         +      +  +    +  +   +  +  + +    + + +   + + +  +      +   + + +     +    +           + +            + +  + +    +     +     +   + +              +      + +   +    + + + +     + +  +  + +  +  +              +    +  + + + + + +          +  + + +  +  +    + +  +                 +           + +  +   +  + + +  +    +  +  +  +  +      + + + + 3]6_7_8c8b8c6c:a9_9a8b@e:h=fg>d>b?d4]8Y4X4W3N0I/J*F(A(B'<#9%8!4/"1,+ "    + + +       +  + + + +   +  +          + +    +  +  +     + +    + +        +           +  +    +  +  + +         +       +  +     + +   +   +  +       +  +  +   + + + + +  +  + + +   + +    +  + +       +         +    +    +  +         +    + + +       + +     + + +       +   +           +   +           +   +   + +  +    +      + +       +  + +   +      +  + +   +      + +           +       + + + +          +    +          +  +     + +     +  +  + + +  +  +   +    + +  +   +    + +    +     +  + T<^@[>]@XAaEf=l@`DiCeGlFlGfBiEqJpKuJmJnMsJmQtKwSyPwPzQyW}S\ySSY]]^_Yacca_cjcdidnasrpmosrrvz{v{~uw~y|x~sywxrlwyroqkfodkff`e_``\TUS{V}JwJnLnJmIhEa?aCZ:Z8V6Q6R3O3L2N3B)?)>*>(9"8!5 1!0,)'        +  + +   + +  +     +           +     +    +          +  + +  +     + + +        + +     + +   +    +    + + +     +  +  +   + +  +       + + + + + + +  +      + +              +  +                  +         +    +   +     +   + + + + +   +       + +     +   +      + + +  + + + +  +  + +   +      + +        +    +  + + + +  +       +  + +  + + + +   +    + + +                +    +   +  +    +   +  + +      + +    +  + + + + + +   +  +  + + + +   + + + +  +3X6Y;[8[;_4d9d<`;a>h9kAh7i@kFjAl@oDk?uGpBuErFqCtDyLvLxGH~POKOPPT\VPRXY]WY[_\bbb`bchdnehhrenslhgqnmpmmsphhlojhngfkbdebc_S[[YXORS|PPsN{NrCvJsDdBkAf@a8Y<[:W2P5O/K.P/D+D.A)C'8%7 :#30.*+%%!       +  +   + + +    +   +   +  +                        +   + +  +    + + + + +   +     + + + + +  +     +  +   +           +   + +   +  +    + +  +   + + +    + +  + +      +   +  + + + +  +       + + +  +         +        +               +  +      + +    + +      +        +      +   +      + +  + + +      + + + +   + + +  + +   + +  +  + +           +  +  + +   +      +    +  +     +   + + +         +    +     +  +    +      +   +          + +      + +    +        +  + + +  +  +  +   +  + + +     + + +   + +   + +  + + + +  + + + ]>Z?cB]@aC_=hD^AeDgJfHeBiIfK`JlKgHrLgItNiHuLvO~MuPwNxP{R[UWU[S[T\`Z_ac\`fdgj`jiitnmtwyrwtt|zzw{y|wy~qxux|svrqojpjbfkf^gd[\TVWS}R{NuK{JlIqDoFhFeG\=]iDjBe9]=a9Z5Y7Y5U0K0M+F)D*B&>&;#9"1 -.*&# !   +   + +    +   +    +   + + +  +     +     + +  +   +       + +            + +  +         +  +  +  +   +     +   +          +  +    +  + + +  + +  + +   +  + +  +  + + + + + + + +         +  +         +     +          +         + +  +    +              + +    +     + + +     +  +   +     +   +  +   + + +  +   + +    +  +  + +     + + + +  + +  +    + + + + +                + +    + +   +  +  +   +  + +       +               + +  + +  + + + +  +   +  +      +  + + +   + + +  +   + + + +  +     +]:Z?]i<[6`>e>k?j=iDeDnEmEoAkAoAvDoE}DuHJ}I|GK}OOPRONOSXRU[ZZ\_WY]\badgebejpfhnpnxtqorsmvomnmpqkkqlkdhhkh\hiab][XXZWPPQzK}IuGuJuClGoDf@cZ;\=b;cm=i=iBnGnDp=pHsIlIrIxJwH}J}ON~MHNOQLNRVTWZ^RV\_\a\^b_fddfemiojgfjmrsjrjnqrnklnxhkkfgienhbe_d`^^YWWPNRQ|HFsHrGnGlDl>g@d6a9^8d6Y2W2R1O/K/G0I-F':$95"30+(#'      +      +     + + +         + +            +      + + +   + +  + + +  +   +  +  +    +  +  +    +   +   +   +    +    +      +  +    + + + + + +  +  +   +      + + + + + +                       +  +  +        +  +           +    +      +     +     +   +           +       +   +    + +  +    +    +  +    +    + + + +     +   + +  +     +           + +    +    +  +   + + +  +  + + + +      +  +   +   + + +   + + +               +        + +     +    +   +      + + + + +  + +  +  + + +  +     +  + +     +  + + ^:ZAZ?\>\A^EbB]Dc@dF`FiDeIlGmIpMoJwKnGrNxKuHnM}N{UyUxT{R|TYRQY^`Y\`_b`Y_ebbjdjokknqmuszt}vx|zv|wŁ~vxz{rsrtovwuqllignkgf`__`a\XR{SzR{OnOnLrFoKhE_C_@bS5O6K1M/E+F)A,;$7&4"6 .*,*#   +   + + + + + +       +    +     +     +                     +  +           +    +     + + + + +      +  +  + +  +  +  + + +        +   + +     +         +                     +      + +   + +                + +      +      + +   +   +  +  +   +    +  +   +  + +    +  + +     +  +   + + +   +   +       + + +  +  +  + +  + +        + +            + + +     +  + +   +    +  + + +       + + + +      + + + + + + +      +   + + 7a5[7Y:^<`;g9e7k9l8csBpCnAl@sIsCtGsEsC{KyJ{G~KMQNRRTSSWXZUTWT]c_c\c_fZebdigrnqnnpohrttzpvljmsmcipqiobifg]^b[aZ\XX^VXSIK~IvOvHwDpGmAe?c?b;YaAaAeCiMhAfCjHdDqHlHjKjKhJqHqJrHwQxLvSwTQzYQ~VVYYWWV]V\Y^jhe_gmdfijfmsloyvzsxy|{yz|}{|z|v{uxptutmtvprqndlkgh^]XX[YMWxQyOuMr@kEqEhCdAb?]9Z(8'7%8"2 1.(&$   + +   +   + +          + +    +         + +   +             + + +   +          +           +      +  + +       +     +   +  +    +  +    + +  + + + + +                       +      +    +    +        + +   +   +        +     + +     +   +  + +  +  +     + +   + +   +     +         +    + + +  +  +              +  + + +    +  +   + +     +              + +         +   + + + +  + +   +  + + +   +   +  + + + +          +   +6]8^7e6`:b;b;j9c;l=e<_?k=kn;c8_9[4W7V0S,O0M2E+G)D+>%9%6'4"*/))%!  +  +     + + + +             + +  +                      + + + + + + + + + +  + + + + +   +   +  +  +      +    + + +   +          + +   +    + +  + + +  + +   +  + + +    + + + +   + + + +    +      + +               +      +            +   + +   +    + +    +         +     +      +    +  + +  +      +   +  + + + +   +  + +   +   + + +  +         +         +  + + +  +  + +  +  +   + + +   +  + +  + + +     + +  + +      +      +  +                 + + +    +  +     + +   +    +  + + +  + +  +  +    +   + +     +      + + + +^>a=]>a@aAf?f?bGi?lA`DcGjIsHiKgJoJpKsHtPtNyQuOtNuM}V~ROV}V}WUZYX^\^d^deckdinggooojmnopsyr~~z|w|~xvs~zvxpsnlllmjkgdc_fa]XWYTUQ{SzNpKoMqGjAkA[Cc=X9\7\9O3Q2N.C-I*>(:(=&7!3!1*(("   + + + + +      + +  +        +    +      +       + +   +                 +    + +               +          + + +     +   + +     +     + +  + +  +    + +   +  +   +  + +      +   +     +      +      +   +   +          +  +  +      + +  +   + +   +       + +   + +     +   +   + + +  +     + + + +  +  + + + + + + + + +    +  +  +   +  +  +              + + +        +    + +       +                 +      +    + +  + +    + +   +   + + + + + +   + +  + +    +  +   +   + + + + +  5X9^9d8];f7dg:jjBjk>c=`8d9W:V6T9R0L4H/K,A,B$<&<&;"643("&"    +         +      +  +  +  +   +               +   + +  + +  + + +  + + +  + + + +   +    +     +  +       +  +   +    + +   + +  + +  + + + +        +   +   +  + +  + +       +  +   +      +   +    +   +      + +      + +     + +    + +       + +    +  + + + + + +       + +          + +  +  + +      + +    + +    + + + + +   +  + +          + + +        +  +  +   + + +    + +  + + +  + +  +      +   + + +      +     + + +  +           +        +        +  + + + +    +  +   + +  +   + + + + + + +     + +  + + +     +  X>]C\=j?Z@fDcDgHfGhAfDgNmKpHvHlKjMoLdHvSyQoRxP}S|RzOzNUQ}WZY~X^V[`\^fcacfdhhdekrnxkswssvt}}xz~xx~}~|vwwtux|unjvsmqpjeigfcV\XUUPxTQnMyNpKjFj@eAf=c>Y:\;Q@O6I.M/I.C.@'>,=%:%3"0 .*(!    + +  +   +   + +  +   + +  + + + +     +   +       +          +             +               +   +   + + + +  + + +    + + + +   +  +  +     +   + + + +   + +  +     + +  + +        +      +     +                    +  +     +     +  +   +    +     +    +   +  + + +       +  + +   +         +  +  + + + + +   + +  +   +               + + +    + +   + + +       + + + +                +     +          +  +  +    +     +  +     + + +  + + +       +  +  +5_7Z0a<_9b9_g?n>kFpIsD|EsIsEwI}E{K{H~IKzI}ONPPPQVUSRV^ZUY]]`\cgcfgfhffellopqntplvnpsrlnpqnfocookbfjd`f^cc\]]Z\POMME{QvGyLmFk>e@b>W=Z;c6\2W2R1K3L-J*E.H'C":#8!9!1.+,(   +  +         + + +     +  +  +     +     +    +              +    +  +  + + + + +   +    +         +       +      +  +    +  + +  +    +  + +    +     + +    + +   +  +  +  +        +                  +  + +   +              +  +   + +  +   +   + +   + +   +    +  +     +         + + + + +      +    + + +   + + +  + +  +  +   +  +   +    +  +           + + + + + +         + + +   +    +     + + +    + +     +      + +  +              +  +   +          +    +    + +  +  + +  +      +     +      +    + + + + +  + + + +X?]>gC`AcBbDcFeCdBa@lCg@cHrEhJqHrNoIlPsOxMqKqM}QxY|W}RxP{MWYWW[`[[a]a`iidgdolnjoonuksuuwtzzzyxzÆ~{|wzxy{|{uywqstvpqrjnmec`d[]^ZU\QRQzOnNpHrNfFdAa>\?gk>k;k@gEnCo@sBoEnEoDwGyDvHsKxJtExEwGJVN~MKONKPXSXYXUS\`Zaa_aajiddgidjklnzmpopttqmxprslkhpljimhfbcecda^a`YYZSPOOxOLxKtGuBuDn?j@g?c;]Y=Z?bAYDdCgCaEeAhE`EdGiKjFoJjMoPoKsOxPuRyLxR|OyP{T{W{QZWX~X[YZ`^`beacbnchkgggoxnrrro{r~swyyy~}z~|{ry|~u~uvtstqngmljqff]eecW\WRXQ{MtKsKjFfCjAh@aB^<^mFiCp@lFs?pEz@xHqJuHxKzNG{IHK|IQPSRTURXUY\]V\YX[`_[eb_jdglbdrkiprsvttmtpkkrnkjloneqlhjhidcfeeac^UXXZQPSQHtNyKuApDlAjAeAg3_9a6S1Y5M/M+H.H)D*A&9$='42.,'#% +  +  + + +       + + +   +   + +             +       +       +   + +        +   + +  + +    + + + +   + + +       + +   +     +  +               +  +     + + + +  + + +     + +  + +   +  +      +   + + +   + +     +     +                         +    +  + +  + + +  +        + + +       +   + +      +   +  + +  +              +   + + +  +  + +     +   + +  +   +   + +     + +         + +      +      +  +         +  + + +  +    +              + +         +  +   +  +     +  +     + + +  +      +  +  +   +    + + +]@[?]?b?`:XDd=_DdBkJgEmDnKiIqFtGqJyFuJvLvOsRzTSxS~T{Q{TxUyS}R\T]Y_\\\^`gchfjgknnhppmmovvzrrx{~yǃ}|‚~yrz~xwyyxttsqpklimki`aWX_[YWPySvN{LwHiDlElEgI^@aBT;Y7V2J3F2J0K+?)@):(6$4#-!.('#!  +  + +   +     + + + + +    + +       +            +      + +  +   +    +  +      +            +   + +  + + +     +          + +    + + +  +  +   +    + + +  +      + + +    +    +              +   +     +    +      + +            +  +          + +    + +  +  +       + + +   + + +  +  +     +  +    + +  + +    +      +    + + +   + +  +           + + +  + + + + + +    + + +   +  +   +   +            +              +  +  +  +  +    + +   +  + +  +  + + + +  +   + +  +  +      +  +  6^9`:a;]6i8\;^7e?h?abCdGcCeAhHhCiEiIeJlDoJpDpKmKuLvKuNwSsT|NzTQTWWV\[X\YXabff__acikldmgprswqwrvrsz~ǀǁ{~x}{uxsyqgpqsogkpgka^X_\YPR~\R|LzNqLkLmHdLaFf@a=]@Va=paHdBdEgJlBkEeKoJkFoNnImPxJrJuNxSyNzRWyV{ST~SRWWU}XY[[_d^`d`fblpihnsqrvswttx~yąz~„x}wy~{xwzptooroglmbeb^aZ_YZPQvRvQtCoEtFlCdH\<_;V7[7W;P3N:O2B*B->*8%5'3"0$+*%!   + +    +  + + + +  +   + +       + + +   +           +   +   +  +   + +  + +  +    +             + +    +  +   +   +  +     +    +     +    + + +    + + + + + +  + +   +  + + + +        +    +              +  +     +                 +          +      +         + +  +      +    + + +  + + +  +  +  +     +       +  +  + +   +       +  + +   +  +    +   +  +             + + +      +  +   +   +   + +   +              +  + +  +    + + +  +      +   + +    +  + + +  + + + + +  + +  +     + + +   +     +  :^8Z<^6a8b;`9f?h@ie>n=j>m?lCnAmDo>oIoIuI|D|MzF}LzKLMPTNPPOORXZUVNX[\[__aa][[fccgmhkoolqspzrqropljnmjjoklrmneigl\eebcZ^YYTSWLO{OuJKuKuHsEkAlBf>j6a>a8Y7N3T1Q/I-G+H(=#:';!5"33"+)%$    + +  + +      +      + +  +  +   + +       +   +     +     +  +   +   + + +   +          + +    + + + +   + + + +  +  +   +  +  + + + +                +   + +      + +  +    +   +    + +  + +  + +  +   +        +    +   + + + +   +     +              +   +        +   +  +     +   +  + +    +            + + +   + + +       +   +   +   +  +  +  + +     + +    + + + +   + + +        +   + +      +        +   +   + + +     +  +      + +   + +       + +              + +    + +        +      +  + +   + +   + +   +  +  + +    +  +    + + +   + ]@aAb?\?_=dBeBbEhEiJhCoDmHkFkDlGqJrFlHpN{MxOwPvP}N~WUXV{YU~VXT__]_dhYdcjhchhoojlnzouvxxzuw{z|}Ƀ}{xu{wqu{tqqmkitmgfdfc[`WUVR}Q}TxNqIoDh>sIfD_a;T;Z8P3I3N,H.H'@+>)<*6!1#,%%#!   +  + +   +  + + +   + +  +     +   +   +   +         +          +   +  + +      + + +    +         +   + +   + + + +    + +   +         +    +   +      + + +  +  + + +  + + + +             +  +   +  +               +             + + +   + +   +         +             + +    + +      + + +       +  + + +  + +   +  +      + + + +    +  +   +              +  +    + +  +  +      +  +             +       + + +  +    + +       + + +  +  +  +  +     + +  +    + + + 8X=]<_8b9a<_8f@h>iAif=c@mDtBnCuHoAsDpAsJ{FzEyIKO~JNMNRXRTSUS\YV__Z`d^_cc]dgaicagkmljlrtqyqmrtqvulkthpshlqogcijkj[Xb[`]VUVRMJL{MwHtIvDnm@j;Z_Ad?o>k>s?hAoBqEqDqKuGoGxKzJxO|C|LKNzSPMQTQVXVQ\W][ZYc]^dcaajeedegninljmiproovstruppjmkmlkkjnkiejbd^ee^_\]TWPP~QMNuGzJrCwFkAi@e:d<\8X7S4P/T3P/I*G,>&=):&@"6/1+'#    + + +  + +  + + +  +  +   + +  +    +   +  + + + +   +        +        +     + + + +  +  + + + +          +       +  +      +   +  +  + + +                 +  + + + + +    + +  +  + +   + +  +   +  +         1'I)4 +  +    +                           +   + + +               +     + +   +  +     + + +   + + +  +  + + + +  + +    + +   +    + +      + + +     +   + +  +    +     +  +     +    + + +  +  +          + +   +  +  +   +   + +  +   +       +   +  +  +  +        +  + +    +  +  +  +  +    +  +   +  +  +      + +    +    +  Y?`?cBa@_@bDbGhClBlCbHiCeJlNjIrIoJrLuKvOyPtQxQzPzX}Q|WU~WS~X]_[_`c[ac_`eiikhqontypmr{w~}|{|u{͈̂}z{xz~vz{{tzwtssnisohcg\b\_YYP~ZON{IvMmInBfIhB`:Y?Y8U:V6P4K/O/F-=-;)<'9'54*)&    + + + +  + + +   +   + +  +    + +     +   +  + + + +      +    +    + +  +  + +   +  +  +  +       +    + + +  +  +   +         + + +  +   +  +           +         +  + +  +  + + +  + + +  +    +   + + +   + +"$K/@&!  + +  +               + +     +     + +   +  + +          +   +     + +     +      +   + +   + + +     +  +  + + +     +  + + + + +     +       +   +    + +                  + +      +       +           +    + +    +  +   +  +  +   + +  + +  + + +  + + + + + + + +   +   +     +     + +  + + +  <\9^8b7^7]b=a9f=c?fAn@k>l;k=pd<[9^3\9Q/P-O.J,G*D(<%bDc@gGdGjDhGhDkImIuOrPjKlMnMtLQvQtTxS~LV}QS|SXzZU]X\eZ^^`edeegfhijqrqtsuuut}{wz}Ɓw|āzǀ~ą{Ã{|zs{uutzorsrinomjgb_Yd\[SNuOzOuN{MqHhDkBaEbC\:V9Y;N9Q0P2G1E0?)8'8(4$5$1--'$    + +  +   + +  +   +  +  +  +  +   +      +  + +  +          +    + +    +    +   + + + + + + +     +  +  +        +    +  +   +       +  + +  + +   +    + + + + + +    +        +        + 4(G(F%"      +    +           + + +  +  +  +  + +   + +   +  + +         +     +   +  +  + +   + +       +   + +     +   + +  + + + +   + +  +         + +    +  + + +                    + + +    +  + +       + + +   + + +     +  +         +      + + +   + +   +     +   +    +    + + +     + + +  + 5\7`8^6d8_;gBe;i;n=f9hBj@f>n>kDjDoFpCqDsHxIzBvGKzK}JOJKRLRQU\\PYV[VVY\_`]aZc_adcfjodujrpuhlxpunlnvznzprkueligrncmfeb__`]X\[[VRMPNM|SwFpHnClFoAd=b=Z8[5\8X5O-O0N)G-=*@(=%6%6/-,&"!  + +   +     + +    + + + +        + + + +   +  +   +  +          + +  +    +  +   +     +    +  +          +        +  +  +  +          +  +          +     +  +  +  +   + +  +  + + +  + +  + +  + + + +    + +  +             +&!?"G&+ +  +    +   + +      + +  +   +  +  +  + +       +    +   +    +     + +    +   +  +     +       +   +  +  +  +   +              +      + +   + +   + + +   +   +    +  +          +    + + + +   + +            +      +  + +       + + + +    + +   +          + + + +    +    +   +  +  + +  + + +  + +  +   +   + + + +   ^B[?e>]AeB`BdB^@gCdEeBiDmHiJkIoKqJrLyKsLrPyQyLR~QU}OXUXVT`f]d`b_aegalkiklinltttvtuztyxˉ~z΃|ňŀƂȁzww{ywsvqtqmujhhih`g`_]aUU}UPzKoLmDmDiBdB^?]=Z=Q9T7Q6K6P-D(E-;+8%8'3$2#0)'%#  + +  +  + +   +    + + +  +  +  +    +  +  +  +    + +    +      +      + +        +  +  + +    + + + +  +    + +   +      + + +                +  + +   +   + + +        + + +  + +                + #F.C)3    + + +  +                 + +          + + + +           + +  +      +   + + + +     + +   +     + +   + + + +  +     +          +     + + +   +   +            +       + + +    +    +  +   + + + + + +  + +  +    +      +    + + + +     +  +  +  + +  + +  + +     + + + +      + + +  5`8`=]8g9Y<_=c8fAgi>a5\3\8W7Q2Q1M1J0B(A*?*:$;"7/3.(&   + + +    + + + +          + +  +   +     + +      + +     +  +  +  + + + +                      +  +     + + + + +                    +       +   + +  +      + +   + +             + +;*M)3  +    +  +   + +         +         +  +   +    + +         +  + +      +               + +       +    + +  +    +    + +   + +      + + +        + +   + +    + + +   +    +  +     +   +   +     +   + +  + +  +    +  + + + +  + + + +           +  +    + + +   + + + +      + + + +  +  +        +   + + + + +  + + X;aA`@Z?]BfAiBdEdgBl;jAg;pb=^;_8T6V2S4F/J/H*D,=%:'8$8"40 *&$#   + +  +  +      + +   + + +       +  +      +      + +   +    +  +     +  + + + +          + +    +   +    +   +  +  + + + +                 +   +   +  +  +   +  +    + +       +     ?&E&     +   +   +                + +          +  + +     +    +       +    +   +        +    +   +         + +              + + + +    +     + +  +  +  +  +   + +     +    +     +   +   + +      +   +  +   +  + + + +    +  +  +  +         +      +       + +  +     + + +  +    +    +     + +  +  +  +        +    + + `Bc=aEjHcAaAg@cClEcEfEqLhKjLiJwMrIrMwLtSpQSM{Q{W~Q}S\cY{\[Y\^bci__bofokjilkrtwztovvoy{{~Ɓȇǃ†ńΆƇ|ă†ǁz}vy|x}~~{rvwtpnggj^_ea^\YS[NzYwLuGtKjGdGaE_e@a@i;iCf?k?k?oBmCwGzGsIxCHIFxOICMPSPOQTQVVWZXY^YaZ`Zehdfdchgpioimolnomrwqrxsorqevohotvqoqjkkfmcc^c`Y_VXWTTVML}K{IsFwHl>o=g<]:_7\5U7X6R4U/I-J*B*B(<"7&7$3 0*+)$"  +   + +  +     +            + +        +   +  +   + + +   +   +    +       + + +  + +    +          + +  + + + +  + +     +                    +    +  +  +    + +   +  +   +      +               19     + + +   + + +  +     +             +   + +   +   + + + + + + +   +   + +  +  +    +  +       +  +     + + + +  + +  + +  + +  +     +   +  +  +  +       +     + + + +          + +   +   +    +   +      +   +     + +     + +      +      + +    +    +       +  +  +       +   +   +    + +  +      + +  + + +   + +  + e;_A_Ae?bCiBhEeHhHmFgGkHeKoKmBqIkMsKtOxPqOuVuS|QRV~WYRYYW[[_caa^cfefhnjhlslqnssruy|xx~ĄLJƄÂƁ˄Ł~„|zǀ~y}uvxtptoujkilbgebY\UR|XU~PyKsOkJqAf>d<^<_9\>Q5Q8K2F1E-A-@)A%9#7%22,*!  + + + + + +  +        +   + +  + +    +  +   +  + +   + +          +  + +  +    +    +          + +     +  +     +       +     +  + + +  +         +  +           +  +       2     +    + +        + +  +      +    + + +     + +      +      + + + +   +          +     +   +    + +   +   +    + + +  +  +   +    +    +  + +    + + + +                       + +  +  + + + + + +  +  + + +   + + +    +    +      +    +  +       +     +   + + +    + + +  + + +8T8a:Z;bf?jfAn@mApAuHoBuCmAwIyIrJwJyG}LJzQOLyPUIQSSXVWWYWVV`^baedbgadkdfqhkjsmtrruxqprn~routwritrjknikhempcjfcZ__^RXVVSPU~C}I~KxKpAp?f?mp?iEqBpDq@tFvJoFwJsG~O{MNNINKRSXUR\RWVX^_\``Xa_bgfgdgpclkpttomrwv}tvuxutzq{pyrqpkkplmnhignm^_e]\aUV\URMOLxIDm?pDh?d;_;a\@^:^>[8R3L3R0B)?+?'=&6#32"*#,#$  +     + +   +  +   +      +   +  +  +     +  +   +       + +   +  +  + +  + + +  + +   +  +  +  + +  +      + +               +    +        +        +    +    *   + +     +  +          + + + +  +  +          + +        +     +      + +   +  + + + +  + +      +  + + +      +   +  + + + +  +          +       + +   +    + +  + + + + +  + +    +    +      + +      + + +      + + + +  +   + + + + + + + +   +   +  + + + + + +   + + + + =c:^7d=f9b>a8l>h>jAqAnBq@lEuAx@pFoFtDyG|I}HxNK|GPGLYNLUXSWT_SVX_^X^`Zacagfidjefjlqlvppo}qzuy}xwvw}tqupkstrfoimfqgkdfffda[Y[XUTVPQNzLsHpCnFiBoD^6b7]?^9[4W1M-I,G.D'A):#;%4 -.'&'$"  + + +   +   +         + +  +    + +   +      +   +   + + +  +  +        + +    +       +  + + +  +        +  +   +  +           +        +  +      +   +      + +  +      %)(    +   +  +  +  +      +       +   +       +   +      +     +  +  +  + +   +   +   +      +   + + + + + +  +     + + + + +   +           +       + +  + + +    +         +    + +  +    + + + + +  + +      +   + + + +  +     +  + +         +       + + +   +    +  + +  +   + + + +  +    + +  +   +    +   + +  + + +   +  + +  +  bA_B^EeHiBaChEdHnGhIkIkJfGtLqMqKnKoTsQvOK{ROU{UV{S}aR_Y[[c]ae_kdcfahmkolkuqvrtyqwz|}z}Ё‚DŽćÂɈȃɁȊ̂w~||soquuqkkilgdcdd_VVXUwSwJtJrFiLbDj@[@X:]i6d9g&<$<00*)#    + +   +    +   + + + + + + +            +       +  +   + + + +   +    +          +      + + + + +  +    +      + + + + + +  +        +           +           +    +    +     $**# +     + +  +  + +      +            +    + + +     +               + +   +   +            +    + +  +  +  + + +   +     +     +     +  +     + +  + +   +           +      +       +   + +     + + +    +  + + +    + +  +  +    + +     +  + + +   +  +       +    +   + + + +  +    +  + + + +  +   + + +        + + +      +  +    +_AeGeCcAdAhAkFhEmGnHiFoGoImMlHrLsQrP{WuPRQ|YyQXzYZY\X][[b]Z\akacj`jmjgrnstqrw|uv~yz||ƂƁǀƃȆҌ΁ȆȅČ΀ˈ„~~džx~yytlrqnqpdgbb`e\^XzR~UL{KuJpIlImBcBjA\8^1S;U1L6K0I.C-?+8&=)6 1"*)'#!          + +  +  +        +               +  +   +    +      +      + +  + +  +  + + +        + +  + +  +       +        +      +        +  + +  +  +   + + '#         + + +     +       +  +    +  +  +      +    + +    +    +   +  +          + +  + +  +    + +   + + +   + +       + +  + + + +          + +   + +     +  +     +  +          +  + +  + +      +  + +   +  +   +     +  +  + + +    + +  + + +  + 8_:d2a8`@h?hmAj@iAh@jBlHuKuDrDyDwDyJzLzJrJH~LJKRRYSRYQXUXZ\WZ[]_be_c]`fjjmojjsqznxwnxvsxxsxx{oyuzpyswptqnfnnhlcjb^cd[a[YXRRYRQwIwHqFsFk?j?j=c;a8Y5Y3S1P/M2G&D)C'?%<"4%6-"/$$#    + +  + + + + + + +          + +   + +   +          + +            + +     +              + +      +   + + + + +   +    + +       +      +   + +   + +          +     + +         +  +             + +          +  + + + + +  +  + + +    +    +   +  +   + +   +     +           + + +    + + + + +       + + +     +  +  +      + +  +           +           +    + + + + + +   + + + +  +    +   + +     + + +  + +  +    +  +   + + +       +  +  +   +          + + +    +  +  +  +  +   +  + + +    dC^F_EaB]DfEkGeGdMjFjChLlEpHwLsLzUpUxJxUzOwQ}RsTV}X~]XX_[_U`a\`ebj`igelmelrr{xztz~x||ƒńÄʂ˄~ΈˇΉˆˇ̆̆~ƁÁ{~|~tv}pvwpkgfbfa\\[YWyU{OvLuNmEmKl@k@`A^=X6[.:&9'5#7 0!&&(     + +  +  +       +      +   +  + +    +     + +  +          +   +       +   + + +    + +    +    +          +  + +  + +       +   + + +   +     +        +      + + +  + +        +     +           + +  +  +        +  +                 + + +    +   +  + +  +     + +       + +  +   + +         +    +        + +   +   +       +     +  + +   + +   +    + + +  + +  +    + +   +    +   + + + + 9[>^6d(8%1%3!/($!  + + + +    + + +   +  +  + +   + +  + +     +  +    + + +   +  + + +             +   +        + + +   +     +       +           +   +       +    + +  + +     +  + + + +     +    +        + +  +    + +     + + + +   + + + + + +     + + +   +   +     +            +      + + +  +    + +  +   + +  +  + + +   "! "    + + +    + + + +           +        +         +       +     +  + +  +  +    +    +    + +      + + +     + + + + 7i8efh9`5`:U8^3P5O1M+L&F*;$<&<"6 3!1+'" +  +    +  +   +     +  +  +  +      +  +       +      + + +   +     + +  +       +       +  +    +  +  +   +    +   + +      +   +        +     +  +    + +  + + +  + +       +    +  + +  + +    + + +    +      +  + +     + +   +       +   +  +  +        + +   +     +    + + + + + + + + + + + + +        +   +   + + +  +          ! ""#!"#          +     +    + +   +  +    +          +   +  + + + + + +          +   +   +  + + +   +  +   +     +  + +  + +        +  +   +      +    + + _FfBjJgCaBlJeHiLgKnLmJnNlLkMpKnKzQvLzNzU|QPVXzPTY~Z]YV`^^`bchefkmdjknnuprqwut{v}w}vƆ}ɅÉ̂ƅʆу·͌Єɇ{χÈŇ͂z|utsvvwqvklnjgaZY_X\WZwN|KwLsMjJhEkCc=[9U6R5X5Q5L2J3C+F.<'=(3&6%2"4+&"  +  +  + + +    + +    + +      + +             +  +   +   +   +   +       +    +  + + +   + +  +         +       +  + +    +   + +   +    + +   +    +   +    + +  +     + + +       +          + + + + + +       + +      + +      + +    +  +  + + +  +   + + +   + + + +   +  + !$$"$"!! !    +   +       + +    +  +     + +    +         +  + +   + +  +  + +  +   + + +   + + + +   +  + + +    +     + + 8f:d>a;b9c8h@d@kBs?gBoDqFsCmDqJtDuJyFEyNJwF}KNKMJOYSUWVRXVYU\\]`]aa`afeffggilknnpqqyx|xw{xtxwxxvx{yzuqvnqovpimghngadad`]UUTRO~VLzGxKpKnDpGnBk;i):$3#1 0)('   + +   + + +     + +  + + + +    +     +   +             +       + + +   + +           +  +    +  + + +  +  +     +   +  +    +  +          +     +     + + +   +   + +   +   + +     + +  + +               +     +  +  +  + + +     + +          + +             +   +    + +     + +            +   +   + !#$"#%""!!!!   + + +      +  +   + +  + +  +       +           +    +  + + +   + +  +   +  +       +  +  + + + + +   + + + +      +    + ?`:^Dd>o

l>m>n>n?n?nBl@oFuBzH{ItKsGwI}MwK|NyLyJNO}UOTWUR]ZS[Z\]a]]^dg^iebiijmjqntpnuuss~zx{|~wӁ|pȀ}z{s}qtqruqrqovohgfhdbZ]]\ZVQYPH~H{GsLtHmBk?hZ7Y4W4M-K-D-D+=*>%;$1#2!4/)&&       +  +  + + + +  + + +   +   + + + +      + +    + +               + +  +       + +  + +     + +       +   +   +    + + + +       +  +  +    +    +             +     +   + +  + +   + + + + + + +  +    + +        +                + +        +        +        +   +  + + + +  +   +   +   +    +     +    + +      +   +       + + + + +   +    +  +  +  +       #"'$! " !!!        + +  +   + +  +         + +   +  + +    +  +                + + +  +  +  + +    +   +  + + + + +   +   + + + +   +     jDhBdEdBkCkFfGjInDjHtHqNpNmMnIxLlONpUR}OxXVVSW}X^VZ]a]\Z`ab_ehnhllmmskzzvsv}{}~}ȃ˅ˋˍً׈ٌΏɌڏȁυ‹ÇȄǃ€ǃz}wwuvxlpplhirjba]aZXPzS}N{OvMqKnEhKc>[=VU;U6J2G3J+C+;(;&7$5!/ 1#+(&%    +  +  +   +  +  + + +   +   + +    + +  +  +   + +     +  +          +             +  +  +      +  +   + + +      +     + +  + + + + + +  +      +        +         +    + +    +   +       +                 + +      +  + +   + +  + +    +     +           +    +   +  +       +    +  + + +           +  + + +   + + + +   + # "%%!!!!!   +  +   + +  + +  + +     +    + +   +  +                + +      +    +        + + + +  + + +  + +      + + +  +  6f>d:lAjAdBm;hAbCgBkFwAuEtKwJqG|EyF{JxK{I}IvFJH|QRQTPXVQXVW\^W_V`d`d]eggiiephoolwruorvqy|}ztyxӀv~vy}z{tswznutprrmnnlgkd`c_[YYWUTQQN{M|BxHs@mBpBeB`8^:Z3V8T3Q0P1H/D)D,='>'5401+)&   +      +    + + +   + +  +      + + + +        +      + +     + + +  +  + +        +       +            + +                  + + + +  + + +       + +    +   +  +   +  +  +    + +       +   +      + + +      +   +   + +    + +    +              +   +      +        +  + +       +    +   + +  + + + + +     + +    + +    +  + +     !#!""          +   + + +       + +  +   + +   +    +   +  +   +      + +  +  +    + +  + +   +     + +    +     + +    +    + + +  + + + + + +  +     + +  +  aE^AbFcHeDiHfGnJmHpKnHqNpGnNtFzLsH|PwQTT}X|U~VxYZT_\_[`b^Ydbfejbnjmnkiutzv~vw{yw}}~~ǂɊЇ|ˈшۇ҆͋ЋЇڋЁ͋Ljʃ͇̃|ӂŃą˃qvsyyvvpokjfda`c`ZYT~ZPyNuPnEhDgBiFb@_7\9Q=S5N4Q0E/C+@)>&3'5#.1+*,$   +    +  +  +    +     +    +    +    +  +    + +      +    + + + + +            +    + +      +    +   + +      +  +  + +    +  +     +            + +  +       + +              + +   +      +  + +        +  + +     + + +                +   +  +   +       + + +  +  + + + +  +  + + +          +    + &!#""# "" + +    +   +  +  +  +   +       + +  +       + +    +  + +   +     + +    + + +  + + + + +  +    +   +  + + + +    +    +  + +  + + 9d9\9fAj=g?j=j>n=qDrDqBoJpDoJuGtEyJxKD}LJJHPORNSSPY[RWZWZZWZ^[`fcgflgiifnnoruqpnnw|zzy{tԀvs΀y~Ԁtw{uyˀrtxtrsplsnkjccg__bW_OWQNSMNsHuLrIpCkAd<`<^5]8T9P3K-P-M,K0F,B$;"<"8$1"+-'&    +       +   +  +   + +  +     +    + + + +  +    +   +        +  +   + +        + + +    +   +    + +   +     +  +   +         +    +   +      +  + +   +             + + + +  +     +   +  +     +        + + + + +     +  +  +  +  + +    + + + +    + + +       +  +       +    +       +   +       +  +  + +   + +   +    +   +  +   + +   + +     '#'$                  +          +  +   +  + +   +   +        +   +     +    +                +    +  + + +                + +  + +   + +    + fDeCi?aFkArFnEkFiHlHpIsMsFpMuKwP{LqJyPzVyS{ZSV[XUXZ\_^Y^aa_fdebjohtlkmnsuvu|yz}z}Ņʏǐ̑ЈφƍȊŌ҉҇ϊކ׈цփ̈ς|ʀ}~xyxzzstxmllkf_gi[_\ZSQTwLoMsJkAfDhBc?]gAlc;^>V9S4Q0K3J,E+E*:);)6!2!1 *&#     +        +  +  +       +  + + + +  + +             +         + +               + +    +    + +   +      +        +         +      +    + +   + +   +  + +   +  +    +  + +  +  + + + +  +  + +           +    +   + + +    +        + + + + + +      + +    + +    +    + +  +!%%&%!#"        +  + + +    +  +  + +  + +  + +  +    +       +    +     +   + +   +   +  +  + +   +   + + +   +  + +  +    + + +  + +  :b=e;iY8Y:T7M5C0G+A-<.<'8+7/ *()&     +  +  +           +  +  + + + +  + + + + +      +    + +   +   +        +  +         +     +      +  + + +       +   +       +              +  +      + + +       + +       +    +        +                          +   +   + +  + +   +  +  +  +      +   +     +  + + + + !#""##  +        +   + +   + +  + +     +                 + +  +   +  +  + + + + + + +  + +   +  +    + + + + +    + +  + + + +gi?oBqCh>cFp^;`7X8U:N5Q2G0G1B,A':#:'2%5/)#$!    + + + +      +      + + + + + + + +    +           +       +  +     +  + +        + +  +                 +       +  +  +     +  +  + +       + +   +  + + + + +  + +     +         +   +           +   +    + + +       +      +   + + +   +  " $"   + +    + +      +  +  +      +     +   +    +    +            + +  +  + +   + +  +     +    +      + + +  + + +   + +  + + + 7_>i>dk@nc=d9\9R6V2U2R3O-F+I'>%>#9":"52)'& +   +   +  + + + +    +   +   +   + +  +  +  + +  + + + + + +  +  + + + +   + +     +   +       + +          + +  + + +        + + + + +         +     +   +          +    +    +   +                    + + +      +   + +  +        +     +      +  +              +     +      +  + + +    +  +  +   +   +  +   +   +    + +    !   "      +     +    +  +  + +    +   +    + +  +    + + + +       + +   +    +             +         + +   +  +   +   +  + +  + + + +   +  +      +  +       +    +    `=iD_Dd@lEkIrGlJoCkPmKpNxLxOvOyS|K~VvP{Q}TZXY_`W\]U]\babnhehohilkmxkpyqwywv~{~ɀÃƇ~ȉԐԊ̊ЊՎҎ׋܋Є҂ЇЇɊƈƒLJā„Ń|{y|wsuzprlpneje\b]\W]UQwRvIqJnLnDgDf=^;^:\>T5O3R/J5M-C/>'<&8'5"3 ,+*#!      +  +  +   + +       +  +  +     +       +       + +    + +  +     +        +               + +       +  + +      +  +       + + + +  +   + +       + + +    +            +       +   +      + + +  + +  + + +   + + + +    + + +  +     #! %            +  + + +   + + +   + + + +       + + + +   + +      +  +     +    + +   + + + +    +    + + + +  +  + +  + +  + + + +  + + +    +  +   + + +  +e;l=j>eAfAdBjDp@mHjFvEw?wDtGwHxHyMJIK|PRQLSSTPTTSYY[_X^_if]^^ebjjonhnlrnpps{xvsu|}΂{yҁրׁ݁ڀx~Ԁ}uvruovslpnroknkibb\]b\ZXVUUMPzNBuFs@qDe>e:h<[=[0U8S6R2J+G*B,=)B#=!8!61,*$!   + + + +  +     + +      + + + +   +   + +   + +  +  + +  +     +     +  +   +         +  +      + +            +      +       +  + +  +      +    +    +  +     + +  + +  + +  +  +  +      +   +   +      + +           +    +    + + +  + +  + + +      +  +   +  +     +  +   !      +    +      +    +   +   +  +     +  +   + + + + +  +    + + + +   +     +                   +  +     +    + +  +   +  + +   +  + + + +    +     +   + + + + gCjEd@dGiBiMkHmHnJpKrHoNqKsQsPyL{StMyW~TU}V~T}OS^[V^a_]^c[aeeengjitiplovsuvvw{|{~}ˇƃύ̋ՍЏ܇ؓӎ̋؉ՇҋцΎӁ׈˅ˉʆΉʼnĄ|~}zyxtroronleb``f[\]_QV{IoJoDmJlCcDftCsEpEoFzGyGvHJ}G|N}FJ{RzPL}QOQWR[VYYV^^_eYf`dgbdiegigjoplropqywwuyvz}}΂~{y}xz΁Ɂu~vxtwrornsehkdbibe\a_YXUTLMN}IwL|FqAk?i@f:d=Z5^7[3Z3R.K/J+I(=&@(; 9#7 -,*&"  +   + +  +  +    + +  +     +    +   +  + +   + + + + +       +            +       +  +       +              + +     +     + + +     +    +       + + + +    + + +  + +    + +  + +    +    + + +     + +   + +  + +  +     +        + + +          +  +   + +     + + +   +                   + +           +     + +   +  +  +  +     +  +    +    + + + + +                 +   +    +     +            +    +  + +  +   + + + +  + +   + + + + +    +    + +  +   dCfFaIfEmHeGiHpIlInJwIuNpOxPyPvQxQ{T|RwQxUSSWY]Y^[``W_affjchhgjkpnlqutqvzw}y|{}DŽwÃɂŌˊːЉӆَ̍܊ԏӇΊчЉʆɇˎ΃ʁΈłςłˇ~{{z{strsqgjcg\db\YVUY~RMyNtJoKgEeBhA\;]:[8Q5R1Q.Q0H.D+?)>):%9"7"/+'$$   + + +     +  + + + + +       + +  +  + + + + +         +                  +  +           + + +    +       + + +          + +    +  + +  +    + +  + + +   + +    +  +               +  + +   + + + +     +   + +  +   + + + + + + +"  + + +     +    +       +  + +    + + + + +      + +       +    +  + +    + + +              + +  +   +   +  +   + + +  +  +  +   +  +    +  + + + =f>j$<(=%9#6 5 ,-'%  +  +    + + + +  +  + + + + +   +          +  + + + + +        + + + +               + + +  + +            + +         + +  +    +  +    +           + + + +   + +   + +  +  +  +    +  +  +  +    +   + +    +  +   + +  + +  + + + +   + +  +  +      +       +  +      +     +    +          + + + +   +  + +  + +    + + +  + + +  + + +      + + +   +       + +               +   +       +  +   + +    +  +   +   +    +       +    +            +  + + +  + aEeEZBfEjBdJmFjIdLiFqKoLsNpOxMzOvSxPyO{UwQWU]TYZ^`b\\\[cjhmbfbninlqnsnuxywxz~vÂ~ʁĄ̆όΉ{Ճυфю܄ڊًʌՅьІюɃ݄͐ˉՈ΂ʊƀ|z}wywotroghe_bbV\TNYzL{LtLsLnCiFg?a;Z>[gG[>\>W;[p@rAsDr@lDuBuEtC}I}ByKwGuLKuJIIONNWQSURZZUX`]`b]]``aicjhkifcqwqnonsvvvuq{uy}x{x}|x}ր{y{xzsxsppvvtoilhgcd]b]Z[WTWMRyST{KzDp=nEoHa>e>b:W8\7W6M1L3I,@(@)B$9'?14 ,-)' +   +   +    + +        +  + +  +    + +     + +  +  +    +  +  +     +     +   +       +         + +       +     + +   + +      +     +      +    +    +       +   +          + +        +       +    + +     +  + +     +       + + +   +   + +   +      +  + +        +      +  +   +   +  +   + + +     + +  +     + +  + +  + + + +   + +    + +  +     + +  + +  + +    +            +         +    +  + +  + +      +   + + + + +     +  + + + +   +    +      + + +  + +   +   + +  +     `GbAhFfEdLiIhJpOnFlMpNxR}MvVwMxUwOyTRwWR}UR[ZZY\Z[_f_bbfjmk`hhirjumupuwxs{|xt~Ƀɂ€ӋʊҀΉ݉ՏْΑԎێю׍׍ф҈و׈ЇDŽˉʈɅ|ǂƁ~}|wytsjlpofd]`_[WXRT~PsLrIlGi>a?b>a<`;Um=mAlCq?mDmBnErJwCxBwGHG|Q}MJP~JNSRQWRJVUTVZY[af]_gdg`gdddjlidrnorrwwruu}}~}Ӏσ҉|~{~wwzs}{wtxqvrtwopmiejh\keY]]ZVURRMM|NyGxCl>l:f;g<\8Z7]4Z6Y/J-O/J+M'=%:';"8#0-*'&        + + + +  + + +  +     +    +  + +   +    +  + +     + +   +     +    +  + +  + +             +       + +   +          +  +  +   + +     +   +    +  + +  +       +         + +   +  +            +  + +  +    + +  +   +    +   +  + +   +    +  +       +  + + + +   + + + +      +      + + + +  +       + +  +   +        +                 +    +         + +  + +  +     +  +  + +       +  + + + +  +  + +  + +  +     +   + +  + + + + +     +   +   + hDg@fHgFgFnHpEkLlJpGtLuNtFwLtKvR~RxS{W}[V{RVWZZZ\`_]i\gg[bcmhmnmrrlwrtvxyx}ǂЅ…˅֌ӉБәٍ̎؎ԓތҍߋғ؎΍Շӊ̉Ԇ~~рƆ~vztylwmmflkd`X[Z[OSLyLsGnGhFg?c=]?[7U9S6R4K3I/F,C*@%9%8$3%2"+($#   + +   +  +  + + + +   + + + + +    + +   +     + +  +  + + +     +   + +     +    +          +      +    +            +         +  +   + +    +  +      +      +  + + +   +  +       +    + +       +   + + + +  +   +  +     +  +   + +  + +    +  + + + +        +    + + +   +  +  +     + +  + +      +      +           +   +   +      + + + +  + +         + +        +    +    + +   + +  + +  +  + + + + + +   + + +  +  +?a8nB`bqGnEuj@f>oAg>n=k@sCq@pAyFsBqHqJzJ}E|FuILKJRORNTULUXYXWU^^\[\b]]cediihgojklrozsxqqz|xzzljvЃԀہՂ~|}Ճ{~{v|vltxojusshhqhfa\\\\WZUNOJR|KuHtFrFkAg?a;^6[7]6L1P3M3E/I*C(@):%9"831)&(!!    +  + + + +  + + + +  + +   + + +           +            + +   +  + +   +   + +  +        +           +  +    +     +   +  +             +       + +  +      +    +   +  +    +     +   +  +        +                 +  + +         + + +    +     +    +     +  + + + +    +     + +     +      +       + + +  +   +  +  +   +      + + +  +  +      +      +  +   +        + +      +  + +  + +     + +    + +  +   +   + + + +  + + + +    +  +  +  + +   + +  +     + + +   +   jFgFdIpFlHqDuGlKjMzKnPwMtLqP|NyQzU|RzP{XPz_[|\}\^X[`_`]b`gbeclikjxsoyn{uuxzx{}xx{ψLJDž͉ԍщБڐό֑׎׊ԍׇЕՑ֊υЅ΅ɄЋŀdžƊƁ}||trsotoeorbddaa\XU|VwQyPuJvFjIiFkAd>]AX9X7R5T2O2E.K,B*B%4'7/"- /%&% + +  +  + + + + + +  + + +    +  + +  + + +  + +  +    +  +   + + + + + +     +       +      +         +     +  +   +          +  +       +       + +        +   +    +    + + +    +  +  +       +   +  + +    + +  + +  +   +   +  + + + +    +  + +   +   +   +  +  + + + +  + +    +    +   +  +   +    +  + +    + +       + +    +  +  +   +  + +   +         +   + + +  +  +  +      +    +  +  + + + +  +   +    +  + +   + + + +   + +    +  + +  + +  +   +      + + +   + @k=lpCs?n;oAlCvEqBsFnDsKqH~GxGxK{H|IMMPLQPRRVPUVUVWY]^S_ab^ifg``ldihgkvvwrtwts|~{ˁw|Ѐ|݄~ځڃ}}yҊ}؀uxssyrn{woqrikii_iage`[XVTWSPQxHsDjCoe>f>i?i>r>l?jCs>s?oFpBsHsJrGwC|HL}FV~RULMKUNRRRSVWTRY_`_\\cadbgjhosriimsqsoqxysw|uxyy݀zօ҇{{܁ց~y~}tyyz{tsusrmurjsmbd_c^][XVSWNK~OyHtDqBgAd>b=`:W:T1X2O2N.J/H,D'B':$<#01.((&"  +    +   +    + + + + +   +   + + + +    +  +     +   + +    +  +  + + + +  +    +  + +      +     + +     +  +  + +   +  +    +    +                           +     + +     + + +  + + +  + +   +     + +    +            +  + +   +   +   +  + +         +      +    +           +     +   +       + +  + +  +  + + +  +        + +    +  + + +  + +  +  +  + +  +  + +    +  + + +      +   + +  +     +  + + + + + +  +  +   + + + +     + +      +  +  +  +  +      +  + + + +  + + +      +   + + fFfIcGoHlJpIjHnMkInNvMrLwJxQsQyQzV~N~RPYSYYX`^^Y\bbbjkednnhqmmnrwoouvvyyx}wŃπ|̓˂NJ҄ЈӃՈԊޒڇܕۑޑՔӕݑБىЌҊ̌ғۉԈʉʈ̀Èǁ|x}qtqoklkfdca]\YWY~SzQmMmNgDa@dAc=[9W8S:R6O1N4D3C*A(5%1(4!1 +($## + +    +   + +  + + + + + + + +  + +  +  + +   +           +     + + +  +   +   +  +  + +                     +             +  +                     +    + + +     +  +  + +              +     + + + +   +   +           + + +  + + + + + +  + +     + +    + + +    + +      + + + +   + +    +     +    + + + +  + + +      + +   +        + + +      +    +    +    + +  +  +    + +    + +       + +      + + + +    +    +  +  +    + + +  +  + + +=h>n>d@k>q@pCiDmFoEoCo?uGvBqJ{CtCyM{J|IzHNLJMRPQSRUXVXXY\]YY]_fWfbfjnjjjknkgturwswwww|rzׄ~}Ղ܀}҂z~ր|x{~us|tqtjqpvofkfc_[V[YRQP~SM}H{ItEtDlCl>c8`:Z=U4W1P2P1I5F*D*@)9#7"6"3.('"      +  +  +   + + +     +  + + +    +  +  + + +    +   +   +  +   +    +    +    +   +  + +  + + +  + + +         +      + +                  +    +  +      +         +     +  + + +   + +    + +      + + + + +            +     +         +  + +  +    +  + + +  +  + + +   +  +  +  + +  +   + +  +   +   +  +   + + +     + +  + +  + +       +  +  +  + +   +   + +  +  +  + +    +      +  +   + +      + +    +   +    + +   + + + +   + +  +  + + +  +     +  + + + +  +    +   +  +   + +  +     +      +    +  + +cGgGmBjDhGpHrKoNoHoNoLsLtP|PyVwOrOxVuSxTWO\[Z[d]\`]bdfhmhkkmgloskwsmuxw|~}}Âǃ~ÀƁɇы~яĀӊːڑ̂ߔܕېޘՌّՋ׋؇Ѝ׎͒ʊLJЇÅʉ…~ˀ~~wvywsmkjmef`_YWZXU|KzKvGtJnJfDa@`>c9W;R;N5I1J2F.A)?)?&7$-. ))&!!  + + +   + + + +  + + + + +  + +     +   +   + + +      +      + + + +  + +    + + +     +  +  +   +   + + +        +        +    + +                  +   +   +         + +  +   + +    + +  +        +        +            +    +     + + +  + +   +    + +  + + +     +  + + + + +  + + +  + + + +    + +  +  + +  + +          + +  + +           +   +    +         +  +   +   + + +  + + +  +  +  +        + +        +    +  + +  + +  +  +  +     +    @eBhAq=l?m@kApHjAhCpCpBnDoL~ExH{F}G{KJ}K{KNV~QSUTSPZV\_[ZY\a^\e`d`f_fllhlmnznojv{sȀ}sw|~y|}ڂ~}؇ۃxx}v}{xzyłwrqxsjrnnikgdfa_YZWVTQOL|I}GyHw@oAj9fA_@[8Y5U1U3M2L,H+E(>+?(?"0 2 ,)($    + + +  + +    +  +     + +   + + + +      +   + +  +        +  + + + +  +     + + +  +  + +                +    +        +              +        +  +    + +  + +   +  +   +   +  +   + +      +   +      + + +        +   +  +   + + + + +   + + +  +   + +    + + + +  +  +    +    + + +    + +  +  +    + +   +  + + + +   +     +   +   +  + +  + + +  + +   + +  + + +  +   +   +  +      + +         +   +   +       + +  +     +   + + + + + + +   + + +   +  + +  + +  + +  +  + +   + +      +  + + + + + +  +   bDiBdEjJfGpGkIoJsQoJpPsRsLtU}R[xT}[^[W\\ZXZ___dfcdf`himmjfovolnvxr~y~ŃɀȆȅʈʇ҈ˏՓڌږٔٙژܓܐԋߒӎԉϒԎ̇̊Ѓʈ{΄słz|vuxutpooij_h[b[\WR~PsMuJoEfLhC`>bBV=Z8X6N2M2G2E0D->%@*9&2#2"*%##"     +  + +      +    + + + + +    +  +  + +        +    + +      +  +   + +   + +  + +  + +      +   + + +                 + + +       +     + + +   +  +    + +  +  + + +   +   +  +   + +    +             +       + + +  +  + +    +   + + + + + + + +    +  + + + + + + +   + + + + +  + + + + + + +   + +  +   +  +   +   +   +  + +  +         + + +  + +     +           +   + + +   +  + +   + +     +   + + +     + +    + + +  + +  +    +  +     + +  +     + + + +   + +=d=`CiChCkCo@h@pCtCsDwIyEsFuD}H}DvF}MLSPPK}PRSQRSWW[Y\\aX`^Xf_ccejinjifppoppvuzzxxwyāɅՁ|~}}ҁ~рӀ؀{~zuwqyvvnosolifloaga[W]SRXSNO~KyIxHqBpCgDfe8]9]4Y5O1K-I+K*A+B(;#5"300,($#            + +  + +   + + +    +      + + + +   +     +             +  +    + + + +  + + +  + + + + + +             +    + +                +         +   +        +   +    + +      +  +   +  + + + + +     +   + + +     +       +   +       + +  +   +  + + +     +   + +         + + +        +      +    +  +   +   + + +   + +   + +   + + +     + +   + +  +        +     +     + +     +     +  + +  +  + + + +  +    +      +     + +  + +         +      + +   +         + + + +       dChFqHjGmIpBpMpGnLtQwPqMwKrQ}UyVyR|VzUWQVW\Xa]^^_fabebkijpommlswnxpuz|yyDŽz͊ώ̆·̒džؑފАЏ֑׏ГАޑݔщ֙͛وЏ֊ۏˉ͋ҁ|΄~~„y|~vssxkpgdjb]\Z\S|R~N~IyJhIkG_@f?ZlBlEvDuCvCuDCuJ{IwG}JJLLLLOOSRPWPQUWV[_\W[Z^_\cddfegleknnqorlsrzsyz}xx||݇ہ~߃|؀قzҁҁxЃxvuzywyyrunpgpjkhdh`Z][YSQRPwLxLyIpFnCrDiBd>`<]:X4R1R.L,F,G';(A'8&7"1..)&&   + +    + + +   + + + + + + +  +     + +      + +      + +       +   +       +      +  + + + + + + +        +     +      +      + +  +      +   +     +  +     +          +    + + +    +       + +  +  + +  +  + + + +  +     +   + +  + + +   +  +     +   + +   + + +  + +                + +  + + + +      + +  +   +  +  + + + + +    +   +    +     +  +     + + +      +  +   +  +      + +     +         +  + + +   +   +    +     +   + +  + +  +  +  +    + + +  + +   + + + + +  +  +  +  + +        + +  +  + +   +   +  +      + + +  +  aGlHhEjGkJfKnJmMnMuItNrNpM|W{QTwPySWwSVZZ[]Z`]__faadmdeinjnpfsrysus||w{~ɀʆƈNJׅЏЋӊҏחΌِ֕֒ސݙ܌ڎيϐ݋ڈو҆ӌ׌Š̅~Ãǁyzyo{oklkfea^]SUR~RP{HqNkHoHoCd@\EX9V:U5K/N.C0G-?/:%9$2"1$.*$"   +  +     + +    +  +  +  + +  +  +    + +   + +     + + +        +         + + + + +    + +                    +    + +  +  +    +            +          + +      + +   + + + + +  +   +  + + +   +               +          +  + + +  +  +    +  +  +     +    + + +   +     + +      +   +  + +   + +  +  +   + + + + + +    + +       +  + + + + +        +              +   +  + + +  +    +    +         +        +   +    +  +  + +  + + + + + +        + + + + + + + + +=j:c@nBp9nClAnCt?rAmEuJ|D{H~K{I~QxJ~G~LKKQNKMPSRVOTVY[]_aZ`faggbcbhcklrjtqrrqpmyxp|z{|Ѓ݈և}ۇ׈؃׉xށwx~{w|{rw|svkgojofjfed_XWTSSLMLJnKz@iAd?a=b5[5]1T1Q/L/L.J)G';%8#95/-,&%!      + +   + + +  + + +  +  + +  +  + +  + +  + +  + +     +      + +              +   + +  +   + +    +   +   +   +           + + +           +    + +       +      +    + + +    + + +    +    +    +  +    +  +      +      +         + +   +     +    + + + + + + + +     + + +   +  + + + +   + +    + +          + + +    +   + +  +  +       + +  +   + +   + + + + + + + +   + + +          +               +   +  +    +  + + + + + + +      +     + +    +       + + +         +     + +        +  +   + +  hEfEjHjImJoGnKsMhKsPxKwMwQxY|U~Q{U|WW~SZVWVW]Ygc`ccgjfffkkqjnpskkwr~{v}z|}…|ƃЃ~ǃф֓Ѝ֊Ԓӈْٔܟ׏ғޏݐۑ׎ٍЌԅуɇ҄ńƄzy~vxtjmlj^jcd__V}UU{LsOsMuDdHc>cA`=]>X>U9S3L1K1A-A'9)9$6 2 -!, %%"!   + +   + + +   +  +       +   +  +   +   + +  +      +        +  +  + +       +  +   + +  +   +    + + +       +      + +  +      +       + +  +   +  +        +   +   +  +     +  +  +  + +    + +    +     +         +    +   +        + + +    + +   +  +   + + + +   + + +   +   +  +  +   +  + +   + + +   + +  +  +  +       + + + +   +    +   +  + +  + +      +  +   +        +    +        +    +   + + +  +  + + + + + + +  +  +   +  + + + +  + +  +  + +  + + +  + + + + + + + + +   +   + + + +   + Bf;i>iBo?lDmCwJpIrGpDxJuH}DyJ~NxKyEOzRO}KOUUQWPUYRWT\]Y]d_e]fcdhjeikllrjkpokutyxxy}|{~}׀߆؅؅܆׈ׂԀzxy{~}wxxthlsplkcmg\__S[UVLNOK~IyEp?hBg<_;d4[6X7U5S/Q/K+E(B$G$:#8 ./++""     + + +     +  +  + + +  +   +    +    +  + +        +         + +            + +   + +        + +      +     +   +   +  +    + + +   + + +      + + +        + +       +   + + + + +    + + + +      + +    +     +   +    +    + + + +   + +          +      + + +   + +   + +   + + +       +  +   + + + + + +  + + + + +            +       + +   +   +   + +   + + +  +      +           +    +     + +   +  + +  + +   + + + + + +  + +   + +  + + +  +  +   + +  +  +       +  +   + +  +     + + +  + +    +   hHgFoHiHjGkJjPxOxKrNqQrNtNyR}RX~RrQ|WUZX]a]^_Z[^fbc_bpfnqirnqrnyp|t}~yz|ƃ|ȃ~ɃʄʌΌԌ؎ՅьӔۑڗےڗӒߍۇχݐ˄ЇʃΈ̅~y}yoyoiofdecdcYYWTNvPrNkBfGdBaDbC_9T6X8P4H4F0B(?/>)6"9$3!/ ,'#$      + +  + +  + + + +   +   + + +   + + +      +  + + + +   +  +   +   +        +     +   + +   +    + +  +   +    +      +                 +  + +                            +  +     +    + +    + +  +    +  +   +     +     +   + +   + +      +  + +  +  +    + +        +   + +  +   +    +  +   + +   + + +      +  + +        +   + + +   + + + + +   +   + + +      +   +   +           +  +    + + + +  + + + +  +         + + + +    +     +  + +     +      + +    + +  + +   +  + + + + +     >e=l>o=m@n?iDpFhDyFuFtI}MzGuJ|JMO~NJHNONUSVTTVX\S^[b[\`b]dhc^kngkkjpjtsvozuuuxu׆ރy~~ۄމۆ~}ӂقӂԃрЀ{{wyyrurlpvllcmfdb_cZZTXRPL{LtKsKkHf=i@iBb9]>b7S6V.P2J/F+E(<(?%7 5"//)$!    +  + +      + + +   +   + + + +  + + +   +  +   + + + + +  +      +   + + +  +   +  +  + + + +   + +  +   + +  +  +  + +  +   +        +     + +        +  + +  +  + + + + +  +              +   + + + +    +   +    +    + +             +                +   +     + + +    +  +  +  +   + +      +    +   + + +  +   +     + +    +  + + + + +  + + + +  +  +         + +  +        +   + +    +  + +   +   + +   + + +              + +  +            + +  + +   +   + + + + +   +  +    + +   +  + +   + +   +  +  +  +    +   +  +   + +    +   + + +    gFgJfGiGjKvFmNtLqQuMuNxP{NtWPQ|PZWUXTXWYXd``b^aea`gbmmriqmrwwpywux~|Ă~ɁŇ̇ΊΆ͆ϋߑщޔՏۏՕׇՍҗօ׊׌؇ω֍ԈȄ΅}vw{}~vurlljkebaWZYWP}JvHnLrCb?jDaB\>];P9Q1L5L.E.>)=)4%3%1$0-)$" +   + +  +     + + +    +  +  + + + + +         + + +   + +   +     +   +   +   + +     +         + +                  + +   +     + +  +            +      +   +  +   +  +     +    + +  + +  + +        +  +  +   +     + +      +    +    +   +   +     +      + + + + +      + +  +       +  + + +  + +  +   + +   + + +  +   +  + +  + + + + + + + +   +  +  + + + + +    +   +  +   +           +        +    + + +  + + + +   +  +   + + +   +  +   + + + + + + +      +    +  +  +   +  + + +  + +     ;g@k@s@mBn@j?oDnBmJwGuDxKvEsG}JNMPOIOLLZVTWXW^X]]\[_[_cdgghojamlnecqqiuyoxz{w|{{؃{Ӏ|݈܄ي߅~ӂxЁ{zv}zsuswopoojefhe_b_YWVRVKzHzGzLtApAs@b>c>_5a9N6P,M2G.C*E*='9"6 15-'& "  +  +  + +  + +      + +   + + + +  +  +   +  +  + + +   + +   +       +  +   +  + + + +   + +  + +     +   +    +  +  +                +   +  + +     + +             +  +    + + +        +     +         +      + +   +  + +       +  + +                 +  +  +  +  +  +        + + + +         +      +     +     +    + + +  +   +  +  + +     +  + +       +    + + +     + +   + +      + + + + +            +    +   +   +  +   + + +  +    + +  +     +  + +     + + + + + +  +   +  +   + + + + + +  + + +  + + + + + +  + +    + + kGmDlImKtOpKqKoKqUrSuJsPPzQ~QU{UVYY_Z]ZebX^ec_bdljkcfhonqwsqyrstz}|ņŃăʁɇςȈʃƈ׋ғْ҉ޏՕߏߘݔԑڌӒފێ؉ύˉъŅńĄ}ņ{{vuwunnif_cb\XQQ}QPtKmHqHhLe@`=];Y:Y4U4Q3I4I+@(<&9#9"34!+(%##!  + + + + + +     +  +  + +   +  +  + + +  +  + +  + +  +  + +     +   + + +      +    + + + +  +    + + +  +       +  + + +       +       +     +   +     +          +      +            + +   +    +     +  +  +  +           +          +    +  + +  +  +            +  + +  +   +        +   + + +    + +    +  +  +       +  +  + + +  +   +  +  + + + + +        + +         +  +     +   + +   +  + +   + +    +   + + +   +  + +   +    +     +    +  +    + + +   +    + + +  +  +  Bh?hBgApb>`4[4S3M.S/J/I-@%>*9#:"320(%$#   +         +     +  + + + +  + + + +      + + + +  +      +  + +   + +    + + + + + + + +           +     +  +   + +   +  +  +  +  + + +          + +  +  +   + + +    +              +    +    + +   + +  +  +  +      +  +        +         +      +  + + +  +  +   + +  + +     + + + +  +      +          +  + +     +  +  +  + +  + + +  +  +   + + +  +     +  + +     +  +   + + +           +    +    +       +   +          + + +  +  + + +   + + + +  +  +      + + +  +  + +    +   +   +   +  + + +  + +       +  + +   + + + jJkFjIpIlIvPlHoPnK}LyMnX}NVQP~RS{RZ\\YZ[`]`[ebjblcgejvjtxnpoqts{xxx~u|Ņ̇ЃьЃؓގ҆ӎ֑ؑٓܛډߍܒݐޑؒ؏؍АфАڎЀՅńЄ~yztvrupoddikg`ZRQS}NpKqEkJo@gEa?c';%:#31.*('! + +   +         + +   +     +         + +  +  + + + +   +  +     +     +  +   +   +  + + + +  + +      +  +    +    + +   +   +        +    +    +          +      + +  +  + +  +   + +  +  +    +   +   + +        +     + +     + +  + + +  +    +  +  +  + +   +        + + +    +       + +  +       + + +  + +  + +   +   +   +  +  + + +    +  +  + +  + + +   + +  +  + + +       +        +      + +      +  + + +  + +     +  + + +  +     + +  +  +    +    +   +  +  + +   + +  +  + +   +  jEpGmEjHmLwKtMsHsQwNsQvJzP}RyV}SXyWVU\ZU_`b]_]\^hkhiipmhqnrpmwvpwywuzv„}̂ƃāʁĉʌы؏܋Ҍ؍ԑՐܜݔؐޒ܏ܐوڌ͌ӎۆЍƉ˄ąƀzw~{nuflglgg_a\XXPwPzNwSuEiFeDfEb?Y?S7O4P7K/F0B-A.<&5$3". ,''&!   + + +    +   +   +  + +    +  + + + + +   + +     + +   +   +  +      +    + + +   + +  +   +     +         +               + +   + + + + +  +    +  + + +      +  +     +       +      +  +   + + +  + + + +  +      +    +          +      +   + +   + +   + +  + +  +      + + +    +  + +    + +         +  +  + +  + +  + +  +   + +  +   +  + + +  + + + + + +   + + + +        +  +   +   +  +    +    +   +      + +  +     +   +   + +    +  +  + +   + + +        +    +   +  +     + +  + + + ;iBkCjBpBoGsDsFnEpDtNnGwKtJzN}HO}VNNPQPNUYSY\VaWZ\`V_ba_f\dcmhdlpolhopuuous{wzу|؀zއԁ~~~؄ف}|~vҀ{y{~xtpwrrngpocbdf[WYUVQSQQ}EyGdBn@b*6%4!1#/($'$   +  +    +   +      + + + +     +   +    +  +       +    +  + + +  + +   +   + + + +  + +  +    +               +   + +                +   +  + +  +    +   +    +   +       +       + +   + +  +        +         +   + +  +    +      +  + +  + +  + +    +  +    + +  +     + + + +  +   + +  +     +  +  +        +  +  + +   + +  +  + + +  + + +   +   +  +     + +     +     + + + +          +  + +  + + + + + +  +  + + + +   +  +  +       +       +  + +  +   +  +  + + +  +     +     + +   @s@iAg;k?uCs>vBvAlEvFtIyInGyCN}RKPOQPUQZVNZYZVbY\ZZda`]dfkfcmgllcosrrrt|ăƀ{ҁ}|||݁~}ل߁ۅՄ||Ѐ{ǀvx{xtoknpikbjd`_d^VTVQ}G}GyIxGwCnFoAi=d7X8T2Z5T5N-I+C(?(B$9'2 2,+(%'$   +    + + +   +    + +  +   +  + +   + +  + +  + +  + +  + +  + + + +       +   +      + + +   +  +    +  +      +     + +  + + +           + +       +   +  + +   +   +                    +       +  + +      + +  + + +    +         +  +          +         + +  + + + +    + + + +  +   +   + +  +  +       +   + + +   +    +     +    + + +       + +  +    +  +  +  + +        +  +  + + +    +   +       +  +   +         +  +   + +   +     + + + +  + +  + +   + + + + + +   +  +   +        + +   +   + + + + + + +    +  + +   + + + +  +        + + + + +   hHhGkEnNoJvMpMtMqVvOwNLvN{YRVPS]U[[_[\[_]fdidbohgifknmpoqy|{y~~}ȀLJ͆ϊцх՗̏Ώݐݒ܏ڏߋޓߖڑݐی͌׋·̎̍Ӎ҂ɇȀ{|y{rkhgfa`c[YVRN{SwLpGrAgEb;`=b;T6Y6O4I2G0F-B*;$<'4"1#.)*&'  + + +    + +  +  + + +  + +  +     +   + + + +      +  +   +  +   +      +  +  +  +      + + + +   + +  +    +   +   +     +    + +   +           +   +         +     + +  + +           +       +  +         + +   +  +            + +  +   +  +   + + +   + +        + + +    +   +                +   +  + +  +    +  +  + +   + + + +  +  +  + +   +  +    +     + +  +         + +   +  + + + + + +  +  +  +    +  + + + +       +  +  + + +      +  + +  + +  +      +   Dk=pBo@mBj@q>rG{CsJtGvD{KxK}G}LGILMNXTPRTY]U\W_Z_^__Z[dechgflnfiohkroxx}yxuu}{сτՄ}}}߁م݆݀~ԃπсwyzykqutnonmchbd_ZSVTR~OzK|FxGqKjEkBe=[':$7"3.-,&#!   +    +   +    +   + +   +     +   + +     +    +          +  + + +   + +    +   +    +  +  + + + +  +    + + +   +          + +  +    +     +  +   +  +   +          +  +       + +     +    +   +    +        +  +    +     +        +  +  +   +  +     +  + +  +   +   + +      +     +   + + + + +   +  +  + +  +   + +    +  + +   +      + +    +    + + +  + + + +  + +  +   +  +  +       +   +     +  + +       +      + +   +  +  +     +  +  +  +   +  + +  + +  + +  +   +   + +  +   + +   +  +          +   + +  kOjGjHnKoJsLnOnQwSrTnT|S{VzU|R{[uZR]\\Z\`b_g]Ybfdkcljnkmpvloul{w{zzĀ~˅Ƈ҅ǁӑ׆ˍٍߋړٔܕڙ܏؎ц͐ՉۇЁф҂ŀ~~vtrkpimffahXYTV{QxOuLkKmFnFiB[A]?[6U5L5O4C1F/D-<'>&3"5++(%"   + + +   +  +   + +  +      +   + +  +   + + +        +  + +    + + +  + + + +  + + +  + +     +  +    +   +  + +     + +       +  +  +            +      +     + + + +  +  + + +      +                  +  +  +     +  + + +     +     +     +  +    + +   + +    +  +        +   +   + + +   + + + +   + +      +      + + +    + +          + + + + +   +    + +  + +      +    +   + +   +      + +    +  +       + + + +  + + +    + + + + +   +   + + + +   +     +    +         + +  + + + +  + +   +     + +    >gEmEjBpKp?r@qCvIyJ}IuJzH}JH}P{OONPKRVUXYVXTU\Wc[[_fbdachfkjojmoqnlmotvpy}ỳ{؂|ۋޅہ݋ކلz߆}ׇـ܁|y{v{ytvtvnhcjaha\a^[SRQMNL|IwGkBd$6"4 0.(&&!   + + +  +   +   +  +   + + + +  + + +       + + + + +    +     + +  +   +  + +   + +     + + +   +  + + + +     + + + +     + +    +   + + +   +  +             +  + + + + + +  +           +     +               +             +    +  +  +          +   +   +            +  + +   + +      +    +     +  +  +       + + + +   +  +  +  +     + +   +  + +  +     + + + +  + + + +      +    + + +   +   +  + + +    + + + +  +   +     + +   + +     + + +  +     +  +   +   + + + +   +   +  + +    +       +      +   + +  + +  +           + + +  l@oOlHvMxHoSrNuNvOvOyRyRxNzXR\TV\Y^]^^b^g`\iggmkflllsmvyr{yxwr~~yzyɅȉɍΊ΋ІҎΊيٌܐޒ݊؏ߒޗ׉΁͇ȌƂ~}Ɓ|zutqnhgge]`[XTWRuPuIoIlHcCh@]@[;Xi=e=f9[:T3X,L2H,D,@):(@%7!61!-+&(#     +   + + + + +   + +  + +      +    + + +    +   +    +  +   +       +       +    + + +  + +  +   + + +  +       +   + + +  + + +  + + + +             +       +      +  +    +  +  + +        + +     +          +   +        +     +      +        +     +  +      +    + + + + +     +    +   +     + +   +   +   +       +   +  +   +   +  + +   + + +  +       +  +         +  + +      +    + +  +  +         + + +  +    +  +     +    +           +  +    +    + + + +     +   + +        +  +     + + + + + +   + + +   +    + +  + + +  +  + +  +   + + +   + +  + lKwHrGqOsK|PvPnVuW}RvQ|Sz[~W{UUXVZZ^a__Yaaddfbhhnkjrorwnpnuxwx{~}{zŅɇ|ʂȌφ͈ҌˏҐߊ؎ړٛܝٜ՗ږڐ֍ێψ͉фąЃɄ€Ą|yxvqtpqgh^d`ZUUyV}M~LkIkEfDkBgAd=[;Y;T7L,G1G(@.D)>$4!5"1+)%%     +  + +   + + + +    +  + +   +    + + + +             +   +  +    +  +  + + + + +          +   + +   + +     +   + + + + + + +           +       +  + +  + +  +   + +   +          +    +     +             +   +    +                  +  +     + + + + + +   + +  + +     +  + +   +   + + +  +     +   + +  + +  +  +  +   + + + +  +  +   +   + + + + +    + + +   +    +  +  +         +   +    +  + +    + +   +    +       +   + +  +    + +     + +  +    +   +   +            +  + +  + +   + + + +        + +  +   +  + +  Bl?q@pBqDjDsHrDrGwKzLxKuLxM}QHPzMNOQPYVNR^X[WZ_\`_]da]eddiiiovjlvlnulypx}vy||܄Յډ܂ېق݃~Ղ{|}yxvtunumhmhfca^ZYUWSTNL}KvHnDgBhi;d;Y5T4T4V0L0K)E-D,=#7$7!/--'$!     +    +      +      +  +    +         + + +   +  +  +     +   + +   + +  +        +  + + + + +  + +     +    +          +        + +   + + +            +                 + + +        +      +        +        +    +  +                    +    +  + + + + +      +   + + +  + +     +   +   + + +      + +     +  + +  +      + +  +    +    +   +    +      +    +      +       +    +   +    +  +  + + +    +  + +   + +  +      +     +   + +  + +    + + + + +    +  + +    +   +     + +  +       + + + + +     +  tIlJvLvKoPmJ|OwOtXzSzLTPVWY[WW_Z_e[_b`^cacjjglmluquqtxtwzvzxyȌŊÄЋ̋ϑʆԏӖ֌ёۘܙَٔхˊɄ˄ևą~΄ywwuqwqglk^b]b[WRO}MtPlJhIiDhBdB`=V:S3M0R/I+=-A-:$8)9%.!3'%%   +   +  +   +  +    +      +   +   +   + + +       +  + +  +  + + +  +     +  +    +     + +    + +  + +   +   + + +      + +    +      + +       + +       +   +    +      +                       +         +  +    +    +  +  +  +   + + +  + + +  +  +   + + + +   + + + + + + + +      +    + +     +   +  +  +       + +  + + + + + +  +   +  +   + + +  +   + +     +  +      +         +   +    +   +   +  +  +  + + +  + + +  +       +   +  + +     + + +  + +   + +  + + +  + +   +  + + +       + + +  +     DlDq@sAtCnDzGvAwL}IyG{HwO{HNOQUOLTRZ\UXWYYY_^_d]a_hg`fqlhkopnujqttwrwszyʂx{|؃߁މߐ߆|σyu{q{xzrqljhih_W^\WZUJLKsFuDnCn?g;f9[:^4X3K2O*J-H.F-9'? 5 2#6-+$"   + + + +     + + + + + +  +  +  +  + + + +    +  +   + +  +  +  +  +   +  +   +  +    + +   + + +    + +   + + + +    + + +   + + + + + + +    +      + + +   + +     +     +       + +  +         +   +          + +        +           +     + +          +  +  +  +  +   + +   +    + +      +  +     +      + +    + +   +  + +   + +     +       +   + +    + +    +  +  + +  +  +   +  + +   +        + +       + + + +  + +  +           + +  +    +      + + +    + + + + + +   +  + +    + +      +    + + +  + +  +  +  + +    +  +   +  qKzJlQuPsHsLQwTzS|TW|QuV}PUYU^[^]b\_Zbenfgjfdpkroysurwspwy{x~ÀDŽ‚΄~džՋ؈ҐՇ،ؓڒڈߘݐْ܊ՉЎʅيӄۉ˄zy~tytwplkqdc^aVVR}W{RzPmHwEbCiC`:Y8]AY6M3K3J.C/@-?)9#5&4!. .(    + +  +     +   + +  + + + +     +        +  + + +      + + +    + + + +  +   + + + + +    +   +     +     +   +   +  + + + +   + + +        +   + + +        +           +       +           +     +           +        +      + + +    +  +   + +    +      +   + + +  +   +   + + +    + +  + +       +    + + +  +       +    + +  +   + + +       +    +   +  +  + +    +     +    +  +        + +     + +         + + +  +    +  +  +   +  +   +  + +  + + +    + + + +    + + + +     + FlBhHtFnFvCsH|EK{JKwF}O}FO|JMUQQVTRUSPT^]\\Z_`ieehglggillqgtqnmpwxɀx{r~x}߄{އ݃{||܂yunupsssdkfd^f^Y^XQQSNJsD}GsDkCc'8%6#1"-)'$    + +      + +  +     +       +    + + + + + +  +     +  +   +  +  +    +   + +  +  + + + +     +  +  +  +  + +    + +  + +  + + +  + + + +   +    +  +  +   +  + +                 +       +     +    +               +      +        +     +                     + +              + +   +       + +  +  + +     +          +  +  +      +  +  +    +   + + + + +      +    +   + +   +  +  + +     + +  +  +    + + +            + + +  +   +          + + +  +   + +  +      +     +   +     + + +  +   +     +  +   +  +  +  +  +   +  +   +  + + +  +  +   +   mMsLrHqOrIvPtLtLxN{P~RO|P[PZ\S[_]Y_[aca_afdjiljmnguottxwtw|vwƃ€ÂňЂʄ˄҇ȅٍ҇ۏڑٖٗߗߓ܍ٖґ܍Յъˊ̅†…ńƃ|~tymsiekaaWZ]WV}QwI{PkCdG`D`B]=Y'=$5%1!,+''    + +   + +    +    + +   + +   +  + +    +    +      + +   + +    + +    + +  +   +  +   +    +  +     + +   +       + + +  +    + +         + + +    +             +     +     +      +    +         + +       +            + + + +          +        +   + +   + +    + + +             + + +  +      + + + + + + +   +  +  +  +       + +  + +  +    +  +   +      +    +      +        +  + + + + + +  +  + +   +   +  + +  +        + + + +  +  + +  + +  + + + + + + +  +   + + +   +      + + + + + +   + + + BoCs@rFq@rBsJ{HxD}IKDI{NGSJQMRRRWQ[[[^bYcc_ee\bfhkjdhinohqnnmupsvzx|z{ւz~׀ڂ}ڂ؊ق׃ր}Ճw|yyvqorlhje`ed_Y[VUSN|IzIyE|Bjb<]=Z4\7P0N0H/I-A'A&7(1#0!3**$"   + +   +     +   +      +    + +   +     +         + + +    + +     + + + + + + + +  +   +        +  + + + + +  + + +   +     +     +  +  +      +  +     +    +            + +  +   +   +  +     +  +         +               + +              + +   +       +    +       + +   +  + +     +  +       + + +    + +  + +   +    +   +      +       + + +  +   +   +  +  +   +   + + +   + + +   +    + +  + + +      + +        + +  + +  +        + + +    + + +  +  + +    +  +   +   +  +  +   +  + +   +    +  + + +  + +  + + + + +      +   +  +  + +  + +    + + +  + + +  oKpIpHsKqIwRwNtP|Qx[zStWzS}VW_RV`_\Ua_aacdebajmgvontosuvtwuvzƄŇЅ͇΃ӈ҃ӑݍӐِؒߔߕݓڙՖݒۊ͌ψɉ͆DŽŀvzxvoktgoeq^`\YSPPwQ|NrIjGeEa:^)=&4"4))(&$  +     +       +     + +  + + + + +   + + + +   +   + + +   + +   +  +        +      + + +  +      + +   + +   +  +  +   +   +  +            + +    +     +   +    + +   +   +   + +   +              +            +      +      +     +    +         +    +      +  +        +   + +    + + + +        + +  +   +  +  +   +   +  +  +   + +  + +  +  +   +    + + +     +    + +        +  +  +   +   +        +   + + +    + +     + + + +   +   + + + + + +   + + + +   +       +  + +     + + + + +  =sEoBrBwBzDnGyH|ItLzKwNB}L|N}OUONSTVUXWW[ZXXY`b_]gf_aegfelsnmpsrsstrvsx}|΁x~}ރ~؈݊߅܍ߋۆ~~~߁x{yttumklpedfd_ZZWWVPP{LrIoDwk=b:d7^7U3P.M1M+H-A*B(;'8!6"32('!#  +  +   + +      + +  + +   +       +  +       + + + +      + + +    + +  +  + +    +       + +  +    +           + + +   + +  + + + +     + + + +     + + + + +    +     + + +     +   +  + + +  + + + + + + + + + +      +   +   + +        +    +  +  +     +   +    +     + +     +   +      +          +     +  +     +  +  +    +  + + +  + +  +   +    +    + + +   + + +    +  +    +   +  +  +  +   + + +   + +  +    +   +  + + + +   + +    +   + +   + + + +     + +          +   +      +    +          + + +    +  +       + +  + +       + + + + +   + + + +  + + +     + +  +     + +   +    +    +     tPoLoSoLqMtLrOqT{SxPsRX{Q}\TTY_X[Y]`_]bcdibhjgffjlntvpvzwx{{ɆЇЌЊЕދы֙ߑޔژ؍ލׇߐʇÊɈЈy||}xqlhdof__YX\RzSvLnMqIfEkHeAW>^)=':'3#6+*$#  +   +  +  + + + +   + +   +           +    + + +   + +      + +   + +  + +   +  +  + +    + + + +     + +  +  + +  + + + +  + + +  +  + +       +  +       +     +   +  +   + +     +         +       +  +                  +   +      +        +           +  +   + +    + + +    + + + + + +       +   +  +     + + 3         + + + +  +   + + +  + +  + +   + + +  + + + +  +   +    +  + +  + + +   +   + + + +      +       +  +    +    + + +    + +  + + + + + + +  +     + +  + +    +  + + +  +   + + +    + + + +  + + +  + + +   + + + + +  + @kuEtDwG|FwF~K{MxLzH|FMMLLOTRUWVTWXURTX[_^bhbgbegj`kjijpisounrtxqȀ|{nz}|ن؂؅}݄߁~܀ہق{zu|wzvrpofie`b[b[\YSPQvH}EzEiDp@j@h=a;^:Q7S4N2F0D+H'=(:":%6/-**#  +    + + + + +      + +  +   + + +  + +        +  +  + +  +  +    + +    +  + +  +    + +   +  +      +  + +   + +  + + + +      +   +  +  +                 +     +   +      + + +  + +  + + + + + + + + + + + + +  + + + + + + + + + +   +  +     +           + +  +     +  +       +       +     + + + + + +  +  +  +  +  + +   +  + + + + + + + + +       +   + +   + + +  + ',   + + + +  + +       +  + + +     +  + +      +   +   + +      + + +      + +              +  +     +       +   +  +      +   +       +      +       + +    +  +  +    + + +    + +   +  +  +   +   +   +   +  +   kKsIrNsLmOxLxRwQ}UwQ~SzW|TYTWXZ[X]__`__hckigluglqirtwosvwvxyȁ·փƈ؋̈ؒӍۆߑږߎܓސݚևܑޖԋՉ̅׊ʄȉ̃ʀy{vwnydidf^e_\\SRyLkJlOlCiF^?h=Z6R9Q4J7I+J1C'A*;$:$4!.!*.&    +   + +   +  + + +   + +  +  + +    + +  +    + +  + + + +  + + + + +    +  +    + + +  + + + + + + + +  + +   +         + +  + +   +    +    + +  + +          + +       +         +   + +     +    +          +  + +  +   +      +                +      + +  +   +  +      + +             + +     +    + +  +  +  + + +  +  +  +       + +   +     + +  + ++ + +   +    +   +  +  +  +  + +  + +  +  +   +  +  + + +     +  + +   + +    +       +  +   +        + +   +         +   + +   + + +    +   +   +   + +   +     +   +      +     + +    +  +  + + + +  + +  +  + + +   + + +   >lFkFsEoGnFrIuEzIwLzD|NuFG|NLNSRORT\WV\XYZXV`]^aefdeejggfjjmqmklouxvvz~΀}z}{{~ބӌ߄ڈ|vހ΃Ӊ̀{u}zwokfhdebdb\XVXOK~K~P{JqAnKnCc;[<]5\8X3M0L-G*B,@)@"a@d?];W8S2P7J0I0C0@'B$;&7"2,!+&%   + + +   +     +    + +       + + +   + +  +        +   +         +  +  +  +  + +  + + +  +        + + + +   + + +   + +   +  + + +      +   +     +  +   +  +     +  +         +  +  + +     + +  + + +       +    + +  +   + + +  + + + + +  +         +                +       +   + +   + + + +     +      + +         +   + +  + +  +  +     +     + +   + +   + + +   +    + +  +   " @'$ +   +     + +    +       + +  + + + + +   + + +   + +   +  +  + + +  + +   +  + +   + +  +  +   + +  +            +    +   + +   +    +  +  + +          + +   +  + + +          +     +    + + + + +     +  + +   + + +  +BnBo%;)7$8"3$0*+$     +   +           +  +  +  +    +   +     +     +  +           +  + + +  +     +  +    + +     +   +  +  +  +   + +  + + + +     +     +           + +             + + +              + + + + + +    + + + +    + +    +       +        +          +  + +   +   +    +          +   +     +   + +     +  +   +   +  +   +    + + + +  + +   + + + + + +  + + +   1'4$" +    +      +  + +  +  +  + + + + + +     +       + + + + + +   + + +    +     +    + + +      +      + + +   + + + +  + +  + +       +  +  +   + +   +  + + + + +   +     +   + + +  + + +  + + + + + +  + +   >sFqFqElGvEuHwHsD}NuH~JFLMMSPOSS[SWZXZU\Xf^ac]b_aijdkighmpnjrnxwxt{t|ӂx}{؀Ӈه݅ߌނو݅ڀ҆~rvqrstqlheg^]b\ZTVPINo?rDqHpBj>^B\<]8R6S2P0P1D-D,E(>):&9$//,*#!    +  +  +  + + +       + +     + +   +   + + + + +  +    + + +   +         + +  + + + +   +     +  +     +  +  +  + +    +  + +      +            +        + +       + +  +  + + + + + + + + + + + + +  + + + + + + +  + + + + + + + + +    + + + + + + + + + +  +       +        +    +   + +  +   +        +       + + +   +            +      +      +       +             +  +  +      /#@/  + + +   + + +      + +   + +       +  +  +   +  + +  + +  +  +         +      +  +  +        + + +      + + +   + +     +  + +      +     +      +     +  + + +   +    + +      + +          + +  + + +    +     +jEsQsIrLuMzPwR{QSu\{TxSS~VW[UXX]^dXfh_dffjoghilnomusx}ox}z}zȅτƆɉΌΌЎӍёێӔޝٛݗۖߍܕَڈԇֈȃ{ňvv~xtqmvhe`b[WXVSRwIuMgKkGdD]A[9V6R9U5L0J/G.C,?'6'4"0".+*"  + +  +  +     +  +  +  + + +   +  +  +       +  + + + + +   + +    +       + +  + +  + +   +  +    +        +   + +  + + + +      + + + +              +                + +     +       + +        +  + +   + +   + + +  +     +  +        + +              +  +      + +    + +   +                    +            + + +    + +   + +  + +  +  + +    +  + +  + +   +  +   0$2$'   +   + + +      + + +   +     + + +    +    +  + + +   +   +   +          + +   + +   +  +  +   +  + +  + + +  +  +    +   +    +  + + +    +   +   + +   + + +  + + + + +   +  +       +    +  DfEmCvGnCuAuGqCyFtIxJyKLK|NXPRVTRTXYXPbZXY[db\_adbeejkhilmsjoktpw~xsyz{vz~~}܆݅ۈ܁݊߁zـzqvsutsohlcfdb^\]Q[OSL}PxHmGsAg8c)7&tKoHsFuKyKxG}I~JILLRNVNQJUNTQ\[\Y\\`_bZfcicghhjklvfjsp{uxywy{xz{{لԂ؃ހ܄؇؂܁Ӄ{zyvutorggmfdbW[ZZRTL}QuMzLtDnDrCd>k<_:[8T5V2N0J+E0E'<'9$9 42/+"!   +      +   +   + +   + + + +       +  +   +  +     + +      + + +             +  +  +  +  +  +   + + + + + + +    +          + +  + + + + +  + +     +  +       +   +      + + + +           +    + + + + + + + + + +   +  + + + + + + + + + + + + + + + + + +   +  + + + + + +  + + + + + +  +    + + + + +     +    +     + +  +  +  +    + +    +  +  + + + + + + + +  +  + + + + + +   +  +    +    +         +     +   +     + +         +  +   +   + +   +  +    + +  (#       + +  +         +    +     +     +    +  + + + +  +   +    +   +      +  +    +  +  +   +    +  +  +     + + + + + +  +  +     + + +  + +   +   + +        +  +    +  + +  +   + +    +  + + + nFoKuMnPvM~IyRtSuTUuT|USR]WY]X\]gdafcai`nkkkknms{porwxyy}|‡̊эłЋԋيӋԌЎؕωؓޜݐޖۊӓԑُЋσ͉ɂ~xy|uoigfjb_WY[XyOxNsLkKfEgBa;_>U7P4S3R3I2C0C,:*=&;$5 . .($!   +   + + +  +   +  +   + +  +  + +    +    +  + +  +  + +  + +   +   +  +    +   +        + + +   + +   +  + +  + +  + +  +    +   +   +  +     +  +                    +     +  +            +   +      +    +   + +   +   +   +  +  +     +  +   +   +   + +    +     + +   +     +      +  + + +  + + + + + +  +   +            +   +    + +  + +   +        + +    +  +    #    +   +       + + +  +  + +   +   + + + +  + +   + +  +      +      +  +  +     +       +    +  +  +    + +  +   + +   + + +  + +   +   + + + +  + +   + +  + + +   +    +       + +   + + Cm@sFyDvAzDvFsHyG~CCtN}KGLMPTVSOTSUTP]Vb[]]a_]gfdb`Zgjpriivporsuuxswy|z~~ׄ݃|ۈۄӅՁw҄~yqnsmlfhhc^`YY\TRZMxL|IpGnEkDaAf<^+9&6#2!1, )%    +   +   + + +     +    + +    +  +    + + + +     +   + +      +    +           +  + + + + +   + + + +   +  +   + + + +     +   +    +    +  +   + +  +      + + +      +      +        + + +   + +      +      +  +    + + +  + +   + + + +  +  +  + +  +   +   +     +  + + + +  +  +    +  +  +   +    + + +   +    + +                + + + +          + + +   +  + +  + +   +  +   +  +  + +    + +   +  + +   + + + + + + + +   +   + +   + +  + +   +        +   +  +         + + +  + +  +   +   + + + +      +  +       + +    + +   +  + +   + +    +     +    + + + + + + + +   @qGlAxDrGuCsLwJ{GyM~H}I}LO|RLPTPTMYZYZYWRZd[dc`b__dkdhkipqssosrrt{uswx΀{΁τ׆ׂ݅ߊ~܍~҅ہx͂vr}rnllilcf\\]XQYPM|NwGsHtIh>jAe>b=a8^6X4O0H+J,G'A'?(:!6 1+*%"   +  +    + +          + +  +   + + + +  +   + +  +             +  + + +        +   + +  +  +  +  +  +    + + + + +  +   +    + + + +   +    +   +   +  +       +          + +   +  +  + + + + +      +  + +  + + + + + +  + + + + + + + +  +  + + + + + + + + + +  + + + +  + + + + +  + + + + +   +    + + + + +  + + +   + +    +  +       +         +    + + +         +    + +    +  +  +   +      + +  +  +    +  +   +   +  +    + +     +      +  +  + +  +          + +   +         + +    +      +  +   +       +  +   +     + + +      +  +  +    +  +   + +   + +   + + + +  + +  +   + +  +     pHrOmLvNqPrU{RvLyUU|W|P~U~PXW~V^\ac\_ccbhcaeqnrmmqrpzxuwt{ux~ł}̀ˌЍʋɊАώҋӍڐ֔١ٗۗݑܔކۏٍӏ؋ێы˂΃ʄ|{qqprkgb`Y_[WWQxSvOlGmFhBeAa>R@S7P5L3P1N-C+?*9'<#0$2"1,#"   +       +    +   +  +  +    + +  +  +          +    +       + +  + +     +   +  +  +  + +   +  + + +  + + +      +  +   +   +                           +                          +        +  + +  +  +      + +  + +      + + +    + +  + + + +    +   + +  + +   + +    + + +   +         +     +        +   + +  +  + +      + + + + +   + + + + +      +    +   +  +     ! + + + + + +    + +  +  +     +  + +   +    + +        +    +     + +   + +  +  + +  +  +        + + + + + +     + +  +    +  +    + + + +  +   + +    + +   + + +  BnGrHpHtCw@wGxD{F{J}HIORLPPPSVSTUXX[W\a]_`[dbaaf]dnmgpqqlosmrurvu|{zv}܀׀ӂچޅ߁|هz~ԃрovospljlhni^^W\WOXIPDwGpAoAkAh<^?[8Y7Q3U1O0D.B*>)A&:#3 /"+,)#   +  +  +  + + + +  +   +     +   +    +    +  +          +         + +    +   + +  +    +  +    +  + + +  + + +    + +   +  + +    +  +    +     + +   +        +     +    +          +      +  +  + +  + + +  + + + + + +  +  + +  + + + + + + + + + + +  +  +  + + + + + + + + + + + + + + + + + + + + + + +  + + + + + + + + + + +  +  +  +  +          +       +  +     + +   + +         + +    +  +   + +  +     +    +    + +   +     + +   " +  +       + + +      +   +  + + +   + + +      +     +  +    +   +  + +     + + +  + +   +  +  +  + +  +  + + +     +    +  + +    +   + +  +  +    + +  +    +  +   + + +   +  + +  +     rKvOrOxKzQwVuNyZ{OSWTTSYY[aZ\_c`bchelieekhmkomqou}~w~}z|~}~Čǀ׋ȂъӅωؒҏ׍ߍޖט܈ݔՍӑٌ֌Љ̈̄}}{tnlffg`b_ebZ|MxTxSqMqKgEf,:&;$2#3!+-#    + + + + + + + +     + +     +   +     +  + + + + +     +  +         +  + +   +  +  +     + +  +      +   +   + + +  +   +   +       + +             +  +            +          +    +   +  +    +   +     +  +  +  + + +  +     + +     +   + +     +    + +    + +  + + + " +    +   + +  + +   + +  + +  +   +  +  +  + + + +  +    +    +   +    +  + +  + +    +       +  + +   +     +         + +  +   +  + + + +   + +    +  +       + + + + + +   +  + +  EtAqGrC|HuHzL{MLyNJ~MOLMQUXQRXUSTXZZ`_a^Z]\d_dccjjeqpipqwupstq~yw~~z|ىՇކ݉݊܆܁|҃ԁ}zzsvwuwlgma`bZ`_WXLSJ{G{FtCo>h;h<_7Y8W6Q1I/K2I*F$=$>&5 8--+%!  + + + + + +   + + +  + +        +   +     + +  +      + +      +             +    + +    +       + +    +  +  +  + + +  +                +   + +               +       +                +    +   +       + +      + + +    +  +      +   +  + +     +    +   +    !$   +  +     + +   + + + + + +    + +  + +            +     +    + + +       +           + +  + + +  +  + + + +    + + +      +  + + +            +        + +  + + + + + +       +  gMwJsJnRtNwQpS|S~UxW{UT}U\V\_^X^eb\`fcleklpoejtopxokuv{}ÅẤ͈ɉʋғՈӐґ׈؏ԑוޚٍۙٗڐܒ݋ӉӇ̇։}„{wvrlkibe_a_RRMzXzJpIlFiDfB_=^=X7R2P2I2F-E*<'9'7&2#//*#   + +    + + +   + + +  + +  +    + +           +              +   +      + +     + +     + +  + +  +        +   +  +    +  +   +  +   +             +          +              +   +       +     +  + +   + +    +  +    +    +        +  +         ""! +   + +   + +  +    +       + +  +   +       +    + + +  + + +         + +         + + +    +   + +    +     +  +  + + +   +  + +  +  + +  +  +        + + + + +    +  +   BlGqHsGzLtEtJpCE~KJLMIPSRUUQZP]MXXUXa`a[_hd`ckikhgmlmtvrnvwszyzzzҀx~ӄٍԄ܆ۀ|~~xvunwnmljhf^_aaXNUSK~Ju\:P;R5S3G2H1E/@*;'7&2 1#/''"   +  + +  + +  +      + +   + + + +   +  +  +  +       +  +        +       +    +   +  +  +  +  + +   + +   +  +   +  +  +  +   +            +              +           +        + + + + + + + + + +    +  +  + +   + + +  + +  + + + + + +    + +  + +      +     + + + + + +  +   +  +    + +  +      +      +  + +   + +      + +        +  + +   +  + +   +    + + + +      +      + +   + + + +  +    +    + + + + + + +  + +   + +  +   +    CtEpCnGzJvHCMN|LM~NLLOSSRVTRUSUWWS]^Zba^^`hdihjhlqnngqqrnur{vx~҂ڂ|~܄}ׅ҅|xxy~sqnjpkgga^\YWRUTM~EzIqHq@k?f<`7]9X6R7O+J+H)F.B'=%9"332+(!   +   +     + +  +    + + +    + + +  + +  +     +  +     + + + +     +  + +     +     +        +  + + +  +      +       +   +    +  +         +   +  +        +   +             +         + +  +   +    +  +        +     + +    +  + + + +   +  +          +  +       +   +     +   +    + + + + +      +         + + +   +     +   +  + +  +  + + +  + + +       +          + +  + +    + + +  +  +  +        +                   +  +   + + +  +    +    + +  +            rIrNnQyOyN|RzXS}S~S{VZW^W]]bc`d`fdggheedopfjjpwpwvvxwy}}хÁ͉Ȅčђԏڒؗ͒ۈޙЕߕؕߞޗߙ܍ϊӍͅǂDž̂Āuptqmjkl[_[]TNzRwPzHpBdAd@^>_:Z5S7L6I2I-D(>)9&8'5%2, )% +  +     +    +  +  +  + +       +  + + + +  +  +     +              + +     + + +  +  + +   +  + + +  +  + +  +   +             + +             +             +     + +            +   +       +  +   +   +       +  + + + + +        +   +  +      + +        + +   +  +  +   +   + +              +       +      + +   +  +   +   + + + +       +   +   +   +            + + +    +     +  + +   +   +   + +   + +   +       + DyHyEsIzFtFzK{I|I{NK~QTRMOSRRRURTWU\]^^_Zg`chcggllinnormvxmus{tu}{Ѓق~Ճ߄ڀ|w}swswpmlegfbkZXXVTNI{Q}HoGmAjBe=^<_7T:T6X0O1K.H*D&;$5#7-/(#!   + + +  + + + +  +       + + + +  +  +  + + +      +     + +  +  +      +                     +   +   + + + + +  + +  +  +    +    + + +    +        +  +              +           + +   + +    +  +   +              +      +     +      +  +     +  +   + + + +  +    + +  +       + +   + + + +   +  +  +  + +  +       + +    +    +   + +  +        +   + +    +    + +  +        +   +   +  + +      + +           +   +       + +   +  +  + + + + +    + + +  +    + +wMpOtOtR}RNwX{V~LWWX}\YR^__\]d_bhgdimnkfromoqusmps||~zuŇŇ~ϊ˂͆ь҈ՎՎېԑْړړۑד܄̂̅τ~ztrwkoojdkaZVXYPrLyFlJlIcC_>]=\7W:R4Q.K4H.G*<(6"9"3".)"    +    +  +  +  +  +   +  +  +   +     +                +  +     +      +      +     +    +  +      +       +        +   +                      +    +     +               +     +   + + + +     + + + + + + + +  +   +  +  + +   +    +  + + + + + +   +!     +   +   +  +  + +  + +     + +  + +  +   +  + + + +      +      + +    +  +        +  +   + +  +  +   +   + +  +   + + +   + + +  +  + + + + + +    +CqFEqHuD}G{HzFzMNyHOPOORZSSYPTU^[YU\_ch_edeidffpqllqmputyxs|}{vywԁف}܅݅~Հmxxuwosdleeb``YXSYSR~NuIpGnBgFg;a8^8X;Z4M/M.F-E,@&C$7 7"1 1&)'   + +    + + +      + + + + + +  +    + +  +   +   +       + +           +   +               + + + + +    + + +   +  +  + +   + +  + +       +    +               +                  +     +            +      + +  +  + + +    +   + + +  + + +    + + +  + +     +  + +  +            +       +    + + +   + +       +   +       +     +      +  +  +  +  + +     + +  + + + +    +  +   +  +   +       + +  +    +     +     + + + +  +   +    + +   +       + +    +pOzNzQwSyRzMzM|UzX^WMX]]Yaca_a^hddlmcifllkopqvsxwvxzÂzĉ̋‡ЉȈΈɌ֏·ՌԓڗݑݘٚۗԅΊҋЇӆLJ}wrtnrik[gbYXUR|UvJuHsLnDcEb@^=^=T6R3M0H-D0B)@%=$0 2*'$   + +         +    + +        +     +        +        + +  +       + +  +    +   + + +   +  +    +     +      +              +       +               +   +              +     +          +    + +  +  +    +   +    +    + +  + +   + +    + +   +  + + + + +      +  +  +  +       +  +   +   +   +  +  +            +  +  +    +    +  + +    + + +  + +  +  +  + + + +  + + +  +      + + +        + + +  + +  ErHtFyE~GzFvH~JzKL|L~MQOTXRRUYTVUTZ[Z[caa`[_e_ghegllkivlqvr}o}q}z{тڃ~}܁݂ߊޅԂwЀvzyulmjngee`[Y[XSKK{LyCnGn`<`9c=X4Q1R2E-J'@)<*4821-''  + + +  +   + + + +  +   +  + +   +   +     +  +    +                   + + +   +  +   + + +        +  +   +    +   +        + +          + +           +          +   +   +       +    + +  +  +  + +   + + + +      +    + +   +  + +  + + + +  + + + + + + +      +          + + +   + + +   + +    + + +               + +   +  + + +   + + +  +          + +  +  + +   +   +    + +   +  + +    +  +  +   +     + +  + + + + + +        +  +     +  +  + +    + + +  +uN{PuSvTwTwU~OyT|OUOY_Y\^_^]c_ceeijiihpiuqluqmrxowv{yǂwLj}ņ͈̇ʉѐ΋ҌՏڐّؓבޕߒِܔۈ܏чӈ҉΀Ɇ~|x~sotlj`kd`\R}ORvJrMnFfHgB`BY;^>T7Y4N4K/E-C)=+7&5"3",)%"  + + + +   +    + + + +   +     +   +  +   +         +             + +    + +     + +     +   +  + +   + + + +    +      +        +  +                    +   +              +      +     + +    + +  +  + + +     +   + + +  +   + + + + +        + + + +  +       +      +    +    +  +    + + +  +  +   + + +  +      + +       + +  +    + +    + + +  + +  +   +  +  +  +  +     +     +           +  +  + +  + +  +  + + +   +HwD{DtFyM{HzKKKNORNPSSSRO[YXS__\]ad_\]_hbikmbmkpjtgrmxtpyx}z~||ԀӅ~؈~߅ށ܆؄~{t{swopmnjege]Y^\LTTxN{IvLsAlAe>h<^:\8[0P0O3K,L(I*D); 7"11+)!"  +      +   + + + + + +      +   +  +   +  + + + +    +  +                 + +    + +  + +        +    +   +                 +     +         +   +         +       +  +      +  +    +    +         + +   +  +  + +  +       + +   +   + + + + +   +   +   +       + +       +  + + + + + + +      + + +               + + +  +  +  + +   +  +  + + +     +        + +     + +   +    +   +    + +   + + +  +     +        +  +  + + +  +  +      rPxUpQvVwOzNQWzZ|XTYW~XU^^`]dcZfgciqmlooskpuwy{x{y}xx„{ɄNjǂÉ̅҈Օאʉ݋ڒ܏ߎْݝܔܙۍّӂև҇Ҁ|w~|spglogd^`XQ~S{VwKzKsJoEiBg@f=\>W6S5Q6K/H+C-;';&9#4!(.'!   +  + +   +  + + + +  +   +     + +  +   +  + +  +   +   +                     +      + +    +  +   +      +    + + +   +   +                       +       +                                  +       +  + +   + +  + +     + +      +  +   +   + + +  +     + +  +    + + + +  + +    +       + +  + +  + + + +  +                   +   +   +  + + + +   + +   + +  +  +        +      +    +     +         +  +  +     +   +     + + + +     + + BrAuGxL{H{L{GJH{PILMVORUWUYXUU]V\[`X_cdlhbhhgllkqimmoopqxuxyu|~܀}|ԃֆބ~ۇ~xكҀԁxx{srppmh`bc]^\SJMLNqNqCuCoCg>_>]7W1W3N.K0K*G'?'8&7%4/*+#"    + +   + + +  + + +   +  + +    + + +   +   +      +  +   +    +   +    +  +           +     + + +  + + +   + + +   +   +      + +              +            +     +      +  +  +        +             +   +  +       + + +  +    +      + + + +   + +  + +    + + +  +     + +   +  + + +  + + + + +   +   + +  + +  + + + +        + + +  +          + +    +     +         + + + + +      + + +       +     + + + +  +   +    +  +   + +     +  +  +       +     +   + +         rRwSQxQ}ST|W~TZYWWU\]YdYdh__eidgfglmptprr|o|svz{x|Ɔ҉ʇՐ͊АאҏڇޏҖۓܐߐފ͔̈ɉ؂Ќ~xxstuflcn__[[VUzOzJrMnIjDiBa;W;X:Z7N7F0F/F-A*:'7%2 2)#!   +   +      + +  + + +   + +    +      +  +       +  +       +   + +         + +  + + + +     +    +   +  +   + +                    +       +         +           +  + + +                         +    + +    +      +     +   +         + + +  + +   +  +   + +  +    +  +   +     + +     +   + +      + +  +  + +    +     + +   + +  + + + +   + + + +     + +  + + +  + +   +      + +      +   + + + + +   + + +  FyIvG{I{FuHvH|N{M|LORXWVURTSYN]V\X^Y[c^aibkcdhfhqlnkoqurnp|{yɂ~}tڂ؇܂ى݅܏ۇ|zytwzsqqlkhlb_a\WSVUM|KzHvFhCpi8T5R0J-D*F&A*5 ;&/ 2-(#      +         +   +  + +  +  + + + + + +     +      + +  +     +         +   +  +        +  +  + +      +    +       +         +       +                   +         +  + + + + +  +  +  +       +        +  +     +      +           + +  +  +     +    +       +           +    + + + + + +  + +    +   + +  +   +    +   + + +         + +     + +    + +  + + +          +  +   +  + +      +  +  + +        +    + + + +   +       +      +  +   +  +  +  +  + + +  +  + +  +  + +  +   +rQR{QxQ|P|V}QNTV}S\[W[`[d^`__cbimekgflsrpovqyts{}}ƆĀć͆„ˋ؍̎ЌӈЎӅ۔ے՟ݕܗ˅ӌЎ̅Ȅ|wsxvqkjgh_dYWYSzNxKoOqFlHfDaA`;^9V7R2K3F,B,?,='7!6"/ )$$   +        +  + +  +   + + +  + +   +    +     + +    +     + +          +        +  + + + + +  + + + +       +  +      + +     +      +   +       + +   +  +       +  +    +  +  +            +    +     +  +   +     + +  +    +      +   +   + +       +   +   +          + + +    + + + + +  +         + +  +        + +  +  + + +     + + +  + + + + + + +  + +   + +    +      +      + + +  + +  +    + +  + + + +  HzFwHyKyGwJwGFxL{NIPTXNSWTWWSTSUZa_]adag`cfekjkhqpqjpvxsqw~wq}͂Ն݁߅ކz{ǃwvtqmkjide^Ye[QUO~OxRtDrAlBi?j=g:Z6S4Q1J,C,D*?*<$>%2"1-*%!     +  +   +  +      +   +    +   +   +   +       + + +      +      +              +  +  +  +      + + +      + +  + +  +   +      + +  +  +         +    +         +   +  +  +   + + +       +    +  +    +   +            +   +         +    +        +  +  + +    + + + +  +         +   + +   + + +   +   + + +           + + +    +  + + +       +       +    +   + +     + +       +     + + +   +   +       + + +  + + +   + +     +     uOyMyQzP|R|[~TXWY[Y[^\cXYbcg_fgiilophqmxysszr~~www|ȉċ΅ЊΉֆȊΎҖ׎ݑۗԗڍߏՉڈԐЉςƒ|yxunnogldZ]ZZRSQoKrFmKfB]=X=[:W7M2S5H+E-@)A&7'4#.*'$ +  + +  +    + + +   + + + +    +      +   + +   +   +    + +                        + +  +  + + +   +  +        +             + +               +                 +                          +     +    +   +          +   +                +  +   +     +   + +  +   +    +  +  +  + + + + + +   + +    + + +  +    +     +   +   +        +   + +  + +  +  +   + +  +  + +    + +                + +  + +  + +  +  +     + IxKyP{K|I|HJHOKQQPTTXUWVVXSY^e[bb_edaegekepkmokpwoppsx|{r~{v|҄{܄߃݆އ|vzzwpyqhkdf\]`UVQOLPsFrBpAkAi>\;\7]6T1G.I.G,B'A+:%;/ 0)'    + + + +  +  +   + +      +  +  +                     +     +         +  +     +   +    +      +      +   +   +    +   +      +  +   +  +  + +     +   +     + +    +     +       +  + + +     +  +       +  +   +   +    + +            + +  + +          +  + +  + + +   + +  +      +  +     + +  +  + +    + +   +   +   +  +  +  + +   + + + + +   + +     +     +    +  + +      +         +   + + + + +   + +  + +    + +   +    + +   + +    + +             +   +    + + + + +   + + {JyQ{Q|OTR~U|UY]YZ\]`gbbZ_Y_fdggrkjtomppnqz{x|yv~…ˈΆԉ̍ߏ؍ڎҌԌԎَߔޑޖ۔ٍ؅΃}Ły{rrsoehe\`[V~WzQuItMwInA`I`>_?W;W8L1P3B0H*<,?)9$7!.,('   +  + + +  + + +  +   + +    + +   +   + + +  + + +  +   + +   + + + +      + +  +           + +     + +      +   +  +  + +   +   +    +                   +  + +  +   +  +  +      +   +    + +                       +  +    + +     +   +  +    +     + +    + + + +      +  + + + + +    +  +  +    + + +  + +      +    +          + +  +   +   + + +    +     +    + +     + +   + + +   + +  +      +  +    +   + +   +   + + + +     +   + EsIwK~LxF|OwMQMOQRQQRUPVZ]P^`aZ^Ya_d`^fdkhnkjsipnsxtrwozրu~|؁فك؃߅ٍ݉׆{׀}ԁ|zxushuhpba_Z[XNWQzErKtDl@nBc?Z:[:[5S;N3K'F)C*;$<%5$2 .*%   + +   + +   +   + + +       + + +  +   + + +  +    + +   +   +  + +      +                +   +    + + +  + + +   +  + + +  +       +            +  +     +         + +  + +   + + + +  + + +           + +     +      +     + +  +         +  +  + +  +      +  +     +    +  +    +   +      +    +    +  +  +  +   +  +  +  + +    + + + +    +  + + +  + + +           +         + +  +      +    +        +   +  +  + +  +  + +  +  + + +    +   + +  +  + +      +   +   +    + + + + +  +   + + +        + pRxL{MzTQTW~XXS]WX\Yb`caaegeginkmoolqqrstxvu|~z||ÀÁ̂Έ͊Έ֊̍ϊӇܖُߎ؍ڍߐهˆ̀҄|w}ssulfg\\ZZaTTxPqIoFnHe@b@Y;W9J2P4I1A(C(:':#3"/",&'    +  +  +    +   +  + +  + +     +     +   +  +    + +   +            +      +     +  +  +         +  + + +      +  +                   +        +         + +        + + +          + + +       + + + + + +  + +  +    +    + +   +  + + +   +   + +        + + + +  +  +  +   + +    + +   +   + + + + +            +     +    +    +  +  + +  +  + +    +  +                +    + +      +    +  +        + + +   + + + +   KrD|F|K~IN~NzM|O|NYLPSRPV\YW\[]\Y\_`cfbbckjjlimmlmtqtks{v~yɁ{yyڀރڂӋ}{}s}qtpkfd`a`YTVWNRKwJqCnGgFh<`9^9X5Y3M/O1N+B*A&>$4 2,*!"     + + +  +    + +  + + +           +   +  +   +  +   +  + +          +             +        +  +    + +   +    + +        +   + +        +   +            +   +  +   +   + +  +  + + +       +    + +         +          + +  +      +   +      + + + +   + + + + +   + +  + +       + +   +  + + + + + +   + +   +     +  + + +            + +  + +     + +  +  +  + +  +   + +     +   +  + +  +  + +    + + + + + + +   +      +  +  +  + +  +  + + + + +    + +   + +tTzLwR|PR~U}UVQYV\`\_`b_bbgbkcjkmjmktsoqqssy{~{~ʀ΄ʏˎτю׋ˋيېَۑ֔ۗݔ،Ո͇Չ̂Ąw|rzupjhkeb^ZNzT}\xKqThEhD]Cb>^8X5P1M2E.D/B(=&:%5$/-&#"    + + +      +  +      +   + +  +  + +   + + +  +    + + +         +   +       + + +      +   +  +   +            +    +        +  + + +  +    +    +   + +        +           +     +     + + +  +     + + +     + +        +             + + + + +  +  +        + +   + +           + + +  + + +  + +   +  +  +        +   +  +     + +   +       +   +  + +   + +     +  +   +  + + + + + +  + +  + +  +  +  KqB}GzJvMNIN~RLSVJTVRZYYZY[Z]Ybd[_`adhobggloooprnvp}xr{vyȂuцw܄߃Ձ{؂zz~{xrtoogoe_]][XMPONxLwIoGnBk@^=V8V6O1N.H/D+E);(8&9 2+*&$     + +  +    + + + +  + +  +    + + +     +   +    + +    + +  +   +            + +  +      +    +          +       +   +     +       +       +        +  +              +    + + +  + + + +  +  +   +      + +          +    +  +            + +          + + + + +     +     +  +  + +      +    + +      + + +   +  + + +  +    +  +   +         +  + +   +  + + + + + +     +   +   +    + + + +  + + + + +   + +   +       + + +    + +   + + + +    +  +  +   + + + + + +  +        +uPySwK~PQ}P{UU]XZba[\a_`abcdbnillllhnnoxsq{z~~Ƃ~ʁńφ̓͊Јˏٕܐڏݖ܌܏Ցڌԁπтǂ}uvqoljgaaY`VUSwItJrFjIg>h<^B[6S3R5I/L1@,7+8"4"00(%"    + + +  +    +   + +    + + +    +  +      +    + + +  +  +    + +    +                 + +    + +   +  +              +      + +  + +   +  + +  +           + +           +  + +        +   + + +     +        +   +  +          +        + +   + + + + +  + + +    +           +  + +  + + +     +  + + + +     +           + +    +  +     +   +  + +    +  +      + + +   +   +      + +   +  + + + + + HwKzF}J~E~O|NJSQMFNPS]NSUXTT]Y[Yd__^efcjfgehksjppqrwwwuz}|ɂ|~~ޅւ~ׄ~yځ|vxvpsrpkjib\d[WPQQI{OqEuCqEk=_>X7X6V8M1L,D-A'@)= 9!5 .)&&    + + + + +  + +    +  +   + + +  + +   + +         +               +      +  +       +  +   + + +  +                                     +  +     + +   +  + +  +          +          +      +    +       +  +  + + + + + +          +     +      +     +       +  +  +      + +     +      +  + + +       +       +  + +  + +      +  + +  +    + + +   +     +   + + +   + + +    +    + + +   + + +   + + +  +      +   +rLzRyS{UvP|X~XTY_\XZZ`bja_cahgimlihpntntyturpzxxxĂˆ„džȈnjƍڋԉ֑ڈ׋ޑԐҍ̒փՂӀ{Ȁwtqpklcdb\`YPQmJwHqGoBjB^>]8[9R2S0H1D.=)B*;$7#-#/ *$   + + +   +   +     + +  +   +  +   +    +   +  +      + +  +                       +   + + +      +      +     + +      +                + +      +    +   +        +         + + + +    +  +  +    +    +  +   + +   +  +  + +       +  +   +   +  +   +     +  +  + + + + + +  + +    +    + + +       + +  +    +     + + + +  + +  + +   +     +     +       +    +     + + + +    + +       +   +NKxE}DuK|JIKM}PINO|TRWTTWQ[U]\^_i`]ej`^ajjkgojnrlovqxuz~yv|}~ځ}ބ݈ԅمy{ցwvqurklgkafUZWSOL{HtIrDs=n@d>h>b7[5R4Q0Q.H*C+>(9!7"7.+'#   + + + + + +   +  +   +  + +   +  +    +        +      + + +                            +    + +   + + + +       +     +  + + +            +  +  +      +    +    + +  + +              +  + +  +  +     + +    + + + +  + +   +            +     +  +  +  +   +         +   + + +   +        +    + + + + +  + + + + +                    +   + +  +            + +     + +                + +     +  +  xQuR|R{NySTY|XV^[[Y`Zaagbaefhiodhnhoqr|sr{w{vz~ĄƁ‚·ŀʊԆԋՎؐБӔۓۗߖێڏ֊܎׎Ίֈ~}x~pwprmgd`\ZVSP{OsNtBkElCbAYjBb*:)3"1!,+)#    + +  + + +      +       +  +  +     +      +   +            +     +     +     +             +    +    +  +       +         + +        + + + + + +  + + +    + + + +       +  +  + +   +    + +   + +    + +     +       + +        +   + +   + + + + +    +   +  +          +                 +   +    + + +    + + +  + +   +     + FxF{J}KD{IL}ONLKLPQWQWTZZYZ_^ba[Zcfm`ifhnqmdqjtqwrnw|vwyz{ك}݆݅׊܃߂~}w||wqxqojhfkc]]\TRM~LvM{CnFm=g?c9_9S6[1L5N/I0F)>'>$3#4-,'&    +   +  +         +  +    + +  +     +     +    +  +  +       +                + +  + +    +  +  +     + +        +       + +   +  + + + + +   + +    +         +    + +    + +    +   + +    +  + +    +         +    +    +     +   + + + +  + +   +  + +  +    +        + +    +   +  +   +   + + +   +   + + + +  + +   + + + +         +  +     + + +      +   +  +  +oSwR}O|J|WUQWSW]^ZZ]d[fchdjikgkjispvupxxsvv|‚xĂʁ˃˂Ƈ·ЅՑ֌ԏ܎،܏ېޕٌёߓ؈ԋω~|}zrxsqjcedZ^]VSuPyLrIsGfBaAf?R=V:W3L5C2E+<'7%7#1!. .(&             +  +     + + + + +    +                         +      +       +  +   + +                         +    + +    + + +  + +  +                         +     +    + +  + + +   +         + +     +   +     +  + +   +    + +   +  +   +         +     +  + +  + +   +      + + + + +            +   +     +   +       + +    + + +  +  + +     + +  + + + EKyKtG~LOILNTSUOQUXXS][Y^`]aeZcdacbfid`jmjmmripvmrwz|y{Ԃw}߃߈߅؀{ۆ}yzz~nrniheibZ]XSRSPOzDtDoFf@c<_:Y3U4T1Q.H0F.@'<(4!4 3*#$    + +  + + + +   + + +  +      +   +       +      + + +        +        +   +      +  +   +      +  +           +           +     + + + +   + +  + + +        +    +     +  +         +   + + +  + +    + +      +    +         +   + +   + + + +    +   +         + +      +   +   +   +   +  +    + + +         +          +             +  + +      +   +      +  + +   +      + +}RyPOQ~U\SXUY\Z_[]_acaecabmjllkorusutt{||wzπdžlj̈́ʌ؎͎ϋҍԊߓՖސޛڗ܊܊׏ي͍΄ȁwzp|lnihcb[YUSxGsQmMqJjCc=W'8):'1"/,($!  + + +   + +  + +   +    +   +  +  +        +  +        +               + +      +     +       + +                +     + + + +  +     +     + + +         +       +    +     +  + + + +  +  +          + +  +  +     + +    +   +  + +          + +  +        + +  +           +  +  +   +    + +       + +    + +   + +    + + + +     +  +  + + + + + + +   + + + +  +    FyHqI{KLLHOKOQMQLTXST[ZY]_[`a^`_beeekhlnlmnptoro{ty~{uyՀՂЀށ܀ى݅މ߇~{zŁwspninhde[X`URUNH|HvHmGmBf>`;X7^4N4J,M*H)B)@$:#7"/-($"  +  + +  + + +  +  +  + +   + + + +    + + + +               +      +       + +              +         +  +           +             +       +    + +    + +  +  +       +      +     + +   +       + +  + + +  +  +        +    +    + + +    + + +   +   + +  +  + +    + +       +          +     + +    +      +  + +     +      +           + + +    +  +  +     +             +   + +   + +  + +     +xNsV~TX|WT~SUZWVX]`Veg^bgahkfhkpqnorwtvzozuƂхˇ̀Ԍ؊ˉՏ߆֐ӔݓӋۙވۑۓڎσшˇ~{}~rnnig`a_a}WW~PxHoLoEi@_@c:]8Y:O4I,E,D,B+;$9'2!0",& !      +    + +  + +  +     +  +  +  +  + +  +     +    + +                 + +       +         + +    +            +  + +        + + +  + +             + + +  +  + + +  +  +  +       +   +    +  + + + +   + + +       +   +     +      +  +   + +  + +  + + +   +    + +  + + + + +     + +      +   +               + + +  + +  + + + + + + +    +  +   +   + +MwHH~DHJL}RLQLPVQSXT[ZSZ[]\a]agg^`hllegjostnksrrvx{{u{xԌΆ{~~~އق܂߁z{wrrnnghggXYZWORNzD}HoBq?lDcZ:T4R6S1F2E0C.9(;%4%,+) !  + + +  + +  + +  + + + + +   + +  +  +    + +  +    +         +           +         +         +              + + +   + +  +  +  +   + +     +      +     +   +   +   +  +      + +      +  +  +    +  + +  +  + +        +   + + +  +     + +   +   +  +  +    +  +           +      +        +     +   +    +     +   +  +  +   + +     +    + + KxI{O}JL}JP}OJQOJTUWRUVXW[\_a^b]b]dafcdhlhjipgkllvttuyyЀy|ʀ}ڃ~݃ڈ҅مۅԆ{{qwpokiih][WVVRU~HLyFvDoCj%8#9"0.+)     + +  +    + +  + + +      + +              +      +                        +   +                          +    +     + +  +  +          + +    + +  +    +  +     + +  + +  + + +  +      +   + + +  + + +   +   + +     +  + +    +       + +   +     + +  + + +   + +   +  +    +    +          +  +            +     + + + +  + +    + +  + + + + + + + +   + + +    +wUsPxOVRSXU\Z\dV_]hagggjhikkknfotooozqx~{{~ń͌̄NJЍˍԊʐߊАڕ׉ޙߕܑݒ؎Ԇ҂ˉψʂy{{yllkkh`]VWRQzNoNpGiBfAf<\=O8P;J4H/E.E+>#:%1**+)!    + + + + + +  +  + + + + +     +    +   + +  +  +     +    +               +       + +    + +  +   +          + +  +  + +       +  +          +  +    +        +   +    +  + + +   +   +   +   +    +      + + +   + +          + +     +  +    + +   + +   + +       + +  +     + + + +   +          + +  +   + + + +  + + + + + +  +    + CwEzLyMPOMNMQOQSQMRT[Q]ZU\YYa]fffhfigkiklevsoors{~zwtՀ{|ẃ׀ކ~ރ|~ςuwrysoqgjdaaXZUZLPzN}LzGm?t:f=f9\6\8U1R.R-G-F'?)6!:"00'(    +  + + + +   +  + + + +   + +  +    +  +     +  + + +            +            +         + + +   + +   +  +     + + +    +    +         +                + +      +  +         +       +  +       +    +  +    +      +    +  +  +   +       +  +        +  +    +  +  +   +    +  + +   +        +  + +    +   +   +  + + +   + +   +      +      +  + + +   +     +   + +  +  + +   ~SzRRS~SQ\_W^^\`e`c`fghckfsmjnlsrusru}y}zz|Ƀ˄̉ǐ؆Е߈َܒލ܉ԊЉلхyĀ|yvpvlfnca^YWwTxJwLwKlIjBbA_8]6S7T9O/I/A.G-<$5%5#.+)&"       +  +   + +    +      +     +   +     +     +    + + +                +  + + +   +   + +       +        +                +  +        +        + +  +   +  +  +      +  +  +    +     +                   + + +          + + +  +      + + + + + +        + +   +   +  +    +  +  +  + + + + +  +       + +  +  + + +  +   + + + + +       ByPK{L{JPRPNMRVVTRQ\]\\\_Y[`^^]^]fjijjjjpgptqhqqyswqzz|Մ|Մ~|܃߁сyytzsnkja_`[[YVSN~JvEtGuDm=h9a:^8T6O1M*J0D*D(?'=!8 0/*'""     + + +  +   + +  +  +  + + +     +   +   +  +  +   + +  +     + +  + + + + + +   + +                  + +     +   +   +                     +  +  +  + +   + +      +  +      + +    + +  +   +  + + + +    +   + + + +          +       + +   +    +  +  +   +   + + + +   +      +      +     +  +  + +   +    +     +       +         +   +   +    + +                 +  +   +  + +   +     +  +sWxU~O{X}XT~ZZZ[\^T]a`adbhhigihinokumusruqyyŀƄÈʋˉňņӇكϏҔܐٜ̊ڋےٌޑԇԌˇφ}|wropleec`[YO~M{PvOtFkDd?_<]:[6S8M5M/G/B,<*<"/$2"+ *"#    + + + + +       + +  +  + + +  + +    +     +  +     + +          +      + + +                    +  + +   + + +    +         + +  + +          +      +  +       + + +  +   +    + +  +   + +  +  + +  + +  +   +      +  +    + +  + + +    +      +   +      + + +  +   +      +  +  +         +    + +  +     +J|MxMuGxIzQOPMOTS^RPXTXT`Z^Y^X[acfaehfhjjlqjqsjsrsrutx~Ӏ}׆ւ}֌|ڂs|rkptinm__bZYSQLOwKwEtKi@g>_b;[:^8V4K0K/E+B'@'< 9"5"3+)(       + +    + +    +  + + +   +  + + + + +  +     +                 +         +  + +    +    +          +    +          + +     +   + +   +     + + + + +     + +   +  +    +  +    + + +      +              + +  + +  + +  + +   +    +    +    + +  +  + +  +     +        +       +       +   + + +   + + + +  + +  +  + + +   +TzRQySR~\Z~U~U\ZY`^fadhcb_ggjiophllsp{yszz||}ń҇ˊЄԄڎΎ׍ҋՌۋەٗޛݓ׏ڎ֊ڈՉ̀ȃv|x}pmjgjbc\SRT|P{OwIpFhF_=a=U8S9R1M2F/C'?(=';#4+&%     + +    +  +  +       +   +  +   + + +   +   +      +            + + +  + +  +               +   +  + +  +            +     +    +    +        +          +  +   +    +      +  +      +    +  +  + +     +   +         + +           +   +      + +  + +  + + + +  + +         + +  +  + HzLGM|K~MQ~UVPSQSPWOS^T[[[YYZ`ab``fdmigkkklvkrwywut{ww}}Ԅ}؀}|~߈؉ۉ{}قŀzutvsmmgcf]^SWOK}NLyKqHl?g@c?[:^5T8P5K.J)G+:&7&5!50++""  +   + + +   +  +   + + +   +  + +  +   +      +    +    + +                  +    +       +              +    +       +       + +  +  +  +  + +     +  +       +  + +     +      +      + + +     +     + + +           +  + + + +  +  + +     +           +    +        +   + +       +         +     +  + + + + +    +  +  + + + +      vO}X|PU~TyW~YVX]Za\^bc_ebjflkhorvprtsxn|uvy~}{ɃɂąẳՌЌі͋ҊޏՌږՏؕݛіؒݐˋՉˀă|yuorjkbhZYYW~U{QrKqLeBmCeAZ9U<[2L1L2D/F)B+:"4$-!* -'     + + + +  + +  + + +    +  +   + +   +    +  +  +     + + +            +   + +  +   + +   +  +    +              + + + +  +    + + + +  +     + +    +      + +      +  + +  +        +  +   +        +  +  + + +       +         +    + + +      +   +   +  +        +             +    + +   + +B{PGyLQLSOSPTUQUORXYbXVZ^\^h^dk`igpclrjppnpqopruws}|}ӄ{π}م}ۊ܁ׂuuzqpnqujff^c]W[WPHIJs>kBdBb9^=V5[8P1Q0E.F,>+6!9!34)("           + + +    + + +     +   +    + +      + +         +      +  +            +  +             +           +     +    + + + +  + +            +  +  +            + + + + +  +  +  +    +          +       +  +    +   +  +   +   + + +  +  +    + +         +  + +  +  +    +         + +   +      +  +     +  + + + + + +   + + + +     +      +  QwTrRyV|ZVR\[^]_f__ejdahhjmjmpqqtpovvzzvt~ł΅̀ÆǁȌȊŅΉΊԏޒ֖ڏړܘݘ׎؆ևʉĆ~}wuxsfkkb`^RW{LxLyPoLlJhD_=b@[8W9Z5N.F.A*@*:'4%3,,&"     +  + +  + +  + +       +   +  +   + + +   +      +                    +      +   +               +  +      +      + +    +  +  + + + + + +  +         + + +  + +    +  + + +        + + +  +      + +   +          + +   + + + +    +                          + + +   + + +       + +    +  + +      + + + MwI|KLRI{NNJTQNLTTUYWX`\Y___fga_ecgpphhjnotqtpyvnwszȀ{w|~ߍ}ڇ|zxvsmgkcf_]ZWVRR~MLyGiKoBn@a>ee:Z9`3\3U4N/G*F+@$9&7'3 /-(&"    + +   +       +    +   +     +      + +     +          +                    +  +     +      +        +          + +            +  + +    +  + + + +  +         + +    + +      + + +  +      +        +    +    + + + + + +  + +   +    + + + +    +  +   +      +      +    +            +     +      +  +  +  +    +  + + +   +}TWUQX\SXZ`\`\_`a^fiheglhlnpnlyo|roy|x}|{ʁċ̅ȉ׊͒̐׉Օߋٓܗ٘ޑߍ؍ԑՇрyπ|}xshoncab]]TRRoOtIpIm?^A^@[9X7P4J6G.@+<&>&3$2$.!*%$     +    + + +      + + +  +     +  +  +      +  +   +   +               + + + +      +    +     +                +  + + +   +  +  + + + +           +                  +   +  +     + + +  + +    +  + +  +  +        +      +               + +  +       +  +   +    +  + + + + +  F|K|IQNMTMTSQRWWVZUW\\V_W`\_]bdjaikskrjtkptmqpyȁτyxzӀՁ|}ڃׂك~~y{qwzwmmqle`a[TVWPQI|LwGpCi;k;c;\8Q3P0L0G.H->&8%='51)&"!     + +    + + + +  +        + +        +     +       +     +   +  +         +      + +    + +    +                          +  + + + + +  +     + +      +        + + +  + +      +       +    +    +        +   +  +       + +       +          +       +    + +     +  +      + + + + +     VW|T\~UXY\\cZ\c^accfigiinnoltpsuuyuzy|{|xzĆǁȄ҅ςτІύЊݐՉێ۔ߘޑڙޓޗՊގ߇ԇ~}ztppgdhbcTX|ZuQxSyHmIrBf?Y>[:S9R4L1O0E)@*:'7*5#- ,(  + + +  +  +  +     + + +   +    +  +  + + +       +      +            +   + + +           + +       +      + +          + +    + +  +   +  + +    +       +   + + +      +  +       +  + +  +      + + + +     + +  + +    + + NJ~J}I~RPLTPMOUTYXUZ\\[Zb_^_ibffajmnhikeprrsswsou{xwy}{zڇӆֈ߇݈|}yx|xpriihbbWU]USOOxIxHsGn>i7d;\=_5Q3S1K-?+=%>'>#3$2()#     +      +   + +  +  +   +     +     +  +   +    +  +    +        +      +   +  +     +                          +   + +  +      +      +    + +            +    +   +  +  +    + +      +  + +     + + +  +  + +          +       +   +   +  +   +   +   + + +  + +      + + |V|SY|XZ]SbX_ag_cXcgedfeojrpnknutqu|y|zzyńÂĈɉÈІύҒьҍۏ՝܎ۖژܞےْЋņ΃ǃzsxurjpke^c_\|O~SzLqMsIiFaG\?`;J=K4O2G/A->'>%;$3"3-&%#   + + +   +   + +  +  + + + + +   +   +        +   + + +  +  +      +      + +   +       +     + +  +  +        +  +   +         + +     +   +        +   + +         + + + +    + +     +  +        +      +    + + +   +    + +  +  +   + +  +   +  +  J{OO~JQLROIXPTTYT\Y[^Y\]V^ac_fnhjmkliflqqsrnwzty}u}|Ԃ܂ވޅۆރ{~{}xvslh`fZWZYPW~PHvLrGq@kBf>f;`:W6T5R0I-K-A$9'<#1!4-+%   +     +  + + +  +  +  +      +   +      +     +          +               +           +   +             +    +     +    +    +    +    +   +    +    +     +  +      +  +  +  +    + + +   + +  + +      + +            + +   + + + +      + +    +       + +     + + QZUXT]Z\[\c]ac^c^jflmiiorkpqt~ssruxy~}Ā‚āą̄ʇˌъ؋܇Ґޒ݋ی҆ܐ҅Ń|xu{okfd]`XYST}OpMsIiGdBi?a;[6Q8P/M2D.B%6'<&5"-+&$   + + + + +  +    +    +    +     +  +      +   +         +    +           +       +   +   +  +                  +            +   +  +   +       +    +  + + +   +           +          + +   +   + +  + + +  + + + + +    + + + +  + + + +L}LJJKxGTVPJTUVOVW]YZ\Ya\^gdgcbgghlgikkrmtutwpnp~{{yۂր~Ҁۅzۃށ؄~xvpiomfeabYYQWRyMuG|AsDlEl@d<]6X6T2S0K2F*=(9)8#5!4.*&!!   + + +     +  + + +  +  +   +  +      +           +  +   +   +                +  +    +      +  +   +  +  +    +        +      + + +  +    +                  + + +  +       +               +        +    + +      + +    +  + +   +     +        + +    +  + +  +   yTUT{X[YW]`\a[a`bhcfkfflnlhsopposyup~~|ƃŁˆ~ʼnĆɊʌ·׌׋ԋΈԕޕғ؋Ј͆΄̇{vtojjflckY\Y}U{QwIoHmIj?aE\;Y9P4O7J2H+?,A);#5/$+ )#"     + + + + +  + + + +   +   + + +   +     + + +        +                                 +     +    +   +       +     +       +      +    +   + + + +     +          +   +     +             + +     +  +       +  +  + + +  +    + + + +   + +  +HPLIOLKOVPQUYUX^`_T]ZbZ__dfe_blhnhmowrtvowruŀ}x}zσ|܃Ҁւ߇݈݉ߍۃ݃рxruwrkem_YdW]VVKMHrDsJpBe?g<^7\=R2N+I/D.B(>'>'86,+(' +   +     +  +       +  + +    + + + +   +  +      +     +         +             +    +    +  +  +             +  +  +    + + + +    +            + + +  +         +                  +  +    +    +     +      +        +  +  +   + + + +   +  +       + + +  |V[VYWTbbZc_ecdd_dbbnigpqpvrupvtvwvv~Ƃ́Ă΅ŊߍڍՋوۋܐߑݐڐՈ҈Ђ~Âˁ}pmjdiib^VVTxRNmJeKkCc?\:[6S6P3E1E1A)C,:'4$6, ''#    + + + + + +    + +   + +   + +  +   + +       +  +        +     +                   +          + +          +    +                +  + + + + +  + + +   +  +  +   +    +     +  +   +    +  +         +     +         +     +   + + +     +   +   +     I~KOOLOTNSSQSZU\X^[[gYad^fb\fhe`jmqldnilivuvwx{y~ہ{~݄ވ׆و߁zvu{qwqlmb^^YVRQRHFIrGlDq?e<\6Y3Y1R/F1A*H*@'<#9"4!1 /-"  +  + +   +  +    + +      +      +  +  +  + +   +   + +   + +    + +     + +                 +  +          + +  +       + +  + +  + +  +   +   + +    +               + +   +    + +      + +  + +   +     +         +              +     +   +     + +   +      +    +   + +   +  + + +     ZWWXWWT]`aba\cfc`gdbepglrpyrvtutu|ÆƁ҇ˌ̈̎ψɆچҐՋюԔՒۏߖ؞ڒԌӋэ̃Ąyzxvoqpfd`^\USxQ|TsKjElDc>[?Y;W5R4K6H,?+B':$8%3 /)(         + +  +    + +    + + +   + +   + +   +                  +        +               +   +   +  +   +  +              +     + +    +  + + + +   + +    +  +       +      +     +       + +          + +   +      +  + +     + +    + +   +  K{K}NKMROTRT[VWSY[V\^b]Za^edaemimkndqsjjqupuwt}|y}v{܁}}|҄~Ӂ{utvnkhahg[\]YRzTMvIwHlBj@d=`=\8R6V4J3@*C(B%=(<$1,.,$#   + + +            +    +  + +     +  +  + + +   +     +        +  +              +                               + +  +  +       +     + +    +       + +             + + +   +  +  + +      + +    + +   +    +     +               + +   + + + +  +       +  +  +  +  +   +   +  P~ZTVX\VXV^`[cg\i_ghkhjmkipmtoxw}ur~w~Ɖ̈́ņχڇӅՐڄԓԒؑߖߛܔُ̌ψ~ă~supoohdfZXWX~QyPtIoBkDd>\+9)4!/ 0)&#   +    +   + + +    +  +     +  +    + +          +  + +  +                               +   +   + +  +           + +  +  +  +      +  +           +     +  + +          +     +   + + + +     +  +   +    +  +  + + + +     M~LMKM}QSQRPSUSVZYXW`[\a^fjbg]bghjkgkpvnnmuvxvy|}|~݁Ղ߈ۅކ~΁|ӃԄvttwpic`e^ZVQNKQ~ItByKnDbHl9\8U6L4O0M,B+C$A"3#6 /!0*)#   + + + + + + +    +   +  +  + +   +   + +   +  +     +  +  + +    +           +        +         +        + + +     +        +  +  +     +    +    +    +       + +     +   + +  +  +   +                     +   +      + +   +  + + + + + + +        +  +   + +    + YWRY}Z]ZZd__]ieceffgbhfimqrrqqwwyv~zÇLjҌȈΊԉ͉׈ԋԌЙגݏܗߜْщډЌÉywvuishhi\XYXOtUuEtCgIgAZ;Y;S5N9R2I0G)>/>&7%5#,*) &  + +   + + + +       +      + +              +  +  + +       +           +          +             +  +    +      + +  + +            +   + +    +   + +  +          +       +  + +  +   + + +  + +  + +   + +  + + + + +      + MRNSNOQMWWVSZW_ZU\Z\Wgdebeihiijllqnpnqvylswyzz~y׋΂ҁޅ߄ـ{uvvuifbb\_WWRKJ{JwGtAnBa_=V9W*:'5!0$1/)$"     + + + +   + + +  +   +    +  +      +     + +     +         +           +         +   +       +  +   +        +     + + +      +       + +     +     +  + +    + + +   + +       +   +  + +    +  +  +        +    + +     + +    +  + +  + + +   + +  IzIOOLSPOTZUTVXX^_\X[i`a_eecjifcijmqhqposuwtq|xwՀy܃كڊފ؀ڃׁ{{vvsihbc[^_[SRO~KvGnAlAh@a9\:Z6V2K1K/H,C*;&:$9!3,()$     +  +  + +    +       + +   +        +  +   +     +  +   +          +          +    +             +     + +       +   +  +     +         +          + +          +     +    +   +     +  +   +  +       +        + + +       +    + + + + + +     + +  + +   + +  +  TZ~UW]Y\[\a^`bcadihmfkitltoqxosrzy|}Á{ÀÀ́ˆʏЄَޔڎޑԕٗۖϋ֑τǁxw|phnicc\\XyOyPuG{JkHa@b=]7Yi?`:_9X7U7S0K0K)B)E&7$9"62,("     +   + +   +   +   +   +  +    +    + +   + +     +  +          +       +      +  +                           + +     + + + +  + + +   + +       +  + +  +   +  +     + +  +    + +    +  +   + +  +        +     +  +      +  +  +         +    + +   +  +  + + + +   +   + +  +   + + + + VTXX][cacg\bbcbijoioionoowvs}}ztu}Ɓ~}†Dž{Љʌˈ̈́؍ӊђ݋ڍڑٍߑޗܑ؏АԂΈ|zowxiqb_bdUWZvSMuMgIk?h@c8S9S8N3K/B/D-;'8$3%2('*   +   +        +   + +     + +           +      +     + + +       +  +             +         +       + +        + +   +   + +   +  +  + +        +     +   + +               +    + +   + +  +      + +   + + + + +         + + + + + +     + +  LIQMTTYSLYVOUZbZ\`[\_a_^kjbbghphipjprusmuuqĂx~ނև܀{r|{{orlkc^[XXZQQOFyGmAmCf7Y=_>X6P1K,E,E(;(:"9"4/+&%     + + +  +  + + +  + +  +  +  +   +   + + +  +     + +       + +  +     +     +         +        +       +   +       +  + +       +  + + +         + + +   + +                     +  + + +  +  +   + +    +     +    + +       +  +  +  +  +        + +  + +  +    + +  + +    + +   +      +  + +  ^Y^ZY\\Z`bg]befc`pnlnlompovuqxsxz|z}ʃ͇NJȐψ֋؊وޒݘ֑ڌޏΏڈ܄ԉ͈́y}qhqmij__VWzPwQoHxIhDcA^@[?Y@Z8V3K5F/C,?)=)7". 0,%!      +  +  +  + +   + + +  + +   +    +  + +          +      + +                                   +   +     + +   +  +        + +  + + + + +  +  + +        +    + + +         +  +  +      +                         +         + + +     + + +       +    + + +NKN~URSWR[VVY\XZ[XZ^\d^cfgcihemkhgrqwrywrtwy}ywӂz|݃݅~}ׄ؁z}wnupocef[ZRWRO}LuIoGn>f>_<^:]6W4P2R.O,A(B(7%< 4"0*('!      +   +  + + +  + + +      +  + +  +     +  +   + +      +   +   +            +                             +       +            +     +   +       + +  +  +   + + + +       +        +     +  + +      +   +   +  +  +       +    +       +   +    +  + + +  + +    +   +   +  +   +Z_W][_^`dfacffefofjlmnorsrtr|yvvwz~vʀ‡ȍȉъԃӊגΌҊӒؒޗݓՐՍ҅Ȋ}wyqwkhcda[TL~PuIvGjDhB_B_A^:W:R2D1O2E-B*A'8%6"/+&"       + +  + +  + +  +  + +  +    + +     +         +         +  +   + +                  +               +    +         + +  +       +      +        + +   +        + + +  +        + +             +   +  +  +   + +  +   + +  +  +     +   +  +    MRJPMJYRQUT_XXW^]^bagfadgfjldkolkmnsjx|tu{tw{y΋|Ѓ݅р߃م߅܂ف{хxzoqlie]cc_SOTI|IrFkGjCt@h:^>\8U5P0O,N-G*@*<'9"7$1/'$!   +   + +   +  + + + +  + +  +   + +  + + + +  +     +    + + + + +      +          +                +                     +   + + +  + +          + + + + +   + +   + + +  +  +          +        +  +   +            +     +    +     +   + + +   +   + + +  +    + +  + + +  +  \^\]ZXbYccafc`ifjmkjisnwpwuu|yy{{Á‹ĉLJʆΊюԊє֌؏ܑސޗޗψڊϊÉ̈΁|ytvnmkk_YVSTQwPuHvJdGh=]7[7X2M2K.N.B)E-=&4 4"-!.$#     + + +  + + +     + + +  +  +  +  +  +    +   + +    + +  +        +    +                 +                                     + +   +  + +              +    + +          +     +     + +       + + + + +  +  + + + +  + +  +   +  +  +   + + +  +IRRNTSWOT\V_VVY^_^\Yfc`m`hhlhinmrquqpowuy}wźكهԈ؆~އրxwwkqmkgedf^UXULO{FsEpDj@e<\<[8]4Z/K-K(G,H'?(;"4 /**(        +  +  +  + +    + + +  + +   +  +  + +     + +      +          +     +  +    +    +                        +            + +        +  +    + +    +   + +  + + +               + + + +  +     + +              +       +   + + +    +   +  +  +  + +  +   + + +   UZ`]_^a_d_bgidjijdkmmkinsrrwxyq|~Á~Ȃ~ՇЅґՄ։Ѝؑۊ؍ؕܖݙޑړ؈ΎԀł}|uqoliea_[VTxQyQwImEgEd=[<[:Z8U8L1J/I+D*<):&6#-!-(&      + + + + + + +  + + +  + +  +   +  +     +  + +  +   +       +         +          +  +             +    +    +   +   +   +   + +                         +        +    +    +                       +    + +   +  +  + +    + +      +  +      +  MOQNQPSOWXWRVY^\X___deflfahjlokpqottswtyv}{|}~{{Ձ؆ۂ܆߃ڄw~΀vrxqsbhd^b\TMQLzJwHqEiBh?b9b=X8Y6O0G(I'=):&6 6!.-)($    +  +  + + +   + + +  + + + + + +   +     + + + + +           +  +         + +                                    +                     + + +     + +  + +      +     +              +     + +  + + +  +   +             +    +   + + + + + + + + +    + +  +     + +  +   + + +    + X[Y\Z]\[aeb``eghiinoqwqrgwtzsxzz…΀ωȐ̊ԉڈω܍ڌٖޙݏԓڍӎ҈Չʁƀxtrrqggh]\XUQ~QwMoGiGcBe?a;`=S2I3H0C.E+A'9"5'3-+%"      + + + + + + + + +  + +  + +  + + +   +   +      +         +                + +   +   +                +            +  +  +  +        +   + + +             +      +    +    +   +               + + +       +   +    +  +  +  +  +  +   OOSQXRR[WT[\V`\\]h\_\dgeiogfhlghotorwnsm{oy}uۂς}҈ׅۅ}݂|x|votvjlhceXYVVN{OwFlGnDpAi>]:]9\7S2S.L,@+@+<$6#5!7.+$&    + +      +     +  + + + + + + +     +  +  + + + + +    +  + +           + +     +  +  +         +        +                          +  +               +  +        +     + +  +  +   +     +  +      +                                   +  + + +  + + +  +  +     +  +  +   + +   +     ]Z[Z[\^W\`cddidikfpqgiqtmvqw{vx~{{~ȅƒɆχ̇׉Ԅ։ޖٌܔ֕ܔښޏ֒܌҇цw|wtqsih_bZWVRImJtHoCd@aAYAY7U5N0H-E-B)='9(8$0 +&%   + +        +  + +    + + + + +  + +  +    + + +     +  + +            +   +               +     +   +    +                  + +  + + +          + +       +  +               + + +  + +        +      +      + +  + + +   + +   + +    +  +  +   +  + +  + +  + + RHNTQXUSYTQYZ^ZUZ]]fade`ghkhjhiknqlqostrt}yxy~~}߇ڄڃׁۂ~Հxqoxqjlacdf[YTQPKxJuBp=lAe>a8X5Z6N-N*H+E'>$8$6#3+.)(     +   + + + +   + + + + + + + + + +  + + +  +   +   +     +  +           +            +                 + +   +                          +   +         +  +  +  +  + + + +  +         +   +  +         +   +     +  +    +     +    +     +      + +  + +     + + +   + +    + + + + + + + + +   + + + \`cY^ZddYeedecgiijkoppqktrzuxw{z}~Äƀ҈؅ҋ͆ΒӎՑёӌԙޏލݚאہϋڊȉćtrsngfeb`]O~UzOQuFgGeCiD]=W;Q4N8H4J,A+>*7'8$1.+&#          + +   +    + +       +  +  +    + + + +    + + +       + +    +   +         +      +     +  +            +    +     +     +         +  +  + + +      + +   + + +           +     +          + +                +      +   + +   +    +   + +   + +  + + + +   +      + +   +   +PMUQXPYUSSU__b][_]bea`_ffadkjjjlunsrnpp~yyt{Ƅҁ}~܃߆ϊׅ|~yuphmjh`a\^VSPKF{IsEf>hZ6V7P/J2B(F,@)<&9$00+%&!      + + + +       + +  + +   + + + +    +    +   +   +  +  +     +   +     +                +       +    +   +       +                 + + +   +     +     + + +  +  + +   + +  + +  + +   +          +          +  +  +        + + +       +    +  +  + + + +  +  + + + + + +   + + + + + ZaXZU__[``aeaeblhhllqomottptp{yÀˆÎNJÄЍ̈́ʂҁ׎܊ߍܚۘӔڗՓז܎ԊىΑÉ~|txpzlejc^YUW|N}OoMmKg@dB]=];T4R2I6F3F)B(6'=$1!,"+("       + +    +    +    + + +  + +   +   + + +   +  +   +         +       +        +    +         + +      +      +   + +   + +   + + +   + + + + + +     +  +  +         +       +                +  +   +  + + +    + +  +  +  +  + +  +  + + +  +IJSOSPVVWWWR^`_`\\eei^ccecckmomisqlnr{rvyrr|͂ҁ̀߁߃߃~~xҀрryrpqmf^b_W\VTOLtIwHrEj@`=a9\6W7S2P,H,G)@(@&:!5 /-*#     +         +  +   + +   + +  + +      +  +      +  +    + +     +       +       + +     +                 +        +   +            + + + + + + +   +  + + +   +    +    +    +      +   +    +      +  +    + + +   + +      +              +     + +   +   +    +  + + +    +      +  + +   + + [Z[[_^[baegjiikdggoqrmkqruxuz|}yzÀԎƁ΅֎̍ӊՍѓۑԐޗܔӒ̄΍Ņ~zswpskcd[ZSWxN|MpJlDiBi@]B[CV4L1M1M1@/B(9(8$0!-0) !            +   +   +  +  + +   + +   + +       +   +                                    + +          +    + +    +   +  +           +  +   + + + +   +      +          +    +   +   +      +    +   +       +     +  +  + + +  +     + +     +   +  INPPYTXUY[YVV\f\\a\acidi`gilkninurlrov~tvwu|؁ف؂р߄؆ݍy}׀xqstrjge]`VXOOJNxHrHq>j@h?_>Y7T4T2O3H1D)B)?&7%33.-$#  +    +  +     + + + +    + + + +   + + +  + +  +   + +    + + +  + +   +  + +    +  + +      +  +                   +             +    +           +      + +    +    + + +  +  +  +  + +     + +   + +  +  +  +      +   + + +     +          +       + +  +         +    + +  +  + +    +    +   +  +       + +   T_U_ac_bcchhkjglnnknuqvqmwx{{}vyzŇÅňτˈćĄ΅Ɍ̈́Г܋ԑԗގٕޖޚܑؐLJĂɀ}wwzopb[`bXW}PyRxKkEeDdG`<_9W7U2T,L0F1>)<&:&4#,+*$"               +     +   + +   +  +   +  + +   + + +  +       +  + +          + +    +  +                       +            +      +    +    +  +    +     + +   + + + +                  +      +   + + +       +  +  +          + +  +   +  +  + +    + + + + + MHPQZWTZR^[TY[cV^^badbd_dcgfdlojqqppqwsu}ywx{}܀Є܃؈ڄՄ܆р}y|viugpha_YZZMOE~KzG{?iBgC_@Z9X5S5P,I+G(C)=!;"4"..+&"               + +    + +   + + +  +    + + +  +  +   + +   + + +  +  +    + + +                +          + + +  +   +         +   +                 + + +  + + + +    + + +  +  +  +   + +  +   +  +   + +   + +  + +   +      +          +   + +   +  +          +    + +     +       + +  + + +  + + + +  + +  +   +  YXY\\Zedebhddedhhkmiposmlu|{y{τ}ƈՇɍˋϏ͌Ӎڇ׍ݐՎܑߕ݌ِΈΈтŃvxpokanb_ZS{RxOtLkKkHe@a;];V9Q6M6L3?0F*>%8*1"/#*-"#             +         +      +             +   +       +   +        +          +       +         +         +             +    +    +   + +  +   +       +  +  +     +  + +  +      +      +               + + + +  + +  +   +   +  +    + +   +     + +  +O}QOPUQQWQVX[aaZ\`]be`eehjgpmilqiujny{xzpz}t{xx؀߁߀އڇ߉އބԃ{v}qqnjgef\_\ZSPzJ~NuFoAp?d;e;b4\6X0O/P.J,D*9%:#8!1.'%!      +     +  +    +    +  + +  + +   +  + + +           +   +           +                   +                          +    +       + +    + +   +  + +    + +  + +   + +          + + + + + + +    +           +   +  +  +  +  +  +       +     +    +   + +    + + +   + + +  + +  +   + +       + X[[_d_bmcg`ghicoojtppwputuuw~y}ÀzĆŀփljԅՇЋߌԅِ؅ԒӐ܏ٍؗ֓ʌ̀|yrsokgb_hXV~QyNtMoHi@gB_?a9W=R7N4I0I*A,;'<#2#0+*"!      +  + +       +     + + + +   +   +  +   + + +  +     +      + +                        +     +             +    +       +   +   +    +  +    + +   + +        + + +   +  +   +    +   + +                      +      + +  +   + + + + + +    +   + + + +  JLLPOYWWTXX_]\V^\bcfjj^jfkhkmoplompsr{yryyt}xՀx|օ߇߆߅zׁ܁rrqldgcbb^UTURtKuKoCgBj=b"40 -.'#   + + + +   +    + +   +  +    + +    + + +     +  +  + + +  +        +                      +                            + +      +         +   + +    + + + +   +  +     +            +  +  +  + +              +     +      +          +   +                +  + +    +  +    + +   +  + +       +   +  +  [\]]Zb``fcakflkgghmwkpqustuw{x{ƀą~€LJ̐шΎԍؐЋ܋ЍӔڏٗߜߔڎ֍ԑԈŀ}zvoliaaaaVV{TvOoKuJeIfC_Z:P:N3K0L/A,;*<$3&6!0 )&#   +   +   + +      +      +    +  + +     + +  +  +  +    +      +     +                  +    +               +  +              +   +       + + + + + +  +  +    + + +      + + +             +                +           +  +  +  +     + +     + +    + + + +      + + RN~ONMXWVWcVY^V_^_\`eheigdhklmtsmsmzvvtutyvu|̀؈y}Ӏ}݈}ݍم}tyyvrlpeca`Z]\QJM{IxLuCkDn?b;c=^8W2P0P.M+>+A'@$<#1..)$    +          + +   +    +    +   +  +  +    + +  +     +     +   + + +    +  +   +        +      +  +                             + +    +   +   + + +  +      +   +   +  +  + + +     + +  + +   +    + +   +       +  +     +   + +         +     + +          + + + +   +  + +  + + +    + +  + +  + + +  +  + +   Y[\\``eg_dgffelfportkqprwwyy}|~τ{ʇɈԂ֏֐ՕڎҕߜޚސލݍȈƆ€|rvrmkebeW~VW{UqLqFwHjCcCb8Z;U2R4J2C/G-@,@'8!4".+&%          +           + + +    +    +    +  +    + +   + +  +         +   +  +          +       +      +                   +        +    +    +  +  +   + +       +     +                 + +   + +    + +            +  +  +   +   +     +     +      +  + PRNWVZVURXWY^Y]Y]b`fh^jfgedmhwhsgvv|}sx{zzyـ{Ճ݆ڃ݀ކېފބ݄ڄt}xsqgjkibb\[ROMzNwLsEqBh>c@[a;W9W9U0K.I-E)=&?'8"52 ,&     +      +   +   + +    + +    + + +   +     + +    + + +  +   + + +  +  +  +         +                  +  +                  +    +   +      + +  + + + + + + + +  +  +   +       +  + +   + +   +         +                + +                         + +  + +  +   +      +  +  + +     + +    +  + + WWd`_\dYdidnmkgkpvluopsuxys~|}}|ŀ‚҄ЉDŽԎ΋ЊؒҊ։ގڙܚюߊΎԇӁрŁ}ypsmpma^cWUxTvItKvFpEfC\=Z`?_6Y5Q3J2N.D(?$?$9#53+'%!       + +  +  + +  +  + +   +  + + +     +  + +  + + +  + + + +  +        + +        +                  +   +  +   +     +    +           + +   +       +     + + + +  + + +     +     + +  +  +   +   +  + +     + +      +       +         +   +         +     + + + +   +    +  + +    + + +  +  +   +  + +   ]^\]e\bbckaiigkhkmklkoqtwztxw{„z€}ъʊĊ͊ʇ·֌͔ΏՊ՗Ւϋ҄΅σ}w|wpihf`]`Q[TxNwIqFfDeB^=Z:Y*:%50)'#            + + +       +        +  + + +  +  +         +      +  +   +   + +     +                     +     +   + +  +  +   +             +      + +  +   +    +     + + +     +  + +     +             +        +      +     +   + +      + +  +   +      +  +  + LMSQQRWVZXZXYZ``cdcd_bbdkdgfjhppqrurrzz|yׄڀz݄݂݇ۂ݈ڈ݆ڄ~~wvspjijfa^[XVTPKzNpFvDq@n?d<^8V3Q4P,J,D+F%?)7"6 6+*!    +  +  +    +     +  + + +   + +  +  + + +   +   +   +  + +    + + +   +  +           +          +     +   +        +      +         + +    +   +      + +  +     + + +  +   +    +      +  +   +     +      +             +              +   +  +   +  +  +  +  +  + +   + + + + +  + +  +    +   + + `]]^^afeffkdchnroornrqvxwuw~~~{ÂɇƁʈǁ͈Ή҄όْҎߋٙܗߑܒߗ݉ɓЂҋ~yolsplcd`ZTZsPuQoJoImEXBX:\9T1S4K/H)<'A%5$4!1,*$    +          +   +   +   + + +  +  + + + +  +   +  +  +  + +  + + +  + + +  +     +  + +    +   +        +      +            +    + +  +  + + +                  + +           +    +    +  +    +      + +    +  + + +         +  +  +  +        + +       + +        +   +   + + + +    + +    +  + + +   +    + +  + PSRPRRZUVX\\\a[Yccfdhbehmkifporruvvstyvpxx}{Յ؄߇ׁ݆ޏ܃|xxrlpfgf`b`YXPQQyKwDuGkCk>c8]9W3W1T1J+E-F&C)7$;1-*""   +    + + +        +   + +    + +         + +              +          + +  + +  +                              +     +              +  +         +  +    +     +  +  + + + + + +      +  + +  +  +     + + +  + + + +            +    +       + +             +       +  + + + + + + +    +      + +   + + +  +   + +  + +  + + [Y`ccabfddhajhnkljspuqzvszwuyyx~ɃłDžڊψґ؃ՕגܐݓܙڌԆ؆҄|srsnqef]\]TT|PtMnLoFe>^>^:^9W7R1E0F-C)<'>%6",".%'!      +     + +  +       +  + + +  + + + + + +  +  + +   + +   + +  +    +   +      + +  +                   +                  + +    +         +  +    + +           +        + +    + + + + +  +  + +    +  +      + +        +                  +  +   +  +       + +  + +       +  +    + +NVQVSRNU[UZY`[d\cfhcafhgaqniimmu}ru|vwv׀~~׀ׁ݄Ճوއވ߉Іy~xwlipgdca\\XQ~OM|LzFrIt@k(8'8'1"*+$    +              +  + + +   + + +   +      +  + +     +    + + + + +  + +   +      +   +             +     +              +    +                  +             +          +  +   +    +   + +            +       +    +      +     + + +   + +      +  +  +  +     +   +  OLUVPVTXUXZ``^caaac^c`ldcimnkmnxwytzwuvz|u܂׊Ѐ{ӄބ}܄{{wrnlchZ^]WVMQMJqKlCn;b;b8_9Y0R/J,J&A(>'>$6 6-/'#!     +    +  +  +  +     +  +  + + +  +  +   +   + +    + +  +   +   + +  +  +    +  +         +             +        +         +                  +      +  +   + +    +  + + +    + +   + +  +    + + + +  + +  + +    +   +   +  + +  +  + + +       +  +     +  + +   +                  +          + + +   + +      +      +    +       +  + + [[`d_\^fegikdnillkptmxwwwyxz||z{ŀȉǁȏ̄υҋԏאЈߎގْߛՓڊ׈Όyz{polnd`^_YPvOyHoHoIjCe>d:U=M4Q5I1H+A)=*;'7.$-(&" +    +     +      +      +  +     + + + + +  + + +        +     + +   + + +   +   +       +     +       +             +  +            +     + + +       +        +             + +     + + +     +    +      +      +       + +  +                      + +   + +      + +   +        + + + + + + +      +UQRWSZWTZYW\`ab]dg_dmgjgkhkppjnprxqzxyzuzw|||܃ކււ~{|{pljmbb\Z[QQMM~DqGlFi@bD`8[8Z4P5M/G.M(@(<&8&3".*$'"     +  +      + +    + +   +  +  + +   + + + + +   + +   +  +       +   +   + + +  + + +     +   +     + +                  +  +          +                    +  +   +  + + +          + +  +  +  + + +  + +   +  +  + + + + +  +  +   +     +    +  +     +  +   +    + + +     +    +   +    + + +    +   +  +   +    + + +   + +  a_`_b^\jechfpkjjmlpumsuoz|vzu|z̆ă„ŎԈӑϊԇؐۖߐՙ܏ݏ҈ې҂DžŠ{|vwpif`[\XST{I}JqLiHiFeD\:Z8W7S5M2I/F)=&8(4%-.+$          + +      + + +  +        + +  + +  + + +   +   +  + + +    +   +  +   +  + + +  + +   + +  + + + + +   +      [        +                         +   +  +  + +      + +      +                     + +   + +   +         +        + +     z     +       + + +  +  +     + +  + +     +   +    +  + +  + + +VOSRRUX[Za``_`bb_dfccechmpgpoukursw}uu{yw~{~~ـ}~ډ|܀y~y{rolcba]Z[SMQGqNyGmAb?e9]:a7Z5O3K.H/B'G%;(751,)#   +  +   + +  +            +   + +  + + +  + + +   +    +  +        +   +  +   + +     +   +                                    +     +          + + + + +  +  + + +  +   +     + + + +   + + +  + +   + + +  +  +  +  +         +  + +   + +  +                    +     +  +   +        + + +  + +  + + + + + +  + +   + ^[_bbc^gcgdhghrqrilrwnxwur}|{~}~ƅłЉυ׍ΌڈݑԐ׏ٓߠّ݈ԍɏˈvzzpqskcb^XORuNuGkJcDd@[?_7R7J4H2J.D*<+;'5$4"-)'!    +         +  +  +  +     + +  +  +  +  +   + + + +   +  +  +   + +    +  + + +   +  +  +     + +  +            +        + +   +      +    +    +   +     +  +  +  + +    + + +                         +       +       +  +    + +   +          + +       +       + + + +  +        + + +    +   +  +  +      + +   +   + +   +XKPOOYVXU`]\a[d`hjefgdpdloqonmwupmszx|u~y}сԁՃ{ކ߉̂z΅yxppkflb`_aUQPOtExMhFf?iBg8\7[0L-Q1P/E%B)7%3#2"3..#        +    +     +  +  +  +     +      + + + + + +  +    +       + + +  + +   + + +  + + + +     +            +                   + +      +    +                  + +  +    +      + + + + + +    + +  + +  + + +   + +               +   +      +           + +   +            +  +  +    +    + + + + +   +   + + +   +  + +    ]W_abgdd`dnksnrhtuwytrmx~ty|xÅĂ|ƇƃΈ؄Ўэӑ܌ّݐ܏ٔޡՍэԈȅ}€uwpnfff]^]~UMwNhMkJfGm@iBW:S6N1N2O0J.=-<&7$3 0!.("          + +            + + +      +  + +  +     +  +     +       + +   +  +   +   +    +          +           +        +            + +      + + + + +   + +    +                   +                      +            +            +  + +  + + +     +    +       +  + + +   +  +  +  + + +  QUUOTXRW\[`[[i^f]dck`gjghijnqnltw{tvqx|Ł{Ӏ~Ӆۆ}ـ|~srpfgba_S[PS~MwOwKtDk@lAb;Z9\2V2M0K,G(A*B"9%33+*)       +  +  + +  +  +         + +  +  + +  +    +       + +    +      +    +       + + +   +  +    +                            +             +   +      +  +         + +  +  +    + +  +  +   + + + + + +  +  +      +   +                   +                 +     +    +    +     +  +       + +  +   + +  + +  +  + +  + [c[`[edfddepgkkltvqrvrzvxxzy}Áʇ́ˈщ΍ƈϊ؎ޔ܏ޘՐօ֎Ѐ׈ą~xwnjpggafX{T~TyVrIpKlE]Caf>`:X.W8W6L2M-J)B+;":6") (,##      +      +   +   + + + +   +  +   + + +  + + + + + + +      +  +      +       + +  +  + +    +  +             +  +  +              +                                 + +   + + +  +  + +   + + +  + +   +   +  + + +        + +                         + +     +      +         +      +     + +    + +  + + + + + + + +     + + `a`dbefaejchsnpoolkqtnuxzw|v}łǂńŀ†ˈȃΆЋה܈ގё؎ەܔݑߐчІ̅{zwqopheafXUNRpNtJkFg@bAa9Y;Q7O2E2K,@(9&7%.!0*'#  +    + + +  +       +       +   + + + + + + + +  +  +    +  + +   +              + +   +  + + +  + + + + + +           +      +                            + +  + + +   +     +      +              + +     + +     + + +             + +                  +   + +  +  + +  + +     +    +     +  +   +  + + +  + RWTVZ\U`^^][`\Z`aghfibnfrikoumtqwruvuvzz|~ك׀݂ۅ݃փՀxwxwummjbaYWSTMMzGrDoDj@k:bA`6a6[5W-P/G)E->$6%7/.$&!       +   +  +      +  +     + +  +  +    +   + +  + +  + +     + +      +       +  +    +  +   +      +  + + + +                                                    +  +     + + + +  +  +            + + +   + + +  +   +  +      + + +  +  +      +                   + +        +       +    +   +  + +      + +      +   + + + +   +   +   +  + + + + Z^Zigchhghcenmhlkokqtqwxyz~~|ĀÃˊ̍ƆхȇӋԎیؒڏޔޘؓڊЉωȁz~yxqmimcZWSW}QnLsKhEdHaDa;W?P7M2G-A/=,='7)3/-+%  +               +   +  + +    + +  +  +   + +  + + + +  +  + +  +   + +   + + + + + +   + + + + +    +   + +                  +     +                    +         +        + + +    + + +                       +      +         +           +   +      +  + + + +  + + +         + +   +    + + +   +  +  +  +    [OUUSXYY`__\\fbc_gklhjmnhnmmorprrwtuy~z|~ބԄ߉ݎڄڂ}~͂xuqjladdcXUUP{IwEuElDkAc=Z9\4V4T5N-E(A*>&9!7#/0+'!           +   + +  +  +     + +      + + +     +  +  +   +  + +   + +    +  + +    +  +  + + +  +   + +  + +  +            +              +   +                     +          +      + +        +   + +     +    +   +  + +   +    +    + +      +              +  + +                 +     +    + +  +   +  +  + +      + +    + + + + +    +   +  _[cZ_ngijggjlqqumruvj~yz~wā~Ë~ʁʀ˃Æ׈ٌ͌щۇϑݕؓەؐ׈͈͆~vstmghcc[RR|MuNqGgGbId>a=X:S4T/H0B,F(:%8'4#3.'$          +        +   +   +    + + +  + +  +   +   + +  + + +  +  +       +   + +   +    +  +  +  +  +  +  +   +     +                          +     + +     + +      + + + +     +           + +  + +                        +       +  +            +   +     +   +   + + + +        + + + + +     +  +   +   +  +VTNV]]U]]YWZ[acaifajgghlnmmsklmxywyywyՃ|}ہ~ԇ߉݁ـxxzpqpo``_^WVRPzK{GoGlCjB^>]$5!0.''"            + +       +  +   + +    +   + + +    + +  + + + + + + + + + +                 + +     +     +  + +  +  + +      +                  +  +    +    +        +   +            +     + +  +   + + +     +  +   +  +    + +   +    +   + +  +  + + +    +   + + +  +   +      +      +  +        +        +    + +              + +  +   +    + +  + + + +  +  +  + +  +   + \`]d`ibfngljlmqrsxutst{w|yŁ~}Ċā΅ɐ́͋Nj҉׎ܔُڕޓՓܑޑސӐ|ӆ…{wxrkkga`YUU|R~MpJnFnB_>_C]6S5M4S-I2G+;)7&1!-",'$$        +       +  +      + +  + + + + + + + + + +    + +  + +    +  +  +   +  +  +        +  +  + +   +       +                                  +   +        +     +      +   +        +    +    +   +   +       +   +     +    +                                 +    +  +   +    +    +   + +       +  +   + + +   + +  +   RVZVXW]_Z[aaZb_egdkhimnlkookqrqu{tyŀxx|Ѕ܇و|Ԉ߅݈և~ςxwvlrki_`Z\WQV{EtHsItHk?b<]:b9R9M0N.B+H+A'? <$/-)("  +         +     + + + + +   + +    +    +  + +  +  +  +  +  + +  +       +      +     + +  +  + +    + +            +     +             +  +               +                      +   + + +  +   +   +   +   +     + + + +  +   +  + + +  + + +    +  +                   +        +   +        + +  + +   + +  +    +  +  +     +  + + +  + + +  + + + +   + +    + []`bbeffhmjlmqhqxqqvyyzyzɁ̃~΄ՃćІх΋ێߎڒ،ގߕܖߙۈ،ЇЂĆÆqttllfacUXSWzGmPvEoBeF_?Yn@b<]=S8S1L0F(A(B%=$33!0(*"            +  +   +  +   +   + +  + + +   +  + + +  + +  + +   +  +     +   + + +  + +     +    +  +  + +   +  +    +                + +                               + +          +       +      +  + +    + + + + +    +  + +   + + + +  +  +  + + +     +  +  +   +    +     + +    +      + +                  + +  +   +  +  + +  + + +  +       +  +  +   + +    + + + + +  + + + +  `baegg`jelkopjomyorutvyzxāāπÄ҈ʈ̈́NjӅʉՏ܊܊ݕސߋۊƁ̇ǀzwutqgde`VYQV}RsIuCeEd@\@Y?U7K3J/E,G+>&<&1#0#/)'"        +          + +  +     +    +   + + + +  +  +  +  + +  + +  +    + +  + + + + + + +  + +     +  +  +       +     +                                            + +      +   + +  +        + +        +    + +              + +  +  +   +      + +             + +         +    +       + + + + + +  +  + +    + +     +  + +  +  +   +   + +     +  +  +   RZUY\^ebZ]a`efcjdhidmoogcpqrwrtƀu~x}w|Ԇ~~ه܊ۉݑތz|ƁwqrpjfhW^UUVKI|P|CwBr?i>\;V6V6P3O0K/I->&<$9 7#1'('    + +  +      + +  +    + + +    +    +      +     + + + +  + + +  +  + +    +   +   +    + +     +   +     +      +  +  +                  + +  +                + +    +               +     +       +     +   +   +   + + +   + + +  +    +    +  +    +        +       +           +         +   +  +    +  + +  +     +  +             +  +  + + + + + +     +   +  +    +   _ced`hignlfmnoqq{xtttzz~ŀÄɈ҇lj׉Ոɉ׊ҋԐؐݎؒՑًӋڊ~…vwtiglb^VWZP}SuLnIsGbAb;Xb@b6b5Z4W2P0L-H(?&;$7 5//%#!      +      +      +    +   +  + + + +   +      +    +             + +       +     + +    +  +     + +   +           +  +             +                  +                      +      +  + +    +   +     +      +  + + + + + + + + +  +   +  +    +       +    +               +              +            + +     + +  +   + +    + +   +  +  +   +   + + + + hb`gdcjjkkfkluustwnutw}x|{ÂDžƀƀĄDŽЅЇ̅Տ؉ՍՎ܏֎ߗߗҋ~{prrfmk\][RT~LxKkImGdDaA]?_5O4P3A1A-@)8%9!7"/&"%         +     +  +      +    +    + + +  + +        + + +  + +   +  +  +    + +    +     +  +  + + + +   + + +              +      +                                           + + + +  + + +       +    +  + + + +  + +   + +           +     +     + +    +  +    + +  +      + +     +  +         + + +   + + +    +  +      +    +WXU\UZ^a^^_``edf`iifljisqhvoyvv}vxy|z{܅|}~܄߈݀|usqksjdc_[\OTK}OwHrCl>k?_>^8U4S7N,F.G*@)=&9%5!-2(!"    +   +        +       + +           +  +       + + + +  +    + + +  +  +   +   +   + +      +           +    + +             +     +    + + +  +               +   + +     +                   +      +  +  +  +   +    +   +    + +  +  + + + +   + +    +  + + +  +    + +   + +    +   +        +      +   +       +          +      +   + +  + +  +  +   + +     +    +  + + +   + + +  +    + +  +    +  +  +]ddmgfcglnoqspprswtss|y{{||̓ƅˇЉȂρˋҎӊ֔ޘޒڒޝٍܐчфԊ|zy|pocie^XWUuRMmJfDeHb?`@R:P6Q5N2C-A+@)9$-.*%     +   + + +    +      +        +    + + +         +  + +     +  + + + +   +  +  + + + + + +   +    +    + + +  +  +   +             +  +          + +                       +         + + +              +  + +   +     + +  +  + +       +     + +    +        +        +   + + + +     +       + +  + + +  + +        +    +      + +   +  + + +   + + + + + +  + XWWZW]Yh_^e_adajhfhplmmppppyr}s}݁Ёy}u؊Ԁۉ|։ւπ}xutmfi_aZ[STQyGwIqDp@f:aA\:W7R6P.O.B+B*E(;%2 /-'%%           +      +     + +   + +     +  +        +  +    +   +  +  + +  + +  +      + + + + +       + + +      +           +   + +   +  +     +     +            +        +               + + + +    + + +            + +   +      + + + +   + +    + + + + +  + +  +  +     +      +  +   +        +  +  +   +  + +   + +   +  +      +    +      +  +  +  + +   +         + ]d_edgdfghiwssqutzustyxyNJɆȇ΍χӈΆՌьז׋ږޑݖ~ӈԋ˃ʀŀwqpt`ia^XY}ZxK{JsGlHe@cB]>Y=S5O2F1J+F'=*7$2"+('"!       +    +     +   + + + +   + + +  +   + + +   +      +    +  +   + + + +  +   + +  + +  + + +    +  + + + +        +    +       +       +              +       +       +       +    +  + + + +  +   + +    +     +  + +      +     + +          +          +      +  +  +    + + +     +     +  +   +  + +  + +   +   +  +   + +    + + +  +        + +VV[[\\ZYZ\`jdbbflhghklkovqtovru{xyՅyق|؂~y}׈ފڀ~́swspfjcddYQQUxFuKmAoAgBb;]:Z8P2P0O,E&A)=)8#51-+'         +   +  +     +  +     +  +   +  +      +    +  + + +  + +      +   + +   +  +     +     +     +    +      +    +  +       +                                  +      +  +           + +      + + +  + + +           +       + + +    +  + +  + +   +   +  + + +    +   +     +   +          +   +  +     +  + +   +  +   + +  +  + + +    + + +   + + +      + + + + +  +   + +   + + +  +   `afd^jgijlirnuntvotxnqwz}Ņ~˂~͆ՀΊƂؒؕ׍ڌוَߐΈڌȃƄvwwqjojaaWP{PnUoMpGgG_@_a>a@Q6[1S7I1D2F)9'5%2!/!.')  +               +   +  + +  +    + + + +  +      +   + +  + + + + +   + + +   +  + +      + + + +    +     +   +   +     +    + +                       +         +    +       + +       +  +  +   +       +   +   +          + +              +                            +   +    + +   +  +  +  + + +  +        +        +      +   +       +  + WUTZ_SY_WZ]galhfgifglioqxnsxuuuyy~ẑۀπ߂ރۇچx̂u|mulfde`^WLWRM|KrKu@dFg:`=b3S8P6H/F-F)B&7#5+.)&     +  +          +   +  +  +   + +     +     +   +  + +  +   +   +    + + +   +   +  + +     +     + +  +   +  +   + +   + + +                        +     +   +     + +            +    +               +    +  +   +  + +     +  +  + + + +    +  +  + +    +  +    +  +  + + +       + +      +                + +      +  +  + + +  + + +    +    +    +    + +   +    + + + +    +  + +  + +    + +  +    bi_hkggnljsokutrpxr|w|qwƒ~ŒŁІҋюˇԈэהؐՕڒӇԍ́~|ztkjlieacXT}RzPsJiIhF_<`@Y;Z1W8J.H1H(?'9%3$5 .&              +    + +      +     + +   +  + + +   + +  + + + + + + +  + + + +   +  + + + +   + +  +       +  +  + + +   + +  +     + +   +                          + +                          + +   +     +  + + +   +  + +   + + +    + +      +   + + +  +     +   +                   +  +          +   + +   +       +        +     + + + +      +  + +   + +  +  +TZYYZYY^[_e^abbblkjjrmljorprjnswx|́~z~|~چ׃Ԅ|xxw{jgdh]\WRSPKIuBqDq>`=d6Z=W1U1K1F'E B*@$3"0 ,-#! +  +   +   +   +  +   + +    + + +  + + +        + + + +   + + + + + + +  +    + +  + +  +           + + + +  + + +  +         +   +    +   +        +  +      + +                                      +        +       +    +       +           +    +   +   + + + +         + +      + +  +            +     +  + +     +      + +  +  + +       +  +   +  + + +  +       +       + +  +       + +     + +  b`aebigljkkqolsxvtvy{y}}ȉͅŌņώˊږ׎ތל׌~ЂtiyunbhaZWVLxOmDpGgBiC`=Y%7#/+,##  +       + +    +       +     +     + +     + +  + +        + + +  + + +  +   +    +           +     +  +   +       +      +     +                        +                  + + +  +             +  +   + + +                    +   +     +     +  +   +    +     +    +  +  + +  +             +        +   +    +        + + +     + +  + +  +  + + +  +   + +    +      + +  +  + +    + +  + +  + +  + cafggchjnjkhvoswqv{zosx~ǁ~ȅŀƃʎЀՆׇ҉ۓڔϐۓޏדܙτyornsjda]ZUV~LvHqOcFcC_;Z;T7M3J6K0?-=$7%8$5++(        +       +  +   +   +   +   +  + + +        +     + +   +    + +     +         +     +  + +     + +  + +    + + + +  +   + +                   +           +    +             +  +     +  +  + +    +     +  +  + +     +                +    + +   +  + +   + +  +  +     +   +  + + +   +  + + +      + + + + + +        + + +    + +  +   +YYTT\\]^Xbcbiafhjolkkjnnrl|pqt{|z|ڂ}||ׇ~݉ޑلumiijda]VPVL}JyEmAj;h;]:U8X3O/O1D(I-A'<%6#3.'"'!     +  + + + +    + + +    +    + +  + + +    +   +   + + +  +   + +  + +   + + +  + +  + + +       +  +   + + +    + + + +    +  +   +  +    +   +             +     +        +                           + + +       +          + +  + +     +     +   +  +  +   +          +    +      +       +  +      +  +  + + + + +   +          + +     + +       + +   + + +     + + +  + + +   +    + + +  + + + +  fehfhoijijljotrzstpyxxyāĈ~ˉɄƋֈψ̑ύՒЍёڗ܀yvthdd]cYX|TvLrHpGkGb>b=Y?Y8V5N5G0D.D)5&5&/!+ *&!       +      +     + +   +     + + +    +      +    +    + +  +   + + + + + + + +  + +     +  +      + + + + +   +     +  + + +   + +                              +         +     + +           + +   +  +      +   +    +  +    +     +   +       +                +  +  + +     +  + +   + +      +   +  +   +    +  +   +   +    +    + +  +      +      +  + +  +   + X\W\Y^Za]`dgdfhkfjgqjplfpssqryws~|ր}yֈр݂ن׊߀|܋هmmf`Za\UVL}JyImBmCo?b9]6T5R5P3I.F(>&A"6 1 -.($  +    +   +   + + + + + +  + + +    + +  + + +  +   + +        +    + +  +    +   +   +   + + +    +   +  +  +  +  +     + +     + +  +   + +    +    +  +        +                 +     + +  +         + + +                    + +   + + +  +  +     + +    +   +   + + +  + +        + +   +      +         +      + + +  + +      +         +   +  + + + + +  + +      +  + + + + +   + + +   +   + +   + +  +     +       + + + +   +  ^^febngkdfnlqrmtwtx|xz}zx‚Ädž΀ʼn̈́҇׍ŒԄ֒Ӎ֍ܐߋه{uohhb`_X~S{QxKfGiCj@cA^?P6P6O2H5B,=&6$6#5#0*%$    +  +     + +       +   +  + + + + +         + +   + +   +  + + +  +  + +       +  +     + +     +       + +    + +  + + + + + + + +    + +      +     +               +           +       +      +            + +    +  +   + + +  + + +    +  +           +     +            + +   +  + + +  +       +  + + +  + +  +  +     +         +  +  +   +      + + +  + + +  + + +  + +  +   + X^S_[^^_^`\f`gfghegjormrrqmtz{qzy}܁ր߂؊~ng`ZXSVMHvJx@n@h@b;Y"43 +"!      +  + + +    + + +  + + + +   + +    +  +  +  +  +  + + +   + + + + + + +    + + + + + + +      + +  +    +    + + +     + + + + +  +   + +  +  + + +  +   + +       +  +  +    +              +             +                       +   +   + +   +  + +    + + + + + +   + + +            + +  +   +  +   +  +     +  + +  +   +    + +   +      +   +      +  +  +  + + +    + +  +  + +     + + + +   ZYZ[_]_^c`a^`cl`jehiknummrwquw}xy|ـفۀ߁φ݄يׄهڌքև}voWTMzIuFpCi<_>_<[1U0P/E(I*A!;&;"70,&$#    +    +   +     + +      + + +  +  + + +   +  +  +    + +      + +   +   + + +  +           +   +     +  +          +  + +     +  +  + + +     + +  +      +      +               +        +  +  +   +  +    +           +               +     +      + +     + +  +   + + + + +   + +  +          + +    +  + + + +  +        +    + +         +    +  +    +  + +      + + +  + + +      +   + +  +  +    + ``ffaipjjnmtttxuuxuvu|À~††΃ɇЕȊБՎՉڐ׏ܕܒךݘݜ݌րقԇՉ}zzng\U~PuOuLnIbF_=b9T8G1P0I,A)?*<$9&3 . ()$  +  +   + + + +   +     + + + + + +   + +  + + +  + + + + + + +  + +  +   +  +   + + + +  +  +  + +         +   +   +   +  +  +   +  + +    + +      + +           +    +    +        +        +       + +              +   +  +     +  +    +    +    +   + +  +  + +  + +                  +      + +  +   +   +  +     +  +  +    + +         + + +    +  +    + +  +    + +   + + +   +    +  +  + ZSX^_^``_gcaei`dfgeomqglstouxxytwՀy׀؉ڃކ߆{ׇڌʁ҇ǁׂylY}L|GrCiBb>Y7^7R7T3E.H+C(@&5#6$1*)( +   +     +   +    +      +  + + +  +  +    + + +    + + +  + + + +       + +  + + + +  + +      +   + +     +    +   +  + +   +  +   + + +  +  +    + + +    +  +            +   +                 +           +                        +         +       +   +    +       + +   +  +  + + + + +  +  +  +     +        +        + +  +    +    +   +     + +  +   +  +     + + +  + +      + +       +      +   +    +  + +      + +   +    + + ijegdioqmomolpsv|p{x}~Ã̄ӊDžʋьʋۋۋېҘގۇ}~xx΀ro^ULuIl>iAb<](7'3#3 *("        +     +  +   + +  + +    +  +   + +  + + + +   +   +  + + +  + +  +  + +  +  +  +  + + + + + + +  +     + +      + +       +  + + +     +    +  +  +                               +         +     +                 +  + +  + +   +   +  +       + +  +  +      +  +         +  + +   +  + +  + +  +       +   + +    + +   + +  +  +   +      +               +  +  + + +  + + + +   +     YX[^^c]`af_eeggodnqsilplnvvtqy}v}ς|Ձu݉ڈل܃ۂ߃݄ԇՂˈу{|xxzÁĀÀvm\|GjAh:a9]6V5O2L)H-A'E%7#44+%'   + +     +  +  +     + + +  +  +  + + + +   +  +   +  +  +  +     +  + + + +     +  +  + +  +   + +  +  +   +    +        +   +  +      +    +        + +              +   +       +    +   +  +                + +  + +      +       +   + +  +  +           +   +   + + +     +           + +    + + +  +  +  + + +  +  +    +  + + + +    +    +   +         + +     +    +       +  + +       +    gefmdhnkdqjstutquz}z{|yŀʅʂĊˇъ҇ЋЅӉהڕݔڎڇzуsvxurtoc\RQpEcBc?Z:W6R2L.I/C)?)<%4$/-&           +  +  +   +   +   + + + +   + +   +   +   +      + + + + + + + + + +  + +    +  +    + + +  + +   +  +  + +  + + +  +   +  + + +  +  +   + + +    +  +             +           +                         +         + +  +  +  +  + +   + + + + + +  +  +  + + + + + +           + +  + +     + +   + +   + +  +  +   +  +   + + +         +   +    +   +  +    +    + +     + +    + +    +  + WUX\Z]ae[``cackegojnqpunnvttstv|ـքzڀӆ҄݌܊ޏֆ҆~҄ҁӂv~{{y}urutlgGb:`6U9S.M1F*C'@'8!2 0.+)  +      +  +   + +  +  +    + + + + + + +   + +    +     + +    + +       + + + + +    + + +    + +    + +           +     +     + +    +   +  + + +   + +     +       +                     +                +  +            +      +   +      +                  + +      +        + +    + +      +  +  +  + + + +             +   +   +    +       +     +     + +   +    + +    +     +   +  + + + +   + +  + +  +   +  +    +  +   + +   + + + + + +  if_fkoguhtqxtuwuvys{rĀ~ˋÃɐЍˋҊ؇ҒҋΒޓؖޓޕ٘߂Ʌҁ|yy|zptshkidh_TEp?]S-B'A+>&8$3",')!   + +       + +  + + +  + + +   +  +    + + +    +  + +  + +   +  + +  +  +     + +   +  + +  +   +    +        + +   + +       + + +    + +       +     +  +  +  + +    +            +      +                     +          +     + +        + +    +  + + +  +   +  +    + +   +              + +  +  + +   +  +  +   +      + + +     +    +  +  +   +   + +   +  +          +   +   + +    +  + + +  + +  +   cihohherrnrprrtynz|~}ńˇȆ͌ҌʌόЎϐՑ֑ғږܓӍЇЉyywvtkqijfcacY_Z]UPH{?]1I1B%=&7!3''#   + +     + + + +  + +  +  + +  +   + +   +   + +  + + +      + +       + + +  +   +  +  + + + + +  +  +  + +   + + +  + + +  +  + + + + +    + +  + +  + +    + +  +         +     +       +       +   +          +         +         +  +     +     +             +    + + +  +    +      + +    + +  +   +   +   + +   + + +   + +      + +         + +     + + +  +   +  +  + +    + + + + + + + + YXZ[Z]\]befcdagnmnjmphnpruxsv{zx~~Ձބׅx~߈}ڂ؇҂цtyvtnpkglpjlokjrgl^d\qFM,?'8"3 . (&  +  + + +   +    +   + + +   + +     +  + +  + + + +  +           +  +  + + +   + + + + +   +   + +         + +  + +  +   +   +     +    +   + +  + + +   + +  +    +   +    +          +           +  +  +    +             +  +         +   +      +         +      +   +        +    + +                +   + +  + +    + +  + +  + + +   +      +       +  +     + +    + + +  +  +      + + + +   + +   +  + +   + +  + + +  + + +   +    +  +ghgkmnoqlmpspu{rwu|wz|~€ɋˆЌ͇͌Ո̌Џێܒސ٘ߙُՋӀ~~yttejigdc]b`V[UXRULF5`,A"8!3!/ +$#    + +  + + + + +  +  +   + + + + +            +  +    +  +   + + + +  + + +  +    + + + +  + +   + + +    + + +  +  + +  +    +  + +     +          + +                  +     +      +   +           +  +      +     +         +   +   +   +    +        + +      + +              + + +  + +  +  +    +     + + +  +  + +     +     +   +   +     +     + + +  +  +  + + + +  + + +  + +    + + + + +    Z[]V\gZZcb^h`lheghnios{ssvwxx{t{΀ʀՀЀ؆݄߃z܋߃؃Ձt~zutpmmlfgnbaj`dgdcfgbi`xHM.:!0.'"  + +  +    +     +    +     + + +  + + + +    + +     +  + +   + + + +    + +  +  +   + +     +       +  + + + + +   + + +  +    +  + + +   + +  +    + +    + + +   +  + +  +   +  +        +     +        +      +   + +  +           +          +         +         +        +    +    +   + +           + +   + +  +    +     +  +  + +               + +   +  +   + +   + + +  +   + + + +   + +          + +  jglkglknnqprumtzzy}}|ƀ}Ãłɏ͋Î͉ޏІٔ݋בݜݎݒ܉ϊՀ}zxmqrfjmbdZbXYXRWTLSJLD7a*E"0,$#    +  +  +  +  + +  +   + + +  +  +     + +  + + +  +    + +  + +  + + + + + + + +  + + + +  + +  +  + + +     +     + + +  + +  +    + +  + +   +   +       + +    +    +                   +    +      + + +    +    +                  + +   +         + +  + +   +  +        + + + + + + +  +   + +    +   +    + +  +  +   + +  +   +   + +   +   +   +  +  +         + +  +   + +  +   + + + + +  +  YY_a^[_i_^ahchdkhromqtnlvotpz~x|Հ|҅y}Մ~ۉ׊}ˀv{wrvqeqhkddbeagaaeabce_\beoQ]9:!(!   + +  +   +  + + + +   +  + +  + +  +   + +       +    + + +   + + + +  + + + + +   + +   +   +  +     +    + +           +    +   + +  +    + + +     +   +   +    +   +                 +         + +                                 +      + + + +        + +      +     +         +   + +  + + + +  + +   +      + + + + + +   + +          + + +  +    +  +   +  + +  +  + +     +  + + + +  + + + + + +    + + +   + dghdnhbslpruqyvouqrzƇŅÀ̋Ƈʅσ؋ˋ؍ՑՈ֏ߏݒܖُևԁ}łzoojmah_[`]TWTQTMIJOLFH?;p-L .   + +  + + +   + +    + +   + +  +  +    + + +  + +    + +  + + + + +  +   + +   + + + +  + + +  +   + + +   +  + +      +    +    +     +   +  + +  +  + +    + + +  +   + +     +    +           +                 +    +         +   +                     +  + +             +  +  +  +  +  +     +     +     + +      + +         + +    + +  +  +       + + + + +  + + +              + + Y[_ZXacd`bbdcgiobtkslpkqmwzx~xyxʂ̀فv߀׀مځހ΁˃~trxnpbih^[a`]\\Z`XZ``_Zba\bxT_?A)(      +  + +  +    +   + +    +     + +     +     + +   +  + + +   +  +  + + + + +  +   + + +  +  +  +     +        +    +   +  +    + +   +  +  + + +  + + + +      +   +    +                      +              + +         +  +      +  +     +  + +   +    +        +          +         + +     + +   + + +    + + +   +    + +   + + + +   + +    +   +    + +    + +    +  + +    +      +  + + +  + + + +        +    gckpkshpxrrxupzxpww|{Á~Ëǁȇ΋ч͉ҋ܊؏ؑߚߖޕߕݍ܃ԇ}{{pqlijda`XWYPPNLLMDFJCLCE>6t.W#/    + + + + + + +   + + + + +   + + +  +  +  +  + +     + +     + +    + + +   +    +  +   +    + +  +   +    + + +  + +       +   + +  + +   +  +  + +   + + +  +   + +    +    +                +                     +          + +  + +   + +     +  +      +       +         +  +    + +   +     + + + +   +     + +   +  +  +   +  + +  +     +   +  + +  +   +    +  + +   +      + + + + +  +   +  + +  +     +   + V\^c[_hg^ebgdekippnqinqp{utx|w{t~ـyڅ݈ކށՂ؃ՃЁ|{{ropokac[a\`[[[P^TzQ[U{W|^~YWXbZvUkEF.&  + +      + + + +    + +  +  + +  +  + +  + + + + +  +  + + + +    +    + +    +  +   +   +     +     +  +  +       +    +  +  + + + +    + +    +  +  + + +  +    + +  +             + +   +                       +    +    +   +      +      +                    + + +   +  +    + +  +      +       +   + +       +  +  + +     +  + +  +  + + +     + +       + +    +  + +  +  + +  + + +  + + + +       + + + + +     +   +   + +  + + +  + + + + ggpokqntlustwztzw|z}Á~˃ŀˈ͎̆̎ԑގ̌ґޑڑՔڌҊڈ΍ևyxtnifbcWV_XTP}PKKG{H~F|B~@|D}A}>u=~=>}8r,\<   + +  + +  + +  +   +  +   + +  + + +   + + +     +  + +   +  +  +   + + +  +   +    +      +  + +    + + + + +  +   +     +  +          +     + +  + +   + +                          +        + +        +          +                  + +  +          +      + + + +  +  +  +   +   +     + + +  +  +    + +  +     + +   +  + +        +    +   + +     +      +  \^\[ba`^`ehhiijklknxgwswmvxxyx}{}}ڃۂ܋݌܂~~{Ղuxuvqncab]]VWUYTO|Q}T~P|WwQtTuXvOvO}QxWyV}]`{SqHT3*    + +  + + +  +     + +   + + + + + + + +    +    +  +   + +     + + + +  +   +  + +          +   +  +   +  +      + + + + +   + + +    +  + +   +   +    + +   +            +                   +        +                 +      +    + +  +               +        +  + + + +   + +  + +    + + +    +  +   + + + + + +    +      + + +  +   + +          + + + +   +    +  + + +        + + +   + + + +  +  + gfnjffkjnpruwtuyz|~yz|ɆɁ|Ӈ͇ӈǃьىӓԒؓؐܛۗړܙߍՃ׌}΄ąĂtujhd_\WVSMJNHIwEEn?u@yAo8q@z;n=x=n7x5y5z1l.c%E"    +   + + + +   + + +  + +   +  + +  +  +  + +  +   +   +  + + + + + + +  + + +  + + + + + + +  +  + + +  + +     + +       + + + +     + + +  + + + + +  +         +    + +          +           +         +                +  +                     +        +        +   +          + + + +  + + + + + + +    +           + +  + +     +     +  +    +     +        +  +   +  +   +  +  +  +   +       +  _X_[^\ic`f[jijdkinpprovqqrz{zzw|}}Ԃڀڄׁ݁xwnqtlpwkcb_[_[Q\SOyMzOyKwQxGpNqKtPnMlNvSjOsQrQxOrVqVuYqN^B<%   + +  +  +     + +   +  + + +   +      +  + +  +  +  + + +   + +  +  +      + +      +       + +    +  +    +   + +   + +   + + + + + +         +  +    + + +             +          +   +       + +         +      +     +  +                   + +  +  +  +    +     +      +             +  + + + + +   +  +     + +  +   + + + +  + + + +         +         + +       + +         +    +    + + +   + + + +  +   +  iifnjgqrkquq{twtw|z„|~ʆɄˇѐЉ֋Ց׎܍҆ߓݚݔߍڐ߈גЋɇ}z||tolh`bPWTOP}HqI{Iw@xHv?j>t?n8o:k5j5h5l6j5g5n5s4x5v0k%P.   + + + + + +   + +  + + +   +    +       + +   +  + + +  + + +   +    +  + +   +  + + +  + + +   + +   +    +  +       + +  + + + + + +    +  + +     +   +    + + +                +               +      +  + +    +     +  +          + +   +    +                     +   + + + +  + +         +        + +          +  +   +  +    +     +     +     +  + +   +  +  +  +   +  + +   + + +    + + + +\Y`^babegbhlemokgsootwtqvyx|}x΁ڄ{xօَ|~|zxytmclkglcdZ[V\PNsN{PxKyMoJlFkAoFnJhHiFjJhHgMgIhQeImMoQqS{TuPeIF5'    + + + +  +  +   + +  + +      + +  + + +  + + +     + +      + +   + +     + + + +    +  +              +    +    +         + +     + + + +  +   +    +       +  +    +         +       +  +      + +  +    +     +               +  +        +    +        +    + +    +                       + +    +  + + +  + +   +  + + + +  +    + +  +  + + + + +       +  +  +  + +     +   +  + + +  + +  +        +        + + +  +  + + + +   +   + +  bmfmorqvtsrwruuǀ|{Ɔ‚҃ȃʆώ͈ӋɊІܜ؎֌גܛڍٌЁ̀˃zwtoplolda_XXS|KN{HpHoCqBr@m?lg:i;`9c<\5\/\0]/T0a.[-\)Z,[+b*`+i/i4t1p-m!O, +     +      + +  +  +    + +  +  + + + + + +  +    +  +  +   +  + +  + + + + + + + + +    + +  +   +  +   + + + +  + +   + +  +   +      +  +      + +   +  + +  +                +    +  +             +   +     + +             +       +       +   +  +            +   +            +    +  +   +  + + +       + +   +   + + + +   +   +  +     +  + +   + + +   +  +   + + + +  + + +   +   +  +  + + +    + + + +   +  +X\_acbeafefnginnorjjtnwuy~zxx|{w{Ԁ܄߀܋݇|}uulhjhbY[Yh_\XQQNKvJuNfAjBbBc>^8^A[@VAX[=TB[@`DWHbHfKjPoSyPoUiFD.$ +    +    +  + + + +  + + + +  + + + + + + +   + +  +  + + +  + +   +    + + + + + +  +  +   + +  +   +   +   + +                 + + + +     +    + +    +  + +     + +    +       +  +       + +               +          +       + +  +    +       +                     +  + + +     + +         +   +   +          + +   + +   +  +  + +     +  + + + + + +   +  +  + +      +  +   +  + +     + +  + + + + +   +      +  +  +  + +   + +  + + +  +   +  fgjmipmnuirpxxtxyÃ~}̈ҊˊNJ̏ډهߎЌԕݓ֏ߙГʇvxssmnc^`f\]XQS}FvJxAe?f?dfBa=Z=W9U6S9S8R:P7R8Q6Q>Y=RT^9X-?*:';&A,;,A4A4K6H\AbGcLjRnXtUmT];?(     +      +  + + + + +  + +   +  + +     +     + +  +  + +  + + +  +  +  + +   + + + +     + +    +   +    +  +    +   +   +  +   +   + + + +    +   +  +  + + +    +    +  +  +                  +             +     +     +     +           +     + +      +  + +   +  +    +  + +   + + +       + +    +   + +                +   +       + +  +   +    + + +  + +      + + +  + + +   +            +  +    +   + +  + + + +  + + +  +  +     +  + + + + + + +    +  + + +  + +  +   + +   +  ijpvqiopqrp{v{{{vă|~}ɋЈΌȌ҆׉׎͓ދۓۋɇрv|yqolh_^XUYWxUoFeFgAZ=b>^BoAiAa=Z7V3V.I*H+H$?%> :!;;<8:7DDGO P"O&R'U'e(^)b,m1o.o0k$T6 + + + + + + +  + + + + + +  +    +    +  +   + + + + + + +   + + + +   + + +   +   +  +  + +   +  +       +  + + + +    +   +  +   +  +  + + +    + +     +  + +    + +    + + +    +                + +       +     +       +            +        +  +   +      +    +    +       + + + +                         + +  + + +   +   + +   + +    +  + +  +  +              +  + + +    + +  + +    + +  + +  + +   + + +    +  +        + +  + +bbbb_bffgfsjhspnpttvmryyqʀs|~ԁ}߄ׁrwtqpbc`_ZYRNI{HtDnCh=_;^5V8\7\>a?fBZ=U7J3K1A-C.<,9%5$8$3$6(5&8);+@2@1L5H^9T9P=R9\@[9`7W6L/C(G*F";#;435+0466?CC H!J"V"O#W(`)d-e)i1s3x-t'bB"   +  +  + +  +  + +    + + + + + +  + +   +  + +  +  + +   + + + + + + + +  + +  + + +  + + + +  +  + + +     +       + + + + + + +  +   + + +  +  +  +    + +  + + +  +   +   + +  + +   +  +     + +              +  +   +                               + +   +  +      +          +      + +  +    +      +  +  +                         +  + + +  + +   + + +          + +  + +  +    + +  + + +          +  +    +  +   + + + +        +       +   +   +      + + + g_cagcdejmeglhjprrqvlruuw{}|߆|މ߆ފw{vuutlgh`a[]VMMwIsBmDi>e8b7X2X1I0F*N.[8Y=[4Q8F2E+@+>':+0!1#0$3$-(2$6):-:+XC]HaK_KjQmRyWnPWB<&  +  +   +  +   + +  +  +       + + + +  + +  +   +    + + +  + +         +   + +  +    +      +   +  +  + +    +  +   + + + +  + + +    +     + +   + + + + +  +  +   +  + +          +     +               +        +    +          +                          +        +      +   + + + +                        +   +   + + +  +   + +  +    + + + + + + + + +  +   +     +   + + +  +  +   +   + + + + + + + + +  +  +   +   +    + +   + + + +   +   + + + +    + + + + +jkbmlvtxpvruxx|~}~ǃ΃LjِׄԐؓ׋ْؐߒێ؉υ}|xuonlib\^UP}MqKtKiHb;`=V6S3T2I0F5J4R2T0V-N*H#A!330.5.1/766B>GIL!P"N)Z%\'a(h,j1r-t/q+h#S0  + + + +  + +  +  +  +  +   + + + + + +   + + + + +  + +  + +   +    +   +  + +  + + + +     +  +  + +   + +  + +  +    +     + +  +    +  +   +   + + +  + +   +    +               +   +          +     +    +    +    +  +        +   +      +          +       +        +        +   + + + +     +   +   + +  +              + +  +  +      + + + + +            +     +  + + + +   + +   +      +  + + +]^bgbhideejmjkrnmysxts}wwxwӀ؁ڀև}׍܆݊ރه~|zorjfcX[WTPIwK{EpFl@c;];[7T3K0L.D-D&?,J-U8R8J.F*<'8$8#/"+/!1!-2$3%0(5)=-A+;3F3DQASD^C\GfMfPhNtXu[kKK0*  +   +    +   + + + +  + +   +  + + + +  + + + +   +       +  + +  +    + +     +    + +               +    + + + +  +  +     + +   + +   +    +   + +      +    +       +          +                +   +  +   +     +               + +        + +  +  + +  +     + +    +         +      +    + +          +  +    + + +  + + + + + +   + +  +    +  + + +     +    + + +  + +       + +  +  +  + +      + + + +  + +   + +  oiifqqpuvxwuwyw}~ÀÂ}φЁȊЉ̌Ԇ̐А؋֖۔ՒۑӓՒݎӏ΋؂}ytpkle[[VXO}MwGeGoDe=]B_9M7M6G+@.>-:->-J0N)H'H';:3/0++/.0036><A K I"L J"Q$W$_(])d1i1w0v1v(^=    + +    +     + + + +   +  + + + + + + + + + +  +   + + + +    +  +    + +  + +   + + +  + + + +  + +  + +  +  + +  +  + +  +    +   +   + + +      +   +   +  +    +      +                       +   +      + +  +                +   +    + +              +        +  + + +   +    + + +  +   + +   +  + + +    +           +  +   +         +       + + +    +    +  ]^_Z`backfofmpqpsnnsp{wx{zyy|x}ԁۉރޅ߁}zvrkghih^WSYPNyFyGrDt@h9h8W9Q3Q-H2B.G$6'4"8"='D.L0D,@)5%0$,0 ,!-* ,$0#1+4&5+6,C0>,I7E5J_@[8U2N2K,G0?&=&1"/#.&:'@&C$; 9 0,.*(**./0249><? N!I!K!P&U)]%R.g.`1m.t/q)j!I* +       +  +  + + + +  + +  + + + + + + + +  +  +  +  + +    + +   + +  +   + +  +          +  +  +  +   + +  +  +  +   +  +    +  + +  + + + +     +     + +     + +     +  +      +                 +       +     + +   +      +    + +      +      +   +                     +  +   + + + + +  +      +  +  +    + + + +  +       +  +   +  +    +  +         + + +  +  +  +      c__[`deheiijpkklslrmnxnv{}цz΂~~ځ݈݉ڂ|rsvxncfacdSYOO|KJkAo,C4D2M;N>R9TCQG_If@jHkLvLxWrU^IH." +    +  +      + +  + +  + +   + + + +  + +  + + + +    + + +  +  +     +        +      +              +  +  +  +   + +    +  + +  +   +  + + +   +  +  +    + +  +             +                          +  +  + +          +    + +    +     + +   + +           +   +  + +   + +   +     +     +            +   +      + +    +    +   + + + +  + +           +   +   +      + + +  + +    +     +  + + +        +  +  +     pkllunxwowxy|~~ŀ{{ĂЂ€Ɔ‹ˎٍ݌ԑܐِՑޚޏݓɋ҄ą~trokeaZWYK{J|HjHoIhB^HNJ"R"X&W)X'e*h+p1o-u0j$Y8    + +    +  +   +  +  +  + +     + +  +  +   + + +  + + + + + + +  +   +  +    +   + + + +   + +   +  +  + +      +   +  +  +   +  + +      +  +      + +  +  + +     +  + +                     +      +   +     +       +  +         +  +        + +  +        +  +  +      +    +  +  +  +  +    +      +       +  + + +          + + +     +   +  +     +   + +   +   +   + +\^\f`ddghhfjklnrktoyrpv{сr~҃ւ}~ހށځ~zzynlmdh]\XQPP~GvApDo=d=e<[8V4T0L0G,D->&:%70,%#$+4$:"3'.)*)(+)+","-%2#6%7';,;/?1C4J4I9O1 +  + + +   +    +  +   + +      +     + + +   + +  + +     +     +  +      +  +   +     +        +   + + + + + +     +  + + + +  +   + + +  +     +     +   +                    +                +     +                         +    +    + +   +        +    + + +  + +     +    +       +   + +  + +   + +   +  + + +  + +  + +   +   +  + + +     +  +  +  + + + + +  + +       +  +  + +      + +  instuyptrxu|{~xā}ŀńȈ̋ЅΐхވЎҐ܊ؗܘݓېՒ׍̀}uvuqmeg`[TO{SvJlJjH`<]9\W9W0I1J2?.A(:%3!,*(.32+.*(',%*,/.599?AD!G!N$K#M$Q)Y'\-_+i/i)q2p0m%W9 +     +    + +     + +    + + + +      + +  + + + + + +    + + + +    + +      +  +     + + + +     + +  +  +   +  + + + + +  + +   +  +  + +   + +   +      +     +                                +        +  + + + + +                     +    +       +  +  +     +     +     +  + + + +   +  +   +  + + +  +  + +     +        +     +       +  + + + +     + +  +       +  +    +ca`_efegenjljomoqrnvsv{{x{~||څ{}ۂڎ}ʂw}ytfhce[VWRM~KyHoEmDf=a<\7X4N0S*D-G$C$;52/ &"!  + + .(3$3!)!+)&((+,/"0 1(6&>,?/=.D0H8K7OC<JF!Q!P#V&[&_+e,b,m1t1o-g$S8     +  +      + +   +   + + + + + +  + + +   +     +  +     +  + +  +   + +     + +     + +  + +  +  + + + + +  +  +  +  +  +  +       + + +   + + +  +  +   +   +  +   +  + +  +                  +      +   +           +              + +             +     +  +  +               + + +  +  + +  +   + + +   +       + + +      +     +    +                     + +     +  + + + + + +    +      \_[bdcbifbnjjojjtourt{vzw{y΂yڀ|ވׇߋ{{utmjggi[XPPQ~O|HrIr@j;)  + + +  +     + + + +  +   + +   + + + +       +   +  +      + +  +  + +   +      + + +          +  +  + +    +    + + +  +   + +     +  +   +   +  +      +  + + + +            +     +              +     +  +      + +           +           +  +  +   +        +        + +    + + +                  + +  +   + +  + + + + + + +   + + + +   +   + +   +  +   +    + +   + +  +  +  +   + +    +  +   +  + +   + + + + +   + + +    + + + +  + +   + gmprossrsoxyz|yz~ʇ˃Ȅ˅ljʆ܍Ќ̌܋גܘ܏ݓߑߔӋЃˁvtpqg_c^YY}O|LoKkFiD^C\>@C!L"M Q!V#W"Z&\,_,h/q,o0p)k"R2  +  +      + +     +   +  + +  + +  +  + +   +     +   +  + + + + + + + + +     +     + +  +  + +    +  +   +   +   +  + + +    +   +  +   + + + + +      +     + +  +    +                + +      +      +     +   +         +          +   + +            +    +                  +  +   + + + + + +  + +  + + +   +  +   +  + + + + +  +         + +  + + +    + + +   +      + +   + + +    + + +  + +  +  +  + + +  +   +  +         + +a^ccieahiohdkmirpqvvnuy΀w|́}~؁~y~؃xookif_\^[VO{O~HoFkCe=k9V=Z5V3O-N+M)D+<(2$3!+*(!   + + + +  + $."3"/+) $)*+(#,"-#.'4%6':';,B5A2E6I;J=M?RAXBZD\M^KsOkMjWpLeJM.)  +    + +  +  + + + +  +  +     + + +      +  + + + +   + +  +        + + +   + +  + + + +    + +  + + + +    +  + + + +     +   +   + +  + + +    + + + +  +      + +     +    +   +    +                  +   +         +      + +      + +   + +  +         +    +   + +           +    +  +    +    +  +   +     +   +        +  +    + +    +  + + +    + +  + + + + +           +  +     +       +  + + + +  + +    + +  +  + +  +  + +  + + +   + +  +   +  +   + + + + + + +  +   ijpqrvr}~p|x~{ǃDžτljɇɆۉԔ֏אבݏېޏؔܙٔۑۓσ̄y|rkekb_[\~WwSwIlEkGc?\<[4U5P5O/H+C+8&7 . '*&#    + +    '210*&'(*').+4249==BGGN"T"W%Z*c(a/g+l.r1l/n)]?$    +   + + + +    + + +  + +    +  + +    +  + +  +   + + +  +  + +  + + +    + +  + +    + +        + +     +   + +  +  + + + + +      +     + +  +   +   +  +    +   +             +                   +                  +   +        + +    +  + +         +    + + + + +  + +  +  +      + + +           + +         + + + +           +   +     +  + + + + +   + + + +  +  + +    +  + b\jb_^_fdkkifonvrturouux||y~׆؃{ވ܂}zrwuhhfbbZXPPN~N{Dx?l?d;YW@_CaHaLjTsR}NyS[HB/'  + + +   + +      +     + +   + +  + +         +   + +  + +      + +           + +    +            +   +   + +      +   +  + +     +         +  +   +   + + +  +  +    + +    +                 +   + +    +   +  +     +   +         + +        +         +       + +  +  +         + +  +       + +  + +  + +  +            + +      +  + + + + + + + +   + +    +      +  +   + + + +     +  +   + + + + +   +   +      +  +  +  + + + + + +  +  +  + + + + +   +  fomfmupkxuzx{{~~ǂǃɄʉӉԑՅ׉ΑԒڏݓԑߕފ֍؍Єptqnia_\ZSxMvOnIkBi?_;Z5T8L1N4G,<+;&8&1!0-&   +  + + + +  + + (/11+((&&$.0+2267?>E!F L L"R%R$W#Z)_*d,h.n/s*g&Y:     +      +    +     + +     +   +     + +   + + + + + + + + +  + +    +     +      +  + + +    + + +    +   + + +  + + +   +     +    + + +  +  + +   +         +               +      +       +  + +        + +            +       + +          +   +      +  + + + +   +  +      +     + + +       + +  +  +      + + +            + +         +  +   + +  +   +    + + + +   + +      +     + +      + +         +  + \db`fcjkglfnknpowk{tt|zyyy{}~׀ւߑ{x{ustjee_WYQVPNyInDoDd=a=`6U4Y4I/G+C*A%7&7 /-%#!     +   +  + +  !/ 4#.*)()(('$*)#2#1%8&8)>,<0?1I5I7O:I>UATB[E\OdJiPiQnSuReOS;8# + +   +      + +  + +   + +  + +    +  + +     +  +    + + +  +     +  + +    +   +   +  + + + + +   +  + +   +  +  + +    +  + +  + +    + + + + +  + +  + + +  + +     +  +   + +              +      +            +               +    +  + +         +      +          +   +                 +      +       +  +   + +   +       +   +   + + +  +   +  + + + + + + + + + +  + +  + +           +    +  + +       + + + + + +  + + + +  + +   +    +     + + +  + +  + + + + + + +  + + + + + + + + +  + + + +  + inmnpzynwvrv}yĆɁ͉·ωшڄъՌЕݎԉڋ݊݌͏ˈ|suppb_[^VXOrMnJkAcB[>Y;U8R2H0K/D,@(6'20(!     +  + + +  +  + #.1.*%(%'***,.869;>CCH!H S%P#V%X,b.e2l,k0v.m)i!G, +   +  +   +  + + +     + +   +  +  + +  +   + +  + + +   + + +   +  + +  + +  + +    + +  +    +   + + +   + +  +  +   +   +    +  +          +  +      + +     + + +        +    +  +                +                 +  +            + +                +        +    +  + +    +   +                       + + + + +  + + +   + + +   +    +  +      +       +  + +  +  +  +    +  +        + +  +    + +  +          +   + +  Zbfc]fheidkhmnintvpxuzyy{̀Ё|~߁߆ۅ|}ytlmhaa^[UOUI|HmEk@sA]8b7X4P1R-E&H)>&@ 00-*#!   + + + +  +   +  + '+ 2,#)))(*(,,!.!0$2(6&9-<+;2C6A5I8L:N=[>VG\F]FeJiNqPwTnPWCB-% + + + +   +  +  + + +  +   + +  +     +  +   + + +   +  + +     +   + + +    +   + + +  +       +     +  + + + + + + + + +   + + +     +        + +         +    +    +  +   + + + + + +   + + +        + +          +                       +     +           +    +         +     +             +   +   + + +  + + +  + +      +  +           + +  +  + + + +   + + + + +  +  +   + + +  +  +    + +     +    + + + + + + + +  + +  + +   +  +    +   +     +   + + + + + + + +  +  + + + + + +  + +  + +  + + + + fnqutpqs{sxxz{|ĂňƒʼnňɎΉՍ͊يӘҕގٞ٘ޝӗϋԊ~~toovjj^]QRStNqMnDf?\>];U7Q4Q1F-E+A'<'3%1,&  +   + + + +  + + (0/,'')'*'*,)24=7;CF!L"H#L#O)R'_(\)e+g/e,p0r.i'T;  +  +     + +       +  +   + + +  +  +         + + +   + +   +    +   + + +  +   +     + + +    + +    +   +      +  +  + + + + + + +         +      +   + + + + +             +   +   +       +          + + +      +     +             +          +         +     +   +     +   +  + + +     + + +    + +   +   +  +         +  + +       +  +    +  +  +  +   + + +    +      +     +    + +       hdeadcdmggnhmponnywyuzzuՁӁ܁ه̓ր߂wqylofcbb[VRMzIDyCkY5W8W1T,J(E'A%8'7"0+'%    +  + + +   +  +   + 2 .&.&'')'+,"*+-$4&3*5-;,;3D2A5C9K8Ti1F1G8N7N=TAS?\NaEfUeMoWqRiL\=A/#    + +  + +    + +   + +   + +   +  +          +   + + +      +   +  + + + + +    +  + + +  +   +   + +      +  +  + + + +    +  +    +  +   + +     + +  +        +   +    +   + +  +  +  + + +                                  + +               +      +    +       +  +    + +  +  +  +     +  + +   +       + +  +  +  + + +    + + + + + +  +  +    +  +        +         +     +        +       +     +  + + + + + + + + + +  +   +    + + + + + +  + + + + + +   + +mompo~r{uw|y}uƄ‚džȉȊшˌɏ͍̌ϔؚߏΏ݌ۏܛݑԄῳȂx{tomdg]\SR}PzMnChCfF^A^:S1M5F1C.A)9(4&/ ,) #   + +  + +  + + + +    *-0.'%'(&)**,3398@<EEN$P#Q"R!^(^.c/e,p3r4l+o$X8  +    + +  + +  +   +    +   +  +       + + +   +  + + +              + +  +  + +  + +     +  +  +   + +  + + + +    +  +   + +   +  + + +      + + +   +      + +    +         +               + +           +     +  + +          +                     +   +         + +    +    +   + +       +    +         +  + +  +  +  +     +       +      +    +      +  + +  +     + +   +          d__h`ggbijpoosmtqrwx{|z|҄ل܀|yӁ׀{x|skegi^WWTPO{JpBs?i@a=d>Z5R3K/G/A'F):$8#2.&%   +  +  + + + +  +  + +  + + +  &-!. .!( +&(&( ).*.'/'8*8*?.?4?5B5N6N?XAS>VE[EbG]LjJnRiSxOcGO@C G F!R#O%T)Y"Y(\*i/l0q2v,o,c D#     +  +     +  +         +  + + + + + + + +  + +  + + + +  +   +  +  +   +    +  +   +  +      + +   + + +    +     + +    + + + + +  +    +   +  +   +      +   +   +          +                          +   + +                       +  + +            + +  + +      +        +  +     + + +   +                +    + +  +      +      +  + +     +   + + + + + + +   +    _af`lkiplnqlqltlnz{xtuҀσ~~ـٌ܄فyсwρldfke``TRPR}KxJqBl>f:a8\9Y4S3H-C(?'=#5$2.')!  +    + +     +  + +   + (/ -($&'+*!*02"0#.#9*:-9.E0B2A6C5J7N;TBV?[E\I`CjOkQsPyVoO]F>*  + +        +  +  +  +    + +   +            + +    +    + +    +    +      + +    +  + +   +     + +    +  +   +   + + +    + +    +    +    +  + + +  + + +    + +    +         +     +                      +                  + +           +                +  +          +    +      + + + + +        + +     +  +  +         +   +   + + + +  + + + +           + +                + + +  +         + +  + + + + +  + +  +    + +   +  +    + + quqnuvtwxz{x|~ȀNJϋʅΉӏՏ׍χ،ՓבҙݠٞڑӐ׉ƃzzzrlnka^_V{NyRnIqFkD_Aa>Z&5$-!**$!    +  + + + + + + + +  + + +    (20''#(-&)/(+038;:ECLQ#N%P%Y*Y&]'d-e.h1h4m,j&R8   +  +  +  +    + + +    + +  + + +       +     + + +  + + +  + +  +   + +  +   +          +  + + + + + + + + + + +   +   + +   +      +       +  + + + +   + +    + +          +       +                + +              +             +   +              +                 +             + + +  +  +        +   +    + +   +       +  + +  +     +   +     +  +  +    +   + +  +  + + +  ]e\_daelholopvsxsqxx{~|{}}~~҃ބԆ~{zqmmgfg[U\VPIHxGqAmCn=d6\5U2S1N+H)B%@'3 5!,''!  + + +   + + + +  + +    +  + + $.2!+%'%'#'((#-,&3&6)8)?.@/C2F0I8P8M;R>VA\D]HdNkOsMtUwTeJN3- + + + + +   +  +  +  +  + + + + +  + +        +  +  +           +    +  +  +  + +     +  +   +  +  +  +         +   +   + +  +     +  + +  +  +      + + +    +  + +  +       + +   +       +   +        +   +     +       +      +         +      +                       +    +  +       +        +        +           + + +  + +    + + +  + + +  +  + + +  +  +  + +     +           +  + + + + +  + + + + +  +     +  + + +  + + + + +     +   +   +  + +  + + + +dwmpqtp}|xz}zŁŁ΄ċƌˇы̏ωۋ֎ىՒܔېߠ։ӎՄ΃}vjneefWZQzSsLmLgBl@eCX7V5S:E1F/?)9%4$3 /")$      + +   +  +  +   +   + (++)&%(%.',++.323?@CFNO O%M&Z#[(\,d2m-u1u1j&] C' +    + +   + + +        +      + +        +  +    + + +    + +    + + + + + + + + +   + +  +     +    +      +  + +   +  + +  + +       + + + +   + +  +    + +       +   +      +    + +    +   +                +        + +       +       + +       + +      +              + + + +          +  +      +      +         +     +  + +    +      + +    + +  +  +      + + +   +  +  +      + +         + + + + +  + + +  b`emilaqfmmvorowvvxswzu|z}}Ԁy~׃~vnlnhei_[SPM{DsIrBnBe@];\6[3N/M0H%D+8#9 3!1*)"    + +  +  + + + + + + + + + +   + +!)2"+!()&')) ,+!,*0%0*7*6,@,D1E6C6J@L:O:TC]D_CdMkOpTqTsSnNU<7*  + + +   +  + +   + + +  + +    + +   +           +    +          + +     +  + +  + + + +       + +      + +     + +  +    +   + +    +     +  +    +  +      + +       +   +   +      +    +  +                           +             +    +       +   +               +           +     + +  +    +   +   +   +  +   +    + + + +    +  + + + + + +   +     +            +  + +      +        +    +   +  + +   + +  + + +  + + + +  +  +  + + +  +   ssuxyxvw|}z~xz΄͆ȅ؁׎͇דՎٓߜޟےڏ݉ԎӇ|uutijh_`VYPrHvNfD`E`Aa8U6R5L1D,>+;&;#.+-#"    + + + +  + +  + + + + + + +     + + $-5.&'$#('(*/+469<=CJ D J#W$W$T)U'[,d*k-h,t1o+c$R0   +     + +    +   + + + + +   +  + + + + +   + + +  + + +  + + +      + + +    +    + +   + + +  +  +    + + + +  +      + +      + + + +   + + +  +   +  + + + +  + +   +    +  +     +                    +                      +             +        +     +  +           +   +  +   +     +  +     + +      +  +    +     + +    + +  + !  + + +  +    +   + +      +  +   +    +  +   +   + +  +    +   `a_hfg`mkmohotsuqzutw΂̀Մ~vׄށ߃߆~{srlomcc][YKKzN{KsDlAi?_;_9R5L4Q1G*H(?$:#5 5,&&   +   + +  + +     +         #1!/ , ("$*$%+"'* ,/'1(5*3.@.:1I0H4I;N=Q?WCW>_H^H]NnOoSnVqOlHJ2( + + +   +    + + +         + +   +  + + + +      +    + + +        +  +      + +       +     +    + +  +   +  +  +       + + +    +    +    +  +  + + + +  +  +    +   +        +    +               +      +   +            +           +   +            +  +  + + +        +            +      +       +  + + + +  +   +  +  + + + + + +   +   +   +  + +  + + + + + + +      +  + + +             + +  +   +   + +  + +   + +    +   +  +  +  +  + +  + + + +    + + + +  + +    +  +    jussw{u~y~‚ńʃɁʈ͈̅ҋґЏًޞߔߙދޒ܈ЂɊ}tuqnmdc^ZS|SxHsJgH_>a0F3N;O9LAV@_E_FcMaMoPqMyRsQfIG/)  +   + +     + +     +    +  +    +   +           +   + + +   +  + + +    + +  + + +   + +    +  + +  +  + +   + + + +   + +   +  +    + + +   + + + +  +    + + +     +  +  + +   +    + +          +   +       +     +           +    +     +       + + +    +     +     +            + +  +  +      +    +    +   + + + +          +    +  +         + +  + + + +  +   +  + +           + +  + + + +    + +  +  + +  + + +     + + + +      +  +   +   + + +   + +  +  + +  + +  +  +  + + +pwpxrqrt{~|u}ĂˋŀɇȀш̍ӊԑ܊ޗޗޖՌ܌тÁvqoigdeZWQzQoHsGbC`?b:W9S4M/L1D,E*: 4$/#1%#     + + +    + +   + + + + + + + +   + +  */(+#&(&*,/,..799:CEI!G"Q#S#Y'W%Z*a.g*j2z4t*j&Y9  +     +    +  + +            +     +    + +  +  +       +   + +  + + +   +  + + + + + +  + + +  +   +   +  + + +  +    + + + +     +   +   + +   + + +  + +  +  + +      + + +    +          +                  + +               +  +   +  +    +    +  +   +    +       + +   +    +             +      + + + + +     +  +       + + + +         +     +   +  + +     + + +          + + +         +   +    +  +     +     + + + +  + +   +  +  + ecahdldfhikuql{nov{|Ӄw~߄Նׇمބ߈ًփ~}xllhd`c_WRSM{HtAmDc@lFC I#OO#T&[*Y'a+i,f/s+w2o)a!L. +   + +  + + +   + +  +   +   + +    + +   + +    + + + +  +   +   +    +   +  +   +    + +    +   +  +   +    + + + +  + +   + +   + + +    +  + +    +   + +  +  + +    +  +    +    + +     +            +      +    +   + +    +        +        +    +      + +             +          +     +     + +     +         +        +  +  +  +  + +     +   +      + + +   +   +   +        +     +   + + + +   + + +   + +  + + + +     +  + +   bdajefopptnyvkut|yv҂π{~Ӏ~ߍyل҅xnujgg^[[TPO|GsGw@jId=]7S8O1U1F-E,>'=(6"6 .+&   +     +  +  +    + +  + +    +  +  +  +     + *-",&$+&()*, ,!/%3(.'=(92>+H4E1D:O7S:UAVHYA_KeMgNkVnVyQpRgGB1$ + +  +    + +   + + + +   + + + +   + + +   + +     + +     + +   +   +  +    +  +    +  +   +    +   + + +    +    + + +           + +  + +  +   + + +   + + +   + +   +     + +   + +    +        + +     +           +     +     +        + +         +             + +        + +    + +  +   +       +       + +      + + +               + + +    + +  +     + + +   +  +  + +  + + +    + +  + +    +   +  + +   +         + + + + +    + +   + +   + +   + +   + +   + +   +   +  + + +  +  + + + + +  +  + +    +  +  +  + + + + + + + + + qrrwv~{{yzĀ΀Њ·ω܊ևҌӅޑޗސݑۘڎ֌҇΀y|rhne`\Z[|OwJqIjAdB^;V3Z4N/I2D+A->'5"1!/(&!   +  + + + + + +  + + + + + + + + +  + +  + +    +"(/+-&&)(&*(,21169B@DG"I!O&S%]#^*e(j)j,l/r/y-q$W:  +      + + +  + +    +     +  + + +  + +  +   +         + + + + +   + +            + + + +    +   +   +  + +  +   + +   +  + + + +  +    +  + +  +       + + +   +  + +  + +  +    +     +    +      + +                                +  +         +     +         +         +  +   +    +   +  +  +    +         +  +     +       +         + +  +   + +      +  +  +  +             +  +  + +   +  + +     + + + +  + +    + +     +       +     + +    + +   +  + + _cegihmoltpmuvr{{w}τyx|ނ}؍ڃ}ڂߊ߂}qooocb_^bZMTLzFuFl@iAc8\7R4R1M+I+?&='< 7!0'&$    +   +  + + +  +   + +  +    +    +  + +  + $10."*'++).!+) .#/$/)5*8(+:!7 3#-('!     + + + + + + + +  + + + +  + +  + + + + + +    + + + *0.)%'+,&).,0135<<=@FJ!P#R%W+Y%[-X*d-j2p2r1o,eK*      +   +  +   + +   +     +  + + + + +  +  + +   +    +  +      + +     + +    +  +       +  +    + +  +  +   + +  +  + + + +  +   +  + +  + +  + +   + + + +     + +  +       +          +   +     + +          +     +            +  + +           +       +         +    +        +     +   +     +     +     +        +  +  +    +    +     + +      +   + +  + +  + + + +   +  + +  +   +  + +  + + +         +                +   + + + +     + +      + + djnihimknrtmqopuyˁx}xzz؆}}݃ފ݇܉ߌ߄yxuwglcb_\VQLHwGzEjBjAa8`7Z3S,F3C/K'?):#4/.(#!   +  +      +  + + +    +     +   +  +  + + + ,#/$.+(()() '!+ *%.!0$8*9-:)>1B0G7L:N5VBS);%3/*&&!    + +  + +    + +  +     + + +  + +       +    +%+, ,+&'*)),-$.-'.)9+=.>)B3>4I5G;M@S?SB[IZJ]GgNhMrT|UqRjIM5/# + +  +  +   + + + + + +  +   +   +  +               +   +       +      + + + +    +    + + + +    +   +   + +  + +   + + +  + + + +  + +  + + + + +    + +  + +  + + +   +   + + +  +          +  +  +       +   +  +   +  +    +   +               +  +       +  +        +  +  +         + +            +   +     + +       +  +    +   +        +  +  + +  +     +           +   + + +     +  +     + + +  +   +                 + +    + + + +    + + +  + +   +  + +  +   +        +  +      + +     + +     +  +  +  + rwxuqyqw}ƀǂȆ€Ќ̈́Љ̈ֈҎדډԒ՜یٍσō{}qpllaaUYTtWqPlJjE_@D>HJ"J$O&T$S(Z*m0d0m3p0p3u(f!L. +    +   + + + +    + + + +    +    +   + + +  +      + +               +  + + +   + + + + + +  +  + + +  + + + +   + + + + + + +  +  +  +   +  +  +   +   +   + + +      +   +  +     + + + +    +               +      +   +      +            + +   +     +            + + +                  +   +     +       +       +   +   + +        +  +    +  +  +  + + +  + +    + +  + +  +  +          + +  + +  + +   +  +   +   +  + +  +         + +        +     +  + gecjnpuqjqrxrnx~w}{Ҁz݂ފڅՃۄyynmhme[a[WNKxLuHj@kAb;^;U8X-N4L1H)B&<3"3*)$    + + +     + + + +   +  +   + +  +   + +  #/",.*)''((' *."0#6)8)8/9,E.?0G5I8N@N)!   + + +  +  + +  +    + + +    + +   +      + +  +   + +  + +   +     +    + +  + + +     +    +   + +  +  +   +  + +  + + +  +  +   +     + + +  +  + + + + + +      +    +  + +  +  +       +         +    +    +                  +        +         + +   +        +  + + +    +    +     +  +  +      +  + +   + + +         +   +     +        + + +   + +  +      + + + +   +    +  +  +  +  + +   +         +  +    +      +  +  +  +   +   +  +    +           +   +   +  +     + +  +   + + + +  + swx}}|yĂĂƃĀlj̀ɃɇՌѐЈ݉וڍލߎڐۄт}ywknkcbZXWtMsPmJbAg@]:]9R7L6E0A/A-4)1"++$!     + +  + + + +   + +  + + +  +   +   +    + + +  + &./('&&'*',)-,36<@=C!G MR$R$Z)V*`,a,g0i,v/w/w+j#S8      +  +  + + +  + + +  +  +     + +  +   +    + +   + + +   + +       + + +    +   + + +   + + + + + + +  +   + +    +  + +  +   +  + +  + + +  + + +    + + + +  +           +  + +  +      +    +        +  + +                +              +    +     +  +      +     +          + + +    +    +          +    +   +     + + +  +   + +  + +  + + +      +   +  + +  + + + +    +  + + +   +  +     + +      + +  + +     +     +  +   +        +  +gicn`jkqhqutrrxw{ˁ~z}فޅ݁ځ|xsqlejc`Z]ZMyJwFmBpB`?_7Z:V6P,N.G*C)6#7$-#/,#"   + +  + +  +    + + + + +    + +    + + +  + + + +   + + * ..")+)&(!'"&/!.$0$1&2*6+9-<0F2E4C8R?N:SEWA[GbNdHhQmTsXyR{YgGR76 +   +     + +      +  +  +    +              +  + +     +  +  +     +     + +   +    + +   +  +  + + +  + + + + +  + + +  + + + +     + +    +  + +   +  +    +         + + +  + +           +   +       +        +          +    + +   + +   +        +      +       + + +      +     +  +  + +  + +              +    +     +    + +    + + + +  +     +  +      + +  +    +    +  +  +     +            +    +    +   +  +       +  +   + +  + + + +  +  + +  rxstwxyÆ~ʃӌ҉ʊ֍ԍԊސܚۓ͏؄~tvurhb^YZT|OuNqHdIcAZ=Y<F LN%L&Y!T'X%\*g.j,h1s4u.q'b C(      + +  +  + + + + +   + + + +       +  + +  + + + + + + + +       +    + +   +  + + + +       + + +  +  +     + + + +  + + + + +   + +   + + + +    + +     + + +             + +    +    +          +    +   +        +     +     + +  +  +     +      +   +  +   +   +   +    +    +      + +        +       + +      +  +  +  +    +  + +  +    + +      + +  + + +  + + +     +     +        +  +   + +       + + + + +  +     +   hednhkjuqwojsx|wyv~ǂЄԅ߄؃ۇۄy~|{okhce]ZX\G~JxFwGp?c.E4E9N:N:P8TE\EaLaOaLmRpQwRs[vWYC@/   + +   + + + + +   + + +  + +  + + + +           +  +    +   + +          + +   +  +   +        +   + + +  +     + + +  + + + +  + +  +  +   +  +   +  +   +      +      + + +        + +    + +     +                  +              +   +     +      +      +     +      +     + +   +    +    +       + + +    +  +   +    +   +   +   + + +  + +  + +    + + +  +         +     +  +  + + +                      +    + + + +  + + +   + uty}vu}z„͉΄ύɈυϋΌ̆הߐڔؘߒވ͎uywshcj^Z_W~MwLqJkLdD_=W$=#52)$"   +  + + +  + +  +  +  +  + + + +   + +  + +     +  + +  + +     + )!0.!((!'(% ')(!-#+#.-6'8*;1@0?1F5K9O\9S5S2L1D,A-B(=&2 1(&    + + + + +  +  + + + +   +  +  + +  +   + +  + + +  +  + +   + $10+.&&''%*-*..768@C DH$N$Q%S$U&Z(_+c)n/n+~.t-o"fF'  +  + + + +     +   + +   +   +   +  +  + + + +     + +   +   +   + + + +   +   +   +  +  + + +        + + +  +  + + + + + + +   + + +   + +    + +   +  + + + + + + +   + + +       +  +  +  + +    + + +                               +         + +    +        +  + +  + +       +    +   + +   + +    +  +         +      +             + + +    +     + + + +  + +     +  +          +  +     + + + + +               +      + + +  + + +  +  +  +   +    +   +  +   +     + ncikkdnqllvvpwvy|р}{{΃yچׇ߂ڄ|zvmdrha[Z]ZRMzGvEhBh=\9U7Y5R4P.C.B*A$8$6/+%%            +  +   +  +   + +    +    +     +   +   )/#1!+ /$('')+#,"-"-&3)9*<,9,=0D4K9H9J>O=Q?YH_GcIgPlNoXt[}VqNZ?>*!  + +     + +   +   +   + +      +  + + + +    +  +  + +  +    +  +    + +   +   +  + +    +  + +  + +  +   +    +     + +  +             + +   +  +    + + + +         +     +    +   + +  + + +                    +      +          +          +                 +       + +  + + + +     + +     + +   +       +        +  +              + + +      +   + +        + + + +  +  + +   + +  +    + +   + + + +  + +  +    + + +   + +   +  +      +            + + + + +  +   +   + + + + + + + + + + + +  + wqwyz~}ǁǀȋʇτ׊ِۉׄ׎ߘۃЍчΈāruhgfe`VP~QvPuKk@fB\>ZCHG!P"P$[*Y$_'_,f,j0r-r0x,b&Q2    +   + +    +  +  + + +      +  + + +      + + +  + + +  + +         + +  +  + + + + + + + +  +  + +     + + + + + +   +    +   + + +      + + +  + +  +    +  + + + + +  +  + +    + +  +           + + +      + +      +                               + + +  +     +  +    +       +  +  +        +     +  +       +        +   +     +   + + +    + + +  +   + + + +  +    +    +  + + + +  +          +  + +    + + + +   +  +     +    + +      +      +   +    + +ijgjlfkuekozzzȀw|w|ـڃف߆܃ށڀ΀vlnlceYYXRM}LxOyGm?k@e9Z8V3P4M+F-B(@$:$6&.,%!   +  + + + + +   +       +  + +     +         + +  +      +"..$-)((')((,"/ 1'6'6(8-=*=+B3B6F6G:R;Z>`A[JcIfJdQpSrUyPyMdKN..  + + +         +   +  + +  +   +  +    + +         +  + +    +  + +   + +   +  +   +  +      +  + +    + + + + +   + +  + +   + + +    +   +  +   + + +  +  +   + + +    +   +    + + +   +          +    + +       +           +      +           +  +           + +      + +  +     +  +     + +  + + + +   +   +      +     +        +       +  +                + +   +   + +   + +    + + + +     + +  +   +      +  +   + +  +   + +         +   + +     +  + + + + +     +  + + + + +   + + +  + + + + + + + + + + + px}y|}~ˀˁ~ύʅͅЌˍڊُّٖؒۓޘٌϋ˂~wsigc^cWWUtJsLjDe@_>Z;V4U3M-D-C'A(7"7!-'%#  + + + + +  + + + + +  + +          +   + +     +  #,1+%&#'&)'./274<?@DC J!S%O$W#\)](i-h+e0i3t0z.o'_C%        + +   +   +  + + + +   + +    + +    +  +  +  +   + + +   + + +  + + +    + +   + +  +   + +  + +   + + + +       + +  + + + +  + +    + +  + +  +   + +       + +     +  +  + + + +  + +  + + +    + +      + +                     +      +   + +  + + +       + + +  +   +  +  +         + +     +   + +  +    +     +   + +      +  +             +  +    +   + +   +   +   + + +  +  +       + +      + + + +  +   +    +   +                + +     + +   + +  + +        +    +      dhlrkjpuqnq{v{yՁr||~ۅւӄ݅~zz{mkbgbc`UUzOyIpHr=b:hQDQEVETJ_EcMfSnXtWx[vSxITB6( + +           +   +    + + +  + +  +  + + + +     + +    +        + +    + +    +    + +  +   +           +  +  +  +  + +    + + +  +   +      + + + +      + + +  +  + +  +     +     +      +         +              +  +   +            +             +  +         + +    + + +    + +   +  +     + +     + +  +     + +  +    +    + + +       +  +   + +                          + + + +    + +  + +   +   +  + +  + +  +   +  +  +  +  +   +     +  + + +  + + + +    + + +  + + + +  + + +  + + +  +  + + + +  + + + + + + +  wwwzuŀ|}ƄʀȈԇŽԍȆ҈֋֑ێڒޙޕ׋܇~ŀ}}ppcld^ZQQPtJjDlF^=^5P:P7K.D/;+?&9'/!.+#" +  + + + + + + +   + +     + + +  +  + +   +    + + +      + + +  +   + !(+.)')(&%)++.02:9:;E!DL!O#O$[#Y(b+d-g,q/n4y0z(m%P0  +        +  + + + + +    +    + + + +      +   + +  +  +  +   +   + + + +  +  +    + +  +  + + + + + + +      + +   + +  + +    +  +   + +  +   +  + +   + + +     +  +    + + +    +   +    +                 +         + + +                    +    + + +   + +  + +  +            +       +       +       +      +            + +    + +           +   +  + +    +   +   +      +          +        +    + + +     +  +     +       + + + +  +         +  +   + +   hlidlmtpnpqwpvuxwׂ~ׂڂ؅؈ڀ߇ۄڅ݇{{qoiei_XXVRPzJqBtFg?e9b<^6R0S-E,D)?&:$4!5.(%   + +  + + + +  + + +   +  +   + + + +     +                +  #+ +#/*$$$*'**#-#,$/#2(6(9/>3C4F>GL K#O#U'X$W*a+[/h)e.v2q/x-m"Z>$  + +  + + + +   + +  + + + + + +      + + + +   +      +   +  + +  + +  + +  + +   +    + + +        +  + + +   + +  +     + +     +    +     +  +                    + +    +  +  +   +                   +            +    +    +    + +  + +     + +              +   +    +     +        +                 +       +      + +   + +  + + + + +  + + + +      + + +    + +   + + + + + +  + + +  +      +   +  +   +     +   +     + +  + +  +  +        +     +          + +  +  fkjnmqtxprttxuy}t|Ӂ؁ҀՆ؃Ӄ߃Ѓ}yqnool`dU`XU|KJtIqFkBd9H5I=R3A5E5N:M=S@W@VB_IcKdRlR|Qq_oRgGV=5' +    + + +  + +     + + +  +     + +      + + + +   + +  +        + + +      + +  + +      + +     +  +  +   + +     + + +     +  +  + + + +     +  +     +  + +  +            + + +   +  + +           + +  +               +                 +    +    +       +   + +  +          +    +        +  + +          +    +        +   +        +    +  +    +    +  +  +  +  +    + + + + +  + + +     +   +  + +   +  + +        + +         + + + +  +   + +  + +  + + + + + + + + + + + +  + +     +   + + + + y|y}u}Âń׆ŇčʁӍЉʑٌԓԋڕՖٔ۔ݔ؃Ђy}vuojf`Y]SQvLmNlFfA_?Z8X6N4D1D+>(9)6"0 +'"  + +  +    + + + + + + + + + +  +   + + +    +   + + +   +  +  + +      +  + +    + "..,)))&*+++,.237=A7FO#E"M"U#U#^%X.d/m-m4m,s/s)_!G/ + +    +  +    + +  +  +   + + +     + +  +      +    + +        +  + +   + + + +  + + + + + +   +   +  + +  + + +    + +  +    +    + +  + +  +     + +  + + +       +   +      + + +            +                 +        + +     + + + +   +  + + +     +        + + +     +     +    +    +     +   +  +   + +  +   + +    +     +  +   +   +  +      + +  +                 +  +  + + +    +   +    +   + + +                    +  + + + mndnjpqorprlvyz|̂xЀۉ~~}n~rklbc_]WLNGyCpEjBgDQ#J!O"U"\(X)c+f+n.l1y2w*k$W;     +  +  +     +   + +   + +  +     +   +  +  + +  + + +    + +        +  +    +  + + + + +    +  + + +  + +  +  + + + + +  +  + + +   + +   + +  +   +   + +       +   +   + +   +     + +   + +       +     +      +        +          + +     + +  +                    +    +   +  + +      +  +  +      +    + + +    +  +     +    +  + + + + + + +     +      +     +  +   +     +    +  +    +            +      + +  +       +   +lhgunjqrrlwsxst̀ˀ|т{م݁y։݃߄߅w{rfcji^[VVT|LuFrDgFk:b=]6Y7R0L+C+F):'3%41+&  +   +   +      + +        +  +               +        +     +  + +  $/ 2 0 ,*&&(''+ )"/"2*/*7,7-;,B2M7C8L>U@R=[AbK]FdGeJmNpVzSwUeKU82"  + +       +     +  +    + + + +  +   +  + + + + +    +  +  +  +  + +  + +  + + +      +  +   +   + +    +      +  + +  + +  +   + + + + + + + + + +    + +  +    +  +      +  +     + +    +      +     + + +         +      + +   +           +   +                      + +  + +     +  +  +    +   +  +       +      +    +       +  + +  +  +   +      +             +  +  +  +  +  +   + +    +   +  +     +    +   +    +            + + +   +  + +  + + +  + + + + + + + + + +  + + + + + + + + + +  + + +  +vvwzy{wȀzĂɀ˄džʅɓאїƐ܉ԎהߔݚޒτƑȃ{vnei`^Z\UPrLxEhDjCc>Ub?b;T5Q0N/G/F'>(8 72(#$     +     + + + + + + + +   + + + +    + + +  +        +          +      +   +  +  '.$0+!(%$$') ,"1!1"/#3'7&;-:->.?2P4O:L=RZBYG_HoDmQpPuVraqSYHA-%  + + + +       +  + +   +   +  +   +   + +  +  +  +    +  +        +  +  + +      +      +    +    + +    +  + + +   +  +  +   +  +  +  +  +  +  +  + +   +  + + +  +  + +  +    + +    + +  +  +      +    + +       +      +             +        +                +     +      +     +       +    +  +     +     +  +       +  +   +   +   +    +  +  + +  + +  + +    +    +  +  +   + + +   +  +   +     + +  +        +    +  + + +   + + + +   + + +  + + + +   +  + +  +  + + + +  +     + +   vzy}y{~y{LJ̈Љ͊ƀŐՄ͌ˑ߇َߖݔڗ؏ؑ݉ˉw~xlnmk_`VS|MrKrMkCcF`>Z9W7I2G0J/D-?&8$4!0'#$  + + +  +  + + + + + + + +   +   + +  + +    +  +  +   +   + + +  + + + +     + )/)+)&&'('/1,,37::AEF!KQ#O'Z*T&\-`(a-p.l0o,t-j&V5     + +   +  + + + +      + +  +  + + + +   + +  +   +  + +    +  +     + + +   +  + +      + + + +   +   +  +   +    + +     + + + + +          + +   +        + +    +  + +  +  +       +  + + +    +                     +   +  + +  +   +   + + + +          +        +  + +     +   +     +    +     +  + +  +  +   +   + +  +       +  + + +    +   +  + +   +   +   +  +   +  +   +    + +    +    +     +  +   +      + +  +     +       mhmirqqnuwlwwxy}~΂́݁рփ~ۀ{uoiohbdZ^TLRuEyAwCj;b=]:[5V6N.N+>(?&9$1 +!-("   +  +          + + + +  +      +    +    +      +    +   +   +    + +  + +   +!-"*!+**$$'),,"0#/%3&1*7);/B2@6F5G7TePeQoPuT}UmXgON96& + + + + +   +  +          + +   +  +        + +   +   + +  +    +      + +  +  + + +  +    + + + + +   +  +  + + +  +  + +   +   + +  +   +  + +    + + + + +     +   +        +  + +   + + +        +   +                                   +       +  +        + +   + +   +   +  +  + + +  + + + +   +     + +    + +  +        +    +   +  +         + +  +    +   + + +     + +  + +   +  +  +  + + +  + +   +  + + +  + +   + + + + + + +        + +  +   + + +  + + +  + + + + +  + + + + + +     +  +   + + + + +   +    + +vyt|||}{}˂ɇҋčτՉۘ֊ߎڑߒ݌܈˄z|ussmgd_VVzPoOtGnJkCbCZ:U8P5N,F-C/B(9&4 .+&#   + + +       + + + + + +  +  + + + + +  + + + +  +        +           +  + (.-&.%((),+-//07;9BDC!KNQ"X!X&[(_)c-`(i2w2t/q)aK( +        +   + +     +  + + +   +   +  + + + + + +  + + +  + +  + +     + + +  +    + + + +  +  +   +  +    + + +         +     + + + + + +     +   + +     + +   +     +                               + +                           +       +  +    +  +  +  +    +        +  + + + +   +   + + +    +  +                 + + + + +  + +    + +  + +  + + +  + + +     +  + +    +     + + + + + +                       +  +  +  +      +    + + +  +  +   +    hnhphunnqtppxzp}~ρ}ځ݃܅߄x}rjopj`[[VRHP}DsGw@l/@0D5E6G9L:S?PEX>XB_K`KkMjSxYxVhP^HC*$ + +  + +  + +     +     + + +  +  +  +   +     + + + + + + +   + +    + +   +  + + +   + +  + + +        + +   +     +  + +   +  +   +   + +   + +     + +    + +  +   +   + +    +   + +    + +    +       +  +  +       +                 +                   +  + +   +       +  +   +          +  +      +  +          +       +          +    +    +   + +   +      +   +  + +  +  + +   +  + +  +  + +  + + +  + +   +   +      + +    +        +        +     +       + +  +  +    +        zy}|ɀ{~|Ê֊Ί׈ڌԆؑѓىӕ֋ыׇ|ypmtjdb\VQ}LrKlIb@b<[5V8P6O6G2C+=)9$3!/-)%  +  +  + + +  +  + + + + +  + + + +   +     +    + + +  + +  + + + + +  + + +  + + +  +  +     +    ,.)*)%$)&(++./4:1=@DC!L J%W$R$Y'Y(d*k+o0r0u/l(m$O3          + +  +  +  +  + + + + + + + +   +   +     + +     +        +        + + + + + +  + +      + +   + +  + + +  + + +   + +    + + +    + +   +         + + +  + + +   +                            +         + + +     +     +   + +        +           +            +   + +    +     +      + + +  +   +   + + + +  +   +  + + +   + +    +   +  +  + +  +   +         + +  +      +     +  + + +  + + +  +  +    eimntpsurnqtzw}؀{~Ӄ݄߂Єr}urjkkfaYSPMHoBq@k?g?`=R4V1J,F/G)C&7(;!/-'"   + + + + +   +   +  +    + + +  +  +    +  + + +     +   +   + + + +  +   +     +       +  + %.!2 ()(&&))) */"0%2&8&=*=-;0B3D5H7F=O=W=[CYA_G_KhJhRqXqVrP`KR80% + +   +     + +    + + +  + + + +     +    +    + +   +  +      +  +    +    + +   + + + + + + +    + + +   + +     + +    +  +  +  +  +  +  + +   +   +  +  + + +  + +  +  + +  +  +           +   +          +  +   +          +                       +   +      + +  + + +     +   +  + + +             +    + +  + +   + + +     +        +      + +  + + + + +     +  +   + +  +  + + +  + +  +  +  +     +  + +  + +    + + + + +  + + +  +  + +  +      +  +   +  +   + + +  +   + +  +  +    +  +    +  +  +     vu{|~ÆĊ͊ͅͅل׌ؑ׍۔ߍܔܓՉފχˈ{zokhj]TXwQwPtQmEjCbB];[8S1N-O.A*<(9#3"6 **"   + + + +  + + + + +  +  + +  +    +    +     +  + +  +     +  +  +   + +       +  + &1.*'&+)'/))//43::>>CL!L&Q"V)V%^(_,f.h1q/p5p2u$f"D, + +    +       + +  +  +    + +  + + +  +  + + + +      + +     +   +  +   +   +      + + +  + + +  + +   +   + + +   +       +  +  +         +   +        + +     +  +        +  + +      +              +                +            +  +     +     + + +       +    +  +      +   +  +       +  + +  +    +  +  +     +  +   +  +  +   + +  + +   +       + +  +    +   +          + +         +    ngorlnvssssqw{ô}v؃yہ؍؊܆߄z{xrmlie^ZWSO~P{RvAmGn?cP@X@XDXC`MfLmMuTyVzToQ[E@+! + +   +   + +  + +  +  + + +  +   +   + + +  + + +  +    +  + + +      + +  + +    + + +          + +   +  + +  + +  + +  +    + + + +   +   +      + + +    +   +  + +     +    +    + +     +    + +  +  +     +  +    +  +    +                         +    + + + + +  +  + +  +  +  + + + +   +  + + +   + +   +  +  +      + +    +          +    +     +    + + + +    +  + + + + +   +   + +   + + + +       +   + + + + + + + +   +  +   +  + + +  +       +     +    +    +      +    + +    +              {z~|Ɇχȇʊ҈׆܊ΔԎݙؒԔژ݋ҏΈȁt|ompf[Z[TQqIpJeEc?`;W6S2O4H-E-?,=&2 2-("  + + +  +  + +  + +  +   +  +  + + +   +  + + + +  + +  +   + + +  + + +   + +  +   + +     + #./*%'$*$%--,-25==9BE O!K US&S(X([(X0m.m0u1q+v)j&S2  +   +  + + +  + + +         + +  + + +    +      + +  + +  +  +    +     +    + + +   + + +  + + + + + + + + +    +   +    + +  +  + +  + +    +  +    +  + +   +      + + +  +     +    +   +      +      +         +               +      +     + +        +      + +     + +   +          +        + +  + +  +             + + +     + +     +      +    + + +    +  +      + + +    + +   + +  +   +    +  +           +    mllrrqmlqzvuyvuuz~ڃՀێ݃wʃnqjhb`aUVRSLuGn@kF_@[8U3U4M0L*I*@';'5$,0(#   + + + +  + +             + +   +      +   + + +   + +  +   +  + +      + +   + +  (-, (%''&%( *--!.#6(7)5*;.C3C2?4M7J:N>LDW@\F^GiMlRiSqRy[sOfJG42"    +  +   +   +  +  + + +  +        +   + + + +   +    +     +  + + +   +   + +   +     + +     +  +   +      +  +    +  +  + +   + + +  + +   +  + + +          +  + +      +       + +         +     +  +            + +           +      +    +       +  + +  + +  +  + + +          +  +       +       +   +       +  +  +      +  +  + + +   + + + +     + + + +       +  + +    +   + +  +   + +     +      + +                +   +  +    +               +   +uxzƃ|ĉLjƇՍَΑҕՋؖڛݓߖޏܕٌъӅDŽxvwqef_\ZOyTsNmIqCdA]<[:Y3R6N3E-E+8#3&-"()$   + + + + + + +  +        + +   +     + +  + +  +  +   +   +      + + + + + +   + + + + + +   + +    &+-)+$&($&*++*16:7>BL!K"O"S$S%[$Y&d(h,m1w.q0v,n#^!A' +         +    + +  +    +  + +  +    + + + + +   + +  + +    + + +   + + + + +    +    + +    + +  + + + + +   +   +        +    +  +    +    +  +    + + +    +  + +            +    + + +             +        +               + +  +     + +  + +       + +             +   +      + +  +   + + +  +  + + + +  +    + + +    +      + + + +  + +  +  +   + + + + +  + +        +     + + +   +        +            pliompmorpxwuz}Ӏsς̄Ёچ{{~݄{{vippceb[XWKyMzLpDp?h=_;_5V3O-K0E'F*<':1/+%     +  + + + + +  + +   +  + + +            + +   + + + +  + +      + + + + + +  + + + +  +   +#+!/0)* ",'+)!,"/ 0!0%6'5+<*2A2J8L>O>S=\B^@_IhHlMjNmZvMx_qSTB@,  + + + + +  +   +      + + + + +  + + +  + + + +      +      +  + +  + + +      +   +  + + +  + +  +   + +      + +  +     +   + + + +  + + + +    +  + + +  + + +  +  +   + +   +    +                  +  +  +               +           +            + +    +   +   + + +  +     +  + + +      +    +          +  +  + + +         +  +   + +  +   + + +    +     +        +   + +  +  + + +  + +     +     +   +  +  + + +   + + +      +    +    +   + +  + +      +            z{{|}{ǁ{~хňËόӉ؊֒ϒڒ֒יތޚٕ߈Ӈ̇{xnhhhbbYWzOuJoFfFfBZ=Z8Q5K5L3E*@*A%5#/!+%#  + + + + +  +  +  + +   + +  + + + + +  + +  +     +    + + + + +  +  + +  +   + +  +   +  + +    +%+/-')%#('',.+.-7=:AEI O#R!T&Q)]%[(b,j.o-n2x/t(l!P5      + + + + +    + + + +     +   +   +    + +   + + + +    +       +  +     + + + +   +  + +  +  + + +   + +  +  + + +    +  + + +    + + + +  +   + +      +                        +     +      +         +   +  + + +    +  +  +    +    +  +         +    + +    +         + +  + + +                + +  +  +  +       + + +     +        +     +     +   +    +   +  +    jplnornjz|wxywz|w|}ڂًކڋ~ӂwvpqkig]\TVRzL}HrAjCoAc;Z7S6U0L/K(F&@&7!3-'%#     +  +  +  + +   + +  + +  +   +   + + +     +  +    + +   +    + +  +  +  +       +       + + + +  $-"+.%&)'+ +!'(,$1&7'7'5+@-A2D2F8N:P:S=SB^HZF]IgKeTnSrUuYiOkIJ6. + +   + + +   +       +  +  +   + + +  +       + + +      +   +   + +  +  + +   +  +        +  + +    +  +  +   +   + + +  + +   + + + +    +     +  +  +    + +     + +    +     +  +       +   +    +     +     +        +           +              +           + +       + +             + + +    +  +  + +      +   +         +   + +  +  +   + +  +     + +  +   +    + +  +   +   +   + +   +     +  + + + + + +   +   +  +       + +                +          ~v~~~{LjdžĂЈˉ҉͋Ԕڎڕӊړ֏՗͆̎Ć|zplhdcYZTxPyKtGkHcEa;\8S5S8J1A)@,7%9#1,(#  + + +  + + + +  + +   +   +  + +     + + + + + +  + +    +    +     +   +  + + +   +  + +    + $&,,#&%&(&),*(164:=>HIG!M"U%W$Y!\&\,a.h/m4p1v-w'ZD' +       +   +   + +  +       + + +  + + +   +  +     + +   + +   + + + + +  + + +     + + + +    + + + +  + + +  +  +  +   +     + + +    + +   +  +  + + +   +       +    +  +           +                      +          +   + +        +  +   + + +   +    +  + +   +    + +   + +  +   +        +     +      +  + + +   +  +    +     +   +         + +  + + +    +     + + + + + + + +   +          +  +  +   +  ! !fhqklpnpwxv|xzx|ź|ۆ؂و{vvunngffeXWRVIzLyGoBf?b;W7`8U2O1M*B%;':"3/)*#  + +  + +  + + + +    + +  + +     +       +    + +  +         +  +    +       +          +    #-.* %)*&'(*, .#.!2)7(;+:-=.D5E7G6K7V7QDZA[AbHfKgNvOqPtZsVoKS@=)!   +  +  +  +  +    + + +     +   +  +   + +  +  +   +   +  +    +  +  + +     +     +   +     +   +  + +  +  + +    +  + +  +    +  + +   +     +  +  +    + + + +  +    +     +  + + +           +  +     +        +  +                +   +   +                       +     + +  +  +  +  +                   +  +   +  + +   +     +   +   +      +     +  +                 +      +   +   +   +         +  + + + +    +    + + +        +     + +   + + +   + + +        !!    wzzÀ{{{̃ŌχՌՆڌ݌͔ޗڑ֎ގЊ˅̈|||smjhc\XPTJoHhFdBd=[>Z6Q6I.A0?'<(:$2!/*#    + +  + + + + + + +   + +  +  +  +  + + +  +  + +  + +  + + + +  + +  + +      +   +  + + +  +  +   + )-,*'+%)'&+(,0759<?F CLQQ#W$W(Z&^,_.f/n3u2z.p*f&O4      +     +    + + +  + + + +  +    +   + +    +       +  +    +  +   +  +   +     + +   + +   +   +   +       + + +  + + +  +  +  +   + +   +  +     +    +  + +      +   +  +         +       +           +    +             + +   +  +  +    +   +      +   +   +  + +     +       +       +  +  + + +  +  + +  + + + +    +    + + +    +  + +    + +     +  +   + + +  + + +     +  +        + + +    +   +  + + +  +     " nmlmorwqo}~|~zȅzہ݃߆}фwsumnekg\ZSQO{JsFqCl=f8a+>*?2A/C9L9J:W?SD[FeK_LfHkPtQqTqTtNcGI3. +  + + + + + + +   +  +  +   +  +     + +    + +  +   +  +   + +  +      + + + + +  + + + +       +          +  +   +    +  +    +  +   + +   +  +  + +   + +  +  +           +       +    +  +                    +                       +         +  +  + +       +  + + +   +  + +  +  +       +   + +   +   +  + +      +        + +  + +   + +   +   +     +  +    +    +  + + +  + +      +  + +  +   + + +  + +   + +  + +    +   +   + +  +  + +     +   +  + +      !  # yyƒ{Ŋ}{Ȃ҈ӈՇψʕ̊ڇΎܓޗߎՏݔڍϋ͈†xvvsh_`cXUT}JnKqHgE`C^:T2S4O4G,C+9&4$7$+")"    + +   +  + + + + + +   + +  + + + +        + +  +   + +       +   + +  + +   +  + +        + + + +   +  + ".+,*&)'(,*(./1388=BFI"J!Q$S$V$X*a*b+f.n2q4t,r(h'XC&    +   +   + +   +  +    + + + +    + +  +     + + + + +   +  +       +   + +    +   + +   + +       + +     +  +     + + +  + +     + + + + +    +    + +  + +    + +           +   + +                     +            +              +  +   +   +        + +   + +  +  +         +        +     +  + +  +  +  +   +       +    + +    +  + +   +  +  +   +   + +      +    + +          +  + + +   +     khhlrswszvxuʂyu~wوۈ݂yxyxlqld\_ZQK}N{PqJqAeAi=_6S5X4P,C+D'?+:#7 1*&!  + +     +  + +  +      +   +       + +  +     +    + +         +   +           + +    +    +  + )//!, $*&(&)+))!/$2%8&8,7/;2A2L3H7J?R;T@VF\FaDgJeVkRsXqYwPgL[A;-  + + +   +  + +   +  +   + + +   +   +  + +    + +      +  +  + + + + +    +   +   + +   +  + + +    +  +  +  + + + +    +  +  +  +   +    +  + +   +    +    +  + + +  +  + + +      +       + +  +   +          +    +    +                      +  +      +  + +   +    + +    +   +  +      + +  +   +       + +   +  +  +         + + + +     +    +  + + + + +  +  +  +      +   + +   +   + + + + +    +   + +   +   +  +             + +  +    +   +  +     +          !!  " !   zyxzÂ΀Â˄̂҆Ոшڈڕّ؉ߐҘ݈ؗ֎چ́zvqmgb^ZTOLtJrDeE`@]>S8S4K.J,C+>*9$7#4"-       +  + + + + + +  +       + +  +  + + +   + +  + +      +  +    +  +  + + + +   +  + +     +  +  + + + +   + ,--+&&)&&)*+*218:?@BJG O"N!R&U&^%^*d,g/o-r1t/m'j$O0 + +           + + + + +    +  + +   +        + + +  +  +  + + + + +  +   + +        +   +       + +   + + + + + +    + +  +     + +  + +  + +     +  +  +     + +    +   +                       +      +      +  +      +   +   +  +  +  +    + +    +   + +        +       +  +    +     +       +  +   + +  +  +  +    + +   + + +     +   +  + +    + + +        +  + +   +   +  + +  + + +  +  +  + +  + + +  + + +   +       +  +  " !"  lhsnkkpyzvz{u}}ӃՁ{y݊ބ~zzurihhh^[VQQH{DsBn?e=]3Z8Q1O.M+C*B)9!41.(#   + + + + +  + +   +         +        +      + +  +    + + + +   +          + +   + +   +   + +        + +  + +&+ *(%%''%)!+. 0&0%4'=);,9.>0A3F7M?Q>UBTEYA]EbH[PoPkQpTzTrViJJ80 + +   +       + +    + + + +   + + + + +  +    +  + +  + + +  + + + +   + + +  + +      +      + +   +  +   + + +  + + +   + + + +   +   +  + +  +     + +   +  +     + +   +   +  +   +   +  +  +        +       +  + +      + +              +      +         +         +   +  +    +   +     + + +  + + + + +    +                  +  + +    +  +  +   +  +   +  +    + + + + + +  +       +      +   + +   +   +  + +  + +       + + + +   +   +   + +       +   +  + +    !!     yz|ć˄̃ڊ؇؁ڍώ܋؎ܗܗΉڂЃ|{mod_^^^VIvMvChF`A_:Z;T2J4E4D)9)5'4!0 /%   + + + +  + +  +  +   + + + + + + +  +  +  +  + + + +   + + +   +  +  + +      +    +   + + + + + + +  + + + +  +      + $0.((($%%&((-04997?B?!G H#P%R)U&Y(\+b)f-n.m1{.l.o&XC#  +    +   + +  +   +           +   + +  +  + + +  +  +   +  + + +  +    + + +  +  +    + +   + + +  +   +   +    +  +     +    +  + + +    +  + +   + +     + + +    +                 +                 +            +  + +  + +      +  +      +               + +  +              +  + +      +  + +   +  + + + +    +    + +  +   +     +   + + +   + + + + + +   +  +  +  +    + +    +    +  +   +  + +$ "loduvttpq{v~u}~xx؇}}ۆ~|{zlvfh``VPQUxJzItFgAe=\9\5U3O0J,E*@)=7 2+&%"    +   +  + + +   +   +    + +         +  + +  + + +        + +   + +    + +   + + + +  +  +      + +  +   + +   + #2#0-*%#(%** * -#/%8(5(7,8*@1B5E4I6J?NV;=FF!HPS"V$\(Z)_(b0j,t/t2}/s.h"S3  +  +     +   +  +     + +    + +   +  +   + +      +    + + + + +  +    +     + + +  + +  +  +    +   +   +      + +  +  +   +  +      +   +  +   +     + +  +   +                +                  +   +  +   +      + + +      +  +   +    +      +    +    +  + + +   +   +  + +  + + +   +  +        + + +   + + + + +  +  + +  + +          + + + + +    +   + +  + +  +  + +   +  + + + + + +  +     +   +   +   +   +  + kmrio|yrjxv}z{z|υۇنހ݆΀ttpifc^^WPQJ|JrBrFj@^8[8R3R1I,D(F(@$7!6 1&#!   + + + + + + + + + +    +  + +   +  +  +  +  +   +    +  + + +      +    +    + +  + +  + +    + +   +   + + +     +  + +   ", ."(#*()$&%(-%.*"2"4)5,:*<,A2D8H6H9X=YBU?WD]G`IiIgTrPv[qVoU_GJ7/ +  + + +   +       + + +     +  +  + +  +   +   +  +       + + +  +  + + + +  +  + +    +  + +  +   + + + +   + +    +    + +   + +  + +  +    +  +  + + +  +  +      +  +       +  + +  +          +    +    +      +                       +   +    +    +    + +       +        + + + +  +      +      +    +   + + + +    +    +  + +     +     +       +      +  +  +    +    +  +         + +   + +    +   +  +     +  +    + +   + + +   + +  + + + +  + +       +          y~u|̉}ÄĐ̊dž͍ٓ֐ΎڏܓܒސݙݒݖˊڎʀyyxwqegadWLyOzJmBkGd=Z=W:P5J0J,E*@)9(7"6+ &&   + + +   + +  +  + +      +   + + +    + +    + +   +   + + + + + +   + + + + +   + +  + +   +    +  + + +   + +   &*+*&+!%$'+-+1067;ABGG P#O#P$V)T)^*e,m(v0w/t4|(l(_E'     +      +  +  + +   +   +      + + + + + +    +  +     +  +   + + + +  + +   +     +  +  +  +  +  +   +  + +    +  +    + +   + + + + +    +     +      +   +                         +            +              + +  +    +  + + +   +    + +   +           +        +     +    +   +   + +    + +  + +       + + +     +    +     +   +    +    +    + + + +  +  + + +   +  +     + +     + + +      +  +  +     + honlnxwwxv~u}vڄυц܀߇{΂vupjicaYTQMNxHwEn>f?b7X:U2U3M+E-?%C#="70)$#    +  + + +  +     + +    +  +  +     + +  +    +        +    +       +      +   +  + + +  +  +   +             +    +  *,0-!*$$%)&(!0 '*"2%5.:)=,E4J0E4H5U:R=UC]C]HaJcQnRsQwUtTtYqKYA9)  + +  +  +  + +     +    +     +          +     +      +  + + + + +    +       +  + +     +  + + + +  +   + + + + + + + + + + +      + +     +   +      +  +    +      +         +  +    +        +     +      + + +   +           +                          +   + +  + + + +  + +   + +  +         +   +   + +    +      + +          +  +   +  +  + + +    + + + + +      + +    +  +       +  + + +  + +  + +   + +        +   + +        +  + + + +  +     +   + +  + +  +      +  + + + + +   +   +  +  + +        w~wŠΉՈґ֐׎ԏהՏݘ҇}y|qileb]XT|ZsOmJrFg>b=[7R9Q5N0G-A,9(:&,".*"!   +  + + +  + +  +  +  + + + + +  +  +   + + +  + + +   +     +  + +  +   +  + +  + + + + +  +   +    +  +   +    +  )/-*''&# ))++146<;>CHJP!P!X'W)Z&b*d/h-l/x/~.q,e!N1     +  +    +          +     + + +  +  +    + + +  + + + +  +    +   +    + +  + +  +  + +  + + +   +       +  + + +    +      +      + +     +     +  +    +   +               +          +                 +   +   +   +        +       +   +   +    +    +   +   + + +         + + + +   +   + + +    +    +   +       + +   +    + + +        +  + +   + + +  + +        +   + +  +  + +  + +   +  +    + +     +  +  +  +  +    lqokrnwzvr{zy~y|ӂ؃݉ك݀}tupgmha_ZXQOsNuDpBj=`7\6\5V1G.H)F'=#85 /+'    +  + +  + + +      +     +      +      + +  +    +  +   + +        +  +  +  +   +  + + + +        +      +  +   + +  #-/")*'" %(&(,!2"0&7(5/<-;.B,G4H7M8J8PBSBYC^JdOdGgLuQt]tWtPfFK6) +   +  + + +   +  + +   + +  +   +   +       + + + +    +  + +  +  +  +      +   +   + +  + +   +  +   +    +     +    +  +  + +     + + + +  +       +  +   +  + +      +         +       +               +  +       + +  +     +    +  +        +         +       + +   +  +  +  +     +   +   +         +  +             +  + + + +       +           + + + +   + + +    + +  +  +        + +  + +    + + + +  + +    + +  + +  + +  +   +  + +  + +    + +   +   + + +  + + +     +  + + +  +      +       +  +v~|}~ƃ͋׎ΉۋԏۊՌΝؑהܓۖӐԂρńxyrihd]^WTT}SlKlHj@`>V7W9Q2K1E3?,?(;'7"-()!   + +   + + + +    + + + + + +    + +   + + + + +  +    + + +  + + +   + + + +  +    +  +  + + + + +    +  +   +  + + +   + + +   + + + +   + %0-**%$&&'*.*.659;CEFG P$Q"N#S$Y)Z(e'd.u1s3r4r-j$_?  +  +        +  +   +     + + + +     +  + +  +  +   + +    +  +    + +     + +  +  + +   +    +    + +      +  +    + +    +  +     +     +  +    +   +  +  + + +  +  +                     +  +       +       +     +    +  + + +  +   + +   +  + +          +  +   + +   +  +  +      +  +  +   + + +  +    +  +    +   +    +   +     + +   +   +   + +  +  +    +  +  + + +    +       +        + +  +      + + + +  +    + +  + + phvprvuqzu}xy܁ֈچԃڄ{ytwif_b_WSQFFyJlEg7B4ES<]?ZC\JfJjKhUiS}WuXsWbIJ7* +   + +     +      +  +    + + + +       + + + +  +  +  +   +  + + + +      + +  + +  +      + +  +  +  +  + + +    +      +  +     + +  +   + +    +   +  + + +   +     +  + +       + +  +                           + +            +  +            + + +     +   +             +  +     +  +    +    +       + +  +   +  + + +       + +  + +      + +  +  + +    +  + +  +  +    +      +   +   + + +   + + +  +  + +  +   +  + +  +   +   +  +  + + +   +       + + + + + w~||ˎ΀Ҏ͇׊Ύنؓ݋֜ڍۓߖ֍څƅ}tpifd^YYPwOrJkKkBa?^>Y9S8R4E2B+>&<$3!2!*(!   + + + + +  + + +    + +    + + + + + + +   + +    +  +     +  +   +   +  + +  +   + +     + + + +   +  +   + +   + +  +  + +      + %/.+())$*(+-+07<8=?FF!JN$V!X%\$b(\(d,f.q8r2v.t*m+\A'  +    +  + +         + +   + + + +   +   + +   + +  +  +    +    + +  +          +   +  +  + +  + +  +   + + +      +  + +    +   + +    +  + + + +  +  + + +                 +  +       +  +                   +        +      +    +      +     +  +  + +        +  +        +   +   + + +    +  +  + + + + + +     +    + +      +  +  +  + +  +  +    + +   +      +   +  + +   + +  +   + +     +   +      +   +   +    + +  + + +     rvxuxroxzxӁ~|ׄق؃xxrmkfg_\TRRFqDmAk^BZBiHkOiRrXvX}QsUnRTA=)! + +          + +   +   + +  + +   + + +    +    +  +     + + +   +  + +   +  + + +    +        +   + + + + +   + + + +  +  + +   + +  +    +         + +  +         +                  +                +                              +   +   +   +  +         + +  + +    +     + +    + + + +      + +   + +        +    +  + + + +      + +         + +    +   +    + +     +  + + + + + +    +    +    +  + + + + + + +  + + + +  + + +    + +   + + +      + + +   + +        +  + + + ÃĄ˂ȃʃ΄|ӉӋՎ׎֍ؒޏߓؑ܏ߖێݐӇ}~vukfd_Y]O|QwIoNbFf@W=R8T7O5I.F.D+7%7%6")&  + + +    + +   + + + + + +  +  +   +  + + +  +   +   + + +  + + +        + +  + +   + +    +   +  + + + + + + + + + + +         +  ",.+)'$+(&,*/-349??DB!H!L&S$[&S&](c+^+h.m.k7v3y/n+i&Q3   +  +     +       +      +    + + + +   +      + + +  +   + + +   +  +   + +  +  +    +   +  + + +   + + +   +   +  +          +  +  +      +   + + + +  + + +    +    + + + + +      +       +  +      +            +   +         +  +  + +   +    +  +  +       +       +  + + + +   +     +       +   + +   + +  +  +  + + +      +  +    +   + +   +   +       +   + +  + +  +  +  +    + +  + + +    +      + +   +    +  +  vksprtv|Âxك{ׂ}ن܂܁ޅՇzxtonkdd\VVU~UFxKsBnBj=^8]8V4R2I.F)B)>$:!3 0)#   +   + +  +  +  +  + +  + +    +   + +    + + +     + +  + +        +    +    + + +   +  +    +      + + +   + +     + + + + + +  + + )0"/$("(&' & *!*!*#+!0%1(5&2)8*=.@.@5F6H;H#6"5#,&!     +  + + + +  + +  +  + + +  + + + + +  +  +   + +           +    +   + + + +  +   +   + +   + + + + + + +     +    +        *,1,)*'(),()22348AACFFP R'V(['\'^(c-g1n1q7y1w+p#c@  +     + +   + +  +      +        + + + +   + +   +    +     + + +   +     + + +  +  + +  +  + + + +   + + +   +    +    +  +    +  +  +  +  +          + + +   +          +    +               +    + +  +              +    +       + +     +         +  +     +  + +    +   +      +  +   +   +  +        + + + +   + +       +     +   +       + +      + + +  +  +      +  +   + +   +     +         + + +  + +    +  +  + +    +    +    ottnytvuv~~م؄؁݂{߂{txnobeYdTVLO|EwBk=dV;Y9P5H/G,>+:(4"4-%&       +  + + + + +  +   + +  + + + + + + + +   + +  +   + +   +  + +  +  +    +  +  +    + + + +  +    +  +        +         +  +  + + #-/.*&(+*'*,1/166@:DI"K"KT$T%V'Z(`(h*f/g1x5r.w.t,j"M0     +          + + +    + +    + +   +     + +   + +  + + + + +     + +    +     +   + +       +      +  +   + + + +   + +  +         + +  +    +  + +       +   + +             + +      + +          +        +     +          + +        +     +      +  +     + + + +     + + + +       +  +      +   + + + +  +    +  +  + + +           +    +      +     +  +  + +  +   +   +   + +       + + +   + + +         + + + + + + + +  + nqrsƃszzvydž}ׄف߆ޅ{rynjjg^`TVQHvJtDmAgBb9Y8T6L1N.L/='>&;!30+&     +    + +  +  +  + + + +      +       +      +  +  +       +  + +  +  + +     + + + +  + + +   + + +   + + + +  +  + + +  + +         +     +/"-!)()&)+-(2$.!0%0%7,=+=1=1E0F=KXDWC]F^JcHlRrOqWwVxVrO_HE1)  + +  + + +   + +            + +  + + +  +   +  + + +   +  + +  +   + +   +  +    + + + +    +      +   +  +    +   +  +   +   +  + + + + +    + +  +         +  +     +   +       + + +      + +        +      +        +        +   +    +    +        + +  +       +      + + +         + +     +   +       +  + + +   +   + + +  +  +    +       +   + + + + +  +    +    + + + + + +  +  +   +    +  +   +   + +   +   +  +    +       + +     +   + +      + + + + +  +  +        + + + + +    ψҁȉז̏׍חԑܖْދ΅~xwumqg_]YZPJpMtBlBZD\;U9S6L0B0D,;)9"0!.(#!  +  + +   +   + + +  +  + +   + + + +    +    +    +  + + + +  + + + + +  +  + + +  +    + + + +        +    +   +     + +  + + + + + +  +  *0/(-*$%&(+.41879;?CHM$QX$W$X&\&g)`*k-g0|1}0v.p&\?! +   + + + +     + +  +  + + + +  + + +  + + + + + + + + +      +      + +    + + +   + + + +  +  +      +   +      + + +    +  + + +   +  +   +  +   +                                +         +           +     + +         +    +   + +  + + +     +   +  + + +    + + + + +    + +  + + + +  + +       +  +   +  +        + + + +  +   + + + +  +     + +   + + + +     +   +        + +     +                 + +   nyso~}ɀ~΀}҅߃ӂއ߈~|wzmjhgdZTRORHnGtDhAh:\6U5P0N/J+C*@(:'53,&   + + +  +     +  + + +   +    +   +   + +  +  +    +  +          +   +   +  +       +   +   + + + +   + + + +  +  +  + +   +   + +    !--","**(+* +- *!1$2#/+5);-[9W8Q4E3C+F)>%8$5!.#$#   + +  +  +  + + + + +      +  +   + +     +  + +   + + + +  + + + + + +   + +   + + +    +  +  +      +    +             +  +   + +%/1/+($&(()(1.145:?!BGM!P Q%W%`&Z&Y*d+h,m/q3t2w-m&gE1  +   + +        + +  +        +        +  +  +   + +  +     +  +   +   +   + +  +   +  +   +    + + + +   +    + +       +       +     +     +                            +               +         + +     +    + +              +     + +       +    + +  + +   +  +   +  + +           + + +  +     +   + +  +     + +        +      +    + +   +   +   +  +   + +           trvpȀyy{y~{ۃ܁ߑވ΃ׂyptl`e``PWMIuHoCnBj>_3U6R4L/O-F&>'9%4!//$!   + + + +  +  +   + +  + + +   +  +   +          +          +   + + +     + +  +   +     +      + + + + +    +  +  + +        +  + / /"0"+&(&* ,+$.%-%0&."5$9-;/@/D6D6M8R?W@UA`B]HaKjQjKpUtWtWtZzVdME6) + + + +  + +   + + +       +   +  +      +    +   + +    + +  +    +   + + + + + + + +      +     +    + +  +  +      +     +  +    + +   +            + +          + +   + +   +  +                   +                          +                    +    + + + +    +     +     +        + + + +   +   +  + +  + + +   +  +  + +  +  +  +  + + + +  +  + +  + + +   + +   +    +  +   + +    + +    +   + +  +    +  + + +  +  + + + + + + +    + + + āˆˌЅɄד؉ّԍڒ܏ޖ͈ш}wrunhdZ\XXxOqKiJmFh=b:W9Q4G/C)@/<*:$2+)'  + +  +  + +  + + +  +  +   + + +     +       + + + + +  +      + +   +  +    +  +   +   +  + + +  + +   + + + + +  + +  +        +   !,.,)-'+(+.**-256:AD H"E"H"O$T$X'W$_+d*f-f/k0y2x5x/k#W>$      +  + + + +   + +    +   + +    +  + + +   + + +  +   +  +   +     +  +  + +  +  + + +  +      + +             +   +      +    +                               +      +    +       +   + + +     +    +       +      + +       +      +  +    + + +     +  + + +   + +        +  +  +  + +   + +    +    +  +  +        +  +    + +  +     + +       + + + +    + + +    + + + ovy|yuz~yՀy׀рݎو~ފ~~Ӏvrlflib[PMKJtGoIjCf;d8^9T6L2M0J*B%7$2!0-,!     + + +  +  +  +  + + +     + +    + + + + +   + + +   +   +   +   +   + + +   + + + +        +  + +  + + +       +  +   + + + + +  + + + + +   + + + + +   +      + $* -"1!*('((&(++ ,1%3)5*70<6@4G6L7K:M9SBTB`C^ObKdQrRnQzWuQx]rRU85& + +  +    +    + + +  + +  +   +   + +     +        + + +  +  +  + +  +  +   + + +  +    + +    + +   + + + +  +   +         +     +   +  + +       +  + +     +     +                               +   + +                     + +        +     + + + +    +   +   +            + +  + +   +  + +       +    +      +     + + +  + +    + + +  + +    + +   +   +  + +       + +    +        + + +  + + + +  +     + +   + + + +    +  + ‚ǂÇςň͊’ʅьϏԌڋّڕԒޓކЉ͈~yxqtihdZWTXtToFhH\AW?[7W7R4G0B+D(:"4#/($    + + + + +   + + + + + + + +       +  + +  +   + +      + + + +    + +     + +    +  + + +     +   + + +  + +   + +     +  + + + + +     +   +    +  + + +   %.0+,''&,.(*-*-288>D E!E"R"M"W&W'Z(a/a+h0r0y0u3~-|+c!O3      +  + + + +         +  +  + +   + + + +  +                   +  + +   + +    + + +   + +  + +      + +  +  +  + +   +  +  +   +   + +     +        +       + +  +       +      +     + +     +           +                  + +  + + +     + +   + +    +  +      +   +  + +  +  + + +   +  + + + +  +   +  + + +  +      + +      +     +     +  + +       +      +   + +  + + +   +    + + +  +   +       +  +     + +   + +       pnyurvu}xy|zلك߅݇͆ф}miihb]WYWK|NwHnFlAf;c:^3\5R5O*H.;&:": /.$      + + + +  +  +   + +  + +       +     + + +    +        +    +   + +       +  +  +  +     +   +  +   +    + +       + + +   +    (.#/ )+"*(&$*$&%3#2'8)7*70<1B4L3N:N>P>T=UB\DaJbMmPtSsUZ}VzVbHE-) + + +  + + +  +  + +  +   +   +   +  + + +    +        +        + + +      +     +   +  + +  +  + +   +      + + +  +       + +   + + +     + + +     + +   +  +     + + +           +     + +    +   +                +  +           +      +                 +   +   +  +  + +        +  +    + +       + +   + + + +     +  +    +    + +    + + + + + +   +  + +        +   +  +   +   +    +  + + + +    +     + +    + +    +   + + +  +   +  + + + + + + +      Ʉŀ΄˂ʌ͍Ȇ׉ыے֑ג׍؇҉ʂtstph`d`_T{NvPlIjHdBY@W8O3P4K0A'@'9"4"1*%#   + + + + +  +  +  +   +   +   + +   + + + + + +   +     + +   +   + + +  + +  +     +   + +  +   + +    + +    +      +  + +    + +      + + "+10(*%%$'#$).49:=>CBJ!K#NR!U$V&a,j*g*j0q.}/{3|+p"T =$     +   +    +    + +  + +  + + + +   +   + + +    + + +   + +   +  +  + + + +   + +   +       + +   + +   +     +     +  + +  + +        +   +  +         +  +           +     +        +             +           +  +       +   +    + +    + +  +    +  + + + +  +      +  + +  +   + +         +  + +    + +    + +  + +   +   + +      +  +   +  + + + +        +         + + +  pnzutv{Є~ـ݅߂~Ӏ|smugef`Z]RKxHzJoGjC_<]7\3X1T/J/E+A(;%7"61&"     +  + + +  +  +  + + + +     +  +  +   +  +      +  +  +  + + +  +   +     +  +    + +  +   + + +      + + +    + + +     +   +     +  +  +  +      +$.!0 *')'&$%",/1!1$7'6,>0@5A4J6E7P8U=W?\FYF]JcJbMfRtWyYzTnYgNN?4+ +     + +  +  +  + + + +  +      + +  +    + + + +   +     + + +  + + + + + +  +     +     +  +  +     +       + +  +   +   + +   +   +     + +    + +  +      + + +   +  +      +   +  +          +  +       +        +        +  +      +       +        +    +  + +  +    + + +  +  +  + +  + +   +       + +   +   +      + +   +     +  +   + + +  + + +    + +            +    + +    +   +      +  +  +  + + + +   + +       +    +   + + +    ̀ɇŇ͎ІهЈ~όۉюޟԍݏՇˀzxokiea_TTxSuFkGpDeB`>Z8M:J0L/@,?(<$6"/-$      +  + + +  + + + + + +    + +  +   + + + +    + + + +     +  +    + +    +  +   +  + +       +  +   + +  + + + +  + + +   + + +  + + +  +   + + +.)*)$" #%+*,3.27>=A"DII#W&X(\(S&`+h.l0n0o-t2~.t-b$N3   +  + + +  + +         +      +     +      +   + + + +    + + + + +  + + + + + +      + + +   +    +   + + +   +   +         +  + +   +   + +    + +           +  + +           +          +                    +  + +    +     +  +  + + +         + +  + +  + + +     + +   +   +   + +  +  + + + +   + +    + +            +   +  +     + + +  +    + +      +       +   +  +   +    + +  +     + +    +  +   +  pvsw}vځȄ܁܁߂~~ۆҁ̂udi`f\[RMJvGqHi?c;c>\8R1O4M-F-D'9'8 4-)%   +  +  +  +  + +  + +  +  +     +    + +    + +    +      +  +    + + + +  + + + +   +  + +         +        +    + + + +    +  +     +  + +  + +    +  +   + +!)/-+' !!',)#,"0#3*5+5-?+?+A4F8L7JXC[K`JcMbJlVrRxSz]{TjKRA4'   +  +  +      + + +  + +    +  + +  +    + +        + +    + + +  +   + +  +        +   + +  + +         +    + +  +     +    +  +  + + +      + +       + +   +  +          +   +                                           +   +    + +   +    +  + +  +      +    +    + +  +   + + +    + +  + + + +  + + +  + + +  +     +       + +  + +   +   +  +     + + +    +  + +     + +    +       +  +    +     + +    +  + + ȉǂȇЈՇэݏыޑՌޏޑޒۑՉҊƆDžp{qnm[VYPNyKtNiCaBc@\9X6Q4O/B-D(=+3!0 ,%"  + +  + + + +   + +  +  + + +     + + +             +       + + + +  +   +    +    +    +    + + + +  +    + +  +    +  +  +  + + +   +     (0+'$&&&(-*--2649?ABD IO"P!Y$W+`&X&b)k0s2o1{2w-n+g$O- + +   +  +   + +  +    + +   + +         +   + +      +   + + +     +  +  + + + + +   +     +       +   + + +   +        +  +  +   +   +  +  +    +  +  + + +                                 +          +  +    + +  + +   +      +     +  +  +  +   +  + + +   + +  + + + +      +   + +   +  + +     +  +  + +   +    +  +    +   +       + + +     +  + +  +   + +   +  + +    + +   + +  +  +    + + +   ~xztt}uy}ځ}݂܈؀у}|xmihgeX[POPyJwKrCjGc1D4@9H=I=U>S?\C\FaHdNiSmKqSqYx]pVlNOB7+ + +  + +    + +      +  +        + +   +   +     + + + + + +     + + +       + + + +         + +  +        +          +  +    +      +   +        +  +  +  +     +  +  +  +  +    +  +             +     +   +         + +  +       +      +   +   +   + + + +  +    +   +   +         + +       + + +    + +    +  +  + + +  +  +  +   +  + +   +   + +  +  +      + +  + +     + +  +  + + + + + + +     +     +  + + + + + + +  + + + +      +    + ̀υdžЄՊЊ܌Ѝ׍Չה؎ڛ׋Ίʂwzwthhfc\OzPvNuItHfAa9_;[=R8I1G.G,7'9%. / )%  + + + + +   +   + + + +   + +  +      +  + +      +    + + + + +  + + + + + + + +  +         + + + + +  +  + +  + + + +   + +  +  + + + + + +  + + + +          *+.*&'"('*)*.0385?@= BQ#T$U$S"[&\&b*d,m0l/p2p1w-q(m L4      + +      + +   + + +  +      +     +  + +   +      +  +   +  +  +  + + +      +         + +     +  +  + + +       +      +    +              +              +    +  + +          +      +  +   + +   + +     +   + +  +       +   +    + +   +     +   +  +       + + +     +   + + + + +     + +       +   + +     +  + + +    + + + +  +    +    +  + + + +    +   +       +uxosu{{с|Հ{݃܊یބwvvwlkgcf[ZXNwGvGp=j:k7[6V8U0N0I*E';&:!2--&#  + +  + + + + +    +   + +  +    +     +      + + + + +        +  +       +   +   + + +   +   + + + +    +     +   +  +  + +  +      + + +  + + +  + +   +  +  + +  +  + +  + +  +  !) 0"+-*$('(+"/!'"0$1(5(5*8)>0A3B4L8N9P:U7+ + + +  + +   +   +    + + +    +    + + + +     +   +      +    +  + +   +   +      + +   + +  +  +    +    +    +  + +       +  +    + +  +   +   + +   +  +  +   + +        +  +      +      +      +   +               +              + +   +      +  +       +  +   +    +    + + + +   + + +    +  +  + + +    +  +  +  +  +  +     +  + +  +    + +     + +    +   + +  +  +   +     + + +    + +    +  + +   +   +  + +  + + + +      + + + +   + + + „ˉăӆȍ̌׉ۋ̋ؑגוߜ؁ˏuroloh^Z|[~O|KuKqFgDcA[a;a9X.S4I0G+E)C#;$6 0.*" +  + + +  +   + + +     + +  +  + + +      +          +  + +            +   +   + +   +  + +  +      + +  + + +   + + +    + + +  +  + + +  +  +   + + +  + + + + +  + +   +  + + '-. .&* , *-) *-$2#*#5$4'6-7+@+U?XFTC`OdGgNmYsSrVYx[vRaFE2, + + + +  +      + +  +   +   + +      + + +   + + +     +  +  +    +   +   +   +  + +  + + +  + +  + +      +         +     + +     + + +  + +       +     +    +      +   +             + +   +    +        +        +    +    + +  +   +   + +       +  +  + + + +   +  + + + +  +   +   +  +    + + + +   +   + +    +    + + + + + +  + +         +    +  + +       + +    +      +   +   + + +   +       + +     +   + ʅˀ˅ՇōӐԋؖٓܐߙۓϋ΄ƒ~vrteee\\[yPpLxJgEfCZ;V;S:P6I2?*<,8&5/!,)#   + + + + + +  +   +   + +   + +  + +  + +     + +  + +    + + +      +  + +   + +  +  +  + + +     +    + + + + +  +       + + + +    + +         + + + +   +    + + +  + +  +  + +  '/(-,(()'+**/01887<F BH I!M%P'X&[(`)c+h(f-q2u4w3,n'Z >$          +    + + +  +  +  +  + +         + +    +         +  + + +  +   +    + + +   +    +  + + +        + + + + +  +  +     +              +  +     +                 +      + +  +  +    +  +      +  + +  + +   + +    +  +  +  +   + +  + +    + +    + +  +  + +                 + + + + + + + +  + +   +    +  +    +   +      +    +  + + + ttu{|s~~}}ۀzցuymqfi`[\V~OyGtIsIi@g?a;Z0\6M1M.G(@':$9/.)!!  + + +   +    +  +     + +   +          +   +   +      +  +  +  +    + + +  + +  +  +       +   +       +  +   + + + +  +   +    + + +     + + + +    + +     + + +   +  + + + +   + ++.,)*$)%*!+,","2%1#3(5):.?.@0B6I8G5QAH D!I$J%U$V'U%a+_,c,i.q.o1y4u0r(i"U1             + + +  +  + +  +   +    +  +    + +  +   +     +   + + +   +         +  + +     +   +   + +    +   +   +     + +     +      +  +    + + +          +  + +                       +  +  +   +       +        +     +     + + + +    +  +  + + + + + + +  +    +   +  +     + + +       +  +    +  + + + +    + + +  +  +  + +    +       +  +  +       + +  + + +   + + + + totzx{}~x҅މׅމރyrvole_aZ\SLKxMqEk;g@^+A1A-D4I;P%;"3.+"   +   +  +  +     +  + + + + +   + + +    +  + +  + +  +    +      +       +            + + +      + +  +   + +  +   +      + + + +  +  +   + +   + +  +    + + + +    + +    +   #-1 *' ')')&'(/ +1$1'9);*=0A2D1K8JVB[CUE]JgDhPsTqX|Xxcv\jKW?;' + + +        +    +   +   + +       + +     +  + + +  +    +   +   +  +        +  +     +  +    + + +  + +   + +        +  + + +         + +  +         +        +               +   +         +                +   + +  +         + + +     +   + +   + + + +  + + + + + + + +      + + +   + + + +   +   +          +     +  +  + + + +  + +      +  + + + + + +  + +  +   +   +  +  +  +  + + +   +    + + +  ̅̃τΉЌЅӌ܉ډߔ݉ڋل̉~uomjdb[USwHrHhFa?c?X?Q;Q1K/@)D)<+8!2!),    + +  + +  + +    + +     + + +    + +  +  + +  +  +  +   +  +     +   + + +   + + + +   + +  +  +   + + +   +   + +   +   + + +  + + + +   + +      + +  +  +  + +  +   +   +    +  +    +  + &)1)++%((),*'+1229@=DG#OT$R"S%Y%\)e(e-m-o4s0{3~.y-g&J4     + +  +      +      +  +   +     +     +    + +    +  + + +  + +    + + +  +  + + +   +  +  +  +  + + + +      +     +  +      +                    +    +  +     +       +       +     +     +  +  +   +  +    +  + + + +  +   + +  + +  + + +  + + +   +   + +  +   +  + + + +  + +  + +   +  +     +     + + +    + +   +  +      +   +     + + +  + +  +  nqzـu|}އ|ߊՂۀx~wvrhg`a[RN}LsJwIrBf=i8^8Z5R0Q.K'C(<%; 50+(#  +   +  + + + +  + +       +       + +  + +           +  + + + + +        +  +          + + + + + +    +  + + +   +   +  + + + +    +    + + + + +   +   + +   +  +  + +   + +  +    + + + +   +  +  #/-++*)'('*'* 2#6"6,6*8(=2C1F3I9Q9M;TAXCY@YFVKgKmOpStU~]|UwU^LN30  + + +  +    + +   +     +    +       +     +   +     + +  +  +   +  + + +    +    + + + +   +  + + +  +  +  +   +        +      +  + +  +   + +  + +  + +           +  + +   +              +            +  +             +  +          + +     + +  + +    + +    + + + +   + + + + + +  + +  +   +  +   + + + +   +  + + +  +   +   + + + +      +      +  + + + +  +   + +  +  +   +      +       +     +  + ʅ͉ˏЉْэՋޏًۏ݉֋}vpobb[YUT}VrPqFd?c@c@V6R4S.I+D)9&9$1%+($!  + + + + +  + +  +   + +   +   +    +     + + +  + + + + + + + +    +   + +  + +  +  + +        +   + +     + + + +  +             +  + +   + + +  +    + + +  +   + +   +   + +  + + +   +  +'**.(+)*$!$((/3=::=BD D!I&P!Q%V%[+^)c.j*o.o4s1r4q/o'TA#      +   +     + +     +     + +  +  +   +         +   +     +  +  + +    +  +    +      +     +       +  + +     +     + +       +        +   +                       + +      +  + +     +  + + + + + + +  + +  +  + + +   +  + + + + +       +  +  + + + + + +    +    +     + + + + +      + + + + + + +   + + +  + +  +     + + + +  + +  +    +   + +  + + +              xz{vv|~ހڄ؃߂ڃׂxށwuhie[][QRJ{JuJpBfAg:\:Z7O4M0D+B';"T?TEaB\G^JhKlOgRlS{Xs^xYnQX88*  + + + +   +       +  + + + + +     + + + +     +    + + +  +   +  +  +   + +      + + + + +  +   +   + + +   +  +   + + + +    +  +  + +   +    +   +       +  +       +                +         +          +       +         +            + +  + +    +     + +    +    +  + +  +  +  +  + +    + +  + +  + + +     +  + + +   + +   +  +  +  +  +     +  +    +  +       +   +  +      +     +       + +   + + ͊ʼnЊՍ݃֓ڌ׋ڕߒߠߕܖ׃Έŀ|yrqbbc^QU|MuOpFl@`A^=Q6T4F1B.@-@,6"8$,+#      + + +   + +  +  + + + + + +      + + + +  +   +    + + + +  +  + + + + +   +  + +  +  +         +    +  +   + + + +     + + + + +   +  + +   +  +  +  + + +    +  + +   +  + +      +  +  + + + + +  + + + &*,-0&'"#$'/.-22;9<CCC"L#O$M"X#W,`*`'f.i0n/u4{1{/u#j$U6    + +         +  + +  +  +   + +   +  +     + +   +     +  +     +  + + + +  +  + +   +    +  +    +    +  +  + + +     +     +  +    +   +                                +        +     +    +  +  + +  + +    +   + +    + +    +   + + + +    +   +   +    + + + +  +    +  +  + +     +    +      + + +  +  +   +   +    + +  + +     + +    + + +  +  +  + + + +  +   +       +  + + +o|؀|zԂچ҃҃ڂ҄Ղy{spjgb`ZYQR|KHoCnFi=Z8\9X0S0J.?%=&=(4 1*'    + +  +     +  +   +      +   +   + + + +  +    + +     +   +   + + + + +  + +     +   +   +    +      +    +  +  +  +  +  +       +  +    +   +  +  +     +  +  + + +  + +  +  +   #-,*&%$&%) &") +"0$4$6(9*<-B2@3D5H;Q9K>T@XAXD_FcH_PlSoQoSxY{YwVdGM8- + +  +  +      +  + +  +       +   +  +   +     + + +     +    +   + + +       +  +       +   +  + + +     + +         +   + +   +        +   +        +  +           +    +   +                 +          +   +     +   + + +        +      +  + + +  +  + +  + +  +    + +     +   + + + + +     +  + +   + + +   +  +     + + + + + +    +     +  +     + +  + +  + +  + +  +        +    +    +  + +   ؉ɊՍ؊ړڔߕՒӕݖُ؅׈ҁxyusvlcd`UQ|UwFmKlFg@Z=W7X5M4J.C0B*8#4!.+&"  + + + + +     +  +   +  + + + + +     +  + +   + + + +  +   +  + +  +         +  +   + + +    + + + +   + +  + + + +   +   + + +      +  +  +  + + + +  +   +   + +      +  + +  +  + + + +   + + + (/0(# %%((++137379?CM J"R%U#X$U&Z%['c+g0j1p1s1}-}.l%`"A&   +    +   + + +  +  +  +       +  +      +     + +  +   +  + + + +       +  + +         +    +  +   + +  + +        +   + +           +           +          + +                  + + +   +  + + +  + + +    +  +  +   +         +  + + + + +  + + + + +  + + +   + + + +       +     + +  +      +    +    +  + +    +    + +    + + +    + + +            +    xvuv~z݆ډ܄~vlqljc`SUTNO}EvDj?c9_;\6Y5R-E+H+?$+! + + + + + +     +  + +     +   +     +  + +              +    + +  + +   + +   +   +  +    +       +      +    +      +  +   +    +    + +   +   + +   +  +  +    +   +  +               +       +       +                          + + +   + +   +        +  + + +    +  + +  +         +  + +   + +         +    +   + +  + +  +  + + + + +      + +    +  + +   + + +  +   +      +  + +  +      +     + + +   + Ȇˊϐϑڏَޒߌڎߒ֏Ԑφǀ~xpqiiabZV{MxKlGgFh:[=Y:W?N6J.E/=);(6$2 ,'    + + + + + +    + +   + +  + +  +       +  +  + + + + + + +    + + + +   + + + + +    +  +  + + + +  +   +   +  +   + + +  + +   + +  +  + + +  +    +    + + + +  +    +   +  + + +  +  + +  +     + + + +   +      +  + + %)2,*)'(&**+11455=<@BC!O"K(P&S$[)[+^(_.m/h4s/};w1y-n&S2  + +           +  + +   +   +    + +    +  + +       + +         +  +    +  + +  +    +    +   +    +     +     +   +   +  + + +        + +      +         +  +  +  +    + +              +       + + +  +   + +      +  + +   +  + +  +         + + + +     + +       +  + + +   +    +  +    +   + + + +     + + + +     + +  +   +  +   + +  +  +     + +    +   +  +    + + +   +~tuxy}ԇ}ـ׃~߄||uqvpji_`OTNK}HsDiAd>_:\6P4S1N-H,C*>!:!0/,&     +  +    + + + +    +  + +      + +     + +        +   + + + +     +           +    + +  +  +  +    +  +    +     +    +  +  + + + +     +    +   +     +  + +  +   +  + + + +    +    +   + %0!+ *(%%#))+.#./%0'7);'<09.G4E6J5L:Q9T?Y?]B^I`GgHlLpVvXvUXtOjJK0-! + +             + + + +    +     +     +  + +  + + +        +  +     +  +  +    +  +  +  + +   +    +   +  + +   +   +   + + +     +    +    +       +  +       +               +              +      +     + +         +  +   +       + + + +  + +  +  + + +    + +   + +   + + +     +  +  + + +   + +   +    +   +        +   + +   +   +      +  +        +   + + + + + +  + +         +   +   Ԏ͇ҍՊԎԓߎ׊ӛߑޕܜޒц͂~~ohhb`^TPqNlKpB`?c?Z7T5K1L.B/@+:&7%2"* &"    + + + + +  + + + +   + +   +  + +      +  + + + + + +   + + +   +  +  + +  +   +    +   + +  +   +  + +  + +   + + +    +   +   + +   +  +  + + +   +  +  + +  + +   +   + + + + +  +  +  +   +      + +  + + )-,,&'%'))(12/66<?DADHQ$L$V$U#]%a(l,k0i1m1v5~:r1s'\ C(     +  +    + +   +  +  + + + + + + + + + +   +     + +      +  +     +  +  + + + + +   +  + +   +      +    +       +    +                                       +     +    + +   +  +  +  + +   + + +  + +     +  +  + + + +  +  +    +  +   + + +   + + + + + + + +    +   +   +  +   +  +      + +  +  + +      + +  +  +      + + + + +   +         + +   +   w}{yzy~ڇ{ۈٍ߅؁vqupjk`ZSSOOvHt@s=b:[:\7\2U3K+K.A&>"6$0*+(   +  +   + +  + + +   +   +          +     + +     +        + +  +  + +  + +   +      + + +  + +  +  + +    + + + +             +        +  + +  +  + +    + + + + + +    +  +     +  + +  + +      + +  + +  + , -#+!*&*'$$ (#+,'0%1&5(8'6-?/C1I7G5J:M@E KH T#O$Z#Z/['^,e+i1q2t2|1x-w*q#O8         +     +   +  +    + +  +  +  +   +   +  +  +  +     + +  +    + +  +     +  +    + +     +   +  + +    +  + +     +             +    +        +   +   +   +       + +  + + +  +   +  +  + + + + +     +  + + + +  +    + +   + +    +     +     +     +   +    +       + + +   + +  +   + +    +           + + + +      +      + + tzxy~݆ډ~߄؆݊w|rrrdeYbY\NMxEyInBl9g@a:[2R0R.G*C)@&9#30-&     + +    +   +    +     +    +       +  +   +   +    +  +               + +  + + +  +  + +          +   + +  +  +    +  +  + + + + +  + + + +   + + + + + +  + +     +  + +  + + +  + + + +  + +   +  +      + + +      ))/ ) * (%(&!), ,"/$1$1&3)2.9.?,D4E7J6R[8N4F2I,C(:+6&1!,&#!    + + +  + +  + +  + +  + +   +    +   + + + +   + + +    + +   + +  + +  +   +     + + +  + +   + + +  +    +  +   + +  + + +  +  + +   + +  + +  +  + + + + +  +      + + + +    + + + + +    +   + +   +   +       + +  + +  + &++*-''$)-'-1058;:A<DHN#N#V'\%Y(b)d,e-k1p4z3~-{)n+[B* +    +   + + +  +   +   +    +     +  +  + +  + +  +  +  + +  +     +  +  +        + + + +   +    +  +    +    + + + +   +   +       + +           +                     +  +    +       +   +  + + +      + +  + +  +  +    +  + + + +     + + + + +   +  +   + +         +  + +   + + + +  + + + + + +  +   +  +  +  +   +  +  + +    + +   +  +    + + + + +         + +       +       + +   + xuzρ{x݉{ڊىy؅|́rtsga]\XYPI}IxCqEj?f?a:V5P/G0J+D)?&<(8,,&"    +  + +  + +  +    + +  +     + + + +    +   +     +    + +     + + +        +   + +    + +    +    +     +      +    +   +  +   + + +   +  + + +    +  +  +  + +   + + +  + +  +    + +      + +  +  '+/+"-,&&&$' * ( ,$3&0)8(;(;.>4E2J9J=NZB\>WGeFdKeVqYo[rcv[x\sO]>:,$ + +    +     + +        +    +  +   + + +    +      +  + +       + +    +    + + +   + +     +     +              +    + +  +    +   + +      + + +    +  +    +      + +  +        +        + +       +       +   +  +   +   +  +   +  +  +  + + +  +  +    +  +  +  + +  +  +  + + + + + +   +   +   + +  + + +     +    + + + +      +   +  + + +  + +  + + +  + + + + +  +    +   + +       + + +   + +  +       + +        ljڏ؊׌ڔגܓߘӊԉӃ}~qtecda\RO|NuEtEfAbA_:P8L5S3H0D,<&8#5",!''!  +  + + +  + + + +   +     + +  + +   +  + +        +      + +  + +  +       +  + +   +  + + +   + +     + +  + +  +      + +    +  + +   +    + +  + +   +  + +  +  +  +       +   +    + +  + +  +  + + +  + $-0.'+%(''))1/12699AI!J I#M#O#W&X+]+d.d-j5n1t6}0|0t-l"R5       +  + + + + +    +   +   +   +  +  + + +       +  + +     +  +  +   +   + +   +   + +              +  + +  + +             +   +                              +    + +     + + +  +   +  +   + +  +   +   + + +  + +   +    +   + + +    + +   +  + +     +      + +    + +     + + + +    +   +  +  + +        + + +   +       +  +  +  +  +   + + +  +  + +  + + +  +v{y}Ҁ݂w|liihd^_RTTxL{HoEgCd>Z9U3R0I.D*F)B%;"3 0-)% + +  + + + +      +  +   +              +     + + +  +  + + +     +   +  +       +  + +   + +  +  +  + + + +   + + + +  +  + +      + + +  +  + +    +   +  + +   +  + +  + +  + + + + +  + + + +  +  + + + + +     )1".#+",''.' +"+ -.!1&3)3):)9/B.G1G7K;N;OAZCYD]F^K_HjMkSwWt^y[z^zXhLI5/"  + + +     +  +      + + + + +  + + +       +  + +  +    +   +  + +   +  +    +  +  + +  +   +  +  +   + +       +  +     + + +           +        +    +        +   +      +                  + +   +  +     +     + + + +     +   +  +  + + +       + +      +  +    +  +   + +  + +   +   +    + +  + +  +  +    +  + + + + +   +  + +   +    +   +   +  + + + +     +  +   +  +    + + +  + + + +  + +   +҇Ӊф։ҊܐٔߒێؑՊՂ}tvmgia\YVSsJnEgAgA\>U8Q4O4H2D+<'7$6 / ,(   + + +  + + +   + +  + + + + +   + + + + + +  + +     +    +  +  +  + + + +   +       +  +  +  +  +      + + + +  +      +  + +  + +   +      + +   +    +    + +     +  +  +   +  + +  + + +  +   +#)2++(&%')*-/+026:?@A FJSN$Q(Y)V)a'd.h.r1r53z2-v'aH+  +      +   +   + +  +   +  +   + +      +    + + + + +   + + +       +    +    +      + +  +  + + + +          +   +      +           + +       +                  +           +       +  +   +  + +  +  +  + + +   +    +      + +  +  +   + + +      +         +    +     +  + + + + + + + + +  +        + + +   +  +  + +   +     +        + +  +    + + +     + + +   + wŀyz~ډއۇـ{qyomkbZ[UVPzNtIsApAe?]9X6R1J0D,C*='[E[C^D`JhQjQjNwPU}Y{ZrQWH>2$  +        +      +   +    + + +     +  + + + +   +    + +  +  + +    +  +  +           +  +  +   +    +   +            +  +     +                     + +  +     +       +                +     +   +  + + + +  +  +   +  + + +  +     +  +  +    + +   + +   + +   +  + + + + + +  + + +     +   +  + +    +     + +   +  + +     + +        +  +  +  +    +   +      +  + + +  +     +  + +  + + +    + + ˄яӏڐ͕ސޘуz|srmc^`]Q{KtLoFkBdC_=[7N8S1J-F-=&:$5#0!*"!   +  +  + +  +  +    +  +    + + + +    +    +  + +  +      + + + +  +  + + + +    +  + + + +    +   +   +   +     + + + + + + + + + +   +  + + + + +  +   +   +   + + +  + + + + +  + + +   +     + +    +    + + !-.)+'%#)('-.5.5;<">BELKS$S#[%]'`*i)i.m0s5|7{3}2&p"R4  +        +    +   + +  +    +             +   +  +  + + +     +  +   +   +  +  +       + + + +  +     + + +       + +  + + +  + +     +         +       +  +             +  +  +    +     +   +    + +     +     +  + +  +     +  + + + +  +  + +     +  +     + +  + +    +  + +    +    + + + + +    +     +      +    + +  + + +  +    + + + + +   +  +  + +        +   xt}ڈ݃|~шutuhkfe[Z[S}IwFu@iFa;^8]4_5W6N-H)F'@%6"0 /(#   + + +  +    +   + +  + +    +  + + + +   +   g     +   + + +    +    + +         + + +   + +      +   + + + + +      +   +  + +  +     +  +  + +   + + + +  +     +   + + +  + + +  +   +   +     +   + +  + + + + +   +   + "++-,+ ()&%(.--#1%2,1+7/;.>2>9K:L6N=W=UF`E]H_IgPhOqO}PrSu]YyXbMK;/!  + + +  + +    +     +  +   + +  +     + + +  + +     +     +  + +      + + + +      +  +    +     + +  +  + +  +         +   +  +       +   +     +            +             +    +               + +  +     + + + + +  +  + +   + + +  + + + + +  + + +   + + +  +  +  +   +   + + +  +    + +   +  + +    + +  +  +   +  + +   +   + + +     + + + + +   +  +  + + +  + +  + + + + + +  +  + +   +  + + +   +   + + + Ԋُېь͒גْݐٙ}~unmc`j`YR|R|NsHoAd>c?\:W9O3K1B)=(8&8"2-)%  +  + + + + + +   + + + + + +  + +    +     +     + + +  +   +      + +  +  +  +      + +    + + +  + +  + + + + +  +        + + +   +  + + + + + +  +  +  + +   + +      +   +   +   + +       +    + +  +  + +  + + +   + + #+-,.)&&%***--047=>F KKI"R"R'O'\)Z(^)b(d-h2n3w3|2/k&f"C,  +      +     +  +    +     +   +  + +  + +   +  +  +             +    +  +    + +    +                    +               +                  + +            +    +  + + +   + + + + + +    +   +   + + +    +  + + +   + + + +   + + +    +  +      +     +  +   +  + + +  +  + + +  + +    +   +       + +  +  +       +  + + + +   + + + +  +     + +    + + +  +{xv}ہلށފو~{trkcd_^XOVFzOnBkAh=^5^7W3S6J/F'C&7&8"2/'#   +  + +    + +      +   +  +  +    + +  +      +  + +   +   +  +     +    + + +   + +        + +       +        +  + +   +  +   + + +   +     +  + +    +       +  + + +  +   + +  +   +  +  + + + +  +  +    +    +     $+#.,#) & )%-*(-!.$,#1&2*5*;.;0@4F9K8H6Q>N?VC]A`JhJfMgRpZw`~VY{\rWYED/& + +   + +     +              +   + +               + + + +    + +   + +    + + +    +  +         +                         + +    +       +              +     +       +        +            + + +     +  +  +  + +  +         +  +  +  + +  +  + + +  +     + + + + +   +  +    +  +   + + + + + + + + +     + + + + +  +   +   + +  +   +    +      + + + + + + +    +  + + +  + +    + + +  + + + + ڊؐօۑݐޒޓڄ~Ɗwjmmie_]U~WyPsGn=_AXA]=XFJL$Q%R$T&Y"^,a+h-k1r0u5x53|.k%W7     +  +   +     +     +   +   +       +    + + + + +   +  + +   +         + +  +       +     +    +   + + + +    +  + +     +       +                                    +       +   +    + + +  + +  +     +  + + +  +         +   + + +  + +  +  +  + + +   + + +    + +        + +  + +  +  + +      +   +  + + + +  + + +      +  + + +  +  +  +  +    + +   +      + +    +   +   + + +{݆̀ρ}ހنۂ{|utuija`^SOIHxFsFi=f:`7X5Q1M.L.B,A(7 4-''!   +  +  +    + +  + +   +     + + + +           +     +              + +    +         + +  +         +      +     +              + +     + +        + + +   +  +  +  + + +      + + + + + +  + +  +     + + +      +     +  )/#*"+!)' ', ()!*,$.'0",&7,8/<.>2B2G9H7N;R>VA\HYGbGeMiVtRtXs_}`^}SjLS;1% + +         +  + +      +      +      +  +   +       + +  + +   +  +    +              +  + +  +        + +  +    + +     +     + +  +  +    + + +     +     +   +  +           +                                 +    +  + +   +      +  + +  +  +  +  + +  + +   + + +  + +  + +    + +   + + + +  +   +  +     +   +  + + + + + +      +   + +   +  + + + +   +  + +   + +    + +     + + +  + + +  + +   + + +  + + + ӈ׈Ԍݔޓۘ߇مӉ|yuqpjdgZ[RvNqKmHgAe>`h-A6C3F3P8L=Q;Q>Y=XF`EdIfSoUlVvXz[yf\sQ]CA1* + +  +  +  +    + +  +     + +  +      +           +   +  + +   +  +      + + +   +    + + +   +  + + +      + +     +    +   +    +   +  + +  +   +       + +      +          +   +    +                            +   +      + + + + +   + + +  + + + +  +   + + +   + + +   + +   +  +  +  + +      + +   +  +   + + +  + +      +  + + +  +   + +      +   +  +     +    +   +  + +  +     + +      +   +    + + ˎד߆Ԗۓߑ٤؊ёڋxwtlja`[SSyMuLqLeAcBb3@/H7K4J6OCII J L$S$X#W'f(a*g-j+k0q0w3|3}.})g M1 +        +          +  +       + + +     +  + +   +    +  +   +          +   +     +  + +     +     +         +       +   +   +         + +               +               +  + + + +     + + + + +  + +  +       + +   + +  +     +   + +  +    + + +  +  + + +  + + +   + + + +    +   +  + +  +  + + +   + + + + +   +    +    +  + +  +  +    +  + +   +   + +  + zz؇څzڈۆ׃}}rrmlb]`QR}SvGzGuHj@`?^<]5U/T0K.C'=%A$:"/,&&    + + + +         +  +     +            +     +        +     + + +   +     + +    +       + + +    + +  +   + + +     + +  +   + +   + + +   + +   + + +       + + +  + +   + +    + + + +  +  +   +     + +   +   +  +  +    + +  . 0"1!'&)"+( (+ *"."0&/(8(9.>+@0C5L4M8L6LaB]:O3Q2M2A)=(3"1!-('!  + + +  + + +  + + + + +  +   +  + + + +  +   + + +  + + + + + +  +  + + +  +  + +    +   +      +  + +   +  +   + +      + + +  +  +  +    + + + + +  + + + +    + + + +  + + +  +  + +    + +  +    +   + + +    + +     + + +   +       + + !&/-.&*()+'--/52:7@=COJO$L#V%W)^+\-^+h-j1q3v3y90~+o%[;# +     +  +   +  +       + +  +    + +     +         + + +  + + +  + + +   +  +   + +   +  + + +   +   +     +   +   + +  + +     +   +          +   + +                               + +  +  +      +   +  +       +   +  +  +       +      +  +      + +  + +  + + + + +  +  +   + + + + + + +   +   +   +   +      +  +      +    +  + + + +      +   +{}ރՆz܄{~pujc`^\UWOL|GmDo;m;g7`6X2Q/I-I,?%=!4 2,&#  + + +   +     +   +  +        +       + + + +   + +  + +    + + +     +   + +    +         + +   + +       +    +   +       +       +  +  +   + + + +    + +  +       + + + +  +   +   + + +  +   +  + +    + + + +  +  +      )//+!'& ()( +!(!.%."1%6(4';.B1?0?2H3L7S@Z9$ +  + +   +  +  +      + +  +         + +    + + + + +  +  +   + + +       + + +  + + +  +       +           +  + +    + +  +       +  +      +     +          +        +         +   + + + + +     +         + +  + + +     +  + +      + + + +   + + +   + + + + +  +   + + +      +    +        +  + + + +   + +  +  +  +     +   + + + + +     +    + + + + + +     +  + + + ڔێ׍ߓۍڐ̂ІtrmkgeX]VxN{HrMqAk@c>X:U7H/J.F+?)3$6".'&#     + +  +     +   +  +  + + +  +  +    +   + + +  +      +  + +  +   + +  +  +   +  +  +      + + + +  + + + + +  +  + +  + +    +   + +  +        +   +  +    +  + + +   +   + +   +   + +  + + +  + +  + +  + +    + + +      $).-+)'&)*(,)-19:9E=DEL!L&T#V"^(_+g'd.k0q,t6x8:-y)bO5 +        + + +    + + +    +   +       +   +  +      +   +  +  +   + +  +     +   + + +  +  +  +  +  +  +  +   +     + +    +      +   + +    +       +       + +           +    +    +        + + +      +     + +     + +      + +  + + + +   +   + + + +    + +   + + +  +   + +  +   + +  +  +   + + + + + +        +     + + + + + + + +    +   + + +          +       +؁Ӆۇ~ډ~wsijff\YRP~M}IsIlAf9d:_:Y3O1M,G)>*=#4#/,+! +   + + +   +      + +      +   + +   + +   + +  +  +   +    + +  +      + +   + +     +  +   +  +  +   + +  +   + +       +   +   +   +          + +  +  +  +  +   + + +  +   +  + + + + + +    + + + +   +      +  + + + +   (,!(%/#+'()% , $,!,".#7$4*7+=0?0E1M5K6N9N=U@^F\EaBbNrLkRuVw^xX`YvR]KH4, +   +            + +   +  + +  + + +  + + + + +  +  + +  +   +  +   + + +     + +  + +  +   + +   +  + +  +  +     + +  + +         + +  +       +                      +        + +    +        + + +      +  +   + +    + + +  + +    +  +  +           + +       +   + +  +  +         + + + +  +  + +   + +  +    + +     +  +  + + +  + +  + + + + + + +   + + +     ׉ݗّܓߘޗ؊׌̉ƅyurlf[_ZXPwLvHpDfA_>T:U5M1N2H'B)8(6 2 *$!   +  + + +  + + +  +   + +   + + +  +     + +    + +     +    +   + + + +    +  + + + +   +  +  + +  + +      + + + + + +  + +  +  + + +  +  + +  + +     +     +           + + + + + +   +  + +   +  +    + + +   +   +     + +    + +  +     +  +     '0,(*&**&*+,+0179:?B F"IP!S)T%U%Z&a+^,i,q0r3o3{53}+r'aB"  +       +     +      +    + + +  +     +         +   + +        +   +   +  +  +  +   +     + +     +  +   +   +  +    +   +    +    +   +      +   +             +  +            +    +  + +   +  +   +     + +         + + + + +  +     + + + + +  + +     + +   +   + + + +  +  +  +   +    + +          + + +       +    +   + +    +   +   +   +   + + +  +   + +   + ځ܄҆݋҇zqunec`_YVUX|IsFqAn?_8XJ@U;[@YD[IfFhKkQoPv\~Y~_`xVrRX?7'  + + +  +           +       + +  +   + +    +       +       +      +  +  +   +   +   +   +   +  +  +        +     + +      + +          +   +  +               +  +       +   +          +               + +   +   +       + + +   +     + +    +  +  + + + +   +   + +  +  +      +  + +    + + +  + + +  +  + +  +  +  + + +   + + +     +    +       +  +  +  + +݆֒ؓڕߑޑےэЃ{|rwkhfcXVStOwJrNeEcAW>X4R2H0H(:%?(53 +'%   +    + + + + + +        +   +  + + + + +     + +  + + +  + + + +  + + + +   + +    +   + + +  +  + + +     + + +  + +    +  +  +     +    + + +  + +    + +       +          + + +  +   +   + +        + + + + +   +   +    +  + + + +  + +  "+.-+)%)'*(+-1366>=DD"K I"K#R'U&_(]'c,i*n1j4k3y7~1.u*f O1 +     +      + + +  + +    +  +   +  +         + +  +  +     +   + +   + +      +  +     + +              +      +          +         +        +                    +      +  + +  +   +   +    +  +   + + +    + +  +   + +    +    +  +          + + +  + +    +  + + +   +   + +   +    +  + +  + +  +     +  +  +  +     + + + +        فڄފڈ߂܇}oqhoc_ZcVNN}K{FpDf@b8`7V9Q5M/A*A&:$3"7.&#   +    + + +    + +  +       +   + +         + + +     + +  + +       + +  +   +    + + + +   +    +  +      + +      + + +      + + + +          +   + + +    + +   + + + +   + +     + + +   +  +    +       +      +  +  +     + +  +  +  +  + + + +%1,-!* )%")&'+!)-$3"0%:,;*:.;0D4E7K6R;T=WBXBZKWIcJgPmOqNpX|\{azXvVcHK2.! + + +   +     + +  +   +   + + +        + + + +  +   +    + + +  +  +    +   +   + +  + +  + +   +     +           + +    +      +        +    +       + +   +       +  +                      +     +  + +    +  +   + +     +   +  + +     + + + +  +  + + +  + +    +  +              +  + + +   + + +    +     + + + + +  + + + + + +        +     +   +   +    + ًߌ֌ݖ҃Ќ~|rlh`_\\QxKtJsHkCg;Y:Z3L2K/G)?)>&6"1"-(%   + + + + + +  + +  + +     +  +  +  +    + + + + + + +    + +   + + + +    + +         + + +  + +   + + + + +       +   +  + +  + + +         + +  + +  + +  + +  +  + + + + +        + + +  + + + + + + + +  +     + +   +  + +  +   +     +     +  +  +    +   + + *./-&$(%,**...52:?AEFHS"P$Z#X'\(^)c)d,j/p0u64{2y*w'\<      + +  +       +    + + + + +   +   +   +   +       +  +    +      +  +  +   +    +   +  +         +  + +          +          +        +             +    + +        +    + + + + + + + +  + +    + +            + + + + +  + +    +   + +  + + + + + +      +  +  +  + +   +    + +  + +   +     + +    +  + + +     +  + +  +   + + + + + + + +  +  +  + Ճ|ۈۑysuqhdabWYQ}N|E@lEp@`@\8[5N1I-G*C)>'7"42+#!  +  +  + +  + +  +    +    + + +    +    +  +      + +    + +     +   +     +  + +  +    +  + + +   + +  +  +   +  +      +     + +        +  +   +  +   + + +    +   + +  +     + +        + + + +   +    + + + +    +  +   + +  + + + +   + + + +    + + "(+/. * *((+++"0!+"1'4,6(6/B1>5D5E9K9R[2O5Q0B-B(:)7#1!.(&    + + +   + + + + +  + + + +        + + +  +  +  + +    +      +     + + + + +    + +   + +  +       +  + + +   +  +  + +  + +   + + +    +   + + +  + +  + + + +    + +   + +      +   + +  + + + +      +    +  +  +  + +  + + +  + +  +  +  +     +       +  +  "../)$*%'-(),/2029>DFK!J M%Q%X&R$_(h*h+m/t/t21z3.u)n!U4   +   + +     + + + + +  +       + +   + +  +       + +  +      +   +   +     +  + +  + +     + + +  +  + + + +          + +      +                               +    + + + + +    +   + + + + + +  + + + + +  +  + +   + +   + +     +      +      + +  +    +   +   + +    +   + +  +  +    +  + + + +   + + +     + +  + +   +  +   +     + +   +  +҄܀ي߃|}yxkmbbZWXSJ~GtGrHm;c>Y8_9S4L/H/E)<"6#4 3)*$   +  +   + + +       +    +        +   +    + +   + + +  +  +   +       +  +  + +  +    + +  + + +  +  + + +   + +   + +   + +   +  +    +   + + +  +  +  +    + + + +  + + + + +  +  + + + +   +  +  + +   +  + +   + +  + + + + +  + + +  + + + + +     +  + + +  + + +    +    + + &0!/ .!+) %*,+, 0!*.%3(7*9*<,C/D/G0G:I8Q=U:WAYFaNbFfLnMoQyV{U`|]wVfLK52  + + +    +    + +  + + +  +    + +  +   +  + + + +  +      + + +     +         +   +    +      +     + +      +    +   +   + +              +            +      +        +      +    +    +        +    +  + + +  +  +  + +     +  +  + + + +  + + +  + + + + + + +    +  + +        + +  +   + +  +  +    +  +    +    + +  + +  + +  +  + +      +   + +    +  ՗ߟ׍~فspfjagcX|PuJwKu?mAhAZ=]6Z8O3C/?,=';"3 0&$!    + + + + + + + + + + +  + +   + +      + +  +    + + + + +  +  +  + +   +  +  +      + + + + + + +  + +  + +  +  +      +  +  + +  +   +   + + + + +  +     +  + + +  + + +    + + +  +    + + +       + +  + +   +     + + +  +  +        +  + + +   + +2/,())&+*,+,3298A7EA I O$N"R&T*U(a)`1h0h1n/z1u23z/x'^M* +   +  +        +  +  + +  +     +     +  + +  + + + + +   + +   + +   +   +      +  +    +     +     + +  + +  +  + +  + +       +     +   +    +               +               +       + +  + +    + + + + +  + +   +   + +  +  + +   +      + + +  +    + +  +    +   +    + + +  + +  +    +  +    +      + + +  + +  +  + + +    + +   + +  +      + +  |{߃}zvwkkheaXUNV{MyKqGhBa>^6U3O2P*A/?%@#:&1/+$#      + +  +   + +     + +  + +     +  + +  +  +  + +  +            +         +   + +  +      + +       +  + + + +  + + +     +  + + + + +  + + +   + + + + +    +  + +   + +  + +  + + +     + +   +  +    + + + + +   +  +  +         + + + +  +  + +  +    .- 0.!,(&'&,- +#0$:#5&3&8.;-@3C5C8F9O9R&;#1!0)%"  + + +   + +  +  +  +  + + +  + +  + + +      +     +   + +  +     + +  + + +  + + + + + + +   +  + +  +    + + +    +  +   + + +      + + +  +  +        +   + + + + +  + +  +   +     + +    +    + + + +  +     + +     +  + +  +  +  +   + +    +  +     %--.*%)'(*-+*,394:<DI"HJ"M$T"X%X'a'c*c*e,n0u2z3z62{,m'S;  + + +    +       +    + + + +       + +  +     + +  + +    +  + +    + +   +  +    + +  + +        + +     +  +     +  +  +         +   +              +   +    +             +       + + + + + + + +    +  + + +  +  + +  + +  +  +  +   +    + +  +   +  +     +    +  +   +  +  + + +      + +  +  +     + + +  + +    + +  + +    +  +   +     + +  +   +}Ҁ߅ցzxtjhmYVQLPI{HqDt;n>g6]5T4L0I-I'C&:#5 /+)!   + + +  +  +  + + + +   +    + +  +   + +     + + + + + + + + +    + + + +  + +   + +   +  +  +  +    +     + +   +  +  + +  + +          + +  +   + + +   +   +     +  + +            +   +  +  +  + +   + +   + +    +    + + + +       + + +  + + + +      $ *#-",*& ' &)+ *). /&4'8'7*9+;0C2H8G9L:N@WB[AVD\E_KeRnRp[uS_{[{ZWjJN<5"  + + +          +  +     +           +  + +       + +  +  +     +  +    +  +  + + +     + + +  +  +  +   + +   +       + +        + +   + +               +    +             +        +  +  + +       + +  + +   +  +   + +   +         + +   +  + +  +     + + +  + +  + + + +  + + +    +   +     +    + +    + + +   +    + + +    +   +   + +   + +  +  + +   +   + +  +  + + + + + + +  +  + +   דߐܗ֟Ԍ܅Ӆ}ytomg_\V_RwMjNeIeBc>T8V5M-F.<-=);$/$0)'!   + +  + + + +  +  + +  + + + + +   +   + + +    +    + +   + + +   +  + + + + + + +  + + +  +  + + +  + +  +    +    + + + + +      +   + +  + + + + +   + + + +   +    + + + +    +    +   + +   + +    +       +     + + +  + + + + + +      + +  +    +    +    +     + + + + +  + +  '..+,*'())((.03699ABE DM#RU"W%]%_%f+d0g+j/s1z3|6z.y*^"F- +    +        +    +      + +        +   + +  +    +   +    +           +   + + +      +    +    +  + +  +   + +  +                               +     +  + + + + +    +   +  +    +    + +      +  + +   +     +   +  +  + +  + + + + +  + +     +     +   +   +  +    + +    +  + +  +        +  +     + + + +   + + +  +  x߀݉܋~ۏ~тw{qlhch]TQQKFoDrFh;c6]9\4P0G.D,@&>!9"- .)%    + +   + + + +     +   +   +    + +     + +       + + + +  +    +  + +   +  +    +   +  +         +   +    +   + + + + + + +     +    +  +      + + + +    + +  + +   + + +   + +  + + + + +   +   + + +     +   + + +      + + +     +   +  +  +  + +     +        #,.()",%')))!-#-%3!2'3&9(7*>0?.D4B8I9N:V=XBXI\EZKbMiSeKqTUvbx^zZx]Z=A,$ +  +          +   +      +    + + +  + +    + +  +     + +    +    + + +  +   +   +    +  +   + +       +    +                       +           +          +     +   +  + +   +     + +  +   + + +  + +     + +   +    + + +  + +      +   + +  + + + +  +  + +   +  +  + + +   + +  + + + + + + + + +      +   + +  +  + + +   + +   + + + + + +ُՓؕݑܐ݈Љ}}}ypldbZXR|LtJnIhIiF[>X9R7L3J.I/;)7'5!-%&  + +   + +  +  + +  + +   +    + +  +  +           +  +  +     +     +  +  +      + + + + + + + + + + +  + +  + +   + + +    + + +   +    +  + + + +   + + + + + + +  +   + +   + +   + +    +  +   +  +      +   +   + + +  + + + +     +   + +   + + +       +    + .1+&$)((**-*0665<A>F#K!F#N#P#Q%W(Y'\+c,j.k1t3{7z1w4|,o"\9! +    +     +  +   +  + +           +       +   +               +   + +         +   +      + +        +    +          + + + +    + +   + +  +     +   +   +         +   +   +  +  +     +  +          +       + +   +   +  +      + +     + +   +  + +     + + + +        + +  + + + ߃܀шՀς}tstlg_]UTKQxHwApEk?i<^%;!3$2.)&" +    +  +  +   +       + + +        +    + +   +  +   + + +   +       + +  +   +   +   + +             +     + + +    + +  + + + +    + +   + +     +   + +      + + + +  +   +    +      + + +  +  + +  +         +  + + + + + +  + + +   +  +  + + + +  + + +    +     + #3 .$+".'')%), -.-"4'5(6)8.?-C3H/M9R9R9Q4' + + +       + +  + + +    + +       +     + + + +   +  +     + + +     + +     + +  +  +   + + + +  +    +      + +  + + +        + +  +  +      +                          +        + +  +  +  +   +     +  +    +  + + +     +  +    +    + +    + +  +   + +  + +       + + +     +     + +   + + + +   +   +   +  +  +  +   + +  +   + + + +  +    + + +   + + + + + + ܒؐܛۍ͉̓Ȃt{nigc_^}VzTtRqHuFj?]?[Y<D?DM%Q!U(W)`(T'`&i+k-p2k1{5{2}3z,j#U=$       + +          +  +   +        +     + + +    + +    +   + +      +  +    +     +   +  +   +  +         +       +    + +     +             +   +   + +   +  + +  + +   +   +      +  +      +  +    +         + +     + + +     + +      + +   +  + + +  + +     +  +     + + + +        + + + +  +  +  + +   +  ߅ق݃̆ۅ߁ވ~vqojga^XVM|MH{CpBkD^;]3Z/Q/J-G(>&;)8"30*'   + + +  + + +     +     +  +   +  +     + +     +  +  +  + + +  +        +  +  +   +   +  +   +   + +    +    +     +   + +  +   +   + +  + + +  +   +    +  + +     +    +  +   + +    + +   + +  + + +    +  + + + + +   + +  + + +   +  + +     +     +    +   +    + + &0#,),% '%, , '!*)!/2%2)7/;.>0D2C6I6M8S>X@VD\HcH_IhKiUkXsRx[^WxZpKT97%      + +         +    +    +  +  +    +   +  + +  +   + +   +  +      +     +       +      + +   + +       +    +      +                + +  +        +                   +   +  +     + +    + +   +  +   + + + +  +        +   +  + +  + +  + +  +   +  +   + +   + +      + +  +   + +    +         +    +  +  + + +      + + + +    + + + +  + + + + + + +  ۔ېϕؓއ߇~Àyqlfe[\UPzNoGrCjB\;\;O5P9G0C,<+:)4",!+%!    +  +  +  + + +  +  + +   + + + + +  +  +      +  +   + + +     + + +  + +    +  +  + +      + + + + +   +  +   + +  + + + +  +      + + + +  +   +  + + +  +  + + +   +          + +  + + +   +    +  + +  + + +  + + + + + + + + + +   + +   + + +  +  +  +    +   +  +    + +  (-1*))' (%),-*.537BACHKM!Q#P$W(Z&^'b,i)o+m1z2w44+u,d#S4 +     +        +   + + +    +   +  +       +  +  + +      +  +    +  + + +  +   +     +  +  +          +  + + +             +  +    +  +               + +  + +   +     + + +  +  +    +    +  +  + +  +  +  +  + +   + + +  +  +       +  +  +    +      +     +   +   +  +    + + +  +  + + + + +    +   +  +  ؄|ـ||rqidjbYRTR|CwDoHi)?(4$/.%$!    + +   + +  +   +    + + + +  +   + + +    +         +    +  +  + + +     +  + + +       +   + +             +  +  + +  +  + + +  +    +  +     +  +  + + + +      +   +  +  + +  +  +  +   +  + + +  +  + +  +   +    +   + +     + +      +  +  +     + +   +   +  + !+.--+'''')-1,/51=<A@D K"O!R#T&Z W$_+b,e+l2u4s380{-m'X=& +    + +     +  + +   +  + +   +      +   +      + +    +   +  + +     +                +   +          +     +                        + + + +  + +    + +  +  +   + + + + +    +       + +  +             + +  +      +   +   +      +   +  + +     + +    +  +   +    +  +       +     + + + ׋܅ہ҄stnihgbXVNQ{ImInFgAc;_8[6W4N1G*C+C(9 8.(%     + + + +   + +  + +   +    +        + +           +   +   +  +    + +  + + +  +  +  +  +         +  +   + + + + +         +     +  + +          + +      + + +       +   + + + + + +   +     +    +   + +        +   + + + +  + + +  + + + + + +  +    + + + + + + + +   + +      + +     &,"1/ +&((*-(+!+$2%2)5)6*@0@1E1B5I5J*"     +  +       +     + +    +  +     + + + +        + +   + +   +     + +  +    +  +  +      +  +  + + + +   +           +       +       + +   +               +             + + +  + + + +   +  +     +    +    + +      +   + +  +  +    +      + + + +    +   + +     +    + +    + + +  + + + + + + +  + +   +  + + + + + + + +  + +   + +  + + + + + + ً֙΄~{xyqkbc\YVtQpKmHjBb@g;X8T8G2K,C(<$1 01%%  + +  + + + + + + +  +      + +   + + + +    +   + +  + + + +  + +   +  + +  + +  + +  + + +   + + +   + +  +   + + + + +   + + + +   + +  +  + + +  +    +   + +  + + +   +  + +    +   + +  + + +  + +   +  +      + +  +  +    + + +  + +   + +   +  +  + +   +     +  + +  +  +  + +  +  + + +    + + + + + +     + +    (/+((,')'&),(.35=9?EG$I#K V$P%W&]%`+d(l(i+i,n,u6~7+t*m"N3    + + +    +  + +    +    +   +     +           +  +   +            + +     +             +       +          + +      +  + + +    +     +  +   + +  +  +     +        +  + + + + + +  + + +     + +   + +  + + + +    + +       + + + + + +    + +  + +  +      +   +    +߀}ہ߂~z}vlnkaa[WUOuFwGr>q@c ?ER N!R$[$X%X(],d*i0r.q.w7x3~4{-s%]?'    + +                    +     +       +            + +   +   +  + +   + +               +                +         +     +  + + + + +     + +    +  + +       +   +  + +  +       +  + +  +  +    + +      + + + +  + + +    +  + +  + + +        +   + + +   + +     ل~w{vqnmia\SWPOyJjBm>gAh9T9V6N1K)I->$;#4//)   + + +        +  + + +    +  +        + +           +    +  + + +  + +    + + + +   +  +     + + +      +     +        +     +  +   +  +    +   + +  + + +   +   +  +  +     +  + + + +  + +  + +      + + + +  + + +  + +  +  +   +  +   + +   +   +         + +  + + + +   +    +   +(* 2 ) (%&))')!+*"0%1&7&809/93E/B4D7G;S=W>UCTBcC]FgOgPrTuZZ|_~^wVoP_>C+$    +      +  + + +   +   + +     +         +   +   + +     + +  +  +  +   + +   +           +  +       + +                  +  +      +            +             + +   + + +  +   + + +       +         +          + + +   + +    + + + +      + + +    + +   +        +    + +  + +  +   +    +   +  +  +    + +       +   +  +  + + +   +   + ږۚܓߓՍ΄ЈŀtoslkgY[ROuMlIkDeAb9X9W2Q6K-A+<(7'0".))#  + + + + +  +  +  +  +  +  +  + +    + +   + + + +       +  +     +   + +     + + +  + +  +     + +     +   + + + + + + +     + + + + +   +  +  +  + + +  +  +   + + + +   +      + +    +  +     +  +   + +   +      +  +    + + + + + +   + +    +  +  + + + +    +    + +    +   +       *-)&)&')#''+,//3:<BCI#K L$S"P"]'\'_(`+d+d1o/v1|4{62w-l%O2             + +   + + + +     +        +         +  +   +     +   +    +  +      +    +  +    +         +  +         +   +       +    + +  + +  +   +   +    + +    +       + +  + +  + + +  + +  + +     + + +  +     +  +          + + +   +  +  + + +   +   + +  + + +  + +    + +   +  +  + + +|݅Ղބ܉րzrmskdf^]UTJvIvAqFc9`;^:M5P1E*D&D%6&5 5*)%   + + + +  +  +   +   +   + +    +       +   +    +    + +  + +     +    +  + + +      + +    +                 + + +   +   + +   +    +   + + + +     + +  + + + + +  + + + + +     + +  + +  + +  + +  + +   + +  + + + +   + + + +  +  + +  + + +      +   +   +        + +  + +  + +)!/!,+(-$#( % (#* +#2%1&5';,>1B.E0I4K:Q8NDW?YAaIaGhIaOlQnSuZzad~]xZiKJ3/  +  +       + +    +      +  +  +     +     +  + +        +  + +      +     +   +  +       +  +        +     +    +              +      + + +  + +   +     +   +   + + + +     +   +   +  +   +   +          +  + +    + +     +   + + +  + +   +  + + +   + + + + + + +  + + +     +  + +  +     + + + + +   + +  + +  +  + +  +    + + ؒܗݚٗړ֐҇҅}{urhgcXVSTsOnOgIf@^AX:P7O0L-C.@)9'0".,)!        +   +  +      +  +  + + + +  +      +  +    + +    +   +   +  +     +      +   +  + +   + + +  + +    + + +  +    +  +   + +  +   + + + + +   + + +         + +   +   + + + +   + +   + +  +        + + +  +  + +   + + + + + + + +    +      +    + +     + +    +      + +     '*,/)*'%,)*(-241:=A>ALN"M%R'T$X(]&a.^*j-k/q1p2/5{0w(_G+ +   + + + +       + + +      + +  + +    +       + +     + +    +    + +          +   +   + +  +  +  +               +    +        +                 + + +   +  + +    +  +   +    + +    +  +    +   + + +  +   + + +     +    +  +  +  + +  +   +  +    + + +    +   +  + + + + + + +  + + +   +  +  +     +      ~xuqofn^bX]PV~NvG}IiFm>b?]:P8U.M.K*D';&7"/-)$   + + + + + +     +  +    +     +    +   +   +    +   +   +    + + +    + +    +  + + + + +       + + + + +      + +  + +    + + +   + +     +       +  + +  +             + +    +  +  +     + +      +  +   + + + +  + + + +   +   +  + +    +  +  + + +       + + +          + +  + + + +  +    &-!0. *) '%( ',, .%2$3&3(9)<.=2?1F6L6M:S@P?U?]B[F_EiQiUnVs[tV[}Z{\rPYF?.% + + + +     +      +     + +   +   +   +  +   + +  +          +   +   +        +   + + +     + +   + +      +      +       +          +     +                + +   + +     +    + + + +         +  + + +       +           + + +   +    +   +       +     +  + + +  +  + + + + +     +  +  + + +  + + +     + + + +   +  + + +   ֌ەۑяɅˀxskhkc\TS{MyQtIlHe<^>X7T8Q5J1E/>'=(4"- -'    + + +      +  + +  + + + +  + +     + +  +  + +  +  +  +          + +    +  +  + +  + +        + +    +      +       +    + +  +  +  +  +  + +  + + + +  +  + +    +        + + +   + +  +  +  + + + +    + +  + + + + + +   +  +  +  +  +    +  + +  + + +    +    +  + +     +   + + %--0*$$*'+--.2/8:<@H D!L"MM#U'X)Z(]*e(f,n*h.s2s6{81-m(U7 + +  +  +     +      + +  +   + + +   +     + +  +  + +      + +            +   + + +    +   +    +   +     +        +     +      + +    +  +  +          + + + + + +  +   +  + +      +       +   +   +     +          +    +          +         + + + + + +   + + +      + + +      + + + +     +    + + + + + + +  ݃ىцwxssb^a_XST~GIsJrBmBa:c6O4N0J*G*B'B&8$1/ ("   +  + +  + +   +   +    + + +      + + +  +    + +  +    +  + +  + +     +    +  +  + +  + +       +    +    + +    + + +          +  + +  + + + +      + + +  +           +    +  + + +    + +   + +    +  + +  + +    + +  + + +     +  + +  +  +   +     + + +    + + +   + + +  + + + + +    + , .+,'%' & %* , . ."1'5&4+5)<+B4H3F6B;O:O>W?VA\J^GbFeTlQvRnU_w_`~`kJO85" + + + + + + +        +  +   + +   + +            + +    +        +   + +  +  + +    +      + +    +  +  +      +  + +             +   +          +         +     + + +    + +    + + +         +    + +  + +  +   + + + + +  +  + + +       + +      +    + +   +    + + + +  + +   +   +   + +   +      +    + + + +  +    + + + + +    ؐܘݐՍЅÆwusojk`[~U}OvOyInIgAi?\9R6P3N/E*E*8&9$0+)#   + + + + +  + +  + +  + + +    + +      + + + + + +   +    +    +        + + +     + +    +    +   +       +    +  +  +  +  +  + +  + + +     +  +   +   + + +   +    +   + + + +   +    +   +  + + +  +  + + + + + +   + +   + +     + + +  +    +  +   + +     + + +  + + + + +     +  +    +  #+.--($(&*(&,,.267ADC!G!J!N#S#W#\(^'_*e*f-n3s0x3x3}2,w&fG, +      +    + +        + +    + + +       +  +       + +    +    + +     +       +   + + + +    + +    +   +      +            +        +  +     +  + +  + +     + + +  +             +    +    +   +  + +  +  +    + +      +  +   + + +       +    +     + +  + + + +  +    + + + + +   + +  +  +   + + +  + +   ށ~xxtslm`Z^WNLxHrFmClDfA\&6 1#2.%    + + + +     + +     +    +        +    + +    + +  + +  +      +   +    + +     +   + +  +    +  + + + + +   +      +    +   +  +   + + + +   + + +  + +   +  + + +  +   +  +      + +   +  +  +  + + + + +  +  +     +   + +   +  +   +  + +  +  + + + +    + +     +  +    +  + +   %,.#) ,%*''(',"-".&1%3(7(:-=*B4J6K5P;I=S@ZCYJ[B]OdJhSsQuZz\z]~]y\tRYJD/' + +  +      +   + + + +     +     + +   +    + +  + + +    + + + +          +       +   +   +     +       +  +            +               +           +     +  + +   + + + +   + + +  +  +    + +   +  + + +   + +   + +  + + + + + +  +        + + + +     +  +   +  + + + +     +  + +    + + + + +  + +   + + + +   +  + + + + +  + +   +    + +ؚ۔ۋԉ{pxljbeWU{R~QrJjHr?fBb;W:N2J2G.E);)4%3".%    +   +  + + +  +   + +       +      + +     + + + + +   + +     +   + +    +   + + + +  +     +      + + + +  +    + +   + +   + + +  + +  + + + +  +  +    +   + +         +     + +   + +   + +   +  +   +   +  +    +  + +  +   +  + +    + + + + +       + +   + +  + + + +   + + (/,-)%(+'('*0/26:>BGFNR#UQ$U&Z(W)e,d+l/p/w2x8~3/*j$U:#         +    + +  + +  +  +      + +      +     +  + + +    +     + +      + +    +    +        +              +    + +      +         +     +    + +   +    + +  +  + +  +    +   +  +    +  + +     +   + + + +      +   + + +       + + + +   + +  + +    +  + + + + +  +     +  + +   + + +     +  + + + +    +   +  + + + + + z{uqjlh^XVSL{KzKn@p?l8_:Z5T3M+I*A*B%>#2 -+' +   + + +  + + +       +   +      +        + + +       +  + +      +   +    + +   +  + +     + + + +   +  +    + + +  +  + + + + +      +    +     +  + + +   +  +   +     + + +    +   +   + +  +      +   +     + +    + + + + + + +   +    +    +    +   + + +  +  + + + +    + + + + + + + + +    +  + + +   + + +  + + + +  ,/ , ("&' '*)+ .#+#*"1$4*6*>.=2=1F4D6M9I:O@S>UC_GbIfGgKpQoSqW{^z]_z[oIR85' + + +  +  +      +   +   + +        +      +    +             + + +   +   + +   +            +   + + +      + +  + +   +  +     +  +         +         +   +          +  +   +        +     +           + +   +  + +  +   + +  +           + + +  + +    + + +       +   +    + + + + +      + +   + + +   + + + + +  +   + +  + +  + +     ܒ؊yǂytrqmf`]WSJ{MpKmAiAW>Y;U5N2H*@';':!4 1*%   + +   + + +  +   + +    +    +    + +  +  + + + +  +      +   + + +      + + +  +    + + + + +  +  +    + +  + +  + +     + + + +  +    +  + +  +    +  +   +   +  + +  + +   +         +  + +   + +   +   + + +   +  + + + +     + +  +  +       + + + +   +   + +  +  + +  +  +    +     +        +   +  +  + +#*,+'')(&%***-649<>=FM"H!L'R&U%W*\%b(d*l-j-l1y3z3~43u(e!N2           +  +    + +   +       +  +   +       +  +    +  +  +      +  + + + +   +     + + +         +  +                          +        +     + + + +    + + + +   +    +  +    +   + +  +    +  +  +  + + +      +   + +  +    +    + +  + +    + + +         +   +        +   + +  +    +  + +  + +    އ}߂߇}~|ppda\_XQ|L{M|HqHp;j>]9T9T0Q.L,F)=*8"50'$!   + + +    + +  + +  + +   + +        +    + +  +  +   + +     +  +   + +  + + + + +   +   +  + + + +  + +   +  +  +    +   +  +          + + + + +     +         +  + +  + +     +  + + +     +   +  + + +    + +  + + +  +  + + +    +  + + +   + +  +   + +    + + + + +  +  + +    +   + +  + +  + +  + ",!,!,')%)&$*)!0#1&2'5*8*<-=0E0E4L9L;Q;RAV?XC`E^LfLiSpUyPwX{]~_ycx[]FD3*   + + +    +  + +   +     +  +      + + +    + +           +  +    + + +         +  + +  +        +             +           +          +     +  +    +       + + + + +  +  + + +  +  +   + + + +  + + +        + + +     +   +  +  +      +   +   +  +      + + + +   +      +  +  +  +   + +    + + +  +  + +    + + + +  +  + + + + ؏ܐ~{vokbd]aTPrJqEdCdA]?Y:R4K4J3D-@(3!1#-)(   +  + + +   + + + + +   +  +   +  +    + +  +  + + +  +  +   + +  + + + +    +        +    + + + + +     + + +  + + + + + +  +  + +  + + + +  + +  + +   +       + + + + +  +  +  + +  + + +   + + +   + +   + + + +     +      +  + +  +   + + + +   + + +    +   +     +  +   + + +   + +  +   + +  +   +   + +    (,.*+(,*(%+-*019:<DDA"K!H"S&R$V$Z(`)^,d,j)l0q26}12{,u)\B"  +           +     +  +   + +  + +       + +  +    +  + +  +     + +        +                  +   +   +   +             +                + + +  +  +   + +     + + +  +   + +   +    +  + +     +   +    +    +  + +  +   + +  +    +   +  + +    + +  +   +  +         + + + +  +    + + +    + + +  + +  +   ~ޏ~~xonbfc]RRMxJtFmAg=f9Z:S0O3M)B)C#@"3#0,)!  + + + +    +    + + +    + +  + +  + + +   +     + + + + +            +   + + +  +  +    +    +  +  +  +   +  + +   +  + + +      +    +  +   +        +  +    +  + +       +  +  +   + +  + +   + +  + + + + + + + +  + + +  + + + + + + +    +    + + +  + +   + +     +   +   + + +  +  +     + +   +  +   +   +    + '0$+!,).)("%!(("*!+"2%5'6-<19.@2D7J8J6Q:XAU?V@XB[HgNfHpY|SxZz_^eYqTX:5(  +   +   +   +       + +  + + +   + +  + + + +      + + + +  +    +  +    +  + + +  +   +  +  + +   +      +       +     +     +        +     +              + +   + + + + +  +  + +  + + + + +    +     +   +  + +            +   + + +   + +   +        +     +  + +    + +  + +   + +  + + + + + +  +   + + +         + +  +  + + ߙܔމӈx|sle`Y\X~KzMrMiC^@\@X8T9L2K+@*>%=&1!0&&"   + +     + + +     +   +  +   +  +  + +  + + + + + + +    +   +   +  + +    +       + + + + +  +        +  +  +  + +   + + +  +    +    + + +   + + + +   + + + + +   + + +  + + +   + + + +  +    + +  +       +   +     +    + +   +    + + +   + + +  + +     + + +  +  + + +    +  +    + +    +  + + #-53-(+#))'/./0467<@@"H H K R%X%V%X*]*b(d,p/n1r1~85},w,d"L7     +       +    +  + + + +      +  + +    +  +  +  +   +      + +    + + + +      +   +     +           +                   +        + + + + + +     + +  + + + +    + +  +   +    +       +   +    + + + +   +     +  +    + +  +      +    +  + +  +  + + +  +    + +  + +  +        + + + +   +  + +   +  + +  ߍށwzyml`bVVQQJvDmEi<^9Z7T5R/J/E,H+?$1 0-*!  + + + + +        + +  +          + +                + +         +      + +  + + + + +         +      + +  + +  + +   +   +  +  + +  +  + +     +  +      +  +    + +   +    + +        +   + +   +  +  + + +     + +    +        + + +   +  +    +    +  + +  +   + + +         + + +     +   &!,/ -*('$"+(,".-"/&6(3$<*=.=.D3A4IO5O2G1E-?(;'0&10'#   + + + + + + + + + + +       +   +   + +    + + + + + +   +  + +  +     +   + + + +  +    +      +   +  +    + + + + + + +  +  +   + + +    +   +   + + + + + + +   + +   +  + +  +  +   +  + + + +   +  + +  +  + +  + + + +  +       +  +  +  + +  + + +  +   +    + +  +   +  + +   + +  + +  +  + +  +    + + + +   +   + $+--.'("**+)31254>>CCHL$K"S$W%Y*_*\+]-i+j.s7y7t4{70+t%S9  +     +          +   +   +  +     +      +    +            +   +  + +    +     + +     +        + +       +   +     +             + +       +  +      +  + +  + + +         +        +       +   +  +  + +   +  +    + + + +   +  + + +  +   +     +    + +  +        + + +   +ڂԃ|oyqik[VSM~OwGnEn>f:i[E]GiKaPdRpRtV`a]|^_hOS9.  + + +  +     +     +          +  +        +  +  +    +    +    +   + + +            +  +    +        + + +                         +             +  +     +    + +  + +     +  + +   +    + +   +    + +        +    + +    +        +   +    +  + +  +  + + +   + + +  +    + +    + + +  + + +   + + + + +  +     +  + + + ֔ޏˏΊā{wtrf_USRyMoHeA_@_>Z7W8K/J2B'=)5%+".'"    + + +     + + +    +   +   +   +   +    +     +  + +  +  +    +  +        +   + + + + +  +  +   + + + +      + +   +  +    + +       +  + +  +    + +  + +  + +  + +         + +  + +    +  +  +  +  + + +  +   +  +  +      +    +  + + + + + +        +  +   + +   + +  + + + +   + +    +    + +        %2/-),))-)()//49;@@HDJY"T$R$Y(\&b)b,h/e/r1p1y7{3~30|'hH,      +            + +     +  +        +      +     + +       + +          +  +       +       + +     + +             +        + +  + +    +     +  +      +      +  +   +         + + + + +       +  + +    +   +  +  +    +  +   + + +  +  + +   +    + + +    +  +     +    +  + +  + + +    +  ߑ{yvstkmc[[SyNsJuH^Ga<^7Y7U3N2G*B&9#6!0 ./&   + + +  +  +  +   + + + +  +  + + +  + +  +  +     + +  +    + +       +    + +  +  +    + + +    + + + +  + + +  + +  +  + + +  +    +               +  +   + + +    +  + +  + +    +  +   +  +   +    + + + +   + +   +  + +  +   +   +     +  +    + +  + +   +  + + + + + + + +   +      +  + +  +   +   + + +  + + + + + +  + + +  + +   + !'/#. +#(&& % (% ,#.."1$4%5*8+@1B3E7F7O7L=R@VBXB[G^NcJiPjOqVw\|`~c\}[uVaFA,' + + + + +     +   +  +   +   +  + +       +   +     +     +  +        +    +              +         +         +    +  +          + +  + +  +  + +   + + + +    + +   +   +  + +      +  + +    +  +    + +      +    +    +    +   +   +  + + + +   + +    + + +      +  +  +  +  + + +  + +  +  +  +    ً܍Ҁ}|vphh]VU{JmIbCb;\8X9K5J,D-?)8(8%+,!($ +  + +     + + + +  + +  +  +  + + +  + + +   +  + +  + + +  + +   + +       + +  + +  + + +    +    + + +  +      + + + + + + +  +    + + + + +    + +    +   +  +   +   +     +   +  +  +  +  + +  +    + + + +  +  +  + +    +   + +  + +  +  + +    +  + +   + +    + + +   +      +  + +   + +   + + + + + +  +  + #%.-+(&'),&+*.2526@?BF"H Q!U#X#V#^&d+f*e,p,k0t3w3|45z,p&V:   + +  +      +  +   + + +   +     + + + +  +    +   +   +    + +           + +      +       +   +              +        + + + + + +  +  + +    +      +  +     + +  +     +  +   + + + + +   +    +  + +  +   +       + + + + +       + +  +    +  +  + +       +      +   + +   + +  +    +  +   + + فyztlped`dTQ~LGpDk<`?Y5P2Q3L+D(@#;#5,)$!   + + +       +  + + +      +   +      +    + + + + +    +   +   + +   + +   + +  +  +       +   +  + + + + +  +     +   +  +   +  +  +  + + + + +   +     +   + +    + +     + +  +    +   + + + + +  + + + +         + + + +  + + + +   + +  +  +  +   + + + +    + + + +  + + +   + +  +  +  +  +  +   + +   + +    + + + +  %,0!1","))*'!('!*!- 4%2$6*<-:2?4>4D8E;J;LASDWAVG^JaJmJoNiQsUz\xY~j^VmPR;5& + + +  + +    +     +  + + +               +     +    + + + +   + +  + +  +    +      +       +            +        +     +              +    +  +          + +      + +  + +     + +  +       +  +      +  + + + +    +    +   +  + +         + +   + + +  + + + +  + + +   +  +    +  +   +   +  +   + + +  + + + +     ֈ֍Їχ||sqfbb^\T{LoFd>]:[7R2T5D.@(:'9$4-'$  + + +    +   + +  +     + + + +    + + + +   +    + + + + + +    +  +  +   +      +  + + + + +   +  + +    +  +   +  +  + + + +     + + + +  +  + +  +  +     +    + +      + + +     +       +  +   + +  +  +    +  +   + + +  + +    + +   +  + +  + +  + +  +   + +     +    +  + +  +  + +  + +        +    + +   +    + + &./'+('*(*+,-.568>DC JMI!U%Y'W$W&d'a)b-s/h0v4r04y64x&e"F. + +   +      + +  + + + +       +         +     +     +        +     +  +   +    +  +     +      +      +   +  +  +    +     +  +      + + +  +  +   +      +    +          +   + +       +     + +    + +      + +   + +      +  +  +     + +     + +    + +    + + +   + + + +    ݌v{rqlrda\YSTK}GhBk;X9S.P1L(F,>&8#66)(! + + + +   +     +       +  + +  +   + + + + + +   + + +    + + + + + +   +    +     + +   +  + +     + +  +    +  +   +  +      + +      + +   +  +  + +  + + +  + +              +  +  + +  +   + +   + + + +      +       +  + +  +   + + + + + +   + + + +    +    +   +  + +    +  + + +  +  +   +       +   +  +   +  + + + +      + (+$1#+-( (, $)1 -"-%3$3*3(50<3@0D5I1O5I?SADIK"M"P%T&W)]&])a)d-j/m449740p'U9"    +  +          + + +       + +   + + + +  + +       +    +                       +   +    +  +    +   +         +    +    +  +  +  + + + +     +  +       + +  +  +   + +      + +    +    + +  +      +    +      + + +     +  +     + +    +  +    +     +      +    + +  + +  +   ދ݀ԃ؄zwqgaa[[UKH{MxKlB`:Y4N/E+I-=&9&7%0+'   + + + +  + +   +  + +   +  +   +     +    +     + + +  +   +  +  +     +   +      +   + +    +  +   + + + +   + +   + + + +   +     + +   +  +  +  + +     +     +      + +  +         + +  + +  +     +  +   + + +  +     +   +    + +  + +  + + +    +    + +   +  +   + +  + +      + +  + +   + +   + +   + +  + + + + + + +  + + +    +   )* -"-,"-!) +#)*--"0$1&3&4+:)9-E.?4B3L9Q8PUCZIaIbNeNjLsXsY|_{`beZiQY<;'     + +      +   +  +    +     +    + + +          +    +  +    + + + +     +             +       +              +     +                 +   +   +  + + +  +   + + + +  +  + +  + + +   +   +  +  +  +     + +      +            + +   +   +   +  + +   +    + + +  + +  + + + + + +             + +  + +  + + + +  ݍ҄Ά}vofnl^VZQUwGxFc=[8P4G/>/C*7$3!,)%#  + + + + +  +   +  + +    + +  +   +   +   +   +   + +  + +  + + + + + +       + +       + +  + +  + +    + +  +    +  + +  +  + +  + +    +  +  + +    + +    +   +  +    +   +  + + +   +        +  + + + + + + + + +  + +  +  +    +  +  + +     +   + +  +  + +  + + + + + + +   + + +   +    + + +  + +  +    +  +  +    + !-2/,(()(-)+1-16:@BD!EM#I#S#S&Y&c"\(`+h)l3q3n7u4632)n U2 +     +  +      +         +    +  +  +  +    + +   +      +      + +  +        +   +    +                             +  + +  + + + +   + +     + +  + + + +  +                + +     + +      +        + + + + + + + + + + + +       +    + + +  +  + +    +  +         +     + +  +  + + +   ߆ڀ~~qyhiehc\^VM{LHxMsEf;R3O/G(?&;&6#2*&'  +  +  +  +    +   + +      +    +  + +  +    + +        +   +          + + +           +     + + +   + + +  + +     + +  + + +    + + + +   +  +   +   + +   +        +  + +   + + + + + + + + +   +  +   +  +   +  + +    +    +  + + +     +    +  +  +  + + +   + +    +   + + + + + +      + + +  + +    + +  + + + + +  + + + +  + +   +  +     + + '1%/$.!*-!+-, , +#.!/%7'4)7);+=/@4I7F6K;T9T>SD[?Z?]JhMjMnTq[uR^]_h|TfKH7- + + + +           +  + + +  + + + +     +              +    + +   +                +      +   +      +     +  +   +     +                          +  +   + + +    +   +      +   +         +     +  +           + +  +  +        +    + +  + + + +  +  + +          +    +     +   + + + + + + + + + + + + +    + +  + ݐߍފفƀxprnhddZWR~U|MvGnDd<_7P2H-B)7&3#/'$#   + + +  + + +    +    + + + + +    +   +      + + + + + + + +   + + +     +  +   + + +       +  + +   + + + + + +  +  +    + + + + +  + + +  +  +        + +   +  + + + +      + + + + +     + + +   + + +          +  + + +  + + +   +  +   + +  + + + +  +  + +  +   +  +  + +    +  +    +  + +           +   +  + + +   + +  +    )-.)+)((*+++/138A=>EK"F#K$M&X&S%`+_'i,e*i/n2y627}5-w'a?" +   +    + +   +   +  +  + + + +  +   +  + +  + + +   + +          + + + +      + +      +  +       +        + +     +       +   +     +    + +   +  + + + + + +  + +  +  +    +   +         +     +   + +        +    +   +   + + + +  + +     +    + +      + + +      + +  + + +   + + +   +  +  +  +    ك{xxvokja^aRXIOL|Eu>j:`:a6O/D&;&:"40+$    + + + +  +     +              +     + +     + +  + + +  +     + + +   + +     + +   + +     +  + + + +  + + + +  +   +    +   + +     +      +    + +  +     + +  +   + + +    +     +   + + +  +   +     + + +  + +    +  +  + + + + + +  +   + + + + + + + + +  + + +  +  + + +  +   + + + +   +    + +    +  +  +  + + + +  + +  + +   + + + + + +  + $*"1 -!,-() )+ ("++!2#4#6%8)9.?.B2C8I8R9OBVETD]HdE_PjIoRqM|YvXz``g^}RZE8( +      + + +         + + + +   +  + +     +      +  +    +  + +   +   +       + +  +    +  +   + + +   +  + +    + +   +     + +  +   +    +           +    +   + + +  +    +     + +   +    +    + +          +    +   +    +   +   + +      +   + +  + +       + +   + +   +  + +     + + +  +    +  +   + +  +  +   +    + + + +ޘԒ҈҄рzrlgi\[[~U~W|MrFhFeDb?a9V-G*<*7$.!,&&  + + + +   + +  + +  + +  +   +   +  +    + +   +       + + + +   + + + + +  +  +  +  + +   + +   +  + + + +  +   + + +  +   +   + +    + +    +    + +   +  + +            +   +     + + + + +        + +    + + +   +   +  +  +     + +      +  + +   +  + + +  +  +  +   +  + + + + + +    +  +    + + +  +   +  +      +  + +  +  + +  +      + #.2+(&'')')*0.86;=D EK!DL N$U'W$\%^(d*f-m.o3n2z6864x.q$X5   +     +    +          + +       +   + +     +  +  +  +     + + +  + +      +      +  +    +       +              + + +  +  +   + + +  +  +   +  +  +  +  + + +         +    + +    + +  +  +          +  + +  + +    +  +     +     +      +     + +   +   + + +    +      +  +  +  ׄwxxqsqic^[\WN}NwH}Fo@g-9.C9A5I6M8Q=W;T?WJ_BdFhKiRlXlWy\yZ`bdvbgPI7+  +  +     +  +   + + +   + +   +   + + +  +  + + + +     + +  + + +   + + +    +   + +  + +     +           +     + +      +   +    +       +       +     + +  + +    +   + +  + +    + +    +           + +  + +      + + + +     +   + +  +   + +  +    + +  + + + +   +  + +  + +  +         +   +  +        +   +  + ݒۈρІvupkhdXVQQzQoMrEkD_@iRDFN!M"T!X&Y'\&b+\-f+m,r1r08|8:4-l&P7 +          +   + +          +    + +    + + +  + +    +    + +  +   +         +     +     +   +            +           +      + +   +    + + + + +  +    + +    +  +    + + + + + +   +  + +   + +  + + + +  + +       +   + +   +   +       + +  + +         +  +       +  + +  +   +  +  +    ؄xlkdaccY\NJNwFyFo?h<^;\4W1S2S.K(E*: ,#  + +   +  +      +   +      +   + + +          +       +     +   + + + +   + + +         +   + + + +  +  + +  + + +    +         + +   +     +                       + +     +      + +  + +  +  +      +       + + +        +   + +   +    + +  + +    + +    + + +  + +   +  + + +  +  + +   + +  +      +   +  + +    +  + %!.", +.!))).*!/$/%0$2*7(;'<0=.c;W3W1G0D-?)>&@!7!$    +  +  + +  +   +  + +   +     +  + +  +  + +    +  + +   + +  +     + +        +     +     + +    +  + +     +  +    + + +   +  +    +           + + + +    + + +   + +   +  +  + +   +   + +  +       + + + + +   + + + +       +       + + +   + +    +       +  + +  +       +         +    +    +  +   + + + +     + + +  +  +   +  )*-*#*+&*+!-!, /!-#5(5)<*=+?1A1E8F9O7R>V?VA]EaKdJjTnPqWtV|Va_c~`}U_HC,' + + + + +          +    +  +  +     +       +  +    +  + + +        + +      +  +   +      + +  +  +       +      +    +      +      +  +       +         +  + + + + + +     +  + +   +     +    +  + +   +    + +  +   +  +  + +               +   + +   + + +  + + +   + + +  +  + +  + +   + + +     +   + +   +  + +  +  + +    +ۉ҂Ɂ{{lrj^ZZV~TRuHpEmEgE]?]:\(9*=".&  + +   + +  + + +  + +  + +    +   +  + + + + + + +  + +   +  + +  +  +  +     + +   +  +  + + +         + +  +       +   +   +  +   +    + +   + +  +    +    +   + +     +       +  + +  + + +  + + +      + +  + + +    + + + +   +  +  + + + + +   + +    +   +   +   +  + + +  + +  + + +   +    +          + + + +   +    +   + +     +  +  + + + +0.,)))+-'/..376<?B!EMN!U#V'X$Z(]'c,\*l-o0f2y57~51*x(Y?"           + + +   + + +       + +       +  + +       +     +          +  + +      +          +       +           +   +  +   +   +  + + + +  +            +   + + +  + +    + +      +   +     +      +     +    + + +    + + + +      + + + +  + +     +   +     +  + +  + +    +    + +   +   + +}ˀuutnkcbZTRRLyGt?mCk;`=^9Y8P/O2H+B%@&=&8!6/ +  + + + +   +  +   + +    +    +  +          +  +                +     +   +    +    +        + +     +  + +    +  +     +       +   + +  +  +  + +   + + +   + + +   + + + + + + +       +    + +  +  + + +    +      + +  + +   + + + +  +  + + +            +  +    + + + +  +  +   + + + + + + + + +  +  + +    +  +  +     + +     '/!.!*(&#* , (, '!+!/#3*6(:,;+=/@/D8F8G9P:M=UB]CZFfOeHkOlQqWx[{Z]|cf`mQ]=7&  + +  +     +       +          + +  + + +      + +   +     + +  +  +   + +   +  + +   +    +   + +            +   +   + +   +   +   +             +    + +  + + + +  + +  +   + + + +   + + +   +    + +        + +  +  +   +          +   +     +      + + +  + +     +      +  + + + + +     + +    +  + + + +   + + + +   +Ҍ}}uuim`caUWPtPnGrFhA\?_=Z6R1O.F/C+;'9'57"1" + +  +  + + + +  +  +  +  +      + +      +  + +  +   +      +  +   +    +  +  + + + + +   + + +    +    +  + + +    +   + +  + +  + + + + +  + +    +  +  + + + + +   +  + + + + +  + +   +     + + + + + +  + + +  + +     +  +   +  +   +     +    +    + +   + +    + + + +  + + + +    + +   +    +   + +  + +   +   +          + +  +  +   + !(.'-*&)$'+.0-/5:7CCG"F#I J T$S'T(`'[-b*j,e.y4l3x556/})k I/     +    +  +   +  +    +   + +  +    +     +  +  +  +  + +   + +   +   +  +       +   + +  +   +        +     +       +         +    + +      +    +    + +     +   + +     +       + + +   +  +       + + +     + +  + + +    +   +         +      +  + + +        + + +            + + + + +  +  +܄Հ{vsniicc[`RRL{PtJi@k@b8_9O3R4O.G)I#=*8#9 6 0,(  +       +      + + +       +   +  +       +                 + + +   +       +       +   + +  +  +  + +   +  +  + + +   +  + + + +  + + +            + +    +   +      +  + +  + +    + + + + +   +    + + +   + +  +  + + + +  + + +  +  +    +  +    + +     + + +    +  +    +  +  +   +  +   + + +  + +   + +   + +  +   +  + + +   + +   +  +      +   +/#3!+(()"*,, ,"-#.#5#8'7(@+@1G4D2K5NS3T1N.F-A,@&6"2&1$1)-     +   +  + +   +   + + +  +  + +     +  +   +  + + +  +     + +     +    +  +  +   + + +  + + +  +    + +  + + + + +   + + + +     +       +    +  +     +   + +  + +  +   +  + + +  +  + +  + + + + +       +     +   +  + + +  +  +   + + +   +  + + + +  + +  + +   +     +  +     + +  +  +   +    +        +   +  +      +  + +  + + +   + (,.0++&()'',+536::>FF!NM"N"U%V([(d'_+e*o/r0m2s5}764~1y'] B#    +  + +  +                         + +   +  +    + +      +    +   +   +    +           +          +         + +    +  + +  + +   + +   +        +  + + +      +   + +            + +     +     +       +   + + +  + +  +  + +  +  + +     +    +   +    +      + +     + +    +    +  +   +ۀy{zvrlfe]Z\XRKxGkEn>h?a=\9V1O0M,K(D(?&:%6%20)')& +   + +   + + +     + + +        + +         +  +       +  +  + +  +   +  + +    + +  + +      + + +  +   + +   + + +    +   + +   +        + +   + +   +    +   + + +  + + + +    + +   +    +  +      +    +    + + + + +  +         + +   + +  +   + + +  + +  + +   +      + +  + +  +  + +       + +   +    +   +  +    +  +  +  + + +    +  )-!1%0"- +)%)*,!*/%1'6$2,7.;)A0E5F4M6OAQ?Z=YI^G`GcLfMkNsXrY{[^f{^^qS[@?(!  +   +         +  +  + + +       +      +  +        +  +  + +         +  +    +       +   +     + +                +     +  + +   +     +  + +     +  +  + + + + + +   + +   + +    +   +   + +  +  +  + +     +  +        +  + + +  + +  +     +  +    +   + +     +  +    +  + + +   + +   +   ڞ֎׌ф|wxqomgiaYXvNkHiFeEb@Z?a7Z7M6N0F/E)<+9*5%4+'#')$ +   +  + +      +  + +  +  +  + + +   +  +  + + +  +     +   +  + + +  + + +  +  +  + + + + +    + + +  + +  + +    +  + +  + +   + +  +    +   +  +  +  + +  + + + +  +  +  + + + +    +  + + +      +  +   +  + + + + + + +  +  + +  + +  +  +   +    +  +  + +  + + +        + +     +    +  + + + +        +  +   +    + +          +  +  + + + +  +     + (-2.-/&'',,,.067=<AEH F!F"U#T'W(Y&c+`&`)h,p0v5}5061|&p!Q3     +     +            +                +               +   +          +       +    +     +         +   +  +  +    +  + +   +  + +     +   +    +  +  +              +     + +  +  + +   + + +      + + +   + +    +  + +  + +          + +           +  +   + + + + +  ځ{zotmebbZWWRMsJj?n>h;f=_:^8U2I,J0E+A&<"9!0/&% $$!  + +      +  + + +               +  + +     + + +   + + +  +  +  +   +  + +  +   + +    +  + + +  +  +          +  +    + +       +     + +    + +   +  + +   +  +  + +     +  + +     +   +   +    +   + +   +   +     + +  +     +  +      + +    +  + + +   + +  +    + +   + +    +  + + + + +   +  +    + +   + + +  + +   + + +  + +    +   +     + +   +   '/ ,#+ +)"')(#-"1$,&5#6!2-:&?-:.A2J9I2K8G=N@UF_ETNeHgOjKkXjTuX_e_byXbLQ7." + + +         +     + +    + +         +   +  +  +    + +  + +     +             +     + +        + +              +    +   +    + +  +  +  + +    +  +  +  + +  +          + + +           +    +  + + +     +    + +  + +   +     +   +  + + + +  + +    +   +    +       + +   +   +  +  َ؃ʊ΄}swqlbjaYWTuMnIhKdGaDa>\6R0G0H3B+>)9'4"/!-*$##$"      + +  +  +   + +  +   +  + +   + +     +  + + +     +      + + + +  + + +     +  +    + +    + + + + +    + +  +   +  + +    +       + +  + +   +  + +  + +  + + + +  +  + +    +    +   + + +   + +    + + +  +    +    +   +  + +    +    +  +  +  +  + + +   + + +   + +  +  + +      +    +   +  + +    +  + +  + + +  +   +   + + + +  + +  +    + $+,,.*&,)%(..461=<:JCH!M!N"R&V&[)Y(d+e+g2l1q6u6y8}46/t,f!G-     + +    +      +       +       +   +  +                   + + +          +       +          +  + +       +    + +      + +      + +  +    + +      +   + +     +  +  +  +      +  +  +  +   + +         + + +  +       +    +   + + +  +    +   +  +   +  + +       +  +    + + +    +  +         +      + + +܈Յ|~vmkhfg_`XSL{=sDp@k>i?g;V8U/K.G-I%D&<#<5,+%#$#"(   +  + +   + +   +    + + +  +  +  +   +  +       +  + +   +   +   +  + + +  + + + +  + + +     +  + + +  + +  +  + + +      + + +    + + + +  + +  +    +  +  + +     +  + + + + + + + + +  + + +    +  +  + + + +  + + + + +   + + +  +      +   +   + +   +   +    +  +   +   + +       + + + + +     + + +  +  +  +       +  +  + + + + +  +  + +      +   +  +" 0",#.,,+ ( ((".!+#/$6#3'8*4,?-@3F8G:L5H>Q;S>[C`I`E_IhKjNoU|Sx\|`dcdsU_DB1# +  + +   +   + +    + +     + +  +        +    +     + + +  +        +     +   +       +  + +     +   + + + +              +   +               + +     +   +  +    + +   +     +    + + + + + + +  +  + +    +   +       +           + + +   + + +   + +  +      +    +   +    +  + + + +     + + + +  +  + + + +   + + + + + +  + +  ٔՐԌԉăˇ}ppiic_[Q}QrOnJuHlHa>d?Z5O2J0F.A);+=': 3!,)'&!#$$  + +     +  + + + +  +  + + + + + + + +  +   + +        +     + + +    +  +    + +  + +   +  + + +    +  +  + + + + + +  + + +  +    +  + +   +  + +    + + +  +  +        +  +  +  + + +  + + +   +   + + + +  +     +  + + + +  +   +  + + +  + + +    + + +    +   + + +  + + + + +   + + + +  +  + +  + + +    + + + + + + +          + + +  + + +      + +   + + +  + +  +    + + +  (1//'*!)(+,.+317:F=HC"K#N!T$S#](V%a*c)l.o0t1r2n4:66},o%S:       + +      +  +      + +        +  + +     +    +  +   +          +   +                   +    +    + +     +    + + + +       + +  + +  + +   +           +  +    +       +    + +      +   +  +   +   +         +  +         +            +     +   + +  +     +  }~wwxng^]aTVVLIvCqHi?i>d;\2T5I0G*?(A$<&8!50,'#$#!#+! +    +         +  + +  +      +  + + +   + +     + +     +   + +     +    + + +  +  + + +  + + +   + +      +   + +  +  +  + +      +  + +   + +   +  +  + +   + + + +   +   +  +  + + + +    +  +  + +      + + + +  +  + + + + +  +    + + +     + +   +   +  + +      +   +  +   + +    +     + + +     +   +  +   +  + + + + +     + +     + +  + +   +   +      + +   + +  (1!/"+, +. -,,!+!-!,$.+3&8*7->/A3C5D:M8P=O;XDYEaBaJgNgNmOoT}Xr^e_a^oTQ<3" + + + + + + +    + + +         + +  +  +     +       + +   +   +  + +       + +        +     + +                  +      +     +            +  + +       + +       + + +  +   + +  +    +     +  +   + +   +    +     +  + + +  + +   +  +   +   +  +  + +  + + +            +  + + + +  + +   +  +  +  + + + +  + + +     ސُՉЈςyw{omjgY]V}NxQwNuJhJe>^@P8L4K2@3E,>(8)6%3 -,##!! $$&  + + +  +  +   +  + + +    +    + + +  +  + +    + + +  + +          +    + +       + +  +  + +  + + +  + +   + +  +   +  + + +  + + +            +   + +    + + +  + +    + +  +  +    +  +  +  +   + + +  +    + +  + + +  +  +        + + +    +        + + +  +   +  + +  + +  + + +   + + +   + + + +   +  +   + +      + +  +   +  + +  +  +   + +        + + + + + +    + +  !+.1.0+%'*'(./.45:>FI"MM#M$S&\&Y(])`)c*j,s-n-t5}0x:61&i"K. +  + +   +   +       +  + +                   +   +  +          +                  +       +    +    + +   +  + +   + +   + + +  +  + +    +     +      +  +  +   +   +  +  + + +   +   +   + + + +    +  +       + +       +  +  + +     + +  +         ނyq{yuokcf\VSN~N|QvGpBp@b;g4^6\.H/C)I)A'@$8"4"/&$"  "#)" +                +  + + + +     +  +   +  +  +   + +        +  +   + + +        +  +   +      + + +  +  +     + +  + +     +  + + +  +         +     + +  +  + +    + +  +  +     + +  +  + +  + +  +   + + +     + + + +    +  +      + + + +     +  +  +     +   +  +  +  + + + +  +    +  +    + + +       + +  + + + + +    +   + +        +   + +    %+!-,"+#)*)(.*!-#/%0&/)4+8-9,A.B4C8J:J3N>Q>W>`HZJ\JeOrTjV~Z|\}Zbfhv_bHH2, + + +             + + + +    + +   +            +  + +     +     + +      + + +  +  +     +                   +    + +       + +      +   + + +  +   +    + + + +  + + +  + + +  + +   + +    +  +     +     +   + +  +  +    +   + + + +    +  + + +  + +  +       + + +    + + + +    +    + +     + + + + +   +    ևՔЊԆ}vronee]TVRwMsJoHjD^FX';%60%#&  #%"%#  + +   + +   +   +   +     +    + +       +    +  +   +  +   +   + + +     +  +         +  +   + +    +  +  +                  +  +     + +    + +     + + +     + +  +    + +    + +  + +  + +  + + + + + +  + +         +     + +  +   + + +   + + + +  +  + + + +   + +   + +    +  + +    +       +  + + + +  + +    +  +     + +   +  +   +         %3"0!.!&+ &+%,",$/$/!5(7(4+9-?0C1I6K5Q=P:TAVB[F_H_HgIfQoTsSsY{]}_c~bz]mW]@7*  +      + +     +  +    +                   +   +            +     +          + + +    +   +  +        +   +      +     +     +  + + +  +  + + +   +     +    +  + + + +   +  + + + +           +  +        +    +      + + + +   + + +      +    +  +      +   +    +  +   +     ڑۏӄ́zutkic\[_}QPsNvKeG_@\:R5O4S0I2G0:+A(7%3 *&"# !!## %      +    + + + +     + + +  +    +       + + +  + +   + +  + + + + + +  +      + + +  +   +    + + + + + + + +    +  +    + +  + +   +  +    +  +     +   +    +   +   + +  + +  +  + + +  + + +  +    + +    + + + +      + +  +  +  +  +   + +   +    +   + + + + +    +  +   +  +   +  +  +   + +  +   + + +   +       +  +  +      +   +  #+20+))''*.-.3458:;AE!CJ N$V$S%X&a(c(d-i-l0r2t4t73=/+m#U 2     + + +   + +       +     + +   + +   +        +                +              +   + +   + + + +    + + + + + +  +   +  +  +    + + + + + +  +     +   +  +      +  +          + + +  + +     +  +  +   + +  +      + +  + + +  + +  + +    +  + +   +     +     +     ߊ~zwvjici`VURNxHzGqGn<`Q$9$21(&$$%' $#! !! !#   +   +  +  +      +  +     +  +   +    +  +   + + +      + + +   + + +  +  +    +  + +  + + + +  +   + +         + +  +    +   + +   + +   +     +      + + + + +   + +       + +   +  +    + + + + +  + + + +    +  +    + +  +   +   +    +   + + +   + +      +   + + +  + + + +   + +  +    + +  + +     +   +    + +  +  +   +  + + +  + +  + + + +  +  + +   +  +%+ *. + .%*'!+ . .!0'2$8,9,:.:.?6=5E2J8N:T?Y>XC[GdH`JgKiQgPnTwV_Yea|UfE@3& + + +  +     + +     + + +       +     + + +    + +  +  +  + +  +     + +       +    +     +   +  +                +  +  + +       +   + +  + +  + +  +  + +   +     +       + + + +  +  +  +  +  +   +   + +  +      + +       +  +    + + + +   +  +  + +   + + +  + +     + + +  +       + +  +   + + +  +   + +  + + + + + +      ޞԊލ̀{yljkia`YYKtPxImHiDg@_/B6@2DW;P7K5H2C*>&7%7&2 ),' #%& $#! !%# + + + + + +     +    +   +  + +     + +  + +     + + +  +     +    + +     +   +   +   + + +       + +    +  +  + +    + + +   +  + + + +       + + +  +  +   + + +  + +  + +   + +   +     +    + +   +   +   +  +    +  +  +      + +  +  +  +  +  +   +    +    +    + + +  +  + +      + +  +   +  + + +   + +    +   +  + +   +  +       + +    +  + + +  +    %)-.,&&(*(.*//265?>BE%I H!M"P%R(Z%c'c(e'e/t4s/v3y9466|-n"Q1  +   +        +     + +    +    +     +   + +    +     +                                  +     +   +    +   +  + + +  + +      +    + +   +      +      + + +      +    + +     +  +    +    +  + + +  +   + + +  +       + + +          +     +  +              ty}vnlgdd\[WTJzLqBpBi?i=c6V4S1R*L)G*<&7$;5+%$'%*#"  !  !!! #&    +   +   +  +  +  +      + +       +     +  +  +    +        + +   +   + + +  + +    +  +    +   +   + + +    + +   +  +   +   +    +  + +     + +  +  + + +       +   +  +       +    + + + + +        +  +  +  + + +   +      +    + +  +    +  +   +  + + + +    +    + +  +  + +   + + + +        +   + + + +  + + +   + +   + + +  +   +    +     +  + +'0 0!,,&+)+,$0 0"0$7(2'5'>,?,@3C2G8I=M9M;RH\EWDbAaHgQkRoUsRs\~]_^buUdGI3-  +  + +      + +   + +    +   +  +     + +    +  + + +    +  + + +       +     + +            + + +   + +    +    + + + + + +  +    +   +  + + +    + +   +    +  + +   +            +  +   +   +   +   +       +    +   + +  + + + + +   +   + +   +       +  +    + +  +   + + + +  + +  +   + + +  +    + ו̏ʅюÀyqnojca\WVGnOuKjF`>]=a5O2E2E.B+B'<)6#,!0*$" "  !$ #!""#$   +   +   + +  + +   +      + + + + +     +  + + +    + +   + + + +   + + +     +  +  + + +   + +   +  +   +  + +   +   + + +   +  +  +     +  +  + +       +   +       +      +   +    +  +  + +  +    + +  + + +   +  +    + + + + +   + +    +  + + + + + +    +         + + +     +      + + +    +       +      + + + + +   +               + + (/(.((()'*.,/.6;8;ELH"L P!P'W$U#W(_(f(l)o1l-x3x58~65{-}*b!D) +              +  +  +     +   +      +   + +  +  +              +   +        +          +  +   +   + +  +   +  +   +  +   +    +  +   + +              +       +    +    +     +      +    + +       + + + + +     + +  +     +  +  +   +       +߂}}wqxsfdb[\TOSzKtGmEm>kBZ>U6U3T.I+F)>%?%8$7 )+#%%#$#!"##  !!'!   + + +       + +   + + + +    + + +  + +  +  +  + +     +  +     +  +    +  + + +     +   +  +   +    +   + +             +       +  +     + +    +  +  +    +     + + + + +   + + +   +   + + +  +         +  + +  +  +   + +  + + + +   +  +  + +  +     + +   +    + +  +  + +  +     + +          + +  +  +        + + +  +  +    +  + + +    +  +  +  + + #)+!,* () ) *!*+ *!-%/#4(4%8+=-=4@4?5H6K4N:OCVCZF]BbM^KnNoRtUt^XbYZZsQ[C@)  +  +         +   +       +     + + +    +   + +    +   +  + +  + +      +       +  +    +             +                     +       + + + + +    +          + +   + + + + +     +  +  +   + + + + +  +   +  + + +   + +    + + +    + + +  +  +    + +  + +  + +  +     +  + +  + +  +  +  +   +  +  +      +ن܆ʃurkhd`\RQ}JwOoDiGe;_?\=X2M-H-A,@)9)5"2+&#"!!"  ! !   &  + +  + +    + +  + +  + +  +  +   + +  + + +  + +     +   + + + + +    + + + + +        + + + + +   +  + +    +  +    +       +  + + + + +   + + +  +   +    +  +    +   +   + + +  + +   + + +   +  +         + +  +  + +  + + + +  + + +   +  +  +      +  +   + + +  + +     + +  + + +   +   +   +          +     + + + +  +    + + + +  + +  +      + +   + +      "'/./)+'''+,(2746>BF!CHJ"I!\$S#b'[*^%d+g+g,r.n1z5{595y+q([8      + + +      +      +   +    +         + + +  +  +  +  +                    + +              +   +    +  +   +    +  + +    +     +        +  +       +      + +  +    +     + + + +   +    +    + + +     + + +    +        +     +   + + +   + +  +  +       + ߆~~ywvolk]^[VP~S}OvEy@g@i@^8\5U1L-N*C)B);'=#9-)&#&!  !""$!"!#    +  +    +       + +      +   +  + + +  +    +         +      +      +   +    + + +   +    + + +     + +          +    +     +  +   +  +  + +   +   +  +   + +     + + + + +    + + + + + +    +   + +  + + + +    +  + + +  + + +  + +   + +  +     +  +  +      +      +  + +   + +       +  + + +        +   +  + + + + + + + + +  +   +   +   + +   + +      %+*#( ,!'%*)*."/.#0(0)4(8,:+F3F2D7L:M;T@W?SGYI^DdPdJgToQsXxP\bec^kTO<0# + + +          +   +   + +     +  +  +       + + +       + +  +  + +    +           +  +  +         +      +       + +   +   +  +  +   + +  +      + +  +  + +    +  +    + +  + +    +       +     + + +  + +     +  +  +  +      +         + +  + + +   + + +  + + + +    +     + + +  + + + +  + Ί˂{xnokf\WZU{NvPvKkBbB\=\:T7L.J.H/A/>(8(1"+'%$ !!  ! ! !! $    + +    +     +  + + +    + +      +  + +   + + +  +  +  + + + + + +  + + +  + + + + + + + +     +  +    +   +  + +   +   + + + + +   +   + +  + + + + + +     +  + + + + +     + +    +    +  +   +  +    + +    + + + +   + +  +  +  +     + +  + +   +    + +  + +  +    + + +  + + + +   + +  +    +    +  +  +  +  + +      +     +   +  + +  +      +       + !,+,**#))),-4:259=>CF!IN!QV#Y$b'](b)i.i/m/o2~4y4742~(h"H' +     +   +        + +      + + +   +  +  +      +  +    +    +   + +    +   +       + +   + +    +  +  +  +           +  +   + +        +   +    +     +   +   + + + + + +     +  +  +  +  +  + + +  + + +            +   +          +   +   +      +       +׍|}zzslnddh^URTxQoGt>oCj?a#; :/*&$&$! !#!#!! !   " ##&    + +     + + +      + +   +        +  +  + + + +  +   +  + +  +   + +    +  +  +  + + +      +  + +  +    + +   +    +   + +  + + + + +      + + +    + +  +            + + + + + + + +  +  +   + +   +  +  + + + + + + +  +    +  +     +  + +   +  + +   +   + +  +   + + +  +     +  +  + +  + +    +        + +   +   +   + + +  + + +   +  +  +  + +      +  + + +    !))3* ('%),-* 0#0!1)1'1):->,A0E4E9N;J7R@S@XGZM]HbLcLpUoRzWx^~Z^c^zZfHG.' + + + +   +   + +  +   + +    + +    +      +    +  +  + +        +  +       +                     +   +   + + +      +      +   +    +  + + +  + +     +     + +   + +   +     +    +  +   +   +       +   + + + + + + +   +     + + + + + + +   +   + +     + +   + + +   +          ؖڈ؋҇DŽ~|vokg`\XT}TxMqIlGiEc=`>V2N5T3L.I,9(>'3"- -)%""  #! !"!!    !$$   + +  + + + + +  + +  +  + +  +  +  +   + + +       +  + +  + + +   +  +       + +  + + +  +  +      + + + + +  +      +    +   +  + + + + +  + +     + +   + +  + +  + + + +  +           +  +  +  +   +  + + +  +  + +   +    +  +  + + +    + +   +     + + +  + +     +   + +    + + +  +    + + + +  + +    + + +  +       +  +     +  +     +   + + + +      + + +     "*.+)(')*)...-4::9@B!ALLO T(U%V$`(\+g,h/k/t-z2z7067,s%[!:  +   + + +  +    +      +      + + +   +             +     +       +    +  +   +   +     +       + +   + + +  + + +   + + +   +  +     +           +     +    + +       +   + +     + +  + +   +  +   +  + +   +    + + + + +  + + +   +         + +      +     +         + ܍׃}y~nrmocgbSROLIwEo?n?l;]9S6S0N0D+E(C"> 6!-1*%(# "!! "$!" $#$    +   +  +  +  +  +   + +   + +  +     + +        +      +          + +   +   +  + + + +  +    + +   + +      + + + +    +    + + + + +  +  + +    + +  +   +  + + + +   + + + + +   +   + + + +  + + + + + + + +  + + + +   +  +   + + + + + +     +   + +  + +    + +  + + + + +  + +  + +  +    + + + + +    +    +   +    +    +  + +        +   + +   +  +   +  + +   +   +      +  %-, - ,''(',#) /!1&2'0*7(9.?,A2?5J5P8N8K@SBMB^EbCaQiKhLmXsT|[]bb_WhQVC7'  +  +    +  +  + + +  +  + +  +   + +  +   +    + + +        +  + +  + + +     +      +         +               +   +  +    +  +    +  +       + + +  +  + +  + +   +  +       +  +  +        + +   + +       + + + +         +       +  +       + + + +    +      + +      +    +   +  +      +  + ޑۊݎҎ~|zqlijc_V~VwSzQsKnJbDe;_9K9M1N9J0F,@(8#2#.#),'## "!!!!!  ! !!" + + + +  +   + +  + +  + +    +  +  +    +    + +   + +  +   + + +  + + +     + +  +   +   + + + +    +        +  +   +  + +  +  + +    + +   +   + + + +   +    +  + +  + + +    + + + +   + +  +     + +  +   + +            +  + + + +     + +    + +  +  + +   +   + + + + +   + +    +  +     +      + +  + +      + +   +   + + +  +   + + + +      + + +".,--+'*-((..568<;BAE$F"I!SP"W'[(c(^*f,r/o0u2w4}54501r"R3    + +       +   + +    +  +   + +    +            + +   +         +      +       +  +   + +  +     +  +   +  +         +     +  +     + + +  +   + +              +   + +  +     +   + + + +  + + +   + +    +        + + +     + +  +   + +   + +      +        ~z|x|rjik][VTQ}MyJvFnIqBc9`;Y5X0K0K-J+='?(;$2//(&# "! # $!! ! $  + +   +  + +  +        +      + + +  + +     +     + + +   +   + +  +  + +   + +  + + + +      +     + +    + + + + + + + +  + +   + +   + +   + + +  + +  + +   +  +       + +  + + +   +  +   + +    + +     + + + +  +   + + + +  +   + +     +    +   + +     +   +   + + + +  +   + +          + +   + +  +  +    +    + + + +  +  +   +   + +   + +   + +  +  +   +)/. .!,,** * +-"*$0%6)7(6+7/7-@1B4G6L8LBMDSAT?XI_JkJlIiQpSw[z^{`}afezZfJI;,  +    +        + +  +   +  +  +      +   + +   +           + +                 + +   + +  +   +  + +     +   + + +  +   + + +   +   +  +          +  +   + + +        +      +     + +  +   +   + +  +       +    +  +       + + + + +    +     + + + + +  +    +  +    +  +       +  ՖڊԆŀ{|tong`bTQ}PxMqIsLgDgD[<[DGF#L"P![$Y$S'[%b+d)f.g*j0u/y/|5;60x)b!I(                +            +    +     +  +  +    + +                +     + +      + +  +   + + + + +  + +      +  +  +   + +  +   +    + + + +  +       + +                   + +  + + + +   + +     + +         + +  + + +  +  +   + +   +     +  +    + +      + +ބف}vztmef`__XM{KEwEiEk>b>c9[9U2Z1I*E(:':&:!: .'$&" #! ""  !       !! + +  +  +   + +   +  + + +        +     +   +  +    +   + +  + +   +  +    +  +    +   +       + +  + +  +    + +  +  +  + +  + +       +   + + +            +        + +   +   + +   + +  + +  +  + +   + +  +  + +   +  +    +   + + +    + +  +  +      +   +    +     + +      +    + + +    +  +    + +    + + + + +   +        + +  + + +  +    + +    +  +  +  + "/// .+(&*(+-!,!-"1'6%7)8.;-?0C2C9K:K=OX;Z5V3N0<*;+B'7$3$.($$     "!! ! + #   +  +  + +   +   +  +  +    +    +       + + +  + +  + + +        +  + + + + + + +  + + +  +  +    + + +  + + + + + +  +  + +  + + +   + + +   + +      +   +     +  + + + +  +   +    +   +  +  + + + + +  + +  + +  +  +     +  +   + + + +  + + +    + +    +   +  +   +    +  +   + +    +        + +    + +    +  +    +  +   + + +    +        +  +   + +   + +  #-0,+)*&.-*.07234=?CJK$I V#R%X$b'\%d+b.n.o/s5t2z7}495/u'X;         +   +   +  + +       +      + + +   +  + +         +          +      + + + +  + +  + + + +   + +  + + +  +    +  +  + +  + + + + + + + + +    +    +   +   + + +    +      + +   +   +  +  +    + + +    +   +     +     + + +   +                    +     +  +~ҁՀvrhm`fbaSP}LuLvLrFpEr?k<_4T9T0U1C(:(;(9"8 4.$"#!   "!!!!    +  +  & + +    +     + +    + + + +  + +     +   + + +   +  + + + + +    + +  +    +  + +  +  +    +  +         +  + +  + + + +   +        + +    +   +     +  +  +    +  +      +     +  +   + + +  +   +  + +  + +      +             +   +    +  +   + + +  +  + + +  + +   +  + +  + + + + +   +       + +    +     +    +  +   +  +    +  + + + + + +   +  + +  +  + + +  +  +     + +'/",!,+!.+(')",!/$-%.'4*9/:.?*@/F0K;J:M=OAW@WE_H_DdIbJiQnWmZn[}`|bdc}^mST9.% +  +          + +  +    +     +   +    +      + +        +    +     + +                   + +     +   + + + + + +  +  +  + +       +    +  +    + +  + + + + +  + +   +    +    +     + + +  + + +  + + +  +  + +    + + + + +  + + + +      +   +  + +  + +   + +  +     + + + + + + + +      + +  ي݇ۅօʂxtggbY\SR{NxLrJkHf?b<\=U8O5F/A,=*9*5&2-)&& !#"!!#" +  + + +  !  + +    +     +  +   + +    + + +         + +  + + + + +  + + + + +  + +  +   + + +   + +   +   + + +  + +  + + + +   + +  + + + +  +  + +  +  +   +   + + + +      +  + +  +  +      + + + +    + + +  + + + +  + + + + + +  +   +     +  + +       +   +  +  +  +  +  + + + +   +  +  +    + +    +  +    +    + +  +  + +    +        + +     +     +  + +  +     ..++,('()(+,1215;@A!EF K#K"S&V"[#Z'\-b+j/j.k1{2~6z9?8/~+c!L,     + + +    + +  +  +   +    +            +  +     +        +     +         + +  +    +  + + + +     + +  + + + +  +     + +   +  +     +   +   + +   +           +  + +  +   + +         +   + +  + + +    +     +  + + +     + + +  + + +   + + + +     + +      ߃|wzqlmhfb]VPR|PIqEq?k>a8]7Z6P2L/E)<%>*:!: 6,($"! #!!  "   + "% + + + +  +  +       + +     + + +       +      + +  +  +   +    +     + +   +   +  +    +   +   +  + + + +  +  + +   +     + +    +    +  +  +   +  +     + +     + +  +  +  +    +  + +         + + + +    +  +  +    + +   +  +      + + +  +    +  + + + +  + +      +    + +   +  + +   + +     +  +  +   + +  +   + +  +  +   +       +     +     + +  + +     + !,(#/ )*') ',+!/!.0%6%3,<(<.A.@4K4H9L8Q=R>YGYG[J\KbOiMjQpQtY^cbe`yZhDC0' + +          +   + +         +      +   +     + +   +  +   +  +   +   +     +           +          + + + +    +  +  +    +  +  +    + +      +     +  +     + +  + + +    + + + +      + + +  +  +  + + + + +  +  +       + +    + + +  +  + +  +       +  +  + +   + + +  "     + ݏʊɌz|txmjg`^XK|NwLqIiE`@[<_9T6N7K/D+A,=)7&2".%$""%!&#"!!! #     !"#  + + +     +  +      + + +    + + + +  + + +  + + + + +  + +   +   +  + + + + + +     +     +  +    + +  +    +    +     + +     +   +  +   +   +     + +  + + + +   + + +  + + + + + + + + + + + +   +    +  +   + +  +       +  + + + +              + +  +  +  + +     + +   + +  +  + +  +    + + +       + +      + +   +  + +  +     + + +    +   +  + + +    ",.-%'&)))1.,252:@@@E IN#P"P)V%_(_)e)h)g0i+o4v3}3y3530x(\<"        + +  +        +  + +  + +                                 +  + +     + + + +  + + + +   + + + + +   +  + +          +   + +          +        +     + + +   +  +      +  +  + + +   +    + +          + + +    +   +   +   + +   +   + + +    +   + +        +   ރsrnoahZYUOTG|KtIoBkR=ZH]GbFdKeNoTqWlWzV|dc`e`xY]A<* + +  +   + +      + +   +    +  +    +  +   +    +  +  +  +     + +   +                              +  + + +  + + +        +  + + + +   +  +   +  +   +       + + + + +    + +  +  +      +  + + +    +  +   +  + +  + + + +    +      + +    + + + +     +   + +  +  +      +        + +  ߋԃ}~wpsjh][ZZVoMpJmC^?XCACEJ$J$O%[*[$Y)\*a'e*h,q1l1~8}6z672+o$U1    + +  +           +       +        + +    +      +      +          +  + + + + +   +    + + + +  + + +  + +   +  +  +  + +  +    +        + +  +        +  +    +  + + + + +         +  +  + +  + + + +   +   + +       + +  + +    +  +        +  +  +        + + + |snqvyf]ZTXRI~HvAqAh;`7T5Z4K4T0P-B&F&>&;5 *##$$%! #   +    +  "!#   +  +  + +    + +   + +  +   + + +  +      +     +     +   + + +    +  +  +  +   +  +  + + +   + +  + +   +  +     + + + +   +       + +    +  +   +   + +    + +  +   +    +   + + +     +          + +  +  +  +   + +  +      +   +             +   + +  + +   + + + +  +  + +  +   +   + + + + +     +  +  + + +   + + + +    +  + +   +   + +   +  +  + + +  + + +  + +       +  )// -!)*'+!/!,!4$/#5 0&7)7.;.<0D2D4E6K:S>Y=WCXBZGgKdLfLoTo[y\~`}_}dYdz^cPL;/    +    +       + +              +  +     + +  +  +        +               + +   +            + + + + +  +    + +   +       +    +  +   +   + + +     + + + +  + + +  +      + +    +  +  + +  +   +   +  + +     +   +     +  +    +       +  + + +  + +   + + + +  +  +         + ӎ؈҅уĂ{ttmhgX[WzVvOqFo>_B_9U7O6N9J6L/A19);&3$/!&"#()"!$ !  + +  #""   +  +   + + + +   + + +  + + +  + + + +   +  + + +   +   + +   + +  + +  + + +  + + + + +  +    +  +   +  +      +  +      + + +  + +      +      +      +  +  + +   + +  + +  + +  +  +  +     + + +  + + +  + +     + +  +    +  +  + +  +        + + + + +   +  + +   +     +  +   +      + +      + +   +  + + +     +    + +  +  +  +   +  +  + +  + +  +   +   +  + $**0*&-'(((.//532;@AF K!O%U#V%^#Z&Z)b*a'f/j1r0s0x27922x*e C(  +   +     + + + +   + +     +    + +          + + +                 +           + +      + +   +  +        +   +      +          +  + +   + +   +  +      + +   +     +   +     + +  + + + +  + + + +   + + + +        +      +      +     + +   +      +     +  +  +  +          ځρ~}uqdfa\YRV{QsJrDvHg=b[7R9U8K2F/C/B/9%7"/&(&!! "!"!       ! $" !#$      + +  +   +  +   +    +  +  + +  +  +   +  + + +  + +  +     + + + +  + + + + +  + + +  +   +       + + +  +   + +  +  +     + +  +    + +  + +  +  + + + + +        + +  + +     +  + +    + +    +    + + + +    +  + + + + +  +  +   +      +  + +   +      + +    +  + +     +   +  +  + +   +  +  +  +       + +  +  +    + +  + +    +   + + +        +    +   &*,.),&+**.*-2067=@>IKK U"T&[!a&[+b&b/f.n.w,o.{65;80,l"N/ + +   +     +         + + + + +   +   +  +  +  +     +           +              +   +   +       + + + +    + +   +    +        +   + +   +  +     + +           + +  +    +        +  + + +   + +  + + + +    +  +    +   +    +  +   + +  +  +     + +     +              + +    + +   + ކՂ}vtlog^`XWNHoHuJpGi@c?d;_5W3T4R-G+B)<':"4*'#%"$""#     !#!!  ##"!& +   +  + +  + +    + +   +    +  +  + + + +    + +  + +     +  + +  + +    +  +    +    + + +  + +  + +     +    + +  +   + +      +  +   + +  +  + +      +      + + + + +  + +  +   +  + +  + +  +   +   + +  +  +  +     + +  +     +  +       +  + + + +      +    +  + +  +  +  + + + + +  + + + + +  + +  + + +  +  +  +   +        +    +  +    + + +  +  + +  +   +  +   +   +  + + +   + '+/ *". &'(!, ("-++"3&1)6*90C.?2B5E9K:Q=R)='8#., *$$ "#! + + +""  !!#$(!      +  + + + +     + +     + +  +  +   +   +  + + + +   + +  +   + +  + + +   + +  +   +     +  +  +    + +     + + + + +  + + +  + +  + +   + +     + + + + + +  + + + +    +  + +  +  +    +  +  + + + +  +  + +  + +  + +  +   +     +  + + +  + +    +    + +  + +     +     + + +  + +  + +   + +  +   +    +   + + +  +   +  + +    + +     + + + +   + + + + + +  +      + + %+./*)+,+(,+044:6<;@IJN"V$\&W$]&`(h*j,c0r.s/2:::6/)bH#       +    +     +    +    +   +   +            +   +                    + +     + +        +  + + + +  + + + +       + +  + +   +  +  +  + +  +      +      +  + +  + +   +   + + + + + +  +     + + +    +     + + +      + + + +  + + +    +      + + + +    +  +  +    + + +       + +  +    ׈ـxtrlb`_[VSH~QrFuCqGc?c7[;U5P1K/J*D+=&7#6 ,()'&'"!"  +  +!""#!" !   "##%   + +  +    + + + +   +  + +   +   +   + + +    + + +    +      + + +   + + + + + +   + +           + +     +  +    +  +  + +   +   +  +  +   +    +  + + +     + +    + +  + +    +     +       +    + +  + +  +   +  +   +   +  +  + +    +   + + +  + + +     +   +   +    +     + +   +   +  + +  +   +      +  + + +  +   +    + +  +       + + +  + +  +      + +')"/"- '*++- )*"2#+',(2':(60@,=3C2I5J8MAQ=ZA^D[H\HdNaQlQrYsTw^a]`fdqY`CB-  +  +  +       + +    +  + +        +   +    + +   +  +  + +                     +     +   + + +    +      + +    + +  +  + + + +   +    +  +  + +   + +   +     +        + + + + +  +    + +     +    +    +        +  +     +   + + + +  +  + +     +  +  +  + +  + +  + +   + + + +  + + +     +     + + + ߖ׋χхƒqplfgX^ZQR{MsJkEdAcB]=T6P5H2F/C/;(6&2 ))*'%%" !  + +  "$"! """" (    +         + + + +    +  + + + + + +  +     + + + + +   + + +     + +   + + + +       +  +   + + +  + +      + + + +  +  +  +   + + +  + + + +  +   + + +  +  + + +  + + + +  +  + + +  +  + +  +      +    +    +   +  + +    + + +   + + + + +    + +   +       +  +         + + +     +   +   + + +       +  +  + +   + +    +  +  + + +  +     +  +  +  +  +     !(/+.+***0),'//57=DFF I MK#Q$_%Y(Z)d(d+l+r/s,q2w7}8454-w$Z8  +      +          +       +  + +       +  +       +      +        +      + + +     +   +       +    +   +    +   + +    +      + +  +  + + + +        +  +         +  +          + +    +  + + + +     + +        +    + + + +  +  +       +      + +      +   +  +   +  +  ܁قЁtrpleY`YPQQKwHpAl?b>d4\6T0N3F*F)A(:!0-*&$$%"%&!  + + + !!  !$!"!#&!  +  +  +  + +   +          +   +    + + + + + + +   + + + +       +  + +  + + + + +    +  +  + +   + +    + +  +  +  + +  +  +    + + +    + +  +   +  +   + + +     + +   + + +   +   + + + +   +  + +    +  +  + +     + +    + +   +  + + + + + +   +  + +     + +   + + +  +  + +  +    + +   +   +   +  +    +   + + + +  +   + + + + + +    +  + +  + +  +  + +  + +  + + +  +    +  + +  +  +   #*& / ,-(-.,$*!- +!2#4*7)<0:-:4D2E5K9T:N?S>UAaCYL_GdThUpXxXwVc~bggddoSS99$ + + + +     +      +    +  +        + +  + + +    +  +      +  + +      +         +            +   +  + +  + + +  + + +  + +   + +   +  +       +    + + +   + +  +   +  + + +      + +    +      +    + + +  + + + +       +     + + +  +      +    +  +  + + +    + +  +  + +   + +     +  + +  + ՘֍Հʆwqgdde]YW~Q|PvGnEcGh?[:Y6P9S1G-B.A'7$0".!,'&!#    + !#"  "$"!"%""  + + +     +    +   + +   +    +  +     + + +  + +   + +   +    +  + + +  + + +   + +    +    + + + +  + + + +   + +  + +   + +  + + +  + + + + +   + + +      + + + +     + + +   +   + + +   +  +     + +  + +    + + + +             + +  +     +         + + +  +      + +     + +      +   +        +   +  + +      + +    +  + +        + $---')+,++.-*/15<=DCD"I"IP$P'T$\"^'c*h-k/r-x4y48;;:7,k$P.         + +    +   +     + +             +     +        +         +  + +  + +  +  +    + +       + + +  +   + + +  + + +    +   +   +      +   +  +     +    +   +     +    +  +   +  +   +  + +  +   +     +      +     + +   +               + +     +   +  +  +ځ|tpnj^edSVTzMtLJpDi?b;\3Y4R2J4O.D(F%=$5 /0-#(" + +   !#""!%$!!# "!!%#"$' +  + +      +  +   +  +     + + + + +   +  + +       + + + +   +   +    +    + +   + +  +   + + + + + + +    +  +        + +  + +      +   +     + + + + + +  +   + +   +   + +  +   + +  + + +   + +   + +  +     + + +     +  + +   +  + +  +     + +     + + +  + +    +         +  +   +   +   + + +  + + +  + +   + + +   +  +    +  + +  +   + +     +  +  +   + +  +    + + +  +     + %3.!*%,)*"(#-!(!/#.%2%8):.6,=/=5I5D8N5GBT@Y@WBZGcFdReRiPmUpRya\]fedaiFI4, + +        + + +  + +   +  + + +      +  +  +  +       +           +    + + + +        + + +  +        + +   +    + + + +  + +     +   + + +      + +  +   +  + +   + +     + + +   +    + + +    +  + + +      + +  + +      + + +  +     +   + +   +        + +    ޔӇwzvvme_dST}OzPpLlIjGa@S:Y9K4Q4L.G*>*8%4"-!(+%$#!    #$# !"#  &#!"!&!  +   +  +    +     +  +   +     + + +   + + + + +  + +  + +  + + +  + + +    + + + +  + +  +    + + +    + +   +       + +  +  +    +   + +  + +  + + + + +  + +  + + +  + + +    +  + + + +  +     +   + +  + +  + + +  + +    + + + + + + + +  +    +  + + +      + +  + +  +   + + + + +    +       +  +     + +  + +  +    +  +     +  +   + +   + + + + + +     +   +   + +  +  + +  +  +  +    ()+1'-+&*++*-24:=BABG!KN"[%_'Q'_(b,c.k.e+n+z/|5{68832z)c!F#  +      + +  +    +  + +        +  +  +       +      +   +                     +      +  + +    +  + + +   +  + +  +    + + + +     +         +   +  + + +  +   + +  +   +   +   +          + + +  + + +  + +   +  +  + + + +   + + +  +  +  +       +     +   +   + +   + +      + + ԈԂwutkpg[]\NKO{OyGn@p?_<]6X6X2J0M1E,B)@$7 /1*($  + +"  !%"& ! $  # #$$!$&!  + +  +   + + +   +   +   +  +  + + +  + +  +     + +  +    + +     +  +       + +   +   +    + +   + + +  + + + +   +  +     +    + + +  + +  +   +   +      +   +  +    +  + + +  +  + + + +   + + +  + +  + +  + +  + + +         +     + +  +  + +  +  + + +  + + + + +  +  + + +  +     + +    + +     + +  + +  +   + +       +    + +   + +  +    +  +    +          + + + #. +!-.+ + ' + ( + + 0%0!0+1(=(9+;4B5B5D4I7T&  + + + + + + +   +     +   + +     +   +     +     + + + +   + +               + +         +   +   +  + +     +  +  + +     +  +  + +     + + +  + +       +     + + +     +  + +     +      + +  +   +  +  + + + + +   +     + +           +     +  +    +     +  + + +  + +       +      ي~~~oqnob[_[SxKtLlEcBc>X>[7O6G3I.E,7'9(6!-!.'!"     """$ !#!##"##%"%'##  +     +  +   +  + + +    +   + + + + + +  +       + + +       + + + +  +    + +     + + + + + +  +   + +  + + + +    +  + +         +  +     + + +  + +  +  + + + + +   + + +  +  +    + +     +    + +    + +          +  + +    +   + + + +     + + +    +   + + +   + + +  +   + + + + +  + + + +  + + + + +  +  + + +  + +   + + + + + + + + +     +   + + +   + + +        + + + ".-'&**%+++.01759=?BCK K"M$\%W'^)\+_,j*f,w4r2z2y5~94;4,u$V3     + +   +         +  +   +    +  + +    +      +      +       +           +    +    +  +   + +      + +  +   + +  + +   +  + +   + +    +    +  +  +    +      +    + +  +  +  +  +           +    +    +  + +  +  + +    +       +       +     + +  +  +     +    +   ۃx̄zyijfbaUVPJJxCsCk>_9b5_4O3H0J(F-B&9#:"1-)$#! !  + "! $ """ "#$"!## # &#%!%"    + +  +     +  + +  +  + +   + + +  +  +  +  + + + +   + +    +  +   +    + + + +  + + +    +  + + +  +     +  + + +    + + +    +  + +    +     + + +   + + +      +  +    +    +   +    +  +   + + + +  +  +  + + + + +      +     + +  +    +    + +    +    + +  +   +  + + +  +    + +    + + + + + + +  +       +     +  +    +  +   +  +  + +   + +      +   +  +       + + + +  +    +   +    +%5 4",!*((!&(")$,#2%0&."7+6,;-<,C/D7F7KXBUJ]C_GdPbQkQmUsWwX{`cejd\qOP=3 +   +              +    +   +   + +   +   +  +     +   +     +           +              +       + + +  + + + + + + + +   + +     +   +  + +  +  +    +  +         +               +      +   + +  +   + +   +  +  +   + +    + +             +   +        +  + +  +     +  + + ߋфĄyflf]`Z\QzKqJjEnA]AW;R2Q.F5F0E)C-:$2#4*)" "$   $!   #$! &#&" #"%#!!$#"%!      +   +   +       +   + +    +      +  +     + + +   + + +    +    +  +  +    +  + + + + +      + + + +   + +   + +  + + +  + +  + +  +  + + +    + + +   +   + +   +   + +   + +  +  + +  + +   +   +     +    + +    +  + +    + +      +    + +      + + +     +  +      + +  + +    +   + + + +  + +     + +   +  +         + + +     +  + +    + +   +    %,.*(()**',)-4777<IEH!I$P$R"W#Q,`&])f-l+p,m2q6z8s76;;5-o!F(              + +   +      +   +  + + + +     +  +  +  +            +          +    + + + +      + + +   +  +      +  +  + +  +  + + + + + +      +  +     +   +   + + +  + +      +   +  +  +  + + + + + + +      +     +    +  +       +   +   +   +  + +  + +           +  +  +     Ԇԃʃuwo`k_cWU~ROLuEq@\Ab<_5\9P/M,G*F(?&?#3"5 0(#$!  +  !# "!#&&!"$"# #$#$"  '#"'   +  + + + + +     +  + +  + + + + +    + +  + +  +  + + +            + + + +  + +  + +  +     + +  +   + +  + +      + +  + + +  +  +  +     + + + +   +  + +   +  + + +  + + + +    + +   + +  +       +  + + +    +   + +  +  + + +      + + +  + + +  +   + +  + +  +  +  +  +  +    + +    +  +  +   + +  +        +   +    +    + + +   + + +   +   + + +       + +  + + + +   + + +     + + +    + + +..-*-"(!*!0 + *!.!-#4)4(-C-D6J5O7HV:L4O.D.B,9(>(5#-!+& "! "  +   #"#!#"#!!$"!#"$&#"!""!"##    +  +  +          + + + +  +    + +   + + +  + + + + + + + + + +  + +  + +   +     +  + + +  +     +  +   + + +      +     + + + +       +   + + + +    + + +  +  + + + + + + + + +   +   +   +    +    +  + +           + + +   +  +    + + +  +  +   + +  +   +    + +  + +  + +          + +   +     +  + +   + + + + +     +    +   + + + +  + + +  +  + +  +      + + +   + + +      + + #*,,+++)*,,*.27<9::FKF L$R#P#\'[+_-c)h)j/i,t3{6{:6|865.o%T3       +       +  +           +  +  +   +     + +    +     +        +    +    +        + + +  +  + +  + + +    + +  +   +  +   + + + +       +        +    + + +  + +      +     + +  + + +   + + +      +  +               + +     +  +  +  +     +   + + + +   + + +   +      +     +  + ݈xw~rulj`\dZROzKwDnIj@fBb7\4R5L/K/I-?':)8%5 3)!&"! +  +   !!%!%"%!""##"$$ %$!"%#$! +   + +   +  +  +  + +     +  +      + + +     +    +  +   + +    + +  +     + + +   +  + + + +  +    + +  + +    + +  + +     + +   + + +   +  + + +      + +     + + +  +   + + +    + +   + + + + + +  +      +  + +         + + +     +       +       + + + +   +  + + +  +   + +  + +  + +  + +    + +   + + + +    + + +  + +  +    + +   +  +    +       +   + + +  +  + + +  +  + +    +  + +  + +  + +     +."0)1)*'++,/&-'3&2'5(>,>2D2C7I;K5VEJH!L!Q#S%Y(_%d'd+c(j/p0o.3v2}5;>62{'kI%        +      +     +  + +         + +                        + +   +   +  + + + +  + + +   +     +  +           +  + + +  + + +    +   + + +         +       + +         + +    +            + +  +     +    +  +       +        + +  +    + ܇vxurh^n`XU[zOHzKoDi=i8]=\8U0P7P.G)E(;&5%2/.$#!" !  +    "   !!%# %!#""""""" # $$"#$""#%!#$# + +   + +       + +  + +     +    + + + + +     +    +  + + + +    + + +  +  +   + +  + +   +  +     +       +  +  +  + +  + + + +  + +  + +   + +         + + + +   +  +   +  +     + +  + + + + +    +  + + +     + + + +     + +   +  +         +  + +  +  +  +  +      +  +  + +   + + +  +  +     +   + + + +   +  +  +  + +  +   +           +    +  + +  + + +   +  +  + + + + +  +   *.!.!1,!+(*$,!+/ *%4#3*3)3*>0?0G1E;J6N?R*7$8#+(# !    +     ## #!!#! ! ##"%#"###!% $!##%"'"%!   + + + +    +  +   +   +   +      +  +   +  +       +  +  +  +    + + + +      + +    +   +  +    +  + +  +  +  +     +  +  +     +   + +  + + + +    +  +  +    + +  +   +   +      +  +  +  + + + +  + +  +      + + + +  +   + + +  + +    +  + +     +  +  +  + +      +  +    +   +        + +      +   + +     + + + + +   + +           +   +  + + +   + !,-*+,&()(*-.425;=D@K"I%I!MY$]%](`+^)h-i+k-h9s5w76;<5-s&Y7 +    +      +        +   +     + +     + +   + +          +     +  + + +      + +  +  +  + + + +   +       + +   + +  +       + +  +  +   +            +  + +    + +  + + +        +  +  + + +     +        + +   + +   + + +   + + + + +      + +    +      + +       ~xttkmhb]_VLL~MvGl>lAb:`9Y8S1T+G,D)>*9%:0-'"'!!   +  + ! ""$!"$# $!#!"#"%#$"!$""""%$$#"#!#&" %" +  + + +      +   +   + +     +   + +  + + + + +       + +  +  + +  +    +  + + +      + + +    + +  + +   + + + +  +       + +  +  + + + +  +   +   + + + + +  + + +  + +     +     +  + +  + + + +      +   + +  +       +   +     + + +        + +    + + + +  + + + + +    +  +  + +  + +  +  + + + +  +  +        + +  +  +   + +        + +  + +  +   + +  + + +  + + + + +  +     %-"-!,!*"+ )!)&0!/"*'.$4)2&7)<.<.>-C2E6I?R;X9S@WGWG`IaJdNbLhVtVqa|[]hea`sXT<3# + + + +  +         + +       +   + +      +           +  +             + + + +    + +     + +     + +  +  + +  +  + +   +  + + +  +   + +  +   +  + +    + + + + +    + +          +  +  +   + + + + +  + + +   +   +   + +      +   + +     +   + +      +         +  + + +    +  + +  Ґ͌Ђ|wolkg`\UZ{R|JsHeIk@i@Z84'k$O* +            + +          +      +    +          + +    +    + + +  + +        +   + + + +  +     +      +       + +      + +  +     + + +  +      + +     +      +  + + +  +   + + +  +   +    + +     + + + +    +     +         +  + + +  +        + +}މՅz{qulg]X]TU{KJrDmAg?h;d;Z6Y8R.E+F'<&6'5 1.&##!"!!   "! "!  """#"!$# "$$# ""%'$$ #!$!""#!#"$%$%#  +  + +      +  + + +     + + + +  + + +  +     + + + + +   +        + + +      +  + + +    +     + +    + +   + +   + + + + +  + + +   +   + +  +  +     +    + + +  +  +  +  +    +  + + +  +  +  + +  +  +   + +   + +    + +  + +  + +  + + +  +  +  + + +  + + +   + +   +      +    + +  +   +      +    +  + +     + +  + + + + +  +         +      + +   +   +    + +  +   +  +   "-/ ,,+!''++-#- -&0%7'1*=*>0?/C1I5I;K;K?R;Y?^DaIcMgOaMrMnQsV~Y^jfkg~`gKI4' +  +  + +         +      +   +  + + +    + +   +    +    +     + +  +                  +  + + +       + +     +  +  + +   +  + + + +   +    + +  + + + +  +  +    +  +    + +    +  + + + + + + +    +     +  +   + +    +   + +  + +    +  + + +  +    +     +    + + + + +   + +   + +  +   ޏޑӋ{zysnqfc[YQTxJqGuMhC`@c@W;T2N7I,C*?*8'8#2(&%#     +  ! %!!!#  "!#  !#$$"!"# #!#$"!$"$# &$""$" +  +   +   + + + + + + +   +      + +    +  + +  + + + + + + +  + + +   + +  + + + + +   + +    +   + +   + +    + +    + +    +       +   +   + +  + +    +   +  +  +  + + +  + +  +  + + +  +  + + + + +    + +       + +  + + + + +   +   +    + +  +  + +  + +  + +   + + +  +  + +  +    +    +    +      +  + + +  + + +  +    +  + +  + +  +  +       + +  +      +      +   + + +   +   !+,)))-*&*++,3/2:=<D EK K)M$R!W%X(^)d*],i*g/w0o5z56=661z)^!D  +        +         + +          + +    +  +     + +            + + + +    +     + +  +  +     +         +  +    +       + +    + +     + +   +       + +  +  +   +   +    + +  + +   +   + + +   + +           +    + +  +             + + +   +   + +     +   + +  +  +׃v|th^j^`W]TQ}KrEr@fAe>f;]6Q2P1L+E'>%?':"8#$"# !  +"" #!#$!!#!#$"#$#"#!# #!$##$!$"#"$## "&#!!'#$"     +     +        +     + + +   +  +  + +  +    +  + +  +  +  + + + + + +  +  +  + + + + +    +  +  +  +   + + + +   +   + +     +     + + +  +    +  + +  + +   +  +  +  +       +  + + +   +   +   + + + +    +   + +             + +   +         + +   + +  +  + + + +      + + +  +    + +  +    +     +   +  +    +  +  +   + + + +  +   + +  +  + + + +  + +  + +   +      + +   +   + +  &)*!,. *&( *!*!',#,$0%1(:';-;.C4D4I8K9N?P=V?\G`@]GbJhIkSrQpXwZ}^dcgnh\ZB7+ + + + +   + +    +      +   + +  +     +   +  +   +             +   + +   +    +  +  + +  + + + +   + + +    +  + +  +   +  +       +  +        +        +  +    +  +    + + + +   + + +   +  +   + +      + + + +       + + + +    + +     +  + +    ׊֏Ƈʄyutflc`^}RQvIrJmIl@f@_7T?W8L/A.>*B-<)3#-*#$ !"   + %!$!"##!##!$ "!""$#!#%!%"#!##"#$#" !&$!""!'$&#  +  + + + + +   + +    +     + +  +       +  + +  + +  +  +    + +  + +   + +  + + + +  +  +  + + +   +   +     +  + + + +   +    + + + +  +    + + + + +  +  +   +   + +    +  + + +    + + +  +   + + +   +  +   +   +     + +  +  +     +     + + + +  +    + +    +          +   +  +  +   +  +      + +   +  + +     +  +  +  +  +   + +    + +  +  + +      +     +      +     + '*,*(((++*2+/458:?BLJ$JN$N!T*Y&_-c(e*e.h.k1w0v4x9}4?52/v&Z4 + +    +        + +  +           + +      + + +      + +   + +    +    +    +    +  + + +  +  +  +  +  +  +     +    +       +  + + +          + +  + +     +  +     +  + + +  +   + + +   +    + +    +    +   +            +         +    + +  + + +  + |romjgdd`RO}O{IoDgDk@k;_5\4Y1P,J+@'@&;%3$5)"'$   + +  " $$"##%"""""!%!$#! %"###$%""""$#!%"!($  +  +       + +  +  + +  +   +  + + + + +   + +  + + +  +  + + +  +    + + +   +     +     +  + +  +  +    +  +    + +   + + + + + + +    + + +  +      +   +    + +  + +  + +  + + +  +     + + + +  + +   + +   +    + + + +   + + + + + + + + +    +    +  + +  + +  + +  + +  +  + +     +   + + +  + + + + + + +   +     +   + +     +  +       +   + +  +  +   + + + +  +  +    +   + + +        +   %/"*!+ .)),&) 2!/%.%/(3(:*:0@-?2F6J;K&7",")$"   """#&$!#"""!$&#%$!!$$!$"!%$$"$#!#%!#&###$$'!"#!#!#    +    + + +  +   + + + +   +  +  +  + + +     +  +  +   + +  + +   + +  +   + +  + + +  + + + + + +   +      + +     +  +  + + + +  +      + +  +       + + +  + + + + +  +   +   + + + +  + + +  +       + +   + +   + + +  + +  +  + + +  +   +  +  + +   + +  +  + + + + + +  +  +  +   +  + +  +   +  + +  +   + + +  + +  +   +  +  + + +          + +       + +    +    $-).,*&(()////2859?CGJ I$R$X!Z(['_)a+c.i3l.n/y4t67:<7/r%_?  +    + +     +   +      + +     +  +     +    +                  + + +    + + +    +  + +    +  + + + +   +  +  +      +    +   + +   + + +    + +  +  +        +          + +     +  + + +  +  +             + +   +     + + +   +          + փكЁ}pmkja^WXONOsIlEqAk?d8W5S4K,G)B'B)>)80*&"   +  !!"!!!## !""$ ! " $!"""##$"#!""&%#'"##!% #$$$"% (%%           +  + +  +    +    + + + +     +  + +           +    +   +   + + +  +   + + + +  +  + +  +  + +  +  + +   +  + + + +  +   +     +    +  +   +  +          +  + + + +  + + + +   +  + + + + +  +  + +   +  + +   + + +     + + +  +   +       +   + + +   + + +  +  + +    +  +  +  +   + +  + + +  + +  +    +    + +     + + +   +  + +  + +  +      + + +   + + +   + $.,2, * ) ( .%$+$-!/%3'3%4)<+<-B,C4F:I8K?QPDQBZ?[H_N`FeSmSeTmSwX{YclmkiyYfEE/  + + +    +    + +   +       +  +  +  +      +    +  +  +         + +         +  +    +       +  +    +       +   +  + +  +   + +   +  +  +        +     +          +  +   +  + + +   +  +   + + +   + +  +  +   + +   +   + + +  +  + + +  + +  + +     +   +  +    + +    ك؁~ʁvwnkdb`ZTzMmKqNl@lDb@X8U9M6O5F4=/;'7#1-'&!# +   #"# " $("! %#!!!$"""##!$&"&"""'$"#$%$!#!#"!& #"#$$ #$%$!#$ &%"    + + +     + + +  +    +    +   + +  +  + + +    + + + +  + +   + + + +  +  + + +   +   +   +   +  +     +  +  +        + + + + +  + +  + + +  +    + + +  +  +  + +       +   + + + + +   +  +  + +  +  + + + + + + +  +    + +  + +  + +  + + +  +  +    +  +  +  +    + +  + +      +           + +  + +  + + +   + +     +    + + +     +  +   + +  +    + + +   + (+.+*)(,,(.+/1594; FC!L G P"T#V%Y%W(\,g(k,j.m0o0y4x66<661s)[:       + +     +     +    +        +       +   + +  +       + +  + +  +         +     +          +  + +         +   +  + +   +    +    + +  +         +   +  +  + + +    +  +    +         + +    +  +   + +     +       +   + + +   + y܁{|vlne\Y\ZI{NrNyIk@jBc>_8W7O.M.K/G+>(;#6.0("  "  !  !#!"!##$#$%#"!%!"&%#$%!"$"!"! """#$$%&$!!& $$#$"!$)"$%"!%$&#%!  + + + + + +    + + + +   + + +    +  + +  +  +  +  + +   +  +  + +  +       +  +  +  +   + + + + + + +       + +  + +  +  + + + +   + +   +  +  +  + +    + +  +    +  + + +  +   +  + +   + + + + + +   +  +  + + + + +  + +   +  +     + + +     + + + +     +  +   + +  +   + + +    + + +    + +   +   + + +   +    +  +   + +       + +   +       +  +  +     + + +    + + +  +   +       + +     + + +!'.- -(&))) ( /!0&1#7)1(9+:-=,F1E4F7H4MW?W6R2G.K+C)>(6 43/*&   + + "  "$ #"$$#%"!!$!$!!$"!(#&!$! %!$!"##!#"!% $#&$!!$ &$"#&#!#&$#$!!&% + +  + +     + + +         +   + +  + + +  + +  +   +  + +    + +  + +    + + + +  + + + + + + + +   +   + + +    + +   + + +  +   +   +  + + +  +    +  + +  + +  +  +   +   +  +  +     +   + +  + + +  + +  + + + +  + +          + + +  + +  +  +  +      + + +  +   + +   +    +      +   + +   + + + +  +     + +      +       +   +    +  + +   +  +   + +  + +  + + + +  +   +   +    $,"."."-+)").*!.!/0&5#2'8(:->-@/B4A98~'fC#      +     +      +     + +             +    + +     + +        + +       + +       +    +   +  +           +    + +   + +  + + +  + +   +   +      +    + + + +   +  + + +       +  +    +     +      +  +  +   +  + + ߑwywvlmk`\[UX~O~KwMsBhAb8\:Z;P4J.E,E&B'5$93/(!  "%" !  "$!! # $$## #!"#""$"& "!&" "!""!"#$$!##""#%!"(%(&#"""")#"""'%$$&''%##)! +       + + +   + +    +  +  +    +       +  + + +  + +     +   + + +   +  +     + + +      + +       + + +  + +     +  +  +  + + + +   + +  + + +  + +  +  +  +  +    +  + +  +  +   + +   +  + + +   + + + + + + + +      + +  +  + +  +       + + +   +  +   + + + +   + +  + +           +     +   +     + +      +   +     +   + + +  +    +  + +   +   +       + +   + ,+#..-"**$+- /"-!-'-(1-:+;-=-;0D7E5F7Q;P?PBXKXG`HeNeMlSkVnU~^xc[jdkeY[H>)  + +      + +          + +                     +      +        +  +    +  + + + + +     +   +         + +  +  +   + +   + +   +  +  + +        + + + +  +  + + + + + +   +     +  + +   + +   +     +       +  +       + +     + +   +  + +  + ޛא·Ԃzzquib_a\VvR|LtMtDeH`A`:V8P4G,D*?(8'4&0"3+%   !%"#"!#!!%$!&#""" #%%!&$!'" !$%"%"$""$ #"")&!"#!!"""##"$$"$%"!$""##$####  + + +    +     + + + + + + + + + +    +    + +  + + + +    +    + +  +   + +  +    + +  +  + + + + +  +  + +  +    +  + +   +  + +     +  + + +     +  + +    +  + +   +  + + +    + +  + +     + + +      +  + + +     + + + +  + +    +       +  + +    +        +   +     +     + +       + +   + +   +  +   + + +  + +   +  +     +  +  + + + +  + +        + + + +    +     '.)-''+---+//139<<D!AEK#S&S#S%](U(`+i+j,i,o1x2z76;;?6/v+Z1         +                  + +   +   +  +             + +  +      + + +  +  +   +  + +  +  +    +    +    + +  +     +      +  + + +  +  + +    + +    +  + + +        +   +    +  +  +      + +  +  + +  +    +     +    + +     + +         + +   +   +   ܇}zsuojf`_[YOM}KzIlCjAa8[:Y4Q3N0E+A$?'9$7"42(# +    !   "" "%"#!$$" #!##%""$$'$&#$%%$$##%#"%"#&&" %$""#!"$&#"$##"%%##% ""$'#"   + + +    +   + +    + +  +  + +   +           + +  +  + +     +  + + +   +   + +  + +    +  + + + + +    +  +     + +   +      + +  +  + + + + +  +  +     + +   +  +  + +   +   + + +     +     +     + + + +   +   + + + + +          + + + +  +   + + + +   +  +       +  + +  +     +  + +    +       + +  +     +   + +  +   +  +  +    +   + +   + + +    + +    +           + +    $( -!-,& *)("+ + +1%2#2'4%7-=,90D-H4J6H6V:Q=Y?ZF`AfJfJlNkNjVtWwX~d``hecuTR=0# + + + + + +        +  +             +              +    +   +  + +  + +   +  +     + + +   + +  + +  +       + + +    +    +  +  +   +   + +    +    + + +  + +  + + + + + +    + +    + + +  + +  +     +   +   +        +  +        +        +   +  ێމӊȈ|{pqlgdXQSvQ|KqLkBj^3W4L/J+E'>);#4$5-&   +  !##!! !%""""!!! $! $$# %#&&&##!"!##&%"%#!#& ! %#$(%#"$$#$#!##&#'!!!$!#$#!!#%#$&$&%  +  +  +   +  +  + + +  +         + +  + + +    +  +  + +  +    +  +  + + +     + + + +    +   + +   + + +  +    +       +        + +  +   + + +  +  + +  + + +  + +  +   +  +  + + +   +  +  +   +        + + + +  + +  + +  + + + + + + +  + + + + + +  + +  + +     + +  +     +   +  +  +    +  +    +  +      +    +   +  +    + +  + +    +   + +    +   +   + + + +   + + +     +   +   +      +  '(-#. , (+*+ &*%,#/'.&9&9)<+>,=0G*C;J8I8K>S?TF^EbE`GkRfOhRsXt[yX_`ahh^gOM3$ + + +    +     + + + +      +       +   + +   + +     +          +    + +       +  +   +   +  + +   + +   +   + +  +  +   +    +          +   +  +  +  +   +  +     +  +    + + + + +  +       +    + + + + +  + +       +    + +  + + +  + +  +     +     + + + +  +ݍʆ΅{wpofedTX~RQ~MrDkEcDa?Y>Q1V5K-B,?);-8&3!*"   !!"!#!"$!"!!$$$$!$" "# %##$"#""#'%!$$"%!!##'#!(#""!!$""%($$$"$"#$"&'"$#$"'$ !"!$#"#  + +     +   +   +  + + + +      + +  +      +    +  + +  +  + +   + +  +   + +  +       + +    +      + +  +  + + +  +  +  +  +   +       + +  +  + + +     + +  +      + + +    + + + + +  +      + + +   + + + +  +  +  +   + + + +   + + +        +   + +     +  +          + +  +    + +  +  + +        +  +  +  +     +   + +    + + +   + +   +  +   +  + +  + +  +        + &,0+)&*+(-2-/.46==AEH"HP$N'U'Y'Z&a,d'a,i.k-p2t5y27;;<3y&d D      +         + + + +                  +     +    + +   +  + +     +  + +  + +    + +    +  +   + + + +  +  +   +     + +      + +   +  + +  +   + + + +  + +       +     +         +         +  +    + +  +   +    +  +     +  +  ܉}z|tmcdX_ZW~O}KvJp@n]>W<91u)W2        + +       +   +                    +      +   + +     + + + + +      + + +    +    +     + +      + +          +        + +  +    + +   + + +   +  + +        +   +  + +      + + + + +   +  + +      + +   + +       ڊֆ{m{il]_bSSOMzGrAk(9%/(  %%  ""$%(#"&$"#"$'"!! "$#$$ %"!"&&$&!$$#%#$$###$$"#$#&&%%$!'&'!$&%#$%$!#$" "#$ $!%$&#!    + +    +   +  + + +   +      +  + +   +  + + + + +  +   +   +   +      +  +  + + +   +  +   + +    + +    + + +   + + +  + +    +  +  + + +   +    + + + + +   + +  + +    + +          +  +      + +  + + + +  +  +  +    +       + +   +    +       +    + +  +    + + + + + + +  +     +   +   +   + +   + +  + + + +  +  + + +  +   +  +    + +   + + +  +    + + +   +  + +  + +  + +     + +    $-", /**) ) * / *$+.%/#4%<)>*A/>3B1D8J8U=S?QAU?]D\MYKePjOpVnXxQv[zbhgjg^pNT;/ +  + +    +   +     +    +   +  + + +           +   +  + +      +  + + +  +     +   + +  +    +    +  + +        + +          +      +   +    +         + + +  +   + + +   + +  +  +  +       +     + +          + +          +   +    + + +   ׊Ճ|xjmbb^ZXSuRtIhEgBcp>];Y5R3O2F1D'E,;"4.# ! !"&%"""&$!!"$$" "$!%#!% ##"$$&&###$!%%'#&"!""&#"%!#$###"" "%!&##"%!%$%&&%&&"%" ""%####%$#" + + + +     + +     + +  +  +   +  +  +   + +  + +    +    +      +     + +   +   +  + +    +  +  +  +  +  + + +    +   +        +     +   + +    +  + + +  +  + + +  +  +      +    + +   +   + +  + +    + +  + +    + + +   +     +    + + + +      +   + +    + + +      + + + +     +   +    +  +  + +     + +     +    +   + + + + +  +  + +  + + +    +  +   +   +    +  +'0 , -!)")"+'*&"+"/%2"6(2+8/9+?2A0G9B2L:N;R=TD^EUH^HiJeMfLrTr\t_{`f`ifb`lKE0!  +   +    +       + +   +   + +     +    + +         +          +  + + +   + + +  + +   + +   +       +           +   +    +      + +    +   + +   +  +  +  + + + +    +  +    + + +    + + +  + +   +  +   + + +  + + + + + +    +    +   + +  + + + +    +  + ؈ԂŁvqllhdYZ[S}LpFhJfEd;cCGJ%N"S&X%V#V$a'h,h'q2l0s2t47:8<:5|(i#; +    + +          +   + +  +    +       + +      + + + + +        +  +   + +  +      +  + + +         +      + +     +  +     + +  +     +   + +  +    +  +    +  +             +       + +  + + + + +   + +   + +   +    + +      +        +  }ւzuohof^XXVTM{JqEpj9a;V7S4N/I'H$:0''!"  !%#!"$"!###$#$# "$$%#"#####$&%$%'&"#%#%#!"%%"#'"$"$!""!$$%#"")$ #&"$$'"###"'%%#(!#$%##%#$#$"  + +    + +  +  + +  +   +  +   + +    + +  + +  + +   +  + +   + + +     + +   + + +  + + +  +  +   +  +  + +  +   +  +      + + +  +  +   +  + + +       +  +  +   + + + +   +   + +  + +  + + + +  + + + +  +    + +   + + +   +       + +   +    +  + + +   + + +   + + +    +     + + + + + + + +  +  + +   + +   +  +    + + +  +    + + +    + +   +  + +  +   + + +    +  +   + +         + + +  +   +     #-/!,+ &"+, *!(..#-"1)5(;(;,;/@/A4I2J9L8L?UBUGZF_I[M_JfSkQqWs[|Y}\bhkdcx\ZD4! + + + + +       +  + + + + +        + + +    +                  +   + + +  + +  + + +   +   +  +  +       + +         +          +         + +   + +     +   + +  + + +  +   +  + +    + +        + +  +  + +   +  +    + +   +   +       +  +   + +   + + + דDž|zqofda_ZRVJmBkDiFi?c@T6Q8J/F*>)5",'     ! &$# !$ # !!"""#%% ""#!#!!$#$#!(##"%!$!#%"##"%"!"%!#"" !$$"##$&&%'#''"'$)'!&#'!##$$"%$&$$  + +       + +  + +   +    +  +    + + + +    +     +  +  +  + +  +  + + + + + + +   + + + + +  + +    +  + + +  +    +    + + + +  +    + + + +  +    + +     +  +  +  + +      + +   +    +  +  +   + +    +   +  + +  +  +  + +    +  +   +  + +   + + + +   + +    + +        +  +  + +  +    +  + + +      +   + +    +  +  +  + +  + + + +   + +  + + +  +  + +    + +   +  + +  $+0-,+*)&*+,0009=<>BB"I N"L U&Z(^)^)`(g,g/i/t2t/x5;9=62-wW1 +     +   +    + +  +   + +            +           + +  +  +  +   +  +    +  +    +    + +    +       + + +    +    +    +   +  + + +  + + +  + + +   + +   +  +  + +   +   +   +    + + +  + +   +  + +   +   +   +  + +    +  + +    + + +  + +  +    +    ߇ڃ҂txvnpi_^VS\JGwHn?gAa<^:`8T3N/H+C#:!+(#!$$!!  !!####&!!#$$!$(&"'&%!#"####!%$"%"""%# $$%###&!%&$%%#&!#$%#%$&%%'#$&%"&'%#"&'$&"#$#&!)#!##"#"""     + +    + +  + +  + + +    +             + +   + +   +  +   + + +   + +  + +  +  +     +  + + +   +  +  +  + +          +       +  + + + +  +  +     + + +   + +  +  + +  + +  +    +  + + +       +    +          + +   +  +  + +  +  + +   + + +  + +      + +  + + + + +  +    +   +    + +       + +   +     + +    + +     + +  +  +    + +    +    +    +   +    + +   + '2+-+*/)+-!+ ,"0&4#/'<'7/?+B-B2D5G9O8O@TBYEXC^KiJgFfTnTm[x\_{bfonketQL3+ + +   +           +   + + +  +  + +        +           +  +  + +   + + + +   + +      +   +      +   +   + +   +      +   + + + +    +  +     +     + +  +   +    + +  +  +  +  +  + + +  + +    + + +  + +  + + + +      +  +   +   + + +   +   +  + + + +  + ܎ϋΆxwzneec_VLtNtIlFmEcAb=Z8S8G-H-A#/,(#$$#! !$!""# $"!#"#" #!#$" !#%"%#($"#$'$##$!#"&"$$$&$&%)" #%$!#"%"'!##&"'%'&"%$#%'%$!&""&$&"%#!%#% "%#%    +    + +  + + + + +   +  +  + + + + + + +       + + +         + + + + + + + + +  + + + +     + +   +   + + + +   +  +  + +  +  + + +    +   +    + + + +     +   +  +    + + +  + +  + +  +  + + + + + +   +  + +   + +     + + +  +     +   + + +     +  + +     +  +    + +   + + +  + +  +    +   +   +  +          +   + +    + +  +    + + + +    +  +  +  +   + + + +    + + +   + +  +  + + + +     +  + )+,*-**')-++/099;8@DGLJ$V#Q$[&W)_,b(h,n.n3q1t295=;;40j#I'      +       +  + +           + +       + +      + + +           + +    +   + +  +     +   +    +  +       +    + +  +  +  + +  +  +   + +  +         +        +              +  + + +   +           +  + + + +     ׃x҂rvgha_^UYOyByDwCdAa8e$5!,'%%.&!!%## "$!!!"$""!"#!$$"##$#$! #'""%$$&&"%$$ $"#$)#" $$$####$#""## #%!$$"($'#%$&##&###&*&!"'"($#"'"&$##$'$("   + + +      +  + + +   + +   + + +   +   +  + +  +  +  +  +  +  +   +    +   + + +  + +  +      + + +  +  +    + +   +    +  + +  + +  +     +     +  + +  +       + +   + + + +  +   +   +   +         +  + + + + + + +  + + + +  +   + + +    +   + +  +     + +   +   + + + +   + + +   + + +    +  +  + +     +          +    + +        + +  + + + + +    +  +  +   +    +      + + + +   +  $+0%- +&+ (*!+')#-!*%1'0#5)8):-;-=8C2F8I@SA< J!J"P$Y$Z(]'a)c)h,f.e4u.n3x4}7}:;9;.w)e6 +      + +  +       +    +    + +         + + +  + +  + + +  + +    +  +        +    + +            + + +       +    +  + + +   +  + + + +  +  +   +  +    +  +   +     +    + + +    +  + +   +   + +  + +    + + +    + +  + ܈}փumnjbdUZVVHuHo>jIb>`9[6S1O,G-@!3.-,.-'$%"!! !&##"#&"&"&"&#$(( &#!&!"!"$###$&"#*!"%$ $# &"!"%'#$(%###$$#$($&%%%"%&%'%$$%"#&#'%&'$#$#"$$("$#&'$$#!%&&#&   +  + + +  +   +   + +   +  + +    +    + +  + +  + + + +   +  +    + + +  + + + +   + +  + + +   + +   +  +    +    + +   +    +  +   +  + +      + + +     + + + +   + + +    +  + + +  +  + + +   +    +  +  +   +  + +   +  + +  + + + +     + +  +  + + + +    +    + + +       +      +    +    +  + +     + + +  +  +  + + + + + +  +   + +  + +  +  +       +  +   +      + +  +      +   + +  +   +  +    + +  + + %+"+"-)!+ )* +) -!/!.$3%2&5)?+90D4A2F4K9Q:P>R@VBZEfKgJdOqPkTlYxXw[~ddliihyYT;5  +   +    +                +      +      + + +      +  +   +   + + + +    +  +  +  +    + +   + +  + +       + + + + +  +    +             + + +  + + +  +          +   + + + +  +  +  +   +     +  +  +  + +      +  +           +     +        Ίˈdžyqqjbb]^WwMtJmEjH`C`@Z8Z:O,H(<"2",-.!,!',$$!!!!"!#!# !%'!#$##$##!&#%%%!&""%"$""%($%&$%""# &(%"##!$$$##!%#& #!! """&%"#%####!"%%$$"&%!$)""&$%%#""!"$(#    + +  + + +  +    +  +  + +     + +  +  + +   + +  +  +   +  + +   + + + +   + +   + +  + +  +  + +    + + +  + +    + + +   +     +     + +  +  +   + +  +          +     + + + + + +  +  + +  +   +     + + +  +   +  +  + +    +     +    + + +    + + +   +    +      +  +   +  +   +         + +  + +  +   +  + +  +  + + + +   +   + + +  + +      +  + + + + +    + + +      + $+1,)''0**--23769;BE I G"L!Q%W&Y%]&_(c+j+f/r,k/q31~;9:68,u%P0 +      +   +    +     +                      +     + +  + +    + +  +               +  +  +  +       +      + +  +    +  + +          +   +  +     +    +  + +       +  + +       +  +         +        +   + +      +  ݃|rppldb^XZUGxGyFoCmXASIZDfMgMiQlSnRrVu]y_felkn_oOL7% + +  +  +       +   +   + +            +            + +  +   +    + + + +    +          +   +    +  +     +  +      +  + + +   +     +   + + + + + + + + +   + +    + +  + + +  + +   + + + +    + + +  +  + + + + +   + +       +   +     +  + + +  + ܈և΂~tryvcmd`W|RqMqGmGc=a<]>Q4I+C-4&4#2#1$1#1*%'!$!""#%"#" """&"&!&'$!%!("$!'&#" "!""##"#&"#&&$$! %#$%&"%!!&&"#!$#$#&$#$$$)%"% ##$'#!$"""%!&%"$%'& "'&$"#$##$& &  +  + + +  + + + + +  + + +           + +  + +      +    +  + +       + + + + + +  + +   + +   + +  + +  + +   +   + +         +     + +      + + +  + +  +  + +  +   +  +  +  + +  + +    +   + + + +    +    + +  + + +      +   + +   +   +   +  + +  +  + + + + +    + + + + +  + +   + + +    +    +   +   + + + +     +    +       + +    +    + +      + + + +  +   +  +  (.,)*+'),,/./449@@GJL!H N#T$\&^'Z(a+k)l0p,l0x/3~56;@>0~,mI!    + + + + +    +    +  + +  +                     + + +    +  +   +  + + +  +   + +  + + +  + + +  + +  +      + + +  +         +       + +  + + + +  +   +  + + + + + +   + +   + +                +    +  +        +    +   +  +     + + + +   +   + +  +  + +  و؉{|wqldbfaZPMzHyFnGo@a;b5V,G+<(;&:#3!5#8$3/'&"! #%"$#"! '#$#$%##%%"'!" "#&&##$)$"'##'%#%'$%$$!'%"#$&#$%$!%#%&""&#''#%$%&$('&*"#$ %'#%"%'$%#&&'"$%$"'#$$!##%%  +  + + +    + +  + +         +     +   +  + +  +  +   +  +   +   +   + + +  +  +   +  + + +   +   +  + + +      + +      +   + + +   + +  +   + +   +   + +  + + + +  +  + + +     + +  +  + +     + + +  + + +    +  +    + +   +  + +     +  +     +   +    +         +    +  +  + +  +   +   +  +  +        + + + +  + + +   +      +    + + +  +     + +   +     +   +        %+-"2..,*1*!*!+#."3%0$7+<,=+>1E1G5K9P;Q@R>[E`I\McEhNnTcRs[|]zW`ahsh_^bG@&  +  + + +        +  +  +            + +              + +  + +   + +  +  + + +  + + + +   +  + +    + +           +  +  +  +       + +    + +   +  +   + +   +     + +   +   +      +     + + +   +          +    + +  +    + +   + + + + +  + + + ɄʀquildgZ[WPuNvOoJeDdAX6M3J,A,B$6%7'8'5!2!,(")"%"#$#"%&$!"!$&!#$%%%#%"###""#"!###%$$$ &$$""!"$%%&%"&)%%%& #$'##$#(%$'$##)!)#$'$'*#$$$##&'$%#"%$&$'#$$%(#(#'&$!"  + + +     +  + +     + +    + + +   +  + +       + + + +     +  +  +      +   + +    +    + + + +     +  +   + + +  +    + + +      +   + + +   + +   + +  + + + + +   + +  +    +    +     +        +  +  +  +  + + + +  + +  + +   + +   +    + + + +  +  + +  +      +   + + +  + +   + +    +    +    +     +    +  +  + +   +  +  + + +  +  +     + + + +     +    +  + + + +    +  "**+'+,.%--,.2447:ADDJ N"V"T(Z$[,a%`+h)l,q-p1u3~4}79=57.z%\9     +  +       +        +       +          +    +  + + + +  +      +   + +  +   +   + +    +  +     +        +      +  +     +  + +   + +   +                    +      +    +  +     +   +         + +     +ԃ{|xshdiabUOzNOuIhDr?f8Y3W1B,>(>':"<&8#7"3 /+)%$ #$"$%$#"###$%#%%#%%"#%#$""'#&$&%"# &#%&#'##&#&"%"#!"(%"$&$($('#%#&$$(#"#'$"%%%!&'&#"(%'%(&#'%('&#"%#&&" !!"%& "&!  + +   +  +     + + + +  + + +  + + + +  +  +   +  +     +  +  + +   + + + + + + +    + + +  +   +  +   + +    +  +     +  + +   +  +  + + + +  + + +  + + +    +   + + +  + +  +    + + +   +   + + +  + + +   +    +         +       + +   +   + +  + +   +  + +    + +   +   + +  + + + +  + +      + + +       + +  + + + + +        +         +  +  +  +       +      + +  +  +    +     +      (0!,#1!.*#&!*!)*!- 2!0 2'1)709,A4A2L6A8G8NXDTE^H`K`LdNgSoTv[t^x^eelngcx\X@- + + + +        +  +     +      +   +    +   +  +      + + +     + +  +    + + +   +  +         +  +  + +    +     +      +   +  + +  +     +  + + + +       + + +   +   + +  + + +  +       + +     +       +   + + +     + +   +  + + + + ԏҎ}~srkhf\_T{S{PuHqIfE]9V6J+I.@*B*>+@);&7 3 , ,#&#%%&$$$&"$%"$ $##&% &$$&%$%"  ##(##%"("%%'!$'$'&#)!&"$#%"""$!%&#%$$#&#""$"&%$%(""#%$%'(#'&&#'#( ##$%($"#%$&$""#$"#   +      +  +    + +  +  +    + + + + + + + + + +  +      + + + +  +  +    + + + + +  +    + +           + + +  +   +    +     + +  +  + +   +     + + +  +     + + +   + + +   + + +  + +   + + +  + + +      + + +    + +  +   + +   + +  +        +  +  +  +     + + +   +  + +  +  +        + + + + +  + +  + +    + +     +         +    +  + +  +    +  +  +      +    +   +  +   +   + !$2*,-)-+),./11778:CJ H#I$U#R T#Z(^#c*e*i+o0s-r6z4{2}2><>;1oS+  +               +  +  +   +     +       + + +  +   +  + +    + +    + + +  +  +     +   +  + +  +           +  +  + + +    +        +  +   + +      +   +      +  +  +   + +  +           +            +       + +     Շڃ}y|xqgbaS]MQO|GsHk>a;[7E-M/B)C'?&9):'9 6/)&#%$&%%#)##$""&$%$"%%#%&'$#&#%%$#$ "#($&$$$"$'%"*&#"&$#%#%$% &%"$&&((###' #!&#'''("#'%$"#'&"&&%#$!&%"%#&&$&%#!!&#"$$#$%# + +   +  + + + + + + +   +  +    +    +  +  +    +          + +    + + + +   +      + + +   + +  + + + + +  +  + +   + +  +   +  +     +  +  + +      +        +    + +  +   +    +    +    +  + +  +    +     +     +  +   +     +  +   +  +   +  +  +   +   +  +   + + + +  +      + + +   +  +  + + + + +   + + +   +   + +  +   + +  +    +   +   +  +   + + +  + +   +   + + + +  + +  + +  +   +    + +!(,"/"+ ),)!, , +!/#3"2'5(5&:(6/?/A4D6I6N;UBWAYDUFaFgLeLmQoUmVqT|_`cgiphgjLL4&   + +      +  +  +  +  + +     + +            +  + + +  +   +   + +  +   +   +  + +     +     +  +  + + +  + +  + + + +   + + +  +  +     + +   +  +   + + + +  +  +  +   +  + + + + +  +  +     + +  + +      +  +   + + + + + +  +  +  + + ׈ʃ{{tpmh`aVTQrMiKkA]:P6K+H/D+E3>0@+8)3&5",)#%&#$&(%!"!$$' !$$&&$!"& '%!$&#''%&&(" $"&"%*%&##''$%#!#$&$%#$"#'!$#"""'%$%%#'%(")$##%#&&&$#%"#&$$"$$$$&)#%$&#'"!"&("$&#  + +     +  + + +  + + +  + +  + + + +  + +  +   +  +   + +  + +     + + + + +    +  +   +   + +     +  +   +  +  + +  +  +       + + + + + +  + +   + +     +   + +        + + + +       +   +      + + +   +    + + +    +    + + +  +   + +    + +   + +   +      +    +  + +  +    + +      + +     + + + + + + + +    + +  + + + + +   +     +    +  + +   + +           +   + + +  01-/)'*',.,-155;>ADIJIMV%]'](e+f-c*i,n/s0t/0:<8;=5(g F  +     +  +   +    +       + +     +     +          +  +  +   + + +      +   +        +     +   + + +       +   + +   + + +     +    +     + +   + +  +    + +     +  +          +       +  + +   +  +   + + +     + +  ߂Ձqwnic___RR}KyOt>gA_8T0V,I.J/E+F(C%?%;%3.,#%''$"##$###%%%$!%$%$$)!$$$##%&"#!""%!'"'&&##'%$%%"%&# $&$"'$"#&$"#)#'!%**)!"%!$#()$&$$*$'%$&$#"$$$$"##!&#'&#"%# $##%&(%"  + +    +   +    + +    +  + + + + +  + + + + + + + +  + +   +  + +  +  + + + +          +  + + +  + +     + +   + +   +  +  +   +      + +        +  +      +  + +    + +   + +   +    +  +  +  +  + +  +    + +  + +  +  +  + +  + + + +      + +   +  +    +    +  + + +  + + + + + + +    +   + + + +    +      +   +        + + +         +       +     +  +         +  + +  +  +   + + '/.",#, -)!+*!)"--%.$1$8'5+;*@/B3E4I9N9JVBBL#L"K"N Q"Y%[)^%e)b.j+m0u0t1r37<9=75.t"Q&   +      +      +             +        + + +  + +      + + +   +      +    +    +      + +   +     + + +    +  + +      +   + + +       + + +   +     +  + +  + +         +    +    +         +     +     +   ݁Ҁ~xolf^ZTXNQ}HkAg:_8T7Y0U2S1N.G0G+D$?%64.-%)&%*!&&$&$%&$#&$%%'(%%&##$&%$'$####$# #&&#%%!  %%"%%""##& ''%&#&$$$%%%%%$&'$$&#&#%'&)$)"&&%(%&&&#&(%%%'""#"" &"&$&(&(%%!$  + +  +  +  +  + + + + +  +        + + + +  +   +   + + + + +     + + +   +      + +   + +   + +   +   +       +  + + + + + + +  + +  +    +     +   +  +  +   + +      +     + + +    + + +   +   + + +   +  +  +  + +  +  +   +   +  +   + +  + +   +  +  + +   + +   +   + +  + + + + +   +  + + + +  + +      + +       + + +  +   + +  +      +     +      + + +  +   + +    +  + +   +  + + +    + + +  + +  + + + + +    )(!+!.#+"+ ,$!+!*!00!/#2&6)3*:-?.C1G8L7CX;Z6R6L2P4E,;(8&2$1!*,%$%&"(%$&#$%%%"'##&%$#'$%"%""#$)&"##%#$$&'''%$"$%###$!"('(%%""$"!!%$"%"$$"%$"&&&))$"'$%((%)"%&#+$'&""$&'%'%#  &$(%%'%&&($##%$ +   +   +      + + +     + + +  +  +  +    + + +  + +  +      +  +    + +    + + + + +    +   +   + + + + +  + + +   +  +  + +     +  +    +  +   +  +  +  +  +   + + +              + +   +   + + +  +    +    + +     + + + +   +  + +    +  + +  + +  + + +   +   +  +  +      +        +  +  + +  +  +   + + +  +    +      + +   + + +    + +   +  +   +      +   + + +      + +  +  +   +  +  + + #+-+-))**),-01348=C!E!E!M"O$Q#W(Y$a*a'c,k/g,k/m.w08};:@?88*k!B    +  + +              +   +    +     +     +     + +   + + + +      +   +   + + + +       + +   +  +          +  +    +    +          +    + + +      +    +       + +  +   +     + +     +   + + +  +  +      +      + ߂ۃтzvmlqa\[[OJ~CoBf:`;a4Z6[:T0S.K.I-=(C"4"2.+(&&$%%'%$&$&'')$$(&)%%"'%&(#&!)&%#$"%$&'&%$($)$$###$'&#&%&$%%$$''$()'$($#'%%$)('$&)%($%&&'%'%$$)$%#&#&!%&(#"&$'"&"&%##$'$#'%"  + +     +   +  + + +  +      + + + +  + +   +   + + +   + +   +  + + +     +     +   +  +   + +   + + + +      + + + + + + +   +   + +  +  + + + +  +   +  +   +   + + + + +   +   + + +    +   +      +  + +  +  +  + + + + + + +  +  + + + +  +  + +  + + + + +    +    + +   + +   + +   + +    +  +  + +   + + +  +  +  +  + + + + + +  +  +   + +  + + + + + + +  +   + +  +  +   +     + +  + + +  +  +  +        + +   %.+$0#,'#', )"++#*#.%4&1'7+>5>1A6F8H3N?IBRBVAYGUFdLgMfPlSqXxZt]wjcgiwoo`aI>'  +  + +     +   + +    +  + +  +       +    +     + +  +  + + +  +  +  +  + +          +   +    +   + +       +   +     +  +  + +  + +      + +   +      + +     +     +  + + +   +    + +       +      + +  +  +   + + +   +    + + + +  +   ۇʊÀyxoqkb]^SyTrHf=h>bCZ;V@[4U3O4J0E.E+?(9'/-.''*&$(##&'%"#'&$%"'"%'($'!&&&'!%'"$%''$$'&$'#!% "'&!$'"%%()%$%$&(%'"%% #%%!#')&&$$('&'#&%%%&''"#(%'#(%&'#$!!""(!&#%$&&"'##$ #%"# +  + +  + + +     + + + + +   + + + +  +   + +    +   + +    +    +     + +  + + + +  +   +  + + +    + + + + + + +  +  +  + + +  +  +    + + +      +  + +   + + +        + + + +  +   +   +   +  + +  +  + +   + +  +   +    + +    + + +  +    +      +     + + +  +   +  + +  +   +   +   +     +    +   +     +     + + + + + +  + + +  +   +      + + +          +       +    +    + + *0*/.*-*.*(1,528>DA?IO"R&U%T%_*h'^*a-m0s1o/r5~34;7@>92%Z4 +     +  +    +     + + +     +        + +       +   + + +  + + + + + +       +    +   +     + + +      +  + +  + +  +  +    + +   +         + + +      + + + +  + + + +  + + +     + +   +  +   + + +  +     + + + +      ہڀxskko_`YSRLvEi>j=k>e9^:X3U5U/J,E*A(;):#5 /.*&%%'%#%$%''!%$$%&%#&"(&($'$$)$(##& '(%$$#'$&&&#&'%(&##$#&&$%%%##%#&'()&%%(&(&)+#%&%$$(%''+&#&)'%$'&&#%% $!&!"%!)"(%!&$$$$%)"#!"# +  +       +     +  +  +   + + +  + + +         +     + + + + + +  +  + +  + + + +    +     +  +  +  + + + + +   + +    + +  +  + +   + +   +     +   +    +     +   +  +  +  + + +  +   +   + +  +    +      +      + +  +   + +    +  +  +   + + +       +      +  + + + + +    +   +  +  +    +  +   + +   + + + +   +  +     +        +  + + + +  +     +  +    +  + + +   +  + + +   +  +  + +  !+."/!*#-)!+"*"."+!,#0'3$3*7)>,=2>5D0G3K6J<IIE J N!S%Y$[(^(b-f.k,o/u1v088;<<=70t S"  +     +  +    +     + +     +                +    +   +   + + +     + +     + + + +  +      +        + +  +  +    + +      +   + + +   + +  +   + + +   +      + +       + +  +  + +    + +   +       +      +  + + +    +   +  + +  + +   څywrshjg_]QKH{EpFf?aBb#:!0++'*(%#!$&*#%&$"$$#$%$'%$#%$$%*$''$$'##%&#&$%#"#&#''%$!"&&%##!$('(&(&$&$''%&*&"(&($%%&&&)%%&#%$''&(('''%&&#!$"#'%#&$&$%"&$&&%#$$&$'"   + + + + + + + + +     + + +   + + +    + +     + +   + + +   + +  +  +  + +  +      +  +  + + +  + +  + + + +   +  + + +   +  + +   + +  +       +  + +  + +  + + +   +   +  + +  + +  + +     +  + +  + +        +  +   +  +      + +   +  + + +    + + + + +  +  +  +       +   + +  +  + + + +      +       +  + + +   + +  +  +  + + +   +  +   +        + +      +   +  +  +    +      + +  +   + + +    +  +     +         %.".!*!+ *"+,/!,+#/%6%3&6(8(:0=.A3F5G9M>M:J@U>Y?ZM\NcHfPqNiSxX{Xb`fjuliarKI2  + + +     +  +       +      +   +    +   + + +  +    + +  +   + +   +    + + +  +    +    + + +  +  +    +   +  +      + +   + +    +    + + + +      + + +   +       +    +  +  +       +     +    + + +       + +      ߏމyyukpkZSUzLrMrGmAqDd?`@^;W;T/S-@+D,?&9&6 /!-,%$ "'%%#%)#&#'!#%$"&$&%"(&%$$&&#""&"%$&&%%$*#%% $%"%!"$%&"&(%"$$%%&$%"%'$$)$&%&&&$&&#'#$# $&%&" #&$$ $(#$"&'%(%&'%&*%$($# $##""$*&#     +    + +    +    + +  + + +  + + + +   + + +   + +    + + +   +    +   + +    + +   + +  + + +   + +    +       + + + + + +    + +  +  +         + +      +  + +  +  +   +   +   + + +   +  +   +  + +  +   +  + + + +     +  + + +   +  +  +  +     +  +   +  +    +     +   +  +   + + +    +     +       +    + + +   + + +  +   +  +      +   + + +      +  + +   +  + +  +   + ++1*,-()--,,.0494:@B>"K L$R#T$T$]'](Z'^)l,p.o.r2z3|57?=>;4*n!? +     +  + +     +   +     +    +    +       +  +      + +  +  + +           +      + + +      +  + +  + + +       +    +       +       + +  + + +   +  + +   +   + + + +    + + +    ߄~uqqi]bZULRQsJmDkCcB`9]0B4G6J:K=R;SFYCZI]IeMcOfQnNnS{Yw\~]cjirfdvPV:, + + + + +  + +     +            + + + +     +  +     +  + + +   +   + +    +  +       + +     +  + +  +  + +  +      +   +   + +   +   + + +      +  +   +  + + +   +        +  + + + + +  +  +  + + + +     +   + + +   +   +  ޑՀ}~xsg__`S[QqLpGnEjDd>WH"KL#L%Y"[$\*b)b)c,b(t4w.s4y87=9><52kL'  +        +   +   +  +  + +     +    + + +    +  + + +     +  +    + +   +       + +          +   +   + + +   +     +   +    +   +  +          + +            +     +  +        +  +         +   + +    ݉րrvokgaXOQVK|FsFvDm>iP[8V5Q0E4G2B.9+9&3!+)*')*$'$'''!$")'%$%#'$%'!#$&'$'$$%'&'"#&'&&&%&&%'&&$(#$#%!%%' $""'&$(""($%#&&!%&(#&$'(#$%'##&'$&$)#%&%$"""#$%#%&$&&$$($&&%&$#$)%'&$&&$'#&$"      + + + +  + +  + +  +  + + + + + + +   +   +  +  +   + +  +  + + + +     +  +   +    + + + + + +  + + + +   +  +     +     + + +   +    + + +   +   +   + +   +  + +     +   +  + + + + +  +  + + +  + +  + + +   + + + +         +      +    +  +   +   +        + +  +   + +   +  +  +  +  + +    +  +    +     +  +  +      +    +          +  +  +        + +  +  +  +  +  %,.&)*+.**.-3248:B? GH"J"R"V'R%Y)^*Z.f,e.g/s0w0y239<89>6+e<  +   +   +       +     +   +        +    +      + +     + +  +       + +                   +  +  + +  + +  + +  + +  +    +            +   +      +     +  +           +     +    +          +   z~xvmg`_\XVWMIvGqCnCa>d8W=W8R5O+G'G,@%?#7 1,()&'(&&'%)%#$$'"##!%&#!!""&#%&%%%&"("%*#)$$'&%%&'$&%&%% #$&''%'%$'(%#$$)()"%&"(!'&&'%$&$#$&#&'#%%&&% !(%'" %&$'%'$'&$)#%'$"&&&&'&&$$"!&#! '!    +    + +   +      +  + + +     +    + + + +     +   + +  +     +  + +  + + + + + +     + +  +    +  +   +  + +     +      +   + + + + + + +  +   + + + +  +  +       + +  + + + + +  +   +  + +  + + + +  +   +   +     +  + +  +   + +  +  +     + +  +  + + +      +   + + + + + +      +   +   +  + + +    + +     +    +  + + + +   +  +  +   +  +   + +  +  + +  + +   +      +   + + + +  +  +  +   )/1!' )*%, '!+"-&-".#/(6)6):0=/A3I5C:Q9T9OBX?YGY@]GcOhJnUuXy]zWyhfjdmjj[dC8%  +  + +    + + +              +   +  +    +   +  +    +    +   +  +   +    + +  +  + +  +   +   +  + + +  +     +  + + +      +  +      +  +  +        +        +  + + +      + + + +   +    +      +   + +   ˊՅ~~vmhbb]`SQ|KyPpLoBeC^;X:]i;cW7W>UAZHcS[SmMkWhTpTnWxY^joqnsbtVO7&     +    +     +  + +    + + + +         + +     +    + + + +     + +  + +    +  +       +  + +   + +   + +   +  + +   + + + +    + +     + + +      + + + + +  + + +    +    + + + +   + + +   +   +   + + + + + + +  +  ҊρuhoghlcYYTvZyKtLiDl?c?Y";'8!62-')#&&!&')&&$%%%$$$'('!$''$"&'%#')$'&#$#&&#$#%'%%+&%#!'%&(%($'&%$'#'"*(')%#&#)(#($###%%#&%#$%#&%(&'&%(!!$#")'(&&$&&%!'&$#!%)&'&%"$$$%#(!# &##$$"      +    +      +   +    + +  +  + +  + +    +  + + +  + + + +     + + + + +   + +  + + +   + +  +  + +     +  + + +     +    + + + + + + + + + +  +   +       +  + +  + +  + +  + + + + + + +   + +   +      +   +   + + +  + +   +  +  + + + + +     +  +  + + +  + + + +  + +        +    + +  + + +    +        + +   +   + + +  +  +   +     + +   +  +  + + +      + +     +  +  + +  + +     + ,+".- ,"*(* +!*!-")!2#7%2':+>1;,@3I4J8H:O9T?]B_GeJcJhMlQkPgRv]zYZcclkki_mSD, + + + + +   +   +  +   + + +      +   + +      + + + + + +   +     +  + + + +  +       + +  + + + +   + +      + +  + + + +    + + +   + + +  + +   +   + +  + + + +  + +   + +       +  + + + + +  +  +  +     +   + +  + + ˂}ysppk^^^UR|RyOxLiKhJcB]:X6S7M6G2@-A);(8#0!*+,&$%&&&%''&%&&%$%%%&$*&$###%%!&%%&%%#$#$'$&&#%'$$$$#''&(%&%#*&&%#('(('$(%%)&'#&%&%(!#(%%%&$%%""!%$ "$"!$%($#(("%"&&%''#&'&!"$#!%$%!&%#"&#(##&%   + +  + + + +  +    +   +   + + +  +  +   + +   +  +    + +   + + +   +    +  + +     +   + + + + + + + + + +  + + + +   +   + +  +  + + + +    +   + + +    +  + + +  +  + +     + +  +     + +  + + +  + +     + + + +  +  +  + +  +      +         +  +  + +  +   + +  +   +  +    +    + +  +  +  +   +   +  + +  + +  +  + +       +   +  +    +   +  + +  +  + +    +   +  + + + + + +   +       + (.1-+(-)*.0)2376<?=E!K JR"S#W%\$b'f'g*i*s-p1t5r2{36><@94~+c;     + +  + + + +  +  +    +         +  + +  +     + + +   +    +    +  +        + +   + +  + + +     + +  + +   +     +       +   +         + +        + +  + +   + +   + +   +  +    +  + +    +    +   ؁}zrmjbeZ[RSTG|EuBu>iCh7_8[3T/O/K*E'C"=%56 /,+$&$)'&$'$$%$#'&%&"!)%&%%&'*)&$'!'"*%%&%$%)#()&&"$%%%,'%&%"&"$($%$%&#$)(&&&!%$&%$#&'#%%'*'!%''!""&#(&$"%"'&&'%%'#&&$"!(('%$&"("%&$&$%"(%$$%!&'#'#"     +    + +  + + +      + + + +   + +   +  + + + +   + +  +   +   + +   +    + +   + +   +   + +  + +    + + + +        +   +    +    + +  +   +    +  +  + + +  + +   +  + + + + +     +  +  +   +    +  +    + + +   + +         +  +     + +  +          + +  +      +      +    +   +   + +  +  + +   +   +  +  + + +            +  +   + +       +  +  +  +      + + + +  + +   $*"7#*!-+ )*(!(#-#)$/#5%0'7,7+?0C/D3E4N[?ZJ`I\JgNfPqQoZyV{X~^fcilkmVZB2  +  +  + +  +  + + +  +      +   +      +   +   +    +   +  + + +     +  +  + +     +    +      + +  +  +  +   +    +    +   +  + + + +    + +      + + +   + + +      +  + +      + + +  +  + + + +  +   + +      +݉Ѐ~u{wmkee]`RSzPsKoEl@^=`=PNAYB[AbEeKdLfNkOoTqWtZw\_depnketUN8* +  + +           +        +  + +          +      +      +   + +  + +  +      +  + +  + + +    +   +    +  +  +  + +  +   + +   +  +    + +     +     + + + +     +  + + +   + + +    +   + +  +   + +     + ݍҀЅwqwrlda_YXVyMyFqIoCe=^>W;[8N4J.D/@,?*4#4"0)'(+#&('$&'&"#"#"(%((&%%&%"'#&"&&(%'%(%')"%)%(&&#(%(&%$#'&%%##&(+%(&&#&%)'#%##'$$$'&'$(%#(%')"%%"%$(&%!"#&'$(&$$"&$&$%#%""(&'&#*(%*"*"($#$("%#$"#%##   + + + + +   +  + + + + +     +   + +    +  + + +    +   + +  + +   +   + + +   +  +  +  +   +   +  + +  +    +    +  + +  + +  + +   + + +    +  + + +  +   +      +  +  +   +     +   + +   +   + + +    +  +     +      + +     +  +     +  + + +         +    +  +  +  +  + +  + + +   +  +    +  + +     +    + +   + + + + +    + +              +      +    + +  + "&//.*,*))+*/01346>>E LQ M!Q$U'V'[(c'a+e/k)m2p/56~77=A;2-r"D! +           +         +   +     + +  + +   +   + +        +         + +    + + +  +   +   +  +   +        + + +  +    +      + +   + +   + + +  + +    + +   + + +          + + +  +  +  + +    +      + +y׀rttm`e_a\PSGzEwBpCtDh?b5W4R0N0J.G)D'C'<#7 1-+*&"$)'!%$#%'"'#'%$#%'&%%&$)&#&*&&#$&'&'#&%$#(($%('"&#'&"''&),$)#*&%&(%(&)#&&&#&$&()&!'&%'($&&)$##%$('!%$%&%$'()%+$$#"''"'(&$&&%&%&'"'#"%%%)%%#$%"('! +  + +  + + + +  +    +    +  + + + +  +     +  + +  +   + + +      +  + +  +  +  + +  + + +   +   +    +  +  + +  +  + + + + + +    +    +         +   +       + + + +    + +   + +   + + + +    +      +  +      +  +    +  +  +   +     + + +  + + +  + +  +   +       +  + +   + + +    + +    +       + +     +  +     +    + + + + +   +      + + + + +   + +   +    +    +  +   +    +  , 1"/ , +,) +/ )!1+"4&2%4'4*<.@/@5G3F9L6M>V?WB\A_FbDgLfSsUwUqZtX}`f^mklo}agIB+    + + +     +   +  + +    +    +   + + + +    + +   +    + +  +   +   +  +  +       +    +  + +    +  +  + +     + + + +      +   +     +  + + +  +  + +    + +  +   +    + + + +   + + + + +        +   + ؇̓||‚{qki]^]UU{LrKrMrBh<`?^:Z6N5L2D2D(<+6%1"/'()')&&#$%%&'&''&($'%$#$"&#&#'$)%"&)"(")))$(%#%#'#%"%)#'$(&%"))'"!'%*&%'(%'"&$%$+(#%$&%+&'($&'!&%$$(%&!!%&&"&'($$$%&$('$'&&%'&"$"%&#$#$%&'"'%%$%$$%'"$!    + +          +  +  +  +  +     + +    + +  + +      + + +   + + +    +  +  + +    + +  + +      +  + +  +  +    + + +   +  + +  +  + + + +  + +      +  + +   +    +    + +  +   + +  +    +   +  +  +  + + + +   + + +  +   + +  +  + + +   +  +    +   +  + + +      +    +   + +  +  +      + +   + +        + +    +  +  +  +  + + +      +   + +    +      + +       ")/1)*,,-,*-02086=@?GH#N O$U"U'W'`'^*d)c+q,j-y2|6w;8;;=72}+h>   +             +  +  +         +   + +   +   + + +             +        + +    +   +     +   + + +   + + +          + +  +     + +    +  +   + +  + + +  + +  +    + + + + +   + +   +         + ۈzuyvsdibcUXSN|KqDoHl>g<\9`2W1S1P0K,C'=$<#6#1&))&)&*%&&#&&'('&''$#&%'%$'%$'&%%(&(%%"'"$&('%'&##&' $))&$&$#%&%''%&&#&%$&%'#'&%#&(#&$'&')'((&$&%'($"#$""&(&$#))&''%%%)'&&$%%$#%"'$%%#%#(#''''&&'%$$'#%#"!  +    + + +   +    +   +  + +  + + +  +   +  +   +  + +   +  + + + + +  + +   +    + + +  + + +     +  +    + +  + + +  + +    + +  +    +  +   + +   + +         + + +    +     +     +    + +  +   + +    +   +           + +  +   +   +   +    + +  +     + + + +    +     +  + +    + +     +  +         +   +   +   +   + +  +  +  +   + +      +   + + +  +  + + +   + +  + +    +     + +       + ),+"-",+#0- ,!'+/#)#5+2$3*=.8/E2D2A4I3M8R,D4H3J8K=X=UF_FYG_GeQgVhUxSnZyVy]xbgcmjiesRP;+     + + +     +  +  +    +  +     + + + + +  +   +  + + + + +   + + + +    +      +  +   +  +   +  + + +  +  +  +    +  + +    +  +    + + + +      +   + +   +         + + +   +     + + +    + + + +  + +   +     +  ُيՄƃz{vofdaYXWRzSxJqJjDe<]`8Z9Z7S5P3G/C)F+9 9"5 -.)$%&%&(%&$&#&##'$*)%%%%&"&$(*&&*)"*$*'#$!%$%#&#&'%#%##%%&(%&*&$&&#%('%&#&$&&+'%$''$((#(()($%&!$'%'#! %''!(%)&&('&%%''''&%'#"$'$(%%&&$'&"%&'$$)''$"#%%''%#" + +   +  +   + + +   +  +  +  +    + + +    + +  + +   +   + + + + + + +    +   +    + +   + +   + + + + + +  +    +  + +     +    +  +  +      +   + +  +  + + +    +    +   +  +          + +  +    +   + +   + + + +      +    + +   +  +      + +  +      +      + +      + + + +   + +  +  + +  + +     +  + +  +  + +   +      + + +     + + + + +          +   +  +  +   +  + $-0#0 +)+-,"'".".!1$2&0&5,6,>,>4C/H8N3M5O;Z>UEZEYEcNeLkNhQvUxXm[}_abaopnfnKD. + + + + + + +         +        +  + + + +  + +           +  +  + +                +    + +  +  +   + + + +    +   + +    +  + +    + +  +  +  +  + +  + + +   +  + +  + + +        +  + +  +  +   +  + +    + + +  +ޕ݋׉ӊ|xnmoh^bWW~MvOpJqJpGd<[n=c4Z6Z0K,K+K,G#>&=#40-*)'&'(&'&)''&')%+&&%%'&&&*"&'%&&,$)'(,&&"('(*'%%&%%'&)"&%&'$$#&($%(+'&%'&($&%%%'(&$''&&(&%&#&*&)&"&#%#'$'$&#&#&%'$%"&)#'&''$'&#&%$*%''%"%&'&$(%,#($+$&!$'%##*!  +     +  + + + +   +     + +   +   + +   + +  + + +  +  + +    +     + + +  + + + +   +  +  + +    + +  +   +    +   +   +  +  +   +  + +   + + + + + +   + + + +   + +        + + +  + +  + + +  +    +     + + +  +   + + +  +  +   + +  + +  +      +   +  + +  +     + + +   + +   +     +  +  +   + +  +       +    +  +    + + +  +       + +    + +   +  + +    +  +   +     + +     + +    +&+!0$+ /(*"("'+.!-"1$+&3'7*6)A0A2D3E9M8R:U:SDTE\F^FdJiOnOpVsVrW{[{\fgkoof~\_>4#   + +        + +    +  +   +     +    +             + + +   +  +    +        + +    + + +  + + +   +  +         +  +  + +    + + +   +    +     +         + + + + +  + +  + +   + + + + + +   +   ޔۍ׋ЇxzxrgihaZU|P~HvIqChBa=\?T9O9Q5I.E/>)?&7"4"0+&'*(),*)($%(&)%")%'%#*&%'%$'&)&$#%*(&)$)'%)'')&$(&*%&'&(%&($(%%$&'*$%''*(%%%'(&&"$&(()$$'&#'"&&(&&$!$#' %###%$&"##$+##%#%'#'%'(&%$%&&%$&%'&$"'%'%&"$$'"&'#!%$%  +  +    + +  + + +  +  + + + +   +    + + +     + + +  +   +  + + + + + +   +     + + + + + + + +   + +  + +       +  +  + +    + + + + +    +  + + +  +   + + +  + + +   +   + + +      +         + +   + +    + + +      + +    + +  +     + +   +  + +  + +   +   +    +  +   +    +  +  + +      +   + + + +  + +   +  + + +  +  + +  +  + + + +  + +     + + + +  +   + +   +  + +    +   + +  + +   + +-.1.***(*.*/0226:@ABE E#R#P#X)V'`.`(f+d*n-l3w/r2y2~:9;>?83}%W.                     +   +     +    + + +      +p    +  +   + +  +     + + +  +  + + + +     + +  +    + + + + + + + + +    +    +       +     + + +  + +  + +  +    +    +  +     +   +     + + +      ߄݁u{xjhgi]XZUPJ}Ft@n?c>b;\9R4U3L/F/D&A#B"8"3*/()(&)+&*''&$'%%'&&%%&%%$$)#*%)&*&)*)&'$*)#*)&('()&$&&*'(((&&$&(&#)&%''''%#'$#+()$&&(""$'' '('&"#"# %%)%#&%#%'($!%)'$(#')"$&$&&&()#&%$!"('%$&$(%%&(#$%"$&%%$)!%#      + + +       +   + +    + +  +  +  +      +   +  +  +  +  + + +  + +  + + + + +  + + +  +  +    +   + + +   +  +  +   +  +  +      + + +  +       +  +  +   +   +  +     + +  + +   +      + +   + +  +      + +  + +    +  + + +  + +  + +  +      +  +           +    + +     +      +      +  +  +   + +    +  + +  +  + +    +  + + +  + + +   + +  +   + +  + +     + +  +   +   + +    ")!/ ."-#(*%,!,",-&.%-&4$4(9+5+@.>6D5F9K:OUA^HWHdKaNoKmSjUsUtYzabckmgjbzST:%   + +  +  +     + + + +  +    +     + +    +          + +     +   +   +  + +  + +       +   +  + + +   +   + +    + +        + +  +    + + +    +   +     + + +       +  +   +  + + +  + + ߓؑӄ|}utsoihaY[zVtNwLqGe@_C^>];Z9P2K0D/@-<)8'2"1/**)%&$')&$$&"'"&'$'*(+&&%&)$%(&%#')'($)'&(*&'%$%(($(%'"$"&$$'$&&''"&$&&$+$'$#'&"%%'%''#%%$$&&&(#&$!&$'#%$'$$*&&#'&)+%%%%###&'&'$$&$$%&&'('%#&&"'&%'%%%%"($"(!&##$  + + +   +  +   +    + + +   + + + +  + +   + +   +  +   +   +  +  + + +  + +  +     +  +  + + +   + + +   +       +    +    + +        + +    +   + +   +  + + + + + +   +   +    + +  +  +   +    +  + + +     + +  +     + + + + +  +         + +   +    +   +   + +   +   +       +   + + +          + +      +       +   +           + + +  + +  +  +   + + + +    $(,/,)+&,-))/52<:<D@JJ"K#L%O%\&T'^&f*g/i+l1n,s0w5789=B=5.z#I!      +          + + +  +          +   +    +   +   +  +    + +    +  + +  +   +    +   +  +        + +  +  +    +        +   + +        +   + +     + + +  +    + +      +   {|prrhhd[bWPJ|J{J{@l@j>e2`6T6U0N.M+G*A'6"6!3)*(%*))*&($'&*"'#'*((((&',&*+*)&,)&')&$((''$#)&&*&'&+'%&#'%'&&&("(&)*)#,%#$)'(&)#%#(#+(&#($%(%'+$&##%#%%$#')"%'&'$%''#(&(#&$%%%'&''&%'%&%)&'&&%&%&''(&'%##'&$%$"'$&! + + + +       + +    + + +      + + + + +  +    +  + +  + +  +      + +     + +        +  + + +  +     + +    + +  + +       +  + +      + +  +  + +  + +         + +        +  +  + +  + +     +    + + +      +  +  + +  +   +     + + +        +  +  + +   +  + +         + + + +  +   + + + + + + +  +  +    + +    +   +        + +  +   +  +      +  + + +  +  +  +  +    + +     +  #+1 ,*( &+-"'") ("/#1#2&5(:(B*<0C3D7M9J>O@R?P?XE]K`IeOiPjRrY}X}X~^befonldoOC+   +  + +        +       +   +  +      +    +    +         + + + +   +  + +     + +  +   +   + +      +    +    +  + +   +  + +      +     +  + + +  + + + + + + +  +   + + +     +  +  ݌΁v~ulnh]b[Y~QLrKuGmBf>\@^8^8S7J2G0B)D*7&>#0. -()''&)'$#*%')(&'%%'&#$&%'&)$()'*'$&''&''$#(')'%')('&'&"&'*&"&&"%'&%%&('(%$$)&&)$$")&%&*'$)&'$%)% &(& %''%)#&#)&'#&$%'(%&($%($%'%($%%&#'&''%#%('$"#$$'%$$" $(#$%)(%"    + +  + +  + + + +  + +   +  + + + + + + +    +  + +  + + +   + + + +  + + + +  + +  + +        + + + + +  + +   + +     +  + +  + + +       + + +    +  +    + +   + +   +   + +   +   + +      +  +   +  + +  + + + +   +   + + +   +   + +  +  + + + +   +  +  +  + +  +  +     +   +  +    +          + +  + +   + + +      +   +      + +   +  + +   +    + +   + +      + +          + &--.)))'(,,2/258::A@EI!MR#S#U*Y'](\'g-f,q/k0y2x0y7:;<==9*e?   +     +  +             + +    + +  +     + +            +  +      +   + +   +       +    +       + +   +     + +   + +  +    +  + +       + + + + +   + +  +   +  + + + +  + +   +  + ك|tmjgca[SNPMwGrCrAl>hB^;X4T1P1I*F*A);&:!5 .)**-*'**$((&&'($(&&')'$)'(,'$('($&&))($$('&(''('')'"%%'#&&!%&+"'*%$%'&(%()%%&'''&'$$'%$)('''))'$#!$&#$$#')$#(#'%!,"$#%)$#"#$&$%)(,%(#&$')$%%%"'%%$%%'!#,&%#$$"%"$ $#%  + +  +   + +  + + +    +   +   +  + + + +  + + + + + + +     + +      + + +     +  +  +   +  +   + +   +  +     + +  +   +  +   + +    +  +       + + + + + + +   +        +       +     +       + +  + +   +   +   +    + +   +  +  + +  + +     + + +  +  + +         +  + +  +     +   + + +  +      + +       +     +   + + +  +   +   + + + + +   + + +  +   +   + +   + + + + +   +  + +  + ++-",,#(*)+'.+"2!3$0%2+2*9,B1?2A2H7N;P8TAYC^C\GaMeNeQlOhQsTvdzi|_]jjhog_hB7"   + + + + +          +   +            +    +         +    + +           +  + +  +     + + +     +  + + + + +   +  + + +     +  + +      + + + +         +  +   +    + +  +   +   +  +   ޑ݉܅~}pjlfa[VOJwNqIcKdEb=\AU5T5I4H.F*<':&7$3-)&,)*()&%*)('/%&(%,)&*'*)($'%,()"()&)++&&(*'((%$%'%%#'*()%'(#%%&#)'$*%)&"$'''#%#")%&&&(%''#%$'(%&$'(%#&%&#%'&$('(&*%)+'&'%('#%#&"'$ %&&'"%#%)"#'$$(% %$#(&%!#%($&'#$"#    + + + + +  +   +      +     + + +  +  +  +     + +    +  + +    + + + + +     + +  +  +  + +     + + +  +     + +  + +   + + +          +  +  + +  + + + + +  +  +   + +    + +   + +  + +  +  +    +   +    + + +   +  + +  +    +    +    +  +     +    +  +      +  +    + +   + +      +   + +    +  + +   + +    +  + +     + +  +   + +  +         +    + +   +  + +      + !,/1.),)-'--/-558<8BBF KL![&V"Z&`+[)f)d+m-j,u6x3y35;:?>=5+X-   +   +    +   +       +   +   +      +        +        +    + + + +       +               + + + +      +      + +        +  +       + +  + +   +  +  +       + ݂قyqurj_aZURQxJ{ItHtAhCe=a9Z6P1P)P2J*=)B$7"51+.)'(&%'%*$'&&)$)(&**$)&)(&*&)'&*&*'%$&&&)%"'&(%&(%('$'&*&('&&(&&))&&(&((&-$(%&&&*%&('((&$&'%%'$#"%%&'$&'''((%%')$)%%&%$&$(''((%!&$$#''$$($%&'"%&&$#&#%''%%(&)'$#&&"# + +  +   + + + +  + +  +  + + +    +  + +   + +           +    + + +   + + + +   +  +      + + + +   +  + + +   + +  +  + + + + + +  + +  + + + + + + +    +    + +  +   + + +  + +  + + +   +  + +     +  +    + + + +  +  +   +    +     + + + +   +     +  +  +  + + +     + +    +  +    + + +  + + + +  +    + +  +  +   +  +     + + + +   + + +   + +      + + +  +   + + + + +   +  + + +  + +  +  +   + + +    + %+-#/$,)(( *!1 *!.#-$0!5'4%7,:2;2D2C3J9L7L>X@X=;<5-y#K$      +    +   +  +  + + +   +  + +  + +         +        +  + +  + +   +  +  + +  + +   +     +   + + +  + +         + +   +     +  + + +   +  + + +   +   +   + +     +      +}~{{rlge]`XXQP|IrIxDo?k?b;^7L5R.I.H*?*>%9"11.'()(#')*("+)*$**))()(%'(((%('*$)((*)&($'&!&(&('&(%&%&%$'$%%'%&&)%$(+%%%&##))(%'&%((%%$%())'%$$$%$(&$%'&$($"$$+$()%&')($%$")')$&%&'($&$&''%'&($''''#$%&"&%$$#(!$$$'&"&&!  +  + + + +  + + +  +   +  +  +   +    +    + +       + + +  + +  + +  + + +    + +  + +  + +   +  +  + + +          + + +   + +  + +      +      +  + + + +  +    +   +  + + +    + +  + + + + +  + +         +  +  +    + +  + +    + + +   + +    +  + + + + +     +    +  +   +    + + + + +        + +   +    +  +      + +  + +     +      + +  +  + +      +  +  +   +    +  +  + + +    +  + +    +   '-"3-,"("- ,&!(-!.".%3"1'5*5)=0C->2DQDSDYH^HbShKlPmWmW}[~[bdhildiboSEHM"T!Q#R"]$]&b*`)e+m/j.u0r5}2x9A<;0y'_0   +   +    +    +     +     +      +   + +  +    + +   +   + +     + + + + +   +   +   + + +   + +     + + + +     +       +  +  + +   +  + +       + +   + +    ~}~tvpniaVTWMFwHtDo?f9e?\3U5P+M.K*E+;&:!4"./,)"%&),)'&$(-),(+%'&'('$')$*&*-&(+'*(*''&)('#&((%'&('%$%('*&)')($%'$)%''$&#&'&'('*(&''%)%)&'()'%))$'%"%%("&($''(%$$$-&*(*$%&%%$%*$&&%#&'$'$%$(&'''&(&'$#&&$'%'%'%%%&!*%&&""&# + +  +  + + +       +    +  + + +  +  +     +    + +  +  + + +   + + + +   +     + +   + +     +        +  + + + +   +         +    +    +  +    +  + +    +   + + + + + + +  + +  +   +  +    + + +     +  + + + + +       + +  +  + + +  + +    + +  + + + + +      +         +  + +  + +    + + +  +   +  +    + +    +          +      +  +  +     + + + + +  + + + +  +  +      +  +  +    +   $,"0!,)&!*',"+*!.!,'5#6(5,7%<);/C6E;F:K5S>R?[C\@YHgGaMeQhWnOsU}`y__jjpwihzVO9'   + +      + +    +  +   +   +    +  +    +        + +  +    +    + + +  + +        +  + + +    +  + + +  + + +  +  + +     + + + +   + +     +     +   +     + + + ֌ڍԄ{xxnuji^X]Q|T|QoKnHlBb?Z8Uc;X;X5V4K/H+E&?&8#9 --))+)*&((())'*)(((),,'(+(')$+(+)')&'%&,,*(($+)(&%%*%%(()'#+)"%'$(%&(%&&)&$'))(&'(%'%%&)($&$%%%'!!%$($($%&#%(((&&"$%'$%($'$&$*#'+&'$)&&+(%''$+$"&$&&$('#$&%*)'&&%&(&&#"*%)')%&%%"# +   + +   + + +   + +  +  + +  + +  + +  +   +  +    + +    +   + + +  +  +   + +   +     +  +     + + + + +  +  +   +   +  + + + +  +  + +    +  +     +   +  + + +   +   + + + + +  + +  +   + +  + +    +       + + + + +    + +  +  +  + +   + +  + +   +    + +  +          +       +  + +       + + +  + +     +   +   +   + +  + +   +  +     +      + +   +     + +  + + +  +   + +   +  +  +    + +'!3$/..!,("( .")!.$/(/%2%5*;/:)@1@4C3J6K;J9U=TCRFbJ[IdMiTjNvOoXqU{_dfinppkdpQD.  + + +       +        +          + + +   +  +   +       +    +  +  +  +  + + +      +  +  + +  +   + +  +  + + +      +  +   + + +  + +  + +    + + +  +  +  +    ֊ɂʃÀtytidbY]S{RzSuJhEiCb@`8V7U5O1I-G(9+=#4 2 --+'*%(,*%&*+&+%+)'()))''*+'%'*',*(,#&'(%&(($)'('&#*&%&'&$)%('$()'&&$)*%$&$"&&)+$'*('%*(%)%(&$ $()%%*(&()&%%$%&'&($#'(''&*#)'%$%'&()#$%%('$&&!(''&&#%&('&')%*#'$&'&&&'&&&''($'###   +    + +    +  + +      + +   +     +     + + +  + +  +  +   + + +   + + + + + +  +    +  + +   +      + + +       + +  + +   +  +  +  +  +  +   +    + + +  + +     +    + + + +     +  +    +  +       + + +  +  + +   +     +  +    +     +   +  +  +   +    +     +     + +     +    + + +   + + + +    +  +  + +   +     + +    +   +       +  +     + +  +   +    *0.1*,.-,+/10275?<= I M!K"HV"T)`*[!d*c.h-j)q-w1u5}4y;<<=?A7'i> +   +               + +         + +    +       +   + +  +       + + + + +   +    + + +     + + +  +  +    +  +          +      +   + + +  +   + +   + + + + +  +    +   +  + |{uvlifW[[QQMIyHhAq>eL:T@UAWDUDbDgLdPcUrTgVtWu`{`}agjiqll]gA4" + + + +  +     +   + +  +   + +  +     +     + +    +  + +  +     +    +        + + +    + +  +  +      + +        + + +  +   + + +  + +  + +  + + + +   +   +      фʂ{zrtjd^_VU}RxOqLmHp>]?^9[(:)7 5!( . '+)*$)((()()()''%)**(-'*+*+( (+(+'&&&&*%%&((&&&'$%(')%&%'$'#&!(&,''*'#('()('&'&$("(&($+&,#&%%$'%&)'$(#%,&'((&&,(#(''%(%'($'#)%'&%'%(#$%&(%$$&$%%*&&$$)%&%%&%#)$'&)&&"$&&'%%#$#%&&$  +  + + + + + + +   + +  + +    +  +    +   +  + +   + + + + +     +  + + +  +  +     +  + + +  +   + +  +     +   + + + +  + + +   + +  + +  +       +  + +         + + + +     +  +  +   +  +        + + + + + +  +  + + + +   + +     +      + +  +  + +   +    +   +   + + +    +   + + +         +      + +   + +   + +  + +    + +         + +     +  + +    + +  +   +  +  "-01/,,(,),,112488A= G"G I#Q"S!U%X&e)e(h(e/u+q2{2w5y768>;e;X9Y3L2N/J+B%=';$10".,+*+%-(+)+$''.&,++++'(,(***+(&+*&+%,&'%)''(%)'*(*%'%)'#))'&&&%#%'$$&)'%'*('$'&)&%%$&))'(,'%%%%%&%$%(#($(("&*%$(')'&(*($'+&$&('("(&&)$&'(&'((%'*%&)(#'('($%&%')$'$")''"'%)&%'%*"$"!"   +   +   +  + +    +  +  +  + + + + + +    +    +  +  +   +  + + + + +  +   +   +    +  +   +   +  + + +   +  + + + +  + + +    + + +  +    +  + +  +  +  +    + + + + + + + + + +   +  + + +     +  +  +  + +  + + +    + + +   +   +           + +   +   + + +     + + + + +    +        + +  +  + +  + + +  +   +      +  +     + +  + +    +      + + +  +     +    +  +  +    +  +     +  +     + +    +      + + +  +   )."/$,!,". '+ + ,.$2 1$-%4*7*7+<+:/B/G3K:M9Uc=]8Y3P,H1I-B)=%:$3 4 ..+**,)%(''***,+*)-**)*,(%'+++&-"*(+-.'('%'*)'('&+*%(&()('&'%#)(!&$*)$()%*&%')*'''%%"'"(%'%*#&*&%(-#'%%&($%%&"'*,'&'')'&%)&&*)(%'(%&'&&$&($'#%$'+%"&,$(%&(''*'#'(%($%#&##%''(#%"&(%#"    +  +  + +  + +  +  + + +    +    + +   + + + + +     +    + +    + +  + + +    + + + + +   +  +   +        + +    + + +  + + + + +  + + +   +   +   + + + +   +   + + + +   +    + +  +  + +     +   +    +  + +  +      +   +   + +     +   + +    +  + + +   + +  +   + +   +      + +   + + + +   +   +   +       + +   +  +         +   +   +  + +      +  + +     +  + +     +  +  +  +   +   +  + +  + +  '1!/&0#/)(+$( .-".#.'2%3$9*<);/A3H7K8J:Q>Q>UB\F^IbH`LgSsRmRoVz^{\~feljopqkuRS7        +   +   +      +   +     +         + +  +   +  + +   + + +  +     + +  +   + + +  +     +  +  +    + +   + + + + +  +      +   + +  +  +   +   + + + + +  + + + +  +  + + + ׂ~vqtqmcdUZRPrOqGeGi?\CY;\;S4M2F0E*8(8&2$0.',#*(,.,*(+&,*((+&''(*+'+')+)'+*+)'&%),)))()''($'+(&&&()*'')&#'&)(#*+(&*&(%)*&&%)%&$,)''''$$($'#&"%$)&(*''%&%(&'%&'($(%&&#(''(%'#'))$%%%($%'(&$%*"$%(&&)$%'$'$'%$#'"#)'$&&&('%*#%&#%'$" + +    +  +       + +  + + + + + +   + + + +    +    + + + + + + + + +        +      + + + + +  +     +  +  +   +  +  +    + + +    + +    + + +    +   + + + +    + + +             +     +  + +  + + + + + +  +  +     +       +  +  +  + + +     +  +  +      +        +   +   + +    +  +     +  +   +    + + +  +  + + +  +  + +     +   + + + + +      + +  +    + + +     !+/42,,,,*+/+/78;:;AGM"P"Q%T#^$V*`&\*j/i,m-d/p*r/;77??FB;4z%E   +      +  +      +   +   +  +     +        +   + +  + +              +     +   + +        + +     +  +  +       +  +      + +  + +        +           +݂߄ـywqmgaXWYVNMFtEn>hZ7\1W3O0J,F(A)A%7 4/+*+*+-'**)-*(,).'*0++(,,*,%(**-(+))')('+*#'()&''''&((('**%))('*&&%'*'&*)%$&(&)''&)($(('&%%"!)$%''"%)&)&)#(($)#'',%%#)(&%((*"()'(+('$%'()&%$&$%&&#&"$*')%*$($')$%')%''#&%*%(##'& $'$#%'"#   +    + + + +    +     + + +   + +    +  + +   +      + +  +  + + + + + + +        +   + + +    +       +  +      +    + +   +  +  +    +    + +    +    + +  + + + +     +    + +   +     + + +   + +   + +   + +       + + +  +   +    + + +   + +  +  +   +    +  +  +      +  +  +   + +   + +   +   + + +   + + +  + +      + +  +   +    +  + +   + +    +    +  +   +     +   + +   $,/!3$.",!*%+( +$/!.!/$0#1'5&4)8094@2G6H9O8O=P?RLWG]JcKiOiLiSoUoZz[y_zh`homt}kf@1     +  + +        + + + +     +  + +       + + + + + +  +      +  +  +  +  +    +  +  +        +   +       +  +   + + +    +  +  +     + + + ݒՄшyxxmfdd^YVRwRwIpBgCc>b7R1U7N1E1C'?);%2$1"+..(-)**+*+&(,!-,++).' )((**,()&+))'*(*+*)**'-(')%('$*))*%()'(#)*(&)())(*)%(''%$+*'&+(%'($))(##($+&*%&*%'&%&'%%(")'%)''(''(',*#%($'&%&&+'&'%%&&&&%#')''%#%'%*%#''#%%%%%&$'%")&'(%)$&%)&&#%& + +   + +  +  +  +  + + + + + + +  + + +    +     +        +     +     +  +  +   + + +  + +  +    +  + +  + + +  +  +       + +    + + +   +     +   + +  +   +  +     +  +   +    +     + + +  +     +     + +     + +       +   + + +   +  +  +  + + + + + +    + + +  +      +   + +   +  + +     +  + +       +    + + +    +       + +     + + + +   +   +   +  + + +    +  +   + +  +$04..*),,'1/10-7<8?CDF!K P!T%U$Z)a+g-h+r*g/w5s3w.z68z=C;H<4*T!    +           + + +      +    +      + +   +     +      +         + +   +   +       +  +     +   +  + +    +  +         +  +  + +      +  +  ބ{{stjqjZX^PPwO{LnFpGh^9S1P5G,I)E*?'2%3!3,,+)*,.)*+*,))(*--+)+,&)+('*(**++(%*(&'+,*&,-+)%*()&&''&'%&%))+)%%*"))*($'$')*)*'*%(%(&()'$')(&$&&%+**(+'&),,&&()%$)(!(#,&&$%&%&'(")(')&$&'')''''((&%$((*&'''$&$#&(%&%'&&&*'(#)%&&$(&'%&(# + +   +  + + +  +   + +      + +  + +          +    + + +  + + +  +  + + + + +   + +  +   +    +     +     + + +     + +  +  +  +    +  +  +   + + + + +  + +   + + +      + +       +   + +   + + + +   +     +       +     + +  + + + +  +  + + + + + + +  +   +  +  +  + +      + +    +        + +  + +  +   + +    +  +        + + +        + +    + + +  +   + +   + + + +    + + +  + +       + + &!1#0!2 +#(")*!. +#. .%0%3(5):+7.A,B1D7B8H7K,C4?3M6N=Q=U=T>[@\NaKfTkLgYpYtXzU}b`hforqmhvRF2   + +  + + + + + + + +        +   +   + + +   +   +         + +   +  +    +  + +   +  +  +   + +      + +   + +  + +  +  +  +  +  +   +  +     +  + + ݄ҋЁwzskg\a\SRxOwJuGiCdAe@X;W7P2J1I.D*A&4&4!0-,+))/).!*'(+*,+-)+'-(*'+*!+)+&++)/+))*,++('&%)+)('%+(')(*'*'')('!%''(%&&)()&'*&)((/'(''#%%$%'($%+$*$*%*%')&''%&'(&(*$(*$''%'"(%''(#$(%$%'')*,'&&($'%"("%()+$)&&(%&&*'&%##'$%'%%')$$)%%&($&%(%&     + +   +  +  + +  + + +   +    + + +   + + +      +   + +    + + +   +  + +  + +   +     + +    +  +  +    + +   +  + +    +  + +    + +   +  + + +   + + + +   + +  +  + + + +  + + + +   +  + + +   +     +  + +      +         + +  +  +  +  +  + +  +     +  +  + +  + + +   +     +     +  + +  + + + +   +  +   +      +  +    + +      + +   + +   +  +  +    + +  +  +  +     +%1100+-(,&-/13019?C?E H J"O$Y(T$`&]*`'b*n-f1o1n1}6{58>?=@?8.s B +                 +  + +    +  +   + +   +   + +        + +  + +   +  +    + + +    +  +           + + +       + +   + + + + +            + +    +؁~xuwhe`^\YXMJ|Ju@lEd;b:Y6W4Y/M.J,B(>#;$54 ,*- (+)').()-))++/.+)0***)-+*,'*+)'*(-)*%'*)&)#%')'(+0)%$(+$)((**,)+('#&*&*'%*&''&(()'#''($!$('(**%&'(%#(&&&*%%*'()$*'&)&($'((#+%#&)&+&')%&*''&($&%%&%&"#'%''")'%((%*'%()'&)('$(('%"&+()&#%$%%"       + + +        + +   +  +    + + + + +  + +   +  + + + + + + +      +    +    + + +   +  +   +  +    +   + +  +   +  + + + +  +   + +    + +  + +    +   + +  +    + +   +    +  +    +  + + +  + + + +     +  +  +   + +    +        + +   +   +   +    +   +   + +   +    +  + + +     +   + + +  +                     +    +  +  +          +     + + +     + +  + +  +   + +   +     '+$6%1%1#*/ ) *!+%-!-,%1&5%3,;);1;/C2J5J4J:R:[@_B\K\IcKhRlSiZk[yZ}bjfckmmqqa`E4#   + + +  +     + + +   +      +   +     + +  + +    +   +     +      +    + + + +  + + +   + + +  +  +  +  + + + +       + +   + + +   + + +  + + +     +  + ݘޑЍуŁ~rqif`d`VZvOrJsEoHb@^?^;Y8T4L/K+B+;$;*11./ ,*,-**+,.()-) ),-*/'-+** &0)(*)*+-++*))#-%&%%(*))*(-*)))*(('*)))(&))&)''(+**"()#'$$)()+,&(&%##%**(+)&('%$)#(%*)*&()(&)&$(%)()&(&'&''&&%&''%("&#'('#$)'%&&&'))&&#)('$%&'%$%"$$'##')%(#*'&'%%'''&!  +   +   + + + +   +  +   +    + + +  + +  +          +      + + +  + + +    + +   +   +          + +  + +  +  +  +  +   +   + + +    +   +  +   + +       +  +    + +   +  +  +   +   +    + +  +    + +  + + + +  +         +  +   +       +    +  +  + + + +    +  +    +    +   + +    + +  +   + +  +   + +  +   + +  +    + +  + +   +  + +    +     +  +  + + ,122/+*)-/2./2195>;AGF R&M#N%V%\*a.`+h*p-p3v.|5}6687<@A>6-d3 +         +   +  +   +      + +   + +   +   +     + + +  +         +  +  + +  +   +    +  +    +  +     +     + + +    +    + +   + + +   + +     ށ܃ʁ‚siodb\YSPPxDtFjDiAc9];T4S6O-J.H*?$>"7!3,+0)-(()),),(+$+*()-)')./(++(*''+.-**%/,+')%**(.)(.)'&)+&*((&($+$)((*&*+$)((*%()))&&'&)((#$,%$*$&(&&((*$&(&()''&%)$)((*)'('(%(%($''*#*')&(%%'&)&&*)"%($(**)'''*('&)(%$&''''#)'&&&'(%%"'(%$#%$))#" +       +  +      +   + + + +    +  + +  + + + + + + +  +    + + + +   + +    +    +   + + +    +         + +    + +  +    +  + + + + +   + + + +     +   + +  + + + + +  +  + +  +  + + +  +   +    + +  + +   +   + +  + + + +  +  + +     + +  +  +  +  +    + +  +   +  +     +  +     +   +      +    +  +      + +  + +  +     +     +  +     + + + + +   + +         + +   +     + +  . -&.'/"-!,( */#.#3!/!1&.&7&7*:);.@.?3F7H8P@P=VB\G\HdJbMiOiSpYu`|`^kbcjvqtja[<&   + +    +  +          +     + +   +   +   +     +  +    + + + +    +    + + +      +   + +      +   + +   + +    + +    + + +  +  +  Ԗٍψ̅vuxlgf^]ZW{LwJvJlGiCc@W9U5[4J0H.@+>);$7$0--.+++)),)")++.*1.))+)-*!0)+&)))+*,/,)()(+'&(&()+'&(&(''+%+(&'*'&*',)' -,(+)(%())()'%&&&*&!*$%*(%)%')'&(&'+(((&#$($(*&##%%)$('+%%%'(($(*)&'))&'$'&%)'*(('&&&'&'%$$'!(&'"$$#*&'#'%$&'*(%'(%)*$%%'$(&!    +    +  + +  +  +  + +    +   +     +  + + + + +    + + +   +   + + + +    + +   + +     +    +   +   +   +   +  + +    +  +  +  + + + + + + +   +     +  +  +  +     + +   + +  + + + + +     +     +  +      +  + + + +   +   +   + +      + + +    +   +  +    +   + +  +  +  + +       + +  +        +   +   +        +  +       + +  + +       + +           +            + !,12,.,.--.////5878DBI!G$J%R$W'Y(Y+a)m.i+j2r/r,s3y39=>EC@81w#S  +  +     +  +  +    +  +      +    +     + +    + +   +   +      +      +    +    + + + +  +   +   + + +           + +   + + +   +  + ۆuznwok`eVVWRO~JpEsCmAe:b8Z6T3S-G/D+@&6$7"5 ,0+.1+-)')*+.+()))*()..-+)+/+(,**')*(+)*+*,+*)+'+))$*$+)()())((''$'*+*'')$*)&&)'))%)%+)'#"*('%%)&&+'(*(%*%)&%',%&&#&*%(,&%+(%)"*$%)$(())%*%((&&*'))*&'%(&(&()''%%"#")#'&$&#&&)%&#$##%("$&'($"$%))"% + +   +     + +  + + +   +  + + +  +  +   + +  +  + + +     +  + +   + + + + +  + +     +      + +   +  + +     +            +   + +   + + +    + + + + +  + +   +  + +  +  + + + + + + + + + +             + +    + +    +      +  + +  + +  + + + +   +  +   +    + + +             + + + + +  + + +   +  + +        + + + +   + +    +  + + + +  + +      +      +    +    +   +   +  + +  +     + 1",$.%. ,%, +*!(#-!.#-"0!5%5*<)=+>/C5B5I:S9M>U=X@T>dNaJnMlUpYoYxX]xa`kflrqo^|TG0  + + + + +       +  + +         +    + + + +  + +  +   +       +     + + + + +  +    +  +   + + +  +       + + + +  + +  + +  +    +  +  + +     +  ̀}vvrrgid^XWS{TpImKeAjAc=X2Q7Q1I4A)>+;'2$5 +,+*!) /.,**"- **+(*.*,++,*()-(,-*+))'(+(,,*))+)&%('*)&),)*+*(+%&%,*+)'*(*&)&#+&)''+'& '-(*$&#%(-#'(("'%&*%((&('&('(+$)&+&&''%&*( '$&'(%)(*#'*'$*('*#+&*"(''##)*$&&'$&&%)%('"$$)(#&($" &&'%&)%($%%%%&#$'*""    + +  +      + + +  + +  +      + + + +   +  +  +   + + +  +        +  +  + + +   +  +  +  +     +  + +      + +  +    +  + + +   + + +      +      +  +     + +   +   + +   +  + + +   +     +         + + + +  +    + + +        + +    + +        + +   +   +  +           +    + +   +  + + + + +  +   + + + + +     +  +  +          + + + +     + + +  +  + +   +   +  +  +  +&07./'*').+,/83<8>A>G!K"L"O$T'R'Y'c+g+e-m.r-v1w6448=;DB?70i#8  +    +        +   +            +     + + + +     + +    +     +   +   +    +      +    +  +    +  + +   + + +  +  + + + + +  +   +      ێ}уymooe`]WSRQJpDwDj?b;c:d4Y5T.N,F-?+>!6!1!0.0+. ,+.. -,-((+-.---*''0,1++(+).*,-+)-+**.+'**)(())+'),'+-'+-*%+)**''''*'(()((()$&*'(&.&"#&&)#$(%'+'(%&$''%)+&#'(#'(&#*%'))&(%&%*%)(%*$)+(++*&)$)*&')%'(,&%%(&+*%%$'$%)&(),('%(%'%!''%(+(%(&'$%'$$"'(   +     +       + +         +    + +   + +  +     + +  + +  + + +   +  + +  +   + + +  + +    +  +      +    +   + +  +  +   +  +  + +        +   +  + + +          + +   + +  + +     + + + +     + + + + +    + + + +  +   + +    +     + +   +  +  +  + + +      + + +   +             +      + + +  + + + + +  + + +  + +  +       +  +   +  +    +  + + + +       +   +   + + + + +   +  $1"-"2#-#*)"++!."+ 0$/&1(4*:.81<292@4A8G8L:N=O:XI^E^NfOjRmPqVu\V{`WemmkswoeiE0"          +    +       + +    + + +    +    + + +    + + +    +   + + + +   + +     + + + +           + + + +  +    +   + +  + +   + + + + ޜގԉօƀwtqom]]\W{MQGlGkBcHa%7!810*+*,/+ /0 *!,'.-+-+,.+'))),,&&*-))*'&))')(,))*)*+*%))*&*'))-%-+'*(%*&*())(')'(%(**(())&'%#),(((+&#')'*&'(''"''(&*'+&(&$$(((&'&)''$'&(''#+"''&''*('&)'$)'&&%)&))%$&&#'&'))#&$"&(&$&,*''"#)%)'&'(##''(&$%    + + +  + + +  + +    +     + +  +   + + + + + + +  +  + +   +       +  + + +  +     + +   + + + + +  +    +    +   + + +  +  +  + +  +  + + + + +  + +    +     + + +   + +     +  +  +  +  + +  +  +  +   + +  + + +   + + + +    + + +     + +      +  + +     + +   +     + +  +  +       +  +    +    + +  +     +   +  + +     +      + +  +    + +       +     + +  + ,113..+*+*/*-8:75@;? J K#N!Q$V"^&[,c,e,g.j3r/t1{/x4|6<=?EB@3+^0     +    +        + +   +    + + +    +    +  + + + +  + + +    + +   +  +   +  +  + +       + + + +       + + + +  + +   + +     + + +    ۃ}~Ԃqunjgf[VVUNO|FsKj?iB_9T5Z9P2K1D-B+@&8"44".+,*(,1**.*+*,..)-,*/**(+)**(((-(.-&(,(,'*()*)&('*(+)')&%)%.(*&*)(&+)*%*$'())+$*%+&')&&%)--'(*&*&&((**)*&*'&*%((*)%&(*)(&&(&(%*#)%$'()%$+*&%&##+)*((%'$')%%&')((%$")')(&%%%'%*%'&!&&)%#,$()(%')$&&()$'#   + + + + +   +   +  + +     +  + +  + +    +  + + + + +  +   +  +  + +    +  + + +   + + +  +  + +     + + +  +       +  + +  + + +  +  + +     +  +       +  +  + + + + + + + +  + +   +     +      + + +   +          +    +  +  +  + +   +  +    + +  +  + + +      + +    + + + +   + + +    +    +    +   +  + + + +  + +    + +   + +  +  +  + +  +    +   +      + + + +    +     +  + +   + + + + +  +      )4&5"1"+#-*!)"+.0%2 .%5'7(:-:/7/;4A1C3NV;UE_HbI`J_QlOnRsVv]t\bbfdopurp_\9)    +  + +       + +  +     +   + +   +    + + + +      +    + +  +    + + +  + + + +  +   +  +    + +   + + +  + +   +  + +     + + + ޑЉр~wrpsibcYVMyMvOoHgDfC]>\;\5N2N3A+F-;&6"..#+!0++-(,+.0+*.-- )(%**,*(**)(-,,) +.!)*)#'&,+( -+*,*-*+'+'((((*&%&(*&(%'(&+*'')%% '')*)&&('&$'+%'%)&%%")'$(&&'%''%$(*('$(+(&&+'+'''$**'(')%&,%%'$&&)((&!((+''('&&&%()')#$**#'&'%'%)'+$'%#'**(%$$'#,&$#%#'&%%'     + +  + +      +  + + + + + + + +  +  + + +   +   +  +  + + + + +      + +  +  +  +   +   +    +   +   + + +        +     +    + +  + +  +  +    + + + + + +  +      +  + +    + +         +   +    +     + +  +    +    + +      + +   + +     +        + +    + +  +  +         +  + +  + + + + +      +           + +    +  + +      +       +    +    +   + +   +    *30.+,)%)+*143889<?JD!S"Q#[(Y'X'_)_+f,e.l2n1z.z6y93C9?E@@/{"Q  + +   + + + +     +      + + + +    +  +   +  + + +      +    +  +      +   +     +   + +      +     +   + + + +   + + + +    + + +        + ~܃Ղxthgfb^TUUM{KqIqHhMRBXI^K^DfPgQdQlRuTuYy`dekimqmldzRK6     +          +  +   +   + +    + + +  + +   +   + + +    + + + +   +  + +   + +   + + +    + + +  +    + + +    + +  + +  +     + +   + + + + + +  + +    ڎ֌Ɔʄ}|nscceYX}UtHuLsCcCa]8a6[2U2P.I+E+@%;$1$211/-.1,&++,-+,,)(/*+*-+)++,)(*,+)))++*+((&))+(,**%((+(*-($'()&(+*&***+()/&')&'+(%'"*$#$*)((%'&(''#"$()(%&((''&$*)($'('&(&(*)'%'()(*&&'"'%)&*'&')'')((($%()()&$)%$&%(*%&&()(&##'($()&$$)#$&&($%(''#'&'$&(&$#       + +  +   + +  +  + +     +     + +     + + +   +  +     +   + + +  + + +    +  + +     +       +   +  +      + + + +    + +  + +  +  +  +      +  +      +    + +  + +  +      +   +  + + +        +           + +   +    +  +   +  +  +   +   +      + +          + + +      + +     +   + +  + +     + + + +  +   +  +  +  +  + + + +  + +  +     +  + +   +  +    + + +    +(3!2!-/ , //#,++!-$4$1&5)6(<->-VF\E]G_MeQjPtQrOy]t\vc|_dhfmwtj[]<'  + + +  +   +  +   + +   +   + +  + +      +  +    +   +  + + +    + + +    + +  + +      +    + +    + + + + +  +   +  + +  +  +      + + ӕ؊׀~ymoh`_XXXRwHqFkE`AdAa>U6P0S/H,H/@)>'9"-"2+!1 + 1*1,,(* --++0,.*',&,(.*++))(--()*+, -**+(*,)*&*)(+*.- '))))'+,'&,(*.*+&%)*''*&'-&'' (')(((&(%*))%&&)$)$((&%&))&&%'%()%'*% )&&$*&'%%()'$((%%')$(((%)%&')%'&%''"(%%#+&%&,($)&%#&)($(&$)&$%(&''&#'&&'&%#%'&(&'$#$! + +  +  + + + + +  + +  + + + +       + + +  + +  +  +  + +    +    + + + +  +   +  +   + +  + + +    + +       +   +  +   +  +  + +     + +  + +  +  +         + + + +    + +       +  +      + + + + + +   + + + +  + + +  +    +   +   + + +   +    +    + +        + + +  + +   + +     +     + + +  + +     +     +     +         +     + +     + +  +  +  +     + +      +    + #-/52++1+.,+1233:=ECD!H L#Q"P#Z$[&Z(a,o,l)n-j/v0z1|387>=AC;0~%Y% + +      +          + +  + +     +   +  +   +    +  +      +       +   +    +      +  + +   +       +  +   +  + + +    +  +      +  +  + + + ڀyxbpca\ZXQzNzIoDqCl>a?a;Y7T0J,L0G,B'>(6!42/,/-0//**,+-*.-*++.*-+/.,-'.*-+,).,***()*),*,,++-.)&*.(-+*(+**+((%,**)**&"()'$+'(&'%'%*)()%&+*'&**)'')')))(%('()''($+)"&**&&+(()')$))%&(%)*)*''$)*))$$&$'')%&(((%&')('&()*'*&%&(''%&$%'&)'&'%$)$&$&&%&$$()'$('& + + +   +  +   +  +  +     + +        + + +  + + +    +   + +   +  +     + +     + +   +  +    +   + +  + +   +   +  + +  +  + +  +  +  + + + + + +   +    + + + +  +          +  +  + +  +    +   + + + + +   + +    +  + + + + + +      +  +  +   +  + + +    + +         +   +  +   +     +  +     +   + +       +   +   + +       +  + +         +  +     +   +  + + + +  + + +  + $/&3(0$1%(!*!.!,'!+#/#2%3#6(8(4*:.A.B0F6L6L8O:UBUBb@`HcNcPlKmXyW|Ty\X_bfnmqvbuVP1     +   + +   +  +  + +   +  +   +      +    +  +  + +   + +     + +  + +  + + +   +   + +      + + + +    +   +  + + +    +   +  +       + ֌ىҊƅ}woohef]VTRyKrJiGhJ^@_=Nm>\<]6W.P,K.H+E,B&9"71* .//, -/,*)-*,.,/+,/)*//-//'**'+')+++,-.()*-,,**+%&.+(&*'+)*,),(&-%-(+*-&+)'))+*&'&$"&&'('(-*((&*()%$#)*&(&'''"&(%*$)'%++)''($'$&%#''())'((&*'&'+& ''%$&'(&&&+%(*'&&($%(&(('$()&)&,&)($)(%)*(''.%(%)'&&$#%(('$(*%&    +   +   + + + +    + +    +   +  + +  +    +   +   + + +   +  +  +    +     +     +     + +   + + +      +  + + +  + +  + +   + +  + + +  +   + +   +   +   + + + +    +    +     +   +  +        +  + + + +   +    +   + +     + +  +     + +   + +    +         +    + +   +  +   +  + + +   + +       + +  +  +  +       +                  +  +  + + +   + + +        +4!1&1$+ +*- +"*/#3!3$3'5):-9(94@0?5C6H7O9Q>Z@WC^G\IcNeQnRpWlXwZy^{]^iklqunf{L:*     +    + +  +    +     + + + + + +  + +      +  + +    + + +  +  + + + + +    + +  + + +        + + +     +  + + +    + +        +    +  + + ێ؍͇xxpmi_[aWRtOuKqBjFjC`D"G"R$V"V$](a&g&e)o.k,k/l/q2~56}4>m;f7`9W5R-J-I,B+<$=$4$31,0./..,1-./-,--1.,*.(/-,,/,,'*++)'+*.'**(+&'*)+.,(.*%&))+)&%(&*'*,**)*),(**+''-)$##)(",)%&'*'',%('()(''(-(('&*#*%((&)&(&(%)&&&&&'&&(#*&(,&'(&&"&*'+&#(&&&&$($&''$,(*)$'"(($'#'#($'&%&'$$%%%%) *'*(#(%$*%#&%(#'%#&&  +   + + +    +  +  + +  + + + +  +   +  +   + +  +   +  + +  +  + + +  + +   +     +   +   + + +  +   +    +  + + +   +  +  + +     + + + +     + + +     +       +   +   + + +  + +  +  + +    +  +  + + + +    + + + +  +   +   +   +                +   +  +  +   +  + + +    + +  +  +  + +    + +  +      +  +   +      + + +  + + +  +   + + + + +     +  + + + +   +  +  + +    #1!4#4!0 +'+!)!/!01#5%1&4&2-6,:+?.C1B1I8J:O=Q?TB\DaGbHfPmRhVpVu\x\yYcbhhnwqf[_A3 + +  + +  + +  + + + + +   +   +   +  +  + + +    +    + +   +  +    +     + + +     + +    +   + +     + + + +   +   +  + +  +    + +  +   +  + + +  +  +  ז؉ςnqkii`\YX{LrMtFmFaAa=Z8O6N2I2M0B*?-9%7&0 .,0 ,0)4*-12..,)3!-.--/( .*(,-+)**+/ (,,*.(,*/***))),( )'&*((+**)')+ (++)'%*(%)((-%&%)&($*'&+(&*('&))&$)))&()(&%&''(('')#$*()(%%')&&'"&''-&%'%(#)%&((('%&)%'&*#&(*&)#'$*&($'*)&&'''&#')(%))*()&'&*#'#$#''&)%&&%$'$+&$("'&(   + +           + +   + +   +     + +   +   +   +    +   + +   + +    +    +     + + +  +   +  + +   +   +   + + +  + +    +  + + + + +    + +  +  + +         +  +   + +      + + +    +     + +         + +  +  +  + + +  +    +  +    +  +  + +   +      +   + + +   +  +    +  +     +  +  + +     + +  +  + + + + +  +   +        + +  + +   + +    + &22-/(,,+(--3.28:>>E AI"N"Q&W"Y'^#[&b,g.n0i0v-z3u3z8{36@@CCD5'a)        +  +        +  + +     +  +    +   + + +    + +   +   +   +   +  +   +       +   +   + +  + +  + + + + +  +    +  + +   + +    +      +{~utmakhYWTQN{LBpFs?j=b8]7[6R2L-F+I&E%=$;$/41//+012+,.. /.++-,0)*-/() -,+,+*)(+-...&**-&+.,(,)&**').+(-,(+**$((+*%'-$'('+')(&''$(*))'&'($&%**)&,)'&()((+&)"+%($+'&)$'&')&)(('(-(&'%&*'#('%$)'))#%))(*&#%''&%#(&#%)&)(%&&'*)$('$'*&)'*"*&$)''%&'&&%%$&&&&'#(%%&&'%%#    + +   + +  +  +  +   + +  +  +  + +   + +     + +    +   + + +    +           +    + +  +   +       + +  +  + + +  +    + +   + +  + +        +  +  + +  +  +  +    + +  + +   +   +   +  +   + + +   + +  + +     +   +  + + +     + +   +    + + +  + +  +   + +  +  +  + + +    + + +    +  + +   +   + +   +  +  + + + +  +      +            +                    +   (1!2%0#, -!/!' +"-!-#0$/'6'6&:+9):,>1A4E6H9J?Q:T@TBYB`MjNjOhLqYwWqXv\[fekqlspj[V4#  + +  +        +   + +     +  +  +  +  + +  +   +    +   +   + +   + +  +  + +          +  +    + +   + + + +  + +   +  +  +    + + قˀ{yqrdmdY\YSyRzOoHoChCb=Y=U8O9E4C-G&:(:$5"3%/"1 .,*-#/.,-+-+3-+ *-*)/-*!-,//+)+),),(,*,,+,,,*,),) ))'*++)-,-%++**)*)()+)'*'*&'()&%+'&$)))+'%*%'*)$'%''%'+)&(&&&%$#'')&&&)%&%&'&*%%%)'))&$'&#('$#'**#'))+)(('%&'%&'%%'%)%''%((())##&'%)%''''+&)&&%))&'*&')(%''(**&#%*(%'(#    +    +  +  + +    +      + +     +     + +  + +  +  + + +     +    + +     +   + + +  +   +  +  + + +  + + + + +   +            + + + + +  +     + + +   +   +   +  +      +     + + + + +  +    +   +  +       +   +          + + + +    +      + +  +        +     + +      +  +  +  +      +          +   +      +       +      +  +  +    +  + +     + +03.)0+*%+.,0525>;CAD H"J#K#M&V&Y(a&^)h-j+o0m2p3{7t7:9?BD@@0x%G  +   +     + + +  +   + + +          +  + +    + +  + + +  + +  +          +            +   +  + + + +      + + +  +    +    +  +        ߍs}tpmcca[UOO{M{MxGoDl<_;c7Y7X1M.J1F(>':': 22/*.2,!1*!+/-,,12,,-(+1-,,/...--*,-',+,+*,,+*)+++)&*)-,*))#+('+,+,'(*)*(*((+(&,&).&&#&''(''&%&&&()+&()''(%)&')&(*'('%"*('&&(*$-()&'&'%%+'%%*,&%&%#%((&)#()'&(%'%('&&()(('%'&(&*('$'('*$%-%(%)'+,&%(!(&*)%%()#"'&)&(&&(%)($ +        +   + +        +     +    + + +     + + +  + +      + + +    +  +  +  + + +  +       + + +   + +  +    + +    +  +  +   + +  + +    +  +  + +  +  + +           +      +    +   + +     +  +   + +   +    + + + + + +  +   + +    + +  + + +   +   +   +   +  +  +  + +  +   + + +  + + + + + + + +  +     + + +  +        +  +    +      + +    + + +  + + + + +     + + +        +     +   +  + +"2#3&/#.!) ,++"0"-#.(.'4(4+7*8-7/?2F4F6E6K=P?SA\>`FaAcNmMdOgRtXuY\ua]cmlkrpajPB'   + + + + +      + +  + +    +  +   +  +  +  +  + +  +     + +    + +   +       +  + +   + +    + +      + +       + +  +  + + +     + + ыӄρ|zkpkgbZ]P}W|JvGlH_@_i@e8b;Z4T3Q-N)D,>*:'6"1!/0/-- // ///..,-,-/2+).*+.-.+*,,,010(1+-*,--+)0+')'*+-.*,)((',-%(++)+*((()'()+(,,)*"$%(+'++'*$)&,'&)')*&'"(((*&+'%'(*))(%*&*(&("()$)*&'()*&''&(()&)$((&'(&+&'&$&('*(&'(',%&'$&%('+)'$&')$''''()($&#(($#''%)+"*&&)%&)(*'%%'%%" +  + + + + + + + +     +  +    + + + + + + +  + +     +  + +   + + + +      +   +  + + +   + + +   + +   + + +  + +   +    + + + +   +    + +  +   + +  + +   + +   +  + +  +  + +   + + +  +        +         + + +   +     + + + + +    +       + +    + +    +   + +   + +  + +    + +  +   + +         + + +   +  +    + + +    +  + + +  +        +   +   +  + +  +    +  +  +   +    +   +    +  +    +%2#5'1"0!-!- /!( *"+#0".#4$4)2'718+E,A3C6G7I:S,9$9$5#/"/ /-!.. .-/!0,.. 1 ,,- ,!* - , )).*-&*+-++, ) *)+,)0+*** -,,+)*',,++**'()'))*)+&($*+.)**()(&)$!#%-))&&((+'*%)(((('&(+&%*'$+'&%*+$&'%(*'%'',*((&)$&*(("(%*'&&)&&'(+'**"&&%$+()('('$$#$)&$'$%)%&$'&)'(#&'#))&&%(&$(&&&%$'($$'&((%''$$'&&(#  + + +  +  +  + +     +     +  + +   + + + + +   +   + + +   +    + +   +         +   +     +   + +    + + + +   + + +  +  +  +    +   + +  + + +     +  +  + +  +  + + +       +    + + +  + +     + +      + +  +        + + + +        +  + +  +   +  +  + + +      + + +    +    +   +    +                + +        + +       + +   + +  + +   +  + '312/,.+*+-,2275<;<CDJ!M!J$M$[$U&c&b*f/d-k-n.n2x5y46~:@;@??5)a,       +     +    + +  +    +          + +   + +  + + +   +        + + +          +  +  + + + +   + +         +  + +  + +   +     +     ~ommoha]_SVPN{QsEs@iBb=`5V6U8R.K-J+A*;$9!7$4"-/ / +.-/,/01)--0-,..-./.../,*-+)),++.++*+-,(,-('%,,++)-'+,,/)*+,*/))+*%''()'*(*)("&$*)/(&*')*,+(*)('*)))'*,(()&&*''&'***)'%!''%)%)+(*''*%&$'''$'+(&%$%)'&$*()((+%&&),*$+(%#''('%$&*(+!%%&(%*'%&&'$(+&%)'&&(%&!%#&#$*%%$'&$'%&      +  +   + +  + + +   +    +   + +      + + +        +     + + +   +  +    +   +   + +    + + +  +  +    +     + +   +   +  +  +   +  +  +  +        +  +  + +    + + +    +        +   + +  + + +  +     +   +   + +  + +   + + + +  +  + +   +   +  + +  + + +  +   +    +   +       +   +  +              +     +    +   +  + +  +       +   +    +   + +  + )3%/"2!+",("++!'#,$0$4".%4)3);,9,A2A0F4R6P7K>R=UE[D^J_MjJlOoVnUt[{Y}^bgjhslnnVY7' +  +       + +      +  +     + +   +  +   +   +  +   +       +     + +      + + +  +   + + +    +  +   + +  +  +   +   ք~|qjqjfd\X\xXzOsMnGjCcDa;`>V7L5I.H,C+>&9&711!-!1/+!--*,!//0.*-/./0,30.,*,,,-'+,,)...*./-- -,)+*/,+,)'*)-,**(*,&%+)++-)''&)((*(*&(&-&))%&()((+))(&%(%&'$*%%)'('%'#+()+,'"))'-(*'%"&')''%&(&('%**!%)(%%&*),')($($"%(%$%&%'$&&*'')%)&%&&#$&&%#&*$#%(($(#$*#)$$'%%%$(%#($$&$'$#$! +  +            +      + +  +  +  +     +  +  + +   + + + + +    + +  + +  +  +  +  + +          +  +  + + + +    + +  +  + + +   + +    +   +  + +  +   +   +  +    +     + +  +   +    +  + +               +  + + + +    + +   +   +   +   +        + +   +     +  + +  +    +   +    +                   +  +   +       + .432...+&*./224<=8@@CN J%P#W'X&W&Y*]+j,m0u.v-x4}3y6<7??F@=3x$O$ +        +  + +  + +  + +  +           +  +  + + + + + +  + +  +  +   +    +  +   + +     + +   +   +    + +   +   +      + + +  + +    + + +      + + ~~~{vrmjda]\TROG|GuGgAj6[7_7R3O0Q,E-E'C&9%942-3.4-.0 .-12.*/+).-0/-0-0+**+-+*().*-+.,*+-+/*-)+(,,*,,*&.,*+(&(0)'/),*&*(+)('+(%((%+()),,&$)()&('&(+&'+*+-*((,)$&**()%'&*(*&)+'!*(%&$*%'+(%&(%&$'()*&#('%')*%''%*&&'$'*&*$*'$''+&%&+&"($'&(($$$&+'*&$)#&(%)#('')''*$(%'#%!#'   +   +  + +   + +  + +               +  + + +  +  +  +    + +    +  +    +     +  + + +      +    +   + +   +    + + +   + +  + +  +    +  + +      +   +       +     + +   +       +     +  +   +  +    +    + +  +    +     +  +  +            +  +      + +    + + +  +      + +   +   + + +   + + +        +   +    +    +       +       +    +    +       +      + + $,"5#5"5"2 *- -"+ *,#,&0&9';+90;.<BGED$M$Y$U)b(X'a(c-n-r/s.x0z2;9;ADD>=/r;   + +  +   +    +   +          + +     + +  + +  + +      + +       +   +    + +    + +  +  +     + + +     +      +    +  +     + +       \ No newline at end of file diff --git a/test/isp/resource/RAW8_20190712_640x480.raw b/test/isp/resource/RAW8_20190712_640x480.raw new file mode 100644 index 0000000..788d14d Binary files /dev/null and b/test/isp/resource/RAW8_20190712_640x480.raw differ diff --git a/test/visys/Makefile b/test/visys/Makefile new file mode 100644 index 0000000..f6f8cc4 --- /dev/null +++ b/test/visys/Makefile @@ -0,0 +1,30 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +SOURCES = test_visys.c +OBJECTS := $(SOURCES:.c=.o) +EXEC = output/test_visys +CFLAGS = -O0 -Wall -g -lm -I../../driver/visys + +all: $(EXEC) + +.c.o: + $(CC) -c $(CFLAGS) $(INCLUDES) $< + +$(EXEC): $(OBJECTS) + mkdir -p output + $(CC) $(CFLAGS) -o $(EXEC) $(OBJECTS) -pthread + +clean: + rm -f *.o $(EXEC) + rm -rf output + +install: + +.PHONY: clean all + diff --git a/test/visys/test_visys.c b/test/visys/test_visys.c new file mode 100644 index 0000000..ed88b0a --- /dev/null +++ b/test/visys/test_visys.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include +#include +#include + +#include "bm_visys_ioctl.h" + +#define DEV_PATHNAME "/dev/bm_visys0" +typedef struct _visys_ctx +{ + int dev_fd; +} visys_ctx_t; +static visys_ctx_t visys_ctx; + +static int visys_init(visys_ctx_t *ctx) +{ + int fd; + memset(&visys_ctx, 0, sizeof(visys_ctx)); + + fd = open(DEV_PATHNAME, O_RDWR | O_NONBLOCK); + if (fd < 0) { + printf("%s:Can't open %s: %d(%s)\n", __func__, + DEV_PATHNAME, errno, strerror(errno)); + return -1; + } + ctx->dev_fd = fd; + + return 0; +} + +static int visys_deinit(visys_ctx_t *ctx) +{ + if (ctx->dev_fd >= 0) { + close(ctx->dev_fd); + ctx->dev_fd = -1; + } + + return 0; +} + +static int visys_ioctl(visys_ctx_t *ctx, unsigned int cmd, void *args) +{ + int ret; + + if (ctx == NULL || ctx->dev_fd < 0) { + printf("%s:ctx is invalid\n", __func__); + return -1; + } + + ret = ioctl(ctx->dev_fd, cmd, args); + if (ret != 0) { + printf("%s:ioctl failed, ret=%d(%s)\n", __func__, + ret, strerror(ret * -1)); + return ret; + } + + return 0; +} + +int main(void) +{ + int ret; + struct bm_visys_reg_t reg; + + ret = visys_init(&visys_ctx); + if (ret != 0) + exit(ret); + + reg.offset = 0x4; // should be 0x5000008b in reset + ret = visys_ioctl(&visys_ctx, BMVISYSIOC_READ_REG, ®); + if (ret == 0) { + printf("%s:Read reg OK, offset=0x%08x, value=0x%08x\n", __func__, + reg.offset, reg.value); + } + + ret = visys_deinit(&visys_ctx); + if (ret != 0) + exit(ret); + + exit(0); +} + diff --git a/tools/reg_analyzer/Makefile b/tools/reg_analyzer/Makefile new file mode 100644 index 0000000..06e6528 --- /dev/null +++ b/tools/reg_analyzer/Makefile @@ -0,0 +1,47 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # 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. +## + +# To support host build in current path +ifeq ($(CC),) + CC:=gcc +endif + +CFLAGS = -O0 -Wall -g -lm +INCLUDES = -I../../common -I./ + +SOURCES := ../../common/log_common.c +SOURCES += ra_common.c +SOURCES += ra_light_main.c +SOURCES += ra_reg_demo.c +SOURCES += ra_light_visys.c +SOURCES += ra_light_isp.c +SOURCES += $(wildcard vsi_isp8000/*.c) + + +OBJECTS := $(SOURCES:.c=.o) +EXEC = output/reg_analyzer +CFLAGS = -O0 -g -Wall -lm + +all: $(EXEC) + +$(EXEC): $(OBJECTS) + @mkdir -p output + $(CC) $(CFLAGS) -o $(EXEC) .obj/*.o + +$(OBJECTS):%.o:%.c + @mkdir -p .obj + $(CC) -c $(CFLAGS) $(INCLUDES) -o .obj/$(notdir $@) $< + +clean: + rm -rf .obj + rm -rf output + +install: + +.PHONY: clean all + diff --git a/tools/reg_analyzer/ra_common.c b/tools/reg_analyzer/ra_common.c new file mode 100644 index 0000000..c40ed89 --- /dev/null +++ b/tools/reg_analyzer/ra_common.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include +#include +#include + +#include "log_common.h" +#include "ra_common.h" + +static char reg_desc_tmp[4096]; + +int ra_dump_reg_fields(reg_analyzer_info_s *ra_info, + const reg_field_s reg_field[], const uint32_t reg_field_count) +{ + int i = 0, pos=-1; + int has_meet = 0; + char *reg_name; + char *reg_desc; + uint32_t reg_reset_val; + uint32_t reg_offset = ra_info->reg_offset; + uint32_t reg_val = ra_info->reg_value; + + if (strlen(ra_info->reg_name) == 0 && ra_info->reg_offset == INVALID_MAGIC32) { + printf("Invalid reg_name('%s') or reg_offset(0x%08x)\n", + ra_info->reg_name, ra_info->reg_offset); + return -1; + } + + for (i = 0; i < reg_field_count; i++) { + if (ra_info->reg_offset == reg_field[i].offset || + (reg_field[i].reg_name != NULL && + strncmp(reg_field[i].reg_name, ra_info->reg_name, strlen(reg_field[i].reg_name))==0)) { + pos = i; + reg_offset = reg_field[pos].offset; + reg_desc = reg_field[pos].reg_desc; + reg_name = reg_field[pos].reg_name; + reg_reset_val = reg_field[pos].reset_value; + break; + } + } + if (pos < 0) { + //printf_red("Can't find register offset=0x%x\n", reg_offset); + return -1; + } + + printf("\n%-24s %-10s %10s %10s %s\n", " Register Name", "Offset", "ResetValue", "CurrentVal", "Description"); + printf("===================================================================================\n"); + printf("%-24s 0x%08x 0x%08x ", reg_name, reg_offset, reg_reset_val); + if (reg_reset_val != reg_val) + printf_green("0x%08x", reg_val); + else + printf("0x%08x", reg_val); + printf(" %s\n", reg_desc); + + printf("\nBit[s] Len ResetValue CurrentValue(Hex/Dec) FieldName Description\n"); + printf("===================================================================================\n"); + + for (i = pos; i < reg_field_count; i++) { + if (reg_field[i].offset != reg_offset) { + if (has_meet == 1) { + break; + } + continue; + } + + uint32_t msb = reg_field[i].msb; + uint32_t lsb = reg_field[i].lsb; + uint32_t curr_field_val = reg_val; + if (msb != 31 || lsb != 0) { + curr_field_val = (reg_val >> lsb) & (~(0xffffffff << (msb - lsb + 1))); + } + uint32_t reset_field_val; + uint32_t field_len = msb - lsb + 1; + + reset_field_val = (reg_reset_val >> lsb) & (~(0xffffffff << (msb - lsb + 1))); + + if (field_len == 1) { + printf(" %5d ", lsb); + } + else { + printf(" %2d:%2d ", msb, reg_field[i].lsb); + } + printf("%4d ", field_len); + printf("0x%-9x ", reset_field_val); + if (curr_field_val != reset_field_val) { + printf_green("0x%-8x/", curr_field_val); + printf_green("%10u ", curr_field_val); + } else { + printf("0x%-8x/", curr_field_val); + printf("%10u ", curr_field_val); + } + + if (reg_field[i].field_name != NULL) + printf("%-24s:", reg_field[i].field_name); + else + printf("%-24s", ""); + + if (reg_field[i].field_desc != NULL) { + if (strstr(reg_field[i].field_desc, LINE_PADDING_6TAB)) { + strncpy(reg_desc_tmp, reg_field[i].field_desc, sizeof(reg_desc_tmp)); + char *p = strstr(reg_desc_tmp, LINE_PADDING_6TAB); + while (p) { + str_replace(p, strlen(LINE_PADDING_6TAB), LINE_PADDING_9TAB); + p = p+strlen(LINE_PADDING_9TAB); + p = strstr(p, LINE_PADDING_6TAB); + } + printf("%-s\n", reg_desc_tmp); + } else { + printf("%-s\n", reg_field[i].field_desc); + } + } + else + printf("%-s\n", ""); + + if (has_meet == 0) { + has_meet = 1; + } + } + printf("\n"); + + if (has_meet !=0 ) + return 0; + else + return -1; +} + +int ra_dump_reg_define(reg_analyzer_info_s *ra_info, + const reg_field_s reg_field[], const uint32_t reg_field_count) +{ + int i = 0, pos=-1; + int has_meet = 0; + char *reg_desc; + uint32_t reg_offset; + uint32_t reg_reset_val; + + if (strlen(ra_info->reg_name) == 0 && ra_info->reg_offset == INVALID_MAGIC32) { + printf("Invalid reg_name('%s') or reg_offset(0x%08x)\n", + ra_info->reg_name, ra_info->reg_offset); + return -1; + } + + for (i = 0; i < reg_field_count; i++) { + if (ra_info->reg_offset == reg_field[i].offset || + (reg_field[i].reg_name != NULL && + strncmp(reg_field[i].reg_name, ra_info->reg_name, strlen(reg_field[i].reg_name))==0)) { + pos = i; + reg_offset = reg_field[pos].offset; + reg_desc = reg_field[pos].reg_desc; + reg_reset_val = reg_field[pos].reset_value; + break; + } + } + if (pos < 0) { + //printf_red("Can't find register offset=0x%x\n", reg_offset); + return -1; + } + + printf("\n%-24s %-10s %10s %s\n", "Register Name", "Offset", "ResetValue", "Description"); + printf("===================================================================================\n"); + printf("%-24s 0x%08x 0x%08x %s\n", reg_field[pos].reg_name, reg_offset, reg_reset_val, reg_desc); + + + printf("\nBit[s] Len ResetValue FieldName Description\n"); + printf("===================================================================================\n"); + + for (i = pos; i < reg_field_count; i++) { + if (reg_field[i].offset != reg_offset) { + if (has_meet == 1) { + break; + } + continue; + } + + uint32_t msb = reg_field[i].msb; + uint32_t lsb = reg_field[i].lsb; + + uint32_t reset_field_val; + uint32_t field_len = msb - lsb + 1; + + reset_field_val = (reg_reset_val >> lsb) & (~(0xffffffff << (msb - lsb + 1))); + + if (field_len == 1) { + printf(" %5d ", lsb); + } + else { + printf(" %2d:%2d ", msb, reg_field[i].lsb); + } + printf("%4d ", field_len); + printf("0x%-9x ", reset_field_val); + + if (reg_field[i].field_name != NULL) + printf("%-23s:", reg_field[i].field_name); + else + printf("%-23s", ""); + + if (reg_field[i].field_desc != NULL) + printf("%-s\n", reg_field[i].field_desc); + else + printf("%-s\n", ""); + + if (has_meet == 0) { + has_meet = 1; + } + } + printf("\n"); + + if (has_meet !=0 ) + return 0; + else + return -1; + +} + +int ra_dump_reg_find(reg_analyzer_info_s *ra_info, + const reg_field_s reg_field[], const uint32_t reg_field_count) +{ + int i = 0; + char *last_reg_name = NULL; + if (ra_info == NULL || ra_info->reg_name == NULL) { + printf("ra_info or ra_info->reg_name is invalid\n"); + return -1; + } + + for (i = 0; i < reg_field_count; i++) { + const reg_field_s *pfield = ®_field[i]; + if (last_reg_name == pfield->reg_name || pfield->reg_name == NULL) + continue; + + if (stristr(pfield->reg_name, ra_info->reg_name) != NULL) { + printf("Find register: offset=0x%08x, name='%s'\n", + pfield->offset, pfield->reg_name); + } + last_reg_name = pfield->reg_name; + } + return 0; +} + +void _dump_ra_info(reg_analyzer_info_s *ra_info) +{ + printf("input params: [-m %s] [-o 0x%08X] [-r %s] [-v 0x%08x], op=%d\n", + ra_info->module_name, ra_info->reg_offset, ra_info->reg_name, + ra_info->reg_value, ra_info->operate); +} + +char *strlwr(char *str) +{ + char *orign = str; + for (; *str != '\0'; str++) + *str = tolower(*str); + return orign; +} + +void str_replace(char * cp, int n, char * str) +{ + int lenofstr; + char * tmp; + lenofstr = strlen(str); + //str3比str2短,往前移动 + if(lenofstr < n) + { + tmp = cp+n; + while(*tmp) + { + *(tmp-(n-lenofstr)) = *tmp; //n-lenofstr是移动的距离 + tmp++; + } + *(tmp-(n-lenofstr)) = *tmp; //move '\0' + } + else + //str3比str2长,往后移动 + if(lenofstr > n) + { + tmp = cp; + while(*tmp) tmp++; + while(tmp>=cp+n) + { + *(tmp+(lenofstr-n)) = *tmp; + tmp--; + } + } + strncpy(cp,str,lenofstr); +} + +// compare string Ignore case +int stricmp(const char* p1, const char* p2) +{ + while (*p1 && *p2) + { + char c1 = *p1; + char c2 = *p2; + if (c1 >= 'A' && c1 <= 'Z') + { + c1 += 'a' - 'A'; + } + if (c2 >= 'A' && c2 <= 'Z') + { + c2 += 'a' - 'A'; + } + if (c1 != c2) + { + return c1 - c2; + } + p1++; + p2++; + } + return *p1 - *p2; +} + +// find string Ignore case +char* stristr(const char* haystack, const char* needle) +{ + char* char1 = NULL; + char* char2 = NULL; + if ((haystack == NULL) || (needle == NULL) || (strlen(haystack) < strlen(needle))){ + return NULL; + } + + for (char1 = (char*)haystack; (*char1) != '\0'; ++char1) { + char* char3 = char1; + for (char2 = (char*)needle; (*char2) != '\0' && (*char1) != '\0'; ++char2, ++char1) { + char c1 = (*char1) & 0xDF; + char c2 = (*char2) & 0xDF; + if ((c1 != c2) || (((c1 > 0x5A) || (c1 < 0x41)) && (*char1 != *char2))) + break; + } + + if ((*char2) == '\0') + return char3; + + char1 = char3; + } + return NULL; +} + +int ra_search_reg_by_offset(reg_analyzer_info_s *ra_info) +{ + if (ra_info->reg_offset == INVALID_MAGIC32) { + return -1; + } + + return 0; +} + +int ra_search_reg_by_name(reg_analyzer_info_s *ra_info) +{ + if (strlen(ra_info->module_name) == 0) { + return -1; + } + + return 0; +} + diff --git a/tools/reg_analyzer/ra_common.h b/tools/reg_analyzer/ra_common.h new file mode 100644 index 0000000..7740220 --- /dev/null +++ b/tools/reg_analyzer/ra_common.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 __RA_COMMON_H__ +#define __RA_COMMON_H__ +#include +#include +#include +#include +#include + +#define INVALID_MAGIC32 0xDEADBEEF + +#define LINE_PADDING_6TAB "\n\t\t\t\t\t\t " +#define LINE_PADDING_9TAB "\n\t\t\t\t\t\t\t\t\t " + +typedef struct { + char *reg_name; /* Register name, can be null if it exists above, should <=24 chars */ + char *reg_desc; /* Register description, can be null if not exists */ + uint32_t offset; /* Register offset address */ + uint32_t reset_value; /* Register reset value */ + uint32_t msb; /* MSB for this field [31..0] */ + uint32_t lsb; /* LSB for this field [31..0] */ + char *field_name; /* Register field name */ + char *field_desc; /* Field description */ +} reg_field_s; + +/* +For example: +static const reg_field_s demo_reg_desc[] = { + {"Demo reg", 0x10, "Demo field1", 15, 0, "This is demo reg's demo field1"}, + {NULL, 0x10, "Demo field2", 31, 16, "This is demo reg's demo field2"}, +}; +*/ + +typedef struct { + char *ip_name; + uint64_t ip_phy_addr; +} ip_phy_addr_s; + +typedef enum { + RA_OP_INVALID = -1, + RA_OP_SHOW_DUMP = 0, + RA_OP_SHOW_REG_DEFINE, + RA_OP_FIND_REG, +} ra_op_e; + +typedef struct { + char module_name[64]; + uint32_t reg_offset; + uint32_t reg_value; + char reg_name[128]; + char field_name[128]; + ra_op_e operate; +} reg_analyzer_info_s; + +void _dump_ra_info(reg_analyzer_info_s *ra_info); + +int ra_dump_reg_fields(reg_analyzer_info_s *ra_info, + const reg_field_s reg_field[], const uint32_t reg_field_count); + +int ra_dump_reg_define(reg_analyzer_info_s *ra_info, + const reg_field_s reg_field[], const uint32_t reg_field_count); + +int ra_dump_reg_find(reg_analyzer_info_s *ra_info, + const reg_field_s reg_field[], const uint32_t reg_field_count); + +/////////////////////////////////////// + + +typedef int (*module_reg_dump)(reg_analyzer_info_s *ra_info); +typedef int (*module_reg_define)(reg_analyzer_info_s *ra_info); +typedef int (*module_reg_find)(reg_analyzer_info_s *ra_info); + +typedef struct { + const char *module_name; + module_reg_dump reg_dump; + module_reg_define reg_define; + module_reg_find reg_find; +} module_instance_t; + +int ra_search_reg_by_offset(reg_analyzer_info_s *ra_info); +int ra_search_reg_by_name(reg_analyzer_info_s *ra_info); + +////////////////////////////////////// + + + +char *strlwr(char *str); +void str_replace(char * cp, int n, char * str); +int stricmp(const char* p1, const char* p2); +char* stristr(const char* haystack, const char* needle); +#endif /* __RA_COMMON_H__ */ + diff --git a/tools/reg_analyzer/ra_light_isp.c b/tools/reg_analyzer/ra_light_isp.c new file mode 100644 index 0000000..19dbfc0 --- /dev/null +++ b/tools/reg_analyzer/ra_light_isp.c @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "log_common.h" +#include "ra_common.h" + +extern int light_isp_main_control_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x0000 +extern int light_isp_main_control_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_main_control_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_isp_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_isp_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_isp_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_mcm_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_mcm_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_mcm_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_sitching0_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_sitching0_define(reg_analyzer_info_s *ra_info); +extern int light_isp_sitching0_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_exp_bayer_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_exp_bayer_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_exp_bayer_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_is_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_is_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_is_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_cproc_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_cproc_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_cproc_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_main_resize_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_main_resize_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_main_resize_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_denoise3d_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_denoise3d_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_denoise3d_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_dpf_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_dpf_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_dpf_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_denoise3d2_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_denoise3d2_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_denoise3d2_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_dpcc_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_dpcc_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_dpcc_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_compand_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_compand_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_compand_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_shutter_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x0680 +extern int light_isp_shutter_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_shutter_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_mi_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x1300 +extern int light_isp_mi_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_mi_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_jpe_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x1800 +extern int light_isp_jpe_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_jpe_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_afm_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x2000 +extern int light_isp_afm_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_afm_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_hist256_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x2100 +extern int light_isp_hist256_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_hist256_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_lsc_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x2200 +extern int light_isp_lsc_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_lsc_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_exposure_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x2600 +extern int light_isp_exposure_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_exposure_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_vsm_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x2f00 +extern int light_isp_vsm_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_vsm_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_ee_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x3900 +extern int light_isp_ee_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_ee_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_dmsc_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x3e00 +extern int light_isp_dmsc_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_dmsc_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_pre_filt_reg_dump(reg_analyzer_info_s *ra_info); // OFFSET=0x3e00 +extern int light_isp_pre_filt_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_pre_filt_reg_find(reg_analyzer_info_s *ra_info); + + +int light_isp_reg_dump(reg_analyzer_info_s *ra_info) +{ + if (light_isp_main_control_reg_dump(ra_info) == 0) // OFFSET=0x0000 + return 0; + + if (light_isp_isp_reg_dump(ra_info) == 0) + return 0; + + if (light_isp_mcm_reg_dump(ra_info) == 0) + return 0; + + + if (light_isp_mi_reg_dump(ra_info) == 0) + return 0; + + if (light_isp_is_reg_dump(ra_info) == 0) + return 0; + + if (light_isp_exp_bayer_reg_dump(ra_info) == 0) + return 0; + + if (light_isp_sitching0_reg_dump(ra_info) == 0) + return 0; + + if (light_isp_cproc_reg_dump(ra_info) ==0) + return 0; + + if (light_isp_main_resize_reg_dump(ra_info)==0) + return 0; + + if (light_isp_denoise3d_reg_dump(ra_info)==0) + return 0; + + if(light_isp_dpf_reg_dump(ra_info)==0) + return 0; + + if(light_isp_denoise3d2_reg_dump(ra_info)==0) + return 0; + + if(light_isp_dpcc_reg_dump(ra_info)==0) + return 0; + + + if(light_isp_compand_reg_dump(ra_info)==0) + return 0; + + if(light_isp_shutter_reg_dump(ra_info)==0) // 0x0680 + return 0; + + if (light_isp_mi_reg_dump(ra_info) == 0) // 0x1300 + return 0; + + if(light_isp_jpe_reg_dump(ra_info)==0) // 0x1800 + return 0; + + if(light_isp_afm_reg_dump(ra_info)==0) // 0x2000 + return 0; + + if(light_isp_hist256_reg_dump(ra_info)==0) // 0x2100 + return 0; + + if(light_isp_lsc_reg_dump(ra_info)==0) // 0x2200 + return 0; + + if(light_isp_exposure_reg_dump(ra_info)==0) // 0x2600 + return 0; + + if(light_isp_vsm_reg_dump(ra_info)==0) // 0x2f00 + return 0; + + if(light_isp_ee_reg_dump(ra_info)==0) // 0x3900 + return 0; + + if (light_isp_dmsc_reg_dump(ra_info) == 0) // 0x3e00 + return 0; + + if (light_isp_pre_filt_reg_dump(ra_info) == 0) // 0x4000 + return 0; + + //printf_red("%s Can't find register name='%s' offset=0x%x\n", + // ra_info->module_name, + // ra_info->reg_name, + // ra_info->reg_offset); + return -1; +} + +int light_isp_reg_define(reg_analyzer_info_s *ra_info) +{ + if (light_isp_main_control_reg_define(ra_info) == 0) // OFFSET=0x0000 + return 0; + + if (light_isp_isp_reg_define(ra_info) == 0) + return 0; + + if (light_isp_mcm_reg_define(ra_info) == 0) + return 0; + + if (light_isp_sitching0_define(ra_info) ==0) + return 0; + + if (light_isp_exp_bayer_reg_define(ra_info) == 0) + return 0; + + if (light_isp_is_reg_define(ra_info) == 0) + return 0; + + if (light_isp_cproc_reg_define(ra_info) ==0) + return 0; + + if (light_isp_main_resize_reg_define(ra_info) ==0) + return 0; + + if (light_isp_denoise3d_reg_define(ra_info) ==0) + return 0; + + if (light_isp_dpf_reg_define(ra_info) ==0) + return 0; + + if (light_isp_denoise3d2_reg_define(ra_info) ==0) + return 0; + + if (light_isp_dpcc_reg_define(ra_info) ==0) + return 0; + + if (light_isp_compand_reg_define(ra_info) ==0) + return 0; + + if (light_isp_shutter_reg_define(ra_info) ==0) // 0x0680 + return 0; + + if (light_isp_mi_reg_define(ra_info) == 0) // 0x1300 + return 0; + + if (light_isp_jpe_reg_define(ra_info) ==0) // 0x1800 + return 0; + + if (light_isp_afm_reg_define(ra_info) ==0) // 0x2000 + return 0; + + if (light_isp_hist256_reg_define(ra_info) ==0) // 0x2100 + return 0; + + if (light_isp_lsc_reg_define(ra_info) ==0) // 0x2200 + return 0; + + if (light_isp_exposure_reg_define(ra_info) ==0) // 0x2600 + return 0; + + if (light_isp_vsm_reg_define(ra_info) ==0) // 0x2f00 + return 0; + + if (light_isp_ee_reg_define(ra_info) ==0) // 0x3900 + return 0; + + if (light_isp_dmsc_reg_define(ra_info) == 0) // 0x3e00 + return 0; + + if (light_isp_pre_filt_reg_define(ra_info) == 0) // 0x4000 + return 0; + + //printf_red("%s Can't find register name='%s' offset=0x%x\n", + // ra_info->module_name, + // ra_info->reg_name, + // ra_info->reg_offset); + return -1; +} + +int light_isp_reg_find(reg_analyzer_info_s *ra_info) +{ + light_isp_main_control_reg_find(ra_info); // OFFSET=0x0000 + + light_isp_isp_reg_find(ra_info); + + light_isp_mcm_reg_find(ra_info); + + light_isp_sitching0_find(ra_info); + + light_isp_exp_bayer_reg_find(ra_info); + + light_isp_is_reg_find(ra_info); + + light_isp_cproc_reg_find(ra_info); + + light_isp_main_resize_reg_find(ra_info); + + light_isp_denoise3d_reg_find(ra_info); + + light_isp_dpf_reg_find(ra_info); + + light_isp_denoise3d2_reg_find(ra_info); + + light_isp_dpcc_reg_find(ra_info); + + light_isp_compand_reg_find(ra_info); + + light_isp_shutter_reg_find(ra_info); // 0x0680 + + light_isp_mi_reg_find(ra_info); // 0x1300 + + light_isp_jpe_reg_find(ra_info); // 0x1800 + + light_isp_afm_reg_find(ra_info); // 0x2000 + + light_isp_hist256_reg_find(ra_info); // 0x2100 + + light_isp_lsc_reg_find(ra_info); // 0x2200 + + light_isp_exposure_reg_find(ra_info); // 0x2600 + + light_isp_vsm_reg_find(ra_info); // 0x2f00 + + light_isp_ee_reg_find(ra_info); // 0x3900 + + light_isp_dmsc_reg_find(ra_info); // 0x3e00 + + light_isp_pre_filt_reg_find(ra_info); // 0x4000 + + return 0; +} + diff --git a/tools/reg_analyzer/ra_light_main.c b/tools/reg_analyzer/ra_light_main.c new file mode 100644 index 0000000..57cab5b --- /dev/null +++ b/tools/reg_analyzer/ra_light_main.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include +#include + +#include "log_common.h" +#include "ra_common.h" + +#define TOOL_NAME "reg_analyzer" + +extern int reg_demo_dump(reg_analyzer_info_s *ra_info); +extern int reg_demo_define(reg_analyzer_info_s *ra_info); +extern int reg_demo_find(reg_analyzer_info_s *ra_info); + +extern int light_visys_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_visys_reg_define(reg_analyzer_info_s *ra_info); +extern int light_visys_reg_find(reg_analyzer_info_s *ra_info); + +extern int light_isp_reg_dump(reg_analyzer_info_s *ra_info); +extern int light_isp_reg_define(reg_analyzer_info_s *ra_info); +extern int light_isp_reg_find(reg_analyzer_info_s *ra_info); + + +static module_instance_t light_module_instance_array[] = { + {"demo", reg_demo_dump, reg_demo_define, reg_demo_find}, + {"visys", light_visys_reg_dump, light_visys_reg_define, light_visys_reg_find}, + {"isp0", light_isp_reg_dump, light_isp_reg_define, light_isp_reg_find}, +}; + +void show_moduel_list() +{ + int i; + int module_count = sizeof(light_module_instance_array)/sizeof(light_module_instance_array[0]); + for (i = 0; i < module_count; i++) { + printf("%s ", light_module_instance_array[i].module_name); + } + printf("\n"); +} + + +static void help(void) +{ + printf("usage: %s [-m module_name] [-o reg_offset] [-v reg_value] \n" + " [-f find_reg_name]\n", TOOL_NAME); + printf(" example: %s -m demo -o 0x00000010\n", TOOL_NAME); + printf(" %s -m demo -o 0x00000010 -v 0x0001ff7b\n", TOOL_NAME); + printf(" %s -m demo -r DEMO_REG1\n", TOOL_NAME); + printf(" %s -m demo -r DEMO_REG0 -v 0x0001ff7b\n", TOOL_NAME); + printf(" %s -m demo -f _REG0\n", TOOL_NAME); +} + +static int parse_cmd_params(int argc,char *argv[], reg_analyzer_info_s *ra_info) +{ + int param_cnt = 1; + memset(ra_info, 0, sizeof(*ra_info)); + ra_info->operate = RA_OP_INVALID; + ra_info->reg_offset = INVALID_MAGIC32; + ra_info->reg_value = INVALID_MAGIC32; + + if (argc == 1) { + //help(); + return -1; + } + + while (param_cnt < argc) { + //printf("argv[param_cnt]=%s\n", argv[param_cnt]); + if (0 == strncmp (argv[param_cnt], "-m", 2)) { + strncpy(ra_info->module_name, argv[param_cnt+1], sizeof(ra_info->module_name)); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-o", 2) || + 0 == strncmp (argv[param_cnt], "addr", 2)) { + sscanf(strlwr(argv[param_cnt+1]), "%x", &ra_info->reg_offset); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-r", 2)) { + sscanf(argv[param_cnt+1], "%s", ra_info->reg_name); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-v", 2) || + 0 == strncmp (argv[param_cnt], "value", 2)) { + sscanf(strlwr(argv[param_cnt+1]), "%x", &ra_info->reg_value); + param_cnt += 2; + } else if (0 == strncmp (argv[param_cnt], "-f", 2)) { + sscanf(argv[param_cnt+1], "%s", ra_info->reg_name); + ra_info->operate = RA_OP_FIND_REG; + param_cnt += 2; + } else { + return -1; + } + } + + if (strlen(ra_info->module_name) == 0) { + printf("Please input valid module name, such as: "); + show_moduel_list(); + return -1; + } + + if (ra_info->operate == RA_OP_FIND_REG) { + return 0; + } + + if (ra_info->reg_offset == INVALID_MAGIC32 && strlen(ra_info->reg_name) ==0 ) + return -1; + + if (ra_info->reg_value != INVALID_MAGIC32) + ra_info->operate = RA_OP_SHOW_DUMP; + else + ra_info->operate = RA_OP_SHOW_REG_DEFINE; + + if (ra_info->operate == RA_OP_INVALID) + return -1; + + return 0; +} + +int main(int argc,char *argv[]) +{ + int i, ret = 0; + int module_count = sizeof(light_module_instance_array)/sizeof(light_module_instance_array[0]); + reg_analyzer_info_s ra_info; + module_instance_t *module_inst = NULL; + + ret = parse_cmd_params(argc, argv, &ra_info); + //_dump_ra_info(&ra_info); + if (ret != 0) { + printf_red("Invalid syntax.\n"); + help(); + return ret; + } + + for (i = 0; i < module_count; i++) { + if(strcmp(light_module_instance_array[i].module_name, ra_info.module_name) == 0) { + module_inst = &light_module_instance_array[i]; + } + } + + if (module_inst == NULL) { + printf("Please input valid module name, such as: "); + show_moduel_list(); + return -1; + } + + if (ra_info.operate == RA_OP_SHOW_REG_DEFINE && module_inst->reg_define != NULL) { + ret = module_inst->reg_define(&ra_info); + if (ret != 0) { + printf_red("The register or offset can't find in defination\n"); + return ret; + } + } else if (ra_info.operate == RA_OP_SHOW_DUMP && module_inst->reg_dump != NULL) { + ret = module_inst->reg_dump(&ra_info); + if (ret != 0) { + printf_red("The register or offset can't find in defination\n"); + return ret; + } + } else if (ra_info.operate == RA_OP_FIND_REG && module_inst->reg_find != NULL) { + ret = module_inst->reg_find(&ra_info); + if (ret != 0) { + printf_red("The register or offset can't find in defination\n"); + return ret; + } + } + + return 0; +} + diff --git a/tools/reg_analyzer/ra_light_visys.c b/tools/reg_analyzer/ra_light_visys.c new file mode 100644 index 0000000..9e201b6 --- /dev/null +++ b/tools/reg_analyzer/ra_light_visys.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"TEST","This is demo register-0 description", + 0x1200, 0x00000000, 0, 0, "mcm_bypass_en", "Bypass enable. 0: bypass disabled; 1: bypass enabled"}, +}; + + +int light_visys_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_visys_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_visys_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/ra_reg_demo.c b/tools/reg_analyzer/ra_reg_demo.c new file mode 100644 index 0000000..7871b47 --- /dev/null +++ b/tools/reg_analyzer/ra_reg_demo.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +/* usage: reg_analyzer -m demo -o 0x10 -v 0x13572468 */ +/* usage: reg_analyzer -m demo -r DEMO_REG1 */ +static const reg_field_s reg_demo_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + {"DEMO_REG0", "This is demo register-0 description", + 0x10, 0x12345678, 31, 16, "reg0 field0", "This is demo reg0's field0"}, + {NULL, NULL, 0x10, 0x0, 15, 0, "reg0 field1", "This is demo reg0's field1"}, + + {"DEMO_REG1", "This is demo register-0 description", + 0x14, 0x13572468, 31, 24, "reg1 field0", "This is demo reg1's field0"}, + {NULL, NULL, 0x14, 0x0, 23, 0, "reg1 field1", "This is demo reg1's field1 desc line1" LINE_PADDING_6TAB + "and reg1's field desc line 2" LINE_PADDING_6TAB + "and reg1's field desc line 3"}, +}; + +int reg_demo_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_demo_desc) / sizeof(reg_demo_desc[0]); + return ra_dump_reg_fields(ra_info, reg_demo_desc, count); +} + +int reg_demo_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_demo_desc) / sizeof(reg_demo_desc[0]); + return ra_dump_reg_define(ra_info, reg_demo_desc, count); +} + +int reg_demo_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_demo_desc) / sizeof(reg_demo_desc[0]); + return ra_dump_reg_find(ra_info, reg_demo_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_afm.c b/tools/reg_analyzer/vsi_isp8000/isp_afm.c new file mode 100644 index 0000000..5c93e3e --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_afm.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00002000 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_AFM_CTRL", "Auto Focus Measurement Unit Control Register", + 0x00002000, 0x00000000, 0, 0, "afm_en", "AF measurement enable. 0: disable; 1: enable" LINE_PADDING_6TAB + "Writing a 1 to this register starts a new measurement " LINE_PADDING_6TAB + "and resets the afm_fin (measurement finished) interrupt to 0." LINE_PADDING_6TAB + "As long as the afm_en is 1, the AFM unit calculates new sharpness values for each frame."}, +}; + + +int light_isp_afm_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_afm_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_afm_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_compand.c b/tools/reg_analyzer/vsi_isp8000/isp_compand.c new file mode 100644 index 0000000..4664053 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_compand.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00003200 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_COMPAND_CTRL", "Compand Control Register", + 0x00003200, 0x00000000, 3, 3, "compand_ctrl_bls_enable", "Enable Black Level Subtraction in the Compand module"}, + {NULL, NULL, 0x00003200, 0x00000000, 2, 2, "compand_ctrl_soft_reset_flag", "Soft reset of compand module"}, + {NULL, NULL, 0x00003200, 0x00000000, 0, 0, "compand_ctrl_expand_enable", "Enable Expand in the Compand module"}, +}; + + +int light_isp_compand_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_compand_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_compand_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_denoise3d.c b/tools/reg_analyzer/vsi_isp8000/isp_denoise3d.c new file mode 100644 index 0000000..af8f3b0 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_denoise3d.c @@ -0,0 +1,51 @@ + +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define ISP_DENOISE3D_BASE 0x3700 +#define REG_BASE ISP_DENOISE3D_BASE + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, reg_desc, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_DENOISE3D_CTRL", "Denoise3D Control Register", + 0x00003700, 0x00000000, 10, 10, "denoise3d_read_ref_en", "0: disable read ref data from SRAM; 1: Enable read ref data from SRAM"}, + {NULL, NULL, 0x00003700, 0x00000000, 9, 9, "denoise3d_raw_decompress_en", "1: decompress enable; t0: decompress disable"}, + {NULL, NULL, 0x00003700, 0x00000000, 8, 8, "denoise3d_raw_compress_en", "1: compress enable; 0: compress disable"}, + {NULL, NULL, 0x00003700, 0x00000000, 7, 7, "denoise3d_write_ref_en", "0: disable write ref data to SRAM; 1: Enable write ref data to SRAM (Default)"}, +}; + + +int light_isp_denoise3d_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_denoise3d_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_denoise3d_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_denoise3d2.c b/tools/reg_analyzer/vsi_isp8000/isp_denoise3d2.c new file mode 100644 index 0000000..0154aa2 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_denoise3d2.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x5300 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_DENOISE3D2_CTRL", "Denoise3D2 ctrl", + 0x00005300, 0x00000000, 12, 12, "denoise3d_v20_soft_rst", "Denoise3D2:soft reset bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 11, 11, "denoise3d_v20_invgamma_en", "Denoise3D2: inv gamma enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 10, 10, "denoise3d_v20_pregamma_en", "Denoise3D2: pregamma enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 9, 9, "denoise3d_v20_erode_en", "Denoise3D2: motion erosion enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 8, 8, "denoise3d_v20_motion_conv_en", "Denoise3D2: motion convergence enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 7, 7, "denoise3d_v20_inv_dgain_en", "Denoise3D2: inv digital gain enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 6, 6, "denoise3d_v20_inv_awb_gain_en", "Denoise3D2: inv awb gain enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 5, 5, "denoise3d_v20_comp_luma_en", "Denoise3D2: luma compensation enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 4, 4, "denoise3d_v20_ref_reset", "Denoise3D2: soft reset bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 3, 3, "denoise3d_v20_motion_dilate_enable", "Denoise3D2: motion dilation enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 2, 2, "denoise3d_v20_nlm_enable", "Denoise3D2: 2dnr enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 1, 1, "denoise3d_v20_tnr_enable", "Denoise3D2: tnr enable bit"}, + {NULL, NULL, 0x00005300, 0x00000000, 0, 0, "denoise3d_v20_enable", "Denoise3D2: enable bit"}, + + + {"ISP_DENOISE3D2_PREGAMMA_Y_0", "Denoise3D2 Pregamma Y LUT Register", + 0x00005400, 0x00000FFF, 29, 24, "denoise3d2_pregamma_y_2_a", "Denoise 3DV2 Pregamma Y 2 [11:6]"}, + {NULL, NULL, 0x00005400, 0x00000FFF, 23, 12, "denoise3d2_pregamma_y_1", "Denoise 3DV2 Pregamma Y 1"}, + {NULL, NULL, 0x00005400, 0x00000FFF, 11, 0, "denoise3d2_pregamma_y_0", "Denoise 3DV2 Pregamma Y 0"}, +}; + + +int light_isp_denoise3d2_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_denoise3d2_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_denoise3d2_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_dmsc.c b/tools/reg_analyzer/vsi_isp8000/isp_dmsc.c new file mode 100644 index 0000000..e797a9a --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_dmsc.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00003e00 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_DMSC_CTRL", "Demosaic control register", + 0x00003E00, 0x0400288E, 31, 24, "demosaic_thr", "Threshold for Bayer demosaicing texture detection." LINE_PADDING_6TAB + " This value shifted 4-bit is compared width the different of the vertical" LINE_PADDING_6TAB + " and horizontal 12bit wide texture indicators, to decide if the vertical or" LINE_PADDING_6TAB + " horizontal texture flag must be set." LINE_PADDING_6TAB + "0x00: maximum edge sensitivity" LINE_PADDING_6TAB + "0xff: no texture detection"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 21, 16, "denoise_strength", "green channel smoothing filter results account for the weight of the final result, the larger the blur"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 14, 14, "frame_clr_sel", "0:frame clear by vsync. 1:frame clear by frame end"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 13, 13, "frame_end_en", "frame clear by frame end"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 12, 8, "sharpen_size", "green channel sharpen size, the larger the sharpen edge, the greater the graininess"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 7, 7, "vsync_pos_en", "frame clear by VSYNC"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 6, 6, "soft_rst_inner", "soft reset"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 5, 5, "sharpen_line_enable", "0: disable line sharpen, 1: enable line sharpen"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 4, 4, "skin_enable", "0: disable skin area filter, 1: enable skin area filter"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 3, 3, "depurple_enable", "0: disable depurple, 1: enable depurple"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 2, 2, "demoire_enable", "0: disable demoire, 1: enable demoire"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 1, 1, "sharpen_enable", "0: disable sharpen, 1: enable sharpen"}, + {NULL, NULL, 0x00003E00, 0x0400288E, 0, 0, "demosaic_bypass", "0: do interpolation, 1: bypass interpolation"}, + + + {"ISP_DMSC_INTP_THR", "Direction select threshold register", + 0x00003E04, 0x00000000, 23, 12, "interplationdir_thr_max", "direction select threshold value in bright area, the interpolation " LINE_PADDING_6TAB + " operation between maximum threshold and minimal threshold"}, + {NULL, NULL, 0x00003E04, 0x00000000, 11, 0, "interplationdir_thr_min", "direction select threshold value in dark area, the interpolation " LINE_PADDING_6TAB + " operation between maximum threshold and minimal threshold"}, + + {"ISP_DMSC_DMOI_CTRL", "Demoire ctrl register", + 0x00003E08, 0x00001F08, 13, 8, "demoire_area_thr", "judgment threshold of moire area"}, + {NULL, NULL, 0x00003E08, 0x00001F08, 5, 0, "demoire_sat_shrink", "moire pixel forced saturation, 32=no color"}, + + + {"ISP_DMSC_CAC_CTRL", "Control register for chromatic aberration correction", + 0x00003E44, 0x00000000, 3, 3, "cac_h_clip_mode", "defines the red/blue pixel shift in horizon direction" LINE_PADDING_6TAB + "0:set horizon vector to +/-4 pixel" LINE_PADDING_6TAB + "1:set horizon vector to +/-4 or +/-5 pixel " LINE_PADDING_6TAB + " depending on the position in bayer raster"}, + {NULL, NULL, 0x00003E44, 0x00000000, 2, 1, "cac_v_clip_mode", "defines the red/blue pixel shift in vertical direction" LINE_PADDING_6TAB + "00:set vertical vector to +/-2 pixel" LINE_PADDING_6TAB + "01:set vertical vector to +/-3 pixel" LINE_PADDING_6TAB + "10:set vertical vector to +/-3 or +/-4 pixel " LINE_PADDING_6TAB + " depending on the position in bayer raster" LINE_PADDING_6TAB + "11:reserved"}, + {NULL, NULL, 0x00003E44, 0x00000000, 0, 0, "cac_enable", "0: chromatic aberration correction off" LINE_PADDING_6TAB + "1: chromatic aberration correction on"}, + + {"ISP_DMSC_SIZE_CTRL", "demoire size ctrl register", + 0x00003E60, 0x01000000, 31, 16, "dummy_hblk_value", "dummy lines hblank cycles"}, + {NULL, NULL, 0x00003E60, 0x01000000, 15, 0, "img_hsize", "dmsc process image hsize"}, + + + + {"ISP_DMSC_SHAP_FACT", "Sharpen factor register", + 0x00003E14, 0x00008008, 20, 12, "sharpen_factor_black", "Sharpen factor of black edge; 0 means no sharpen"}, + {NULL, NULL, 0x00003E14, 0x00008008, 8, 0, "sharpen_factor_white", "Sharpen factor of white edge; 0 means no sharpen"}, + + {"ISP_DMSC_CTRL_SHD", "Demosaic control shadow register", + 0x00003E64, 0x0400080E, 31, 24, "demosaic_thr", "Threshold for Bayer demosaicing texture detection." LINE_PADDING_6TAB + " This value shifted 4-bit is compared width the different of the vertical" LINE_PADDING_6TAB + " and horizontal 12bit wide texture indicators, to decide if the vertical or" LINE_PADDING_6TAB + " horizontal texture flag must be set." LINE_PADDING_6TAB + "0x00: maximum edge sensitivity" LINE_PADDING_6TAB + "0xff: no texture detection"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 21, 16, "denoise_strength", "green channel smoothing filter results account for the weight of the final result, the larger the blur"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 14, 14, "frame_clr_sel", "0:frame clear by vsync. 1:frame clear by frame end"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 13, 13, "frame_end_en", "frame clear by frame end"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 12, 8, "sharpen_size", "green channel sharpen size, the larger the sharpen edge, the greater the graininess"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 7, 7, "vsync_pos_en", "frame clear by VSYNC"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 6, 6, "soft_rst_inner", "soft reset"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 5, 5, "sharpen_line_enable", "0: disable line sharpen, 1: enable line sharpen"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 4, 4, "skin_enable", "0: disable skin area filter, 1: enable skin area filter"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 3, 3, "depurple_enable", "0: disable depurple, 1: enable depurple"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 2, 2, "demoire_enable", "0: disable demoire, 1: enable demoire"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 1, 1, "sharpen_enable", "0: disable sharpen, 1: enable sharpen"}, + {NULL, NULL, 0x00003E64, 0x0400080E, 0, 0, "demosaic_bypass", "0: do interpolation, 1: bypass interpolation"}, + +}; + + +int light_isp_dmsc_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_dmsc_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_dmsc_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_dpcc.c b/tools/reg_analyzer/vsi_isp8000/isp_dpcc.c new file mode 100644 index 0000000..693dbc3 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_dpcc.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00002900 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_DPCC_MODE", "Global control register", + 0x00002900, 0x00000004, 2, 2, "stage1_enable", "0: bypass stage1; 1: enable stage1 (Default)"}, + {NULL, NULL, 0x00002900, 0x00000004, 1, 1, "grayscale_mode", "0: BAYER DATA INPUT (Default)" LINE_PADDING_6TAB + " 1: enable gray scale data input from black and white sensors (without color filter array)"}, + {NULL, NULL, 0x00002900, 0x00000004, 0, 0, "dpcc_enable", "0: bypass DPCC (Default); 1: enable DPCC"}, +}; + + +int light_isp_dpcc_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_dpcc_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_dpcc_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_ee.c b/tools/reg_analyzer/vsi_isp8000/isp_ee.c new file mode 100644 index 0000000..b23be2b --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_ee.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00003900 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_EE_CTRL", "Edge Enhancement Control Register", + 0x00003900, 0x00000000, 18, 11, "edge_enhancement_source_strength", "Edge Enhancement strength of process"}, + {NULL, NULL, 0x00003900, 0x00000000, 10, 3, "edge_enhancement_strength", "Edge Enhancement strength of smooth filter"}, + {NULL, NULL, 0x00003900, 0x00000000, 2, 2, "edge_enhancement_soft_reset", "Edge Enhancement software reset. 0: release; 1: reset"}, + {NULL, NULL, 0x00003900, 0x00000000, 1, 1, "edge_enhancement_input_sel", "Edge Enhancement input data format select. 0: RGB; 1: YUV"}, + {NULL, NULL, 0x00003900, 0x00000000, 0, 0, "edge_enhancement_enable", "Enable/Disable Edge Enhancement. 0: Disable the EE; 1: Enable the EE"}, +}; + + +int light_isp_ee_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_ee_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_ee_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_exp_bayer.c b/tools/reg_analyzer/vsi_isp8000/isp_exp_bayer.c new file mode 100644 index 0000000..e2dd298 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_exp_bayer.c @@ -0,0 +1,47 @@ + +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define ISP_EXP_BAYER_BASE 0x2680 +#define REG_BASE ISP_EXP_BAYER_BASE + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, reg_desc, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_EXP_H_SIZE_SHD", "ISP_EXP_H_SIZE_SHD", 0x00002680, 0x00000000, 10, 0, "exp_h_size", "Shadow Horizontal size of one block in pixels."}, +}; + + +int light_isp_exp_bayer_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_exp_bayer_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_exp_bayer_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_exposure.c b/tools/reg_analyzer/vsi_isp8000/isp_exposure.c new file mode 100644 index 0000000..d91658f --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_exposure.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00002600 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_EXP_CONF", "Exposure Control", + 0x00002600, 0x00000000, 31, 31, "exp_alt_mode", "0: luminance calculation according to Y=16+0.25R+0.5G+0.1094B" LINE_PADDING_6TAB + "1: luminance calculation according to Y=(R+G+B) x 0.332"}, + {NULL, NULL, 0x00002600, 0x00000000, 3, 2, "exp_src_select", "data source select 1:wdr 0:csm"}, + {NULL, NULL, 0x00002600, 0x00000000, 1, 1, "autostop", "0: continuous measurement; 1: stop measuring after a complete frame"}, + + + {"ISP_EXPV2_CTRL", "raw exposure control", + 0x000026A0, 0x00000000, 3, 2, "expv2_input_select", "00: degamma output; 01: awb_gain output; 10: WDR3 output; 11: not used"}, + {NULL, NULL, 0x000026A0, 0x00000000, 1, 1, "expv2_autostop", "0: continous measurement; 1: stop measuring after a complete frame"}, + {NULL, NULL, 0x000026A0, 0x00000000, 0, 0, "expv2_enable", "1: start measuring a frame" LINE_PADDING_6TAB + "The exp block will reset this bit and halt after " LINE_PADDING_6TAB + "completing one frame if bit 'autostop' is set to 1"}, +}; + +int light_isp_exposure_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_exposure_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_exposure_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_hist256.c b/tools/reg_analyzer/vsi_isp8000/isp_hist256.c new file mode 100644 index 0000000..057f5ea --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_hist256.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00002100 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_HIST256_PROP", "Histogram properties", + 0x00002100, 0x00000000, 9, 3, "stepsize", "Histogram pre-divider" LINE_PADDING_6TAB + "Process every (step size)th pixel; all other pixels are skipped" LINE_PADDING_6TAB + "0,1,2: not allowed" LINE_PADDING_6TAB + "3: process every third input pixel" LINE_PADDING_6TAB + "4: process every fourth input pixel" LINE_PADDING_6TAB + "..." LINE_PADDING_6TAB + "7FH: process every 127th pixel"}, + {NULL, NULL, 0x00002100, 0x00000000, 2, 0, "hist_mode", "Histogram mode, luminance is taken at ISP output before" LINE_PADDING_6TAB + " output formatter, RGB is taken at xtalk output" LINE_PADDING_6TAB + "0: disable, no measurements" LINE_PADDING_6TAB + "1: RGB combined histogram" LINE_PADDING_6TAB + "2: R histogram" LINE_PADDING_6TAB + "3: G histogram" LINE_PADDING_6TAB + "4: B histogram" LINE_PADDING_6TAB + "5: Y (luminance) histogram" LINE_PADDING_6TAB + "6, 7: must not be used"}, +}; + + +int light_isp_hist256_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_hist256_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_hist256_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_jpe.c b/tools/reg_analyzer/vsi_isp8000/isp_jpe.c new file mode 100644 index 0000000..bf0c891 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_jpe.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00001800 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"JPE_ERROR_MIR", "jpe error imr", + 0x00001868, 0x00000000, 31, 0, "Undefined in reg.xml", "Undefined in reg.xml, but mrv_all_regs.h does"}, +}; + +int light_isp_jpe_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_jpe_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_jpe_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_lsc.c b/tools/reg_analyzer/vsi_isp8000/isp_lsc.c new file mode 100644 index 0000000..619dbd9 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_lsc.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00002200 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_LSC_CTRL", "Lens Shade Control Register", + 0x00002200, 0x00000000, 0, 0, "lsc_en", "0: activation request for lens shading correction" LINE_PADDING_6TAB + "1: deactivation request for lens shading correction" LINE_PADDING_6TAB + "Activation/Deactivation is an object of a shadowing mechanism." LINE_PADDING_6TAB + "The current status is visible at ISP_LSC_STATUS::lsc_enable_status"}, +}; + + +int light_isp_lsc_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_lsc_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_lsc_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_mcm.c b/tools/reg_analyzer/vsi_isp8000/isp_mcm.c new file mode 100644 index 0000000..88da4d8 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_mcm.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" +#define REG_BASE 0x1200 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"MCM_CTRL", "MCM control register", + 0x00001200, 0x00020000, 17, 17, "mcm_sensor_mem_bypass","0: use sensor latency memory in MCM; 1: not use sensor latency memory in MCM"}, + {NULL, NULL, 0x00001200, 0x00020000, 16, 14, "mcm_g2_wr1_fmt", "Controls the input format for MCM_G2 channel 1 with same definition as mcm_wr0_fmt"}, + {NULL, NULL, 0x00001200, 0x00020000, 13, 11, "mcm_g2_wr0_fmt", "Controls the input format for MCM_G2 channel 0 with same definition as mcm_wr0_fmt"}, + {NULL, NULL, 0x00001200, 0x00020000, 10, 8, "mcm_wr1_fmt", "Controls the input format for MCM channel 1 with same definition as mcm_wr0_fmt"}, + {NULL, NULL, 0x00001200, 0x00020000, 7, 5, "mcm_wr0_fmt", "MCM Channel-0: 000: 8-bit; 001: 10-bit; 010: 12-bit; 011: 14-bit; 100: 16-bit; 101: 20-bit"}, + {NULL, NULL, 0x00001200, 0x00020000, 4, 1, "mcm_bypass_switch", "Bypass switch. 0000: sensor0 bypass; 0001: sensor1 bypass; …; 1111: sensor15 bypass if any"}, + {NULL, NULL, 0x00001200, 0x00020000, 0, 0, "mcm_bypass_en", "Bypass enable. 0: bypass disabled; 1: bypass enabled"}, + + + {"MCM_SIZE0", "MCM dimension register 0", + 0x00001204, 0x00000000, 29, 16, "mcm_height0", "Image height for write channel 0"}, + {NULL, NULL, 0x00001204, 0x00000000, 13, 0, "mcm_width0", "Image width for write channel 0"}, + + {"MCM_SIZE1", "MCM dimension register 1", + 0x00001208, 0x00000000, 29, 16, "mcm_height1", "Image height for write channel 1"}, + {NULL, NULL, 0x00001208, 0x00000000, 13, 0, "mcm_width1", "Image width for write channel 1"}, + + + {"ISP_MCM_RD_CFG", "MCM read format register", + 0x00001280, 0x00000000, 13, 0, "mcm_rd_fmt", "input format for MCM read channel: " LINE_PADDING_6TAB + " 000:8bit, 001:10bit, 010:12bit, 011:14bit, 100:16bit, 101:20bit"}, + + {"MCM_RETIMING0", "MCM retiming control register 0", + 0x00001284, 0x00000000, 31, 8, "mcm_vsync_blank", "Minimum count of clock from previous frame end to the vsync of the next frame"}, + {NULL, NULL, 0x00001284, 0x00000000, 7, 0, "mcm_vsync_duration", "Vsync active duration for retiming unit which indicate counts of clock"}, + + {"MCM_RETIMING1", "MCM retiming control register 1", + 0x00001288, 0x00000000, 31, 8, "mcm_vsync_blank", "Minimum count of clock from previous frame end to the vsync of the next frame"}, + {NULL, NULL, 0x00001288, 0x00000000, 7, 0, "mcm_vsync_duration", "Vsync active duration for retiming unit which indicate counts of clock"}, + + {"MCM Unknown", "What", 0x0000128C, 0x00000000, 31, 0, "unknown", "unknown"}, +}; + + +int light_isp_mcm_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_mcm_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_mcm_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_pre_filt.c b/tools/reg_analyzer/vsi_isp8000/isp_pre_filt.c new file mode 100644 index 0000000..3b852e2 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_pre_filt.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00004000 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_PRE_FILT_CTRL", "Pre-filter Mode control register", + 0x00004000, 0x00C08802, 23, 23, "part_two_enable", "pre part enable"}, + {NULL, NULL, 0x00004000, 0x00C08802, 22, 22, "part_one_enable", "post part enable"}, + {NULL, NULL, 0x00004000, 0x00C08802, 21, 21, "soft_rst_pre_filt", "Soft reset. 0: release; 1: reset"}, + {NULL, NULL, 0x00004000, 0x00C08802, 20, 13, "demosaic_threshold", "Threshold for Bayer demosaicing texture detection. " LINE_PADDING_6TAB + "This value shifted left 4 bits is compared with the " LINE_PADDING_6TAB + "difference of the vertical and horizontal 12 bit wide " LINE_PADDING_6TAB + "texture indicators, to determine if the vertical or " LINE_PADDING_6TAB + "horizontal texture flag must be set." LINE_PADDING_6TAB + "0x00: maximum edge sensitivity" LINE_PADDING_6TAB + "0xFF: no texture detection"}, + {NULL, NULL, 0x00004000, 0x00C08802, 12, 9, "stage1_select", "Green filter stage 1 select (range 0x0...0x8)" LINE_PADDING_6TAB + "0x0: maximum blurring; 0x4: Default; " LINE_PADDING_6TAB + "0x7: minimum blurring; 0x8: filter stage1 bypass" LINE_PADDING_6TAB + "For a detailed description refer to chapter " LINE_PADDING_6TAB + "'Filter (Sharpen/Blur) Programming' " LINE_PADDING_6TAB + "in the Programming Guide, Part 2."}, + {NULL, NULL, 0x00004000, 0x00C08802, 8, 7, "out_rgb_bayer_pattern","0: RGGB; 1: GRBG; 2: GBRG; 3: BGGR"}, + {NULL, NULL, 0x00004000, 0x00C08802, 6, 3, "rgbir_bayer_pattern", "0: BGGIR/BAYER PATTERN (Default); 1: GRIRG; 2: RGGIR; 3: GBIRG;" LINE_PADDING_6TAB + "4: GIRRG; 5: IRGGB; 6: GIRBG; 7: IRGGR; 8: RGIRB; 9: GRBI;" LINE_PADDING_6TAB + "10: IRBRG; 11: BIRGR; 12: BGIRR; 13: GBRIR; 14: IRRBG; 15: RIRGB"}, + {NULL, NULL, 0x00004000, 0x00C08802, 2, 2, "green_filt_enable", "Enable/disable green channel filter" LINE_PADDING_6TAB + "0: disable green filter (Default)" LINE_PADDING_6TAB + "1: enable green filter"}, + {NULL, NULL, 0x00004000, 0x00C08802, 1, 1, "green_filt_mode", "0: green filter static mode (active filter factor = FILT_FAC_MID)" LINE_PADDING_6TAB + "1: dynamic noise reduction/sharpen (Default)"}, + {NULL, NULL, 0x00004000, 0x00C08802, 0, 0, "isp_pre_filt_enable", "0: bypass pre_filt (Default); 1: enable pre_filt"}, +}; + + +int light_isp_pre_filt_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_pre_filt_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_pre_filt_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_stitching0.c b/tools/reg_analyzer/vsi_isp8000/isp_stitching0.c new file mode 100644 index 0000000..64bedb4 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_stitching0.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define ISP_STITCHING0_BASE 0x3300 +#define REG_BASE ISP_STITCHING0_BASE + + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, reg_desc, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_STITCHING0_CTRL", "HDR Stitch Control Register", + 0x00003300, 0x00000000, 26, 26, "share_en", "Enable/Disable share of sram. 0: Disable share sram; 1: Enable share sram"}, + {NULL, NULL, 0x00003300, 0x00000000, 25, 25, "digital_gain_en_2", "Enable/Disable dgain of very short frame. 0: Disable the dgain; 1: Enable the dgain"}, + {NULL, NULL, 0x00003300, 0x00000000, 24, 24, "digital_gain_en_1", "Enable/Disable dgain of short frame. 0: Disable the dgain; 1: Enable the dgain"}, + {NULL, NULL, 0x00003300, 0x00000000, 23, 23, "digital_gain_en_0", "Enable/Disable dgain of long frame. 0: Disable the dgain; 1: Enable the dgain"}, + {NULL, NULL, 0x00003300, 0x00000000, 22, 22, "regs_inform_en", "Enable/Disable inform module. 0: Disable the inform; 1: Enable the inform"}, + {NULL, NULL, 0x00003300, 0x00000000, 21, 21, "vsync_pol", "VSYNC polarity reversal"}, + {NULL, NULL, 0x00003300, 0x00000000, 20, 20, "hsync_pol", "HSYNC polarity reversal"}, + {NULL, NULL, 0x00003300, 0x00000000, 19, 19, "awb_gain_enable", "Enable/Disable AWB Gain module. 0: Disable the AWB gain; 1: Enable the AWB gain"}, + {NULL, NULL, 0x00003300, 0x00000000, 18, 18, "cfg_upd", "Configuration update"}, + {NULL, NULL, 0x00003300, 0x00000000, 17, 17, "gen_cfg_upd", "Generate configuration update"}, + {NULL, NULL, 0x00003300, 0x00000000, 16, 16, "gen_cfg_upd_fix", "Auto configuration update in the end of frame"}, + {NULL, NULL, 0x00003300, 0x00000000, 14, 13, "bypass_select", "Bypass frame select. 0: long frame; 1: short frame; 2: very short frame"}, + {NULL, NULL, 0x00003300, 0x00000000, 12, 12, "linear_combine_enable","linear combination enable"}, + {NULL, NULL, 0x00003300, 0x00000000, 11, 11, "base_frame_selection", "base frame select"}, + {NULL, NULL, 0x00003300, 0x00000000, 10, 9, "combination_mode", "combination_mode"}, + {NULL, NULL, 0x00003300, 0x00000000, 8, 8, "channel_config_bit", "channel_config_bit"}, + {NULL, NULL, 0x00003300, 0x00000000, 7, 7, "b10_enable_bit", "10 bit enable"}, + {NULL, NULL, 0x00003300, 0x00000000, 6, 6, "lin_enable_bit", "reserved"}, + {NULL, NULL, 0x00003300, 0x00000000, 5, 5, "vs_enable_bit", "very short frame enable"}, + {NULL, NULL, 0x00003300, 0x00000000, 4, 3, "bayer_pattern", "bayer pattern. 00: RGGB; 01: GRBG; 10: GBRB; 11: BGGR"}, + {NULL, NULL, 0x00003300, 0x00000000, 2, 2, "soft_reset_flag", "Activate/deactivate Stitch software reset. 0: software reset un-active; 1: software reset active"}, + {NULL, NULL, 0x00003300, 0x00000000, 1, 1, "mono_input_flag", "reserved"}, + {NULL, NULL, 0x00003300, 0x00000000, 0, 0, "combine_enable_bit", "Enable/Disable Stitch module. 0: Disable the Stitch module; 1: Enable the Stitch module"}, + + + {"ISP_STITCHING0_FRAME_WIDTH", "Stitching frame width", 0x00003304, 0x00000000, 13, 0, "stitching_frame_width", "Frame width"}, + {"ISP_STITCHING0_FRAME_HEIGHT","Stitching frame height", 0x00003308, 0x00000000, 13, 0, "stitching_frame_height", "Frame height"}, + + {"ISP_STITCHING0_EXPOSURE_BIT", "Stitching frame data bit depth", + 0x0000330C, 0x05050505, 31, 24, "stitching_l_bit_depth", "Exposure bit for LS; valid range: [0..255]"}, + {NULL, NULL, 0x0000330C, 0x05050505, 23, 16, "stitching_s_bit_depth", "Exposure bit for VS; valid range: [0..255]"}, + {NULL, NULL, 0x0000330C, 0x05050505, 15, 8, "stitching_vs_bit_depth", "Exposure bit for S; valid range: [0..255]"}, + {NULL, NULL, 0x0000330C, 0x05050505, 7, 0, "stitching_ls_bit_depth", "Exposure bit for L; valid range: [0..255]"}, + + {"ISP_STITCHING0_COLOR_WEIGHT", "Channel color weight for gray computation", + 0x00003310, 0x001D464D, 23, 16, "stitching_color_weight_2", "B color weight for Y conversion. Valid range: [0..255]"}, + {NULL, NULL, 0x00003310, 0x001D464D, 15, 8, "stitching_color_weight_1", "G color weight for Y conversion. Valid range: [0..255]"}, + {NULL, NULL, 0x00003310, 0x001D464D, 7, 0, "stitching_color_weight_0", "R color weight for Y conversion.. Valid range: [0..255]"}, + + {"ISP_STITCHING0_BLS_EXP_0_A", "Black level for exposure 0 channel A", + 0x00003314, 0x01000000, 31, 16, "stitching_digital_gain_exp_0_r", "Digital gain value for exposure 0 red pixel"}, + {NULL, NULL, 0x00003314, 0x01000000, 11, 0, "stitching_bls_exp_0_a", "Black level value for exposure 0 channel A"}, + + + {"ISP_STITCHING0_BLS_EXP_0_B", "Black level for exposure 0 channel B", + 0x00003318, 0x01000000, 31, 16, "stitching_digital_gain_exp_0_g", "Digital gain value for exposure 0 blue pixel"}, + {NULL, NULL, 0x00003318, 0x01000000, 11, 0, "stitching_bls_exp_0_b", "Black level value for exposure 0 channel B"}, + + + + {"ISP_STITCHING0_RATIO_LS", "Exposure ratio between Long and Short", + 0x00003344, 0x00400400, 23, 12, "stitching_ratio_long_short_1", "Exposure merge ratio from S to L (greater than 1)"}, + {NULL, NULL, 0x00003344, 0x00400400, 11, 0, "stitching_ratio_long_short_0", "Exposure merge ratio from S to L (less than 1)"}, + + + {"ISP_STITCHING0_LONG_EXPOSURE", "Long exposure time", 0x00003360, 0x00000040, 11, 0, "stitching_long_exposure_time", "Exposure time for long exposure frame"}, + {"ISP_STITCHING0_SHORT_EXPOSURE", "Short exposure time", 0x00003364, 0x00000008, 11, 0, "stitching_short_exposure_time", "Exposure time for short exposure frame"}, + {"ISP_STITCHING0_VERY_SHORT_EXPOSURE", "Very short exposure time", 0x00003368, 0x00000008, 11, 0, "stitching_very_short_exposure_time", "Exposure time for very short exposure frame"}, + {"ISP_STITCHING0_HDR_MODE", "HDR combination mode", 0x0000336C, 0x00000000, 3, 0, "stitching_hdr_input_format_type", "Input Sensor HDR mode:" LINE_PADDING_6TAB + " 0: dual DCG mode 3x12-bit (default)" LINE_PADDING_6TAB + " 1: DOL 3 Frame 3x12-bit" LINE_PADDING_6TAB + " 2: 3x12-bit line by line without waiting" LINE_PADDING_6TAB + " 3: 16-bit compressed data + 12-bit RAW" LINE_PADDING_6TAB + " 4: 2x12-bit dual DCG without waiting" LINE_PADDING_6TAB + " 5: DOL2 frame or 1 CG+VS sx12-bit RAW" LINE_PADDING_6TAB + " 6: L+S 2x12-bit RAW"}, + + {"ISP_STITCHING0_OUT_HBLANK", "HDR blanking in horizontal direction", + 0x00003370, 0x00100080, 31, 16, "stitching_dummy_s_hblank", "Dummy line horizontal blank for short exposure"}, + {NULL, NULL, 0x00003370, 0x00100080, 15, 0, "stitching_out_hblank", "Output data horizontal blank time"}, + + + {"ISP_STITCHING0_OUT_VBLANK", "HDR blanking in vertical direction", + 0x00003374, 0x00100020, 31, 16, "stitching_dummy_vs_hblank", "Dummy line horizontal blank for very short exposure"}, + {NULL, NULL, 0x00003374, 0x00100020, 15, 0, "stitching_out_vblank", "Output data vertical blank time"}, + + + {"ISP_STITCHING0_INTERRUPT_STATUS", "Stitching interrupt status", 0x00003378, 0x00000000, 2, 0, "stitching_interrupt_status", " Unknown yet"}, + {"ISP_STITCHING0_COMPRESS_X0", "Compression LUT x index", 0x0000337C, 0x00000000, 9, 0, "compress_lut_first_valid_x", " Compression LUT first valid x index"}, + {"ISP_STITCHING0_COMPRESS_X0_SHD", "Compression LUT x index shadow", 0x00003380, 0x00000000, 9, 0, "compress_lut_first_valid_shd_x", " Compression LUT first valid x index shadow"}, + + + {"ISP_STITCHING0_COMPRESS_LUT_0", "Compression LUT data 0", + 0x000033A0, 0x00000000, 29, 20, "stitching_compress_lut_2", "VS compression LUT2"}, + {NULL, NULL, 0x000033A0, 0x00000000, 19, 10, "stitching_compress_lut_1", "VS compression LUT1"}, + {NULL, NULL, 0x000033A0, 0x00000000, 9, 0, "stitching_compress_lut_0", "VS compression LUT0"}, + + {"ISP_STITCHING0_COMPRESS_LUT_1", "Compression LUT data 1", + 0x000033A4, 0x00000000, 29, 20, "stitching_compress_lut_5", "VS compression LUT5"}, + {NULL, NULL, 0x000033A4, 0x00000000, 19, 10, "stitching_compress_lut_4", "VS compression LUT4"}, + {NULL, NULL, 0x000033A4, 0x00000000, 9, 0, "stitching_compress_lut_3", "VS compression LUT3"}, + + {"ISP_STITCHING0_COMPRESS_LUT_4", "Compression LUT data 4", + 0x000033B0, 0x00000000, 29, 20, "stitching_compress_lut_14", "VS compression LUT14"}, + {NULL, NULL, 0x000033B0, 0x00000000, 19, 10, "stitching_compress_lut_13", "VS compression LUT13"}, + {NULL, NULL, 0x000033B0, 0x00000000, 9, 0, "stitching_compress_lut_12", "VS compression LUT12"}, + + {"ISP_STITCHING0_COMPRESS_LUT_SHD_0", "Compression LUT data 0 shadow", + 0x000033B4, 0x00000000, 29, 20, "stitching_compress_lut_shd_2", "Shadow of VS compression LUT2"}, + {NULL, NULL, 0x000033B4, 0x00000000, 19, 10, "stitching_compress_lut_shd_1", "Shadow of VS compression LUT1"}, + {NULL, NULL, 0x000033B4, 0x00000000, 9, 0, "stitching_compress_lut_shd_0", "Shadow of VS compression LUT0"}, + + {"ISP_STITCHING0_EXP0_AWB_GAIN_G", "AWB gain for exposure 0 channel G", + 0x000033C8, 0x01000100, 25, 16, "stitching_exp0_awb_gain_gr", "Stitching AWB GR gain for exposure 0"}, + {NULL, NULL, 0x000033C8, 0x01000100, 9, 0, "stitching_exp0_awb_gain_gb", "Stitching AWB GB gain for exposure 0"}, + + {"ISP_STITCHING0_EXP0_AWB_GAIN_RB", "AWB gain for exposure 0 channel RB", + 0x000033CC, 0x01000100, 25, 16, "stitching_exp0_awb_gain_r", "Stitching AWB R gain for exposure 0"}, + {NULL, NULL, 0x000033CC, 0x01000100, 9, 0, "stitching_exp0_awb_gain_b", "Stitching AWB B gain for exposure 0"}, + + + {"ISP_STITCHING0_EXP1_AWB_GAIN_G", "AWB gain for exposure 1 channel G", + 0x000033D0, 0x01000100, 25, 16, "stitching_exp1_awb_gain_gr", "Stitching AWB GR gain for exposure 1"}, + {NULL, NULL, 0x000033D0, 0x01000100, 9, 0, "stitching_exp1_awb_gain_gb", "Stitching AWB GB gain for exposure 1"}, + + + {"ISP_STITCHING0_EXP1_AWB_GAIN_RB", "AWB gain for exposure 1 channel RB", + 0x000033D4, 0x01000100, 25, 16, "stitching_exp1_awb_gain_r", "Stitching AWB R gain for exposure 1"}, + {NULL, NULL, 0x000033D4, 0x01000100, 9, 0, "stitching_exp1_awb_gain_b", "Stitching AWB B gain for exposure 1"}, + + + {"ISP_STITCHING0_LONG_SAT_PARAMS", "Stitching saturation params for long exposure", + 0x000033E0, 0x007FF000, 23, 12, "stitching_long_sat_thresh", "Stitching long saturation threshold"}, + {NULL, NULL, 0x000033E0, 0x007FF000, 8, 0, "stitching_long_sat_combine_weight", "Stitching long combine weight"}, + + {"ISP_STITCHING0_EXP2_AWB_GAIN_G", "AWB gain for exposure 2 channel G", + 0x000033D8, 0x01000100, 25, 16, "stitching_exp2_awb_gain_gr", "Stitching AWB GR gain for exposure 2"}, + {NULL, NULL, 0x000033D8, 0x01000100, 9, 0, "stitching_exp2_awb_gain_gb", "Stitching AWB GB gain for exposure 2"}, + + {"ISP_STITCHING0_EXP2_AWB_GAIN_RB", "AWB gain for exposure 2 channel RB", + 0x000033DC, 0x01000100, 25, 16, "stitching_exp2_awb_gain_r", "Stitching AWB R gain for exposure 2"}, + {NULL, NULL, 0x000033DC, 0x01000100, 9, 0, "stitching_exp2_awb_gain_b", "Stitching AWB B gain for exposure 2"}, + + {"ISP_STITCHING0_IMSC", "IMSC Interrupt Mask", + 0x000033E4, 0x00000000, 8, 8, "stitching_imsc_hdr_hist_irq_vs", "Stitching HDR hist VS interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 7, 7, "stitching_imsc_hdr_hist_irq_s", "Stitching HDR hist S interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 6, 6, "stitching_imsc_hdr_hist_irq_l", "Stitching HDR hist L interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 5, 5, "stitching_imsc_hdr_exp_complete_vs", "Stitching HDR exp statistic VS interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 4, 4, "stitching_imsc_hdr_exp_complete_s", "Stitching HDR exp statistic S interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 3, 3, "stitching_imsc_hdr_exp_complete_l", "Stitching HDR exp statistic L interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 2, 2, "stitching_imsc_fifo_empty", "Stitching HDR FIFO empty L interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 1, 1, "stitching_imsc_exp_err2", "Stitching HDR very short exp time error L interrupt mask"}, + {NULL, NULL, 0x000033E4, 0x00000000, 0, 0, "stitching_imsc_exp_err1", "Stitching HDR short exp time error L interrupt mask"}, + + + {"ISP_STITCHING0_RIS", "RIS Raw Interrupt Status", + 0x000033E8, 0x00000000, 8, 8, "stitching_ris_hdr_hist_irq_vs", "Stitching HDR hist VS interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 7, 7, "stitching_ris_hdr_hist_irq_s", "Stitching HDR hist S interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 6, 6, "stitching_ris_hdr_hist_irq_l", "Stitching HDR hist L interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 5, 5, "stitching_ris_hdr_exp_complete_vs", "Stitching HDR exp statistic VS interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 4, 4, "stitching_ris_hdr_exp_complete_s", "Stitching HDR exp statistic S interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 3, 3, "stitching_ris_hdr_exp_complete_l", "Stitching HDR exp statistic L interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 2, 2, "stitching_ris_fifo_empty", "Stitching HDR FIFO empty L interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 1, 1, "stitching_ris_exp_err2", "Stitching HDR very short exp time error L interrupt status"}, + {NULL, NULL, 0x000033E8, 0x00000000, 0, 0, "stitching_ris_exp_err1", "Stitching HDR short exp time error L interrupt status"}, + + + {"ISP_STITCHING0_MIS", "MIS Masked Interrupt Status", + 0x000033EC, 0x00000000, 8, 8, "stitching_mis_hdr_hist_irq_vs", "Stitching HDR hist VS interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 7, 7, "stitching_mis_hdr_hist_irq_s", "Stitching HDR hist S interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 6, 6, "stitching_mis_hdr_hist_irq_l", "Stitching HDR hist L interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 5, 5, "stitching_mis_hdr_exp_complete_vs", "Stitching HDR exp statistic VS interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 4, 4, "stitching_mis_hdr_exp_complete_s", "Stitching HDR exp statistic S interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 3, 3, "stitching_mis_hdr_exp_complete_l", "Stitching HDR exp statistic L interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 2, 2, "stitching_mis_fifo_empty", "Stitching HDR FIFO empty L interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 1, 1, "stitching_mis_exp_err2", "Stitching HDR very short exp time error\n\t L interrupt masked status"}, + {NULL, NULL, 0x000033EC, 0x00000000, 0, 0, "stitching_mis_exp_err1", "Stitching HDR short exp time error L interrupt \n\tMasked status"}, + + + {"ISP_STITCHING0_ICR", "ICR Interrupt Clear Register", + 0x000033F0, 0x00000000, 8, 8, "stitching_icr_hdr_hist_irq_vs", "Stitching HDR hist VS interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 7, 7, "stitching_icr_hdr_hist_irq_s", "Stitching HDR hist S interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 6, 6, "stitching_icr_hdr_hist_irq_l", "Stitching HDR hist L interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 5, 5, "stitching_icr_hdr_exp_complete_vs", "Stitching HDR exp statistic VS interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 4, 4, "stitching_icr_hdr_exp_complete_s", "Stitching HDR exp statistic S interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 3, 3, "stitching_icr_hdr_exp_complete_l", "Stitching HDR exp statistic L interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 2, 2, "stitching_icr_fifo_empty", "Stitching HDR FIFO empty L interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 1, 1, "stitching_icr_exp_err2", "Stitching HDR very short exp time error L interrupt clear"}, + {NULL, NULL, 0x000033F0, 0x00000000, 0, 0, "stitching_icr_exp_err1", "Stitching HDR short exp time error L interrupt clear"}, + + + {"ISP_STITCHING0_ISR", "ISR Interrupt Set Register", + 0x000033F4, 0x00000000, 8, 8, "stitching_isr_hdr_hist_irq_vs", "Stitching HDR hist VS interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 7, 7, "stitching_isr_hdr_hist_irq_s", "Stitching HDR hist S interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 6, 6, "stitching_isr_hdr_hist_irq_l", "Stitching HDR hist L interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 5, 5, "stitching_isr_hdr_exp_complete_vs", "Stitching HDR exp statistic VS interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 4, 4, "stitching_isr_hdr_exp_complete_s", "Stitching HDR exp statistic S interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 3, 3, "stitching_isr_hdr_exp_complete_l", "Stitching HDR exp statistic L interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 2, 2, "stitching_isr_fifo_empty", "Stitching HDR FIFO empty L interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 1, 1, "stitching_isr_exp_err2", "Stitching HDR very short exp time error L interrupt set"}, + {NULL, NULL, 0x000033F4, 0x00000000, 0, 0, "stitching_isr_exp_err1", "Stitching HDR short exp time error L interrupt set"}, +}; + + +int light_isp_sitching0_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_sitching0_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_sitching0_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/isp_vsm.c b/tools/reg_analyzer/vsi_isp8000/isp_vsm.c new file mode 100644 index 0000000..46044ea --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/isp_vsm.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00002f00 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_VSM_MODE", "Video Stable Measure Mode", + 0x00002f00, 0x00000000, 1, 1, "vsm_meas_irq_enable", "1: Enable VS measurement done IRQ"}, + {NULL, NULL, 0x00002f00, 0x00000000, 0, 0, "vsm_meas_en", "1: Enable measurement"}, +}; + + +int light_isp_vsm_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_vsm_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_vsm_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_cproc.c b/tools/reg_analyzer/vsi_isp8000/m5_cproc.c new file mode 100644 index 0000000..abfd41b --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_cproc.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x800 +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + {"CPROC_CTRL", "Global control register", + 0x00000800, 0x00000000, 3, 3, "cproc_c_out_range", "Color processing chrominance pixel clipping range at output" LINE_PADDING_6TAB + " 0: CbCr_out clipping range [16..240] according to ITU-R BT.601 standard" LINE_PADDING_6TAB + " 1: Full UV_out clipping range [0..255]"}, + {NULL, NULL, 0x00000800, 0x00000000, 2, 2, "cproc_y_in_range", "Color processing luminance input range (offset processing)" LINE_PADDING_6TAB + " 0: Y_in range [64..940] according to ITU-R BT.601 standard;" LINE_PADDING_6TAB + " offset of 64 will be subtracted from Y_in" LINE_PADDING_6TAB + " 1: Y_in full range [0..1023]; no offset will be subtracted from Y_in"}, + {NULL, NULL, 0x00000800, 0x00000000, 1, 1, "cproc_y_out_range", "Color processing luminance output clipping range" LINE_PADDING_6TAB + " 0: Y_out clipping range [16..235];" LINE_PADDING_6TAB + " offset of 16 is added to Y_out according to ITU-R BT.601 standard" LINE_PADDING_6TAB + " 1: Y_out clipping range [0..255]; no offset is added to Y_out"}, + {NULL, NULL, 0x00000800, 0x00000000, 0, 0, "cproc_enable", "Color processing enable" LINE_PADDING_6TAB + " 0: Color processing is bypassed" LINE_PADDING_6TAB + " 1: Color processing is active" LINE_PADDING_6TAB + " 2 * 10 bit input data are truncated to 2 * 8 bit output data" LINE_PADDING_6TAB + " output data are rounded to 2 * 8 bit and clipping is active"}, +}; + +int light_isp_cproc_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_cproc_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_cproc_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_isp.c b/tools/reg_analyzer/vsi_isp8000/m5_isp.c new file mode 100644 index 0000000..87acd86 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_isp.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define MRV_ISP_BASE 0x0400 +#define REG_BASE MRV_ISP_BASE + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_CTRL", "ISP Global control register", + 0x00000400, 0x80000000, 31, 31, "disable_isp_clk", "1: disable ISP clock of SRAM."}, + {NULL, NULL, 0x00000400, 0x80000000, 23, 23, "pp_write_sel", "1: select yuv output 0: select raw output"}, + {NULL, NULL, 0x00000400, 0x80000000, 22, 22, "ir_raw_out", "0: disable; 1: IR data output from main path"}, + {NULL, NULL, 0x00000400, 0x80000000, 20, 20, "regs_wdrth_data_mux", ""}, + {NULL, NULL, 0x00000400, 0x80000000, 19, 19, "digi_gain_en", "0:digital gain disable; 1:digital gain enable"}, + {NULL, NULL, 0x00000400, 0x80000000, 18, 18, "dpf_raw_out", "0: Disable; 1: Enable DPF raw output (from March 2018)"}, + {NULL, NULL, 0x00000400, 0x80000000, 17, 17, "cnr_en", "0: Disable; 1: CNR is enabled. (from March 2018)"}, + {NULL, NULL, 0x00000400, 0x80000000, 16, 16, "enable_12bit_unpack", "0:disable; 1: enable 12-bit unpack for DMA read"}, + {NULL, NULL, 0x00000400, 0x80000000, 15, 15, "enable_12bit_packed", "0:disable; 1: enable 12-bit pack"}, + {NULL, NULL, 0x00000400, 0x80000000, 14, 14, "csm_c_range", "Color Space Matrix chrominance clipping range for ISP output" LINE_PADDING_6TAB + "0: CbCr range 64..960 [16..240] according to ITU-R BT.601 standard" LINE_PADDING_6TAB + "1: full UV range 0..1023 [0..255]" LINE_PADDING_6TAB + "Numbers in brackets are for 8 bit resolution." LINE_PADDING_6TAB + "This bit also configures the YCbCr sequence align block accordingly."}, + {NULL, NULL, 0x00000400, 0x80000000, 13, 13, "csm_y_range", "Color Space Matrix luminance clipping range for ISP output" LINE_PADDING_6TAB + "0: Y range 64..940 [16..235] according to ITU-R BT.601 standard" LINE_PADDING_6TAB + "1: full Y range 0..1023 [0..255]" LINE_PADDING_6TAB + "Numbers in brackets are for 8 bit resolution." LINE_PADDING_6TAB + "This bit also configures the YCbCr sequence align block accordingly."}, + {NULL, NULL, 0x00000400, 0x80000000, 12, 12, "flash_mode", "0: sensor interface works independently from flash control unit" LINE_PADDING_6TAB + "1: one frame is captured when signaled by flash control unit"}, + {NULL, NULL, 0x00000400, 0x80000000, 11, 11, "gamma_out_enable", "Gamma ON/OFF"}, + {NULL, NULL, 0x00000400, 0x80000000, 10, 10, "gen_cfg_upd", "1: generate frame synchronous configuration signal at the output of ISP for" LINE_PADDING_6TAB + " shadow registers of the following processing modules, write only"}, + {NULL, NULL, 0x00000400, 0x80000000, 9, 9, "cfg_upd", "1: immediately configure (update) shadow registers, write only"}, + {NULL, NULL, 0x00000400, 0x80000000, 8, 8, "gen_cfg_upd_fix", "1: make gen_cfg_upd a level signal, effect since then.; " LINE_PADDING_6TAB + "0: gen_cfg_upd is a pulse signal, only effect for current frame."}, + {NULL, NULL, 0x00000400, 0x80000000, 7, 7, "awb_enable", "Auto white balance ON/OFF"}, + {NULL, NULL, 0x00000400, 0x80000000, 6, 6, "gamma_in_enable", "Sensor De-gamma ON/OFF"}, + {NULL, NULL, 0x00000400, 0x80000000, 4, 4, "inform_enable", "input formatter. 0: disabled; 1: enabled" LINE_PADDING_6TAB + "The ISP input formatter is enabled or disabled by this bit immediately," LINE_PADDING_6TAB + "But always starts or stops acquisition frame synchronously."}, + {NULL, NULL, 0x00000400, 0x80000000, 3, 1, "isp_mode", "000 - RAW picture with BT.601 sync (ISP bypass)" LINE_PADDING_6TAB + "001 - ITU-R BT.656 (YUV with embedded sync)" LINE_PADDING_6TAB + "010 - ITU-R BT.601 (YUV input with H/Vsync signals)" LINE_PADDING_6TAB + "011 - Bayer RGB processing with H/Vsync signals" LINE_PADDING_6TAB + "100 - data mode (ISP bypass, sync signals interpreted as data enable)" LINE_PADDING_6TAB + "101 - Bayer RGB processing with BT.656 synchronization" LINE_PADDING_6TAB + "110 - RAW picture with ITU-R BT.656 synchronization (ISP bypass)" LINE_PADDING_6TAB + "111 - reserved" LINE_PADDING_6TAB + "Side effect: If RAW, ...[Refer to Doc]"}, + {NULL, NULL, 0x00000400, 0x80000000, 0, 0, "isp_enable", "ISP data output. 0: disabled ; 1: enabled" LINE_PADDING_6TAB + "Controls output formatter frame synchronously, if isp_gen_cfg_upd is" LINE_PADDING_6TAB + "Used to activate this bit. For immediate update isp_cfg_upd must be used."}, + + + {"ISP_ACQ_PROP", "ISP acquisition properties", + 0x00000404, 0x00000000, 31, 31, "hdr_en", "in HDR mode, ISP input data bit width is 20"}, + {NULL, NULL, 0x00000404, 0x00000000, 29, 29, "sample_edge_1", "Sample edge control for sensor 2. " LINE_PADDING_6TAB + "0: use input sclk; 1: add half cycle delay of sclk"}, + {NULL, NULL, 0x00000404, 0x00000000, 28, 28, "sample_edge_0", "Sample edge control for sensor 1." LINE_PADDING_6TAB + "0: use input sclk; 1: add half cycle delay of sclk"}, + {NULL, NULL, 0x00000404, 0x00000000, 27, 26, "two_cycle_data_sel", "two_cycle_data_sel[2:0]. " LINE_PADDING_6TAB + "0:select the same bits of data0 and data1;" LINE_PADDING_6TAB + "1: select all bits of data0 and data1 low bits"}, + {NULL, NULL, 0x00000404, 0x00000000, 25, 25, "change_two_cycle_data_sequence", "0: data0 is high bits, data1 is low bits;" LINE_PADDING_6TAB + "1: data1 is high bits, data0 is low bits"}, + {NULL, NULL, 0x00000404, 0x00000000, 24, 24, "two_cycle_merge_enable", "0: not merge; 1: two sequence data merge to one pixel"}, + {NULL, NULL, 0x00000404, 0x00000000, 23, 20, "input_bayer_format", "0: no more than bit16; 1~5: reserved; 6: bit18; 7: bit20"}, + {NULL, NULL, 0x00000404, 0x00000000, 19, 17, "pin_mapping", "Bit mapping from LSB to MSB:" LINE_PADDING_6TAB + "000 - normal 12-bit external Interface" LINE_PADDING_6TAB + "001 - mapping Low 10 bit to High 10 bits, append 2 zeroes as LSBs" LINE_PADDING_6TAB + "010 - mapping Low 8 bit to High 8 bits, append 4 zeroes as LSBs" LINE_PADDING_6TAB + "011 - mapping Middle 8 bit to High 8 bits, append 4 zeroes as LSBs" LINE_PADDING_6TAB + "100...111 - Reserved (from March 2018)"}, + {NULL, NULL, 0x00000404, 0x00000000, 16, 16, "yuv_dma_sel", "0: use align or conversion data for isp_is input. " LINE_PADDING_6TAB + "1: use DMA yuv read data for isp_is input. (from March 2018)"}, + {NULL, NULL, 0x00000404, 0x00000000, 15, 15, "rgb_dma_sel", "0: use input formatter data for latency fifo. " LINE_PADDING_6TAB + "1: use DMA rgb read data for latency fifo.. (from March 2018)"}, + {NULL, NULL, 0x00000404, 0x00000000, 14, 12, "input_selection", "It not defined in reg.xml, but defines in code:" LINE_PADDING_6TAB + "000- 12Bit external Interface" LINE_PADDING_6TAB + "001- 10Bit Interface, append 2 zeroes as LSBs" LINE_PADDING_6TAB + "010- 10Bit Interface, append 2 MSBs as LSBs" LINE_PADDING_6TAB + "011- 8Bit Interface, append 4 zeroes as LSBs" LINE_PADDING_6TAB + "100- 8Bit Interface, append 4 MSBs as LSBs" LINE_PADDING_6TAB + "101...111 reserved"}, + {NULL, NULL, 0x00000404, 0x00000000, 11, 11, "field_inv", "0: do not swap odd and even fields; 1: swap odd and even fields"}, + {NULL, NULL, 0x00000404, 0x00000000, 10, 9, "field_selection", "00- sample all fields (don't care about fields); " LINE_PADDING_6TAB + "01- sample only even fields; " LINE_PADDING_6TAB + "10- sample only odd fields;" LINE_PADDING_6TAB + "11- reserved"}, + {NULL, NULL, 0x00000404, 0x00000000, 8, 7, "ccir_seq", "00- YCbYCr; 01- YCrYCb; 10- CbYCrY; 11- CrYCbY"}, + {NULL, NULL, 0x00000404, 0x00000000, 6, 5, "conv_422", "00- cosited color subsampling Y0Cb0Cr0 – Y1" LINE_PADDING_6TAB + "01- interleaved color subsampling Y0Cb0 – Y1Cr1 (not recommended) " LINE_PADDING_6TAB + "10- non-cosited color subsampling Y0Cb(0+1)/2 – Y1Cr(0+1)/2 " LINE_PADDING_6TAB + "11- reserved"}, + {NULL, NULL, 0x00000404, 0x00000000, 4, 3, "bayer_pat", "Color components from sensor, starting with top left position" LINE_PADDING_6TAB + "in sampled frame (reprogram with ISP_ACQ_H_OFFS, ISP_ACQ_V_OFFS)" LINE_PADDING_6TAB + "00- first line: RGRG..., second line: GBGB..." LINE_PADDING_6TAB + "01- first line: GRGR..., second line: BGBG..." LINE_PADDING_6TAB + "10- first line: GBGB..., second line: RGRG..." LINE_PADDING_6TAB + "11- first line: BGBG..., second line: GRGR..." LINE_PADDING_6TAB + "This configuration applies for the black level " LINE_PADDING_6TAB + "area after cropping by the input formatter."}, + {NULL, NULL, 0x00000404, 0x00000000, 2, 2, "vsync_pol", "Vertical sync polarity. 0: high active; 1: low active"}, + {NULL, NULL, 0x00000404, 0x00000000, 1, 1, "hsync_pol", "Horizontal sync polarity. 0: high active; 1: low active"}, + {NULL, NULL, 0x00000404, 0x00000000, 0, 0, "sample_edge", "0- negative edge sampling; 1- positive edge sampling"}, + + + + {"ISP_ACQ_H_OFFS", "Horizontal input offset", 0x00000408, 0x00000000, 14, 0, "acq_h_offs", "Horizontal sample offset in 8-bit samples (YUV: 4 samples = 2 pixels)"}, + {"ISP_ACQ_H_SIZE", "Horizontal input size", 0x00000410, 0x00001000, 14, 0, "acq_h_size", "Horizontal sample size in 12-bit samples." LINE_PADDING_6TAB + " YUV input: 2 samples = 1 pixel, else 1 sample = 1 pixel;[Refer doc]"}, + {"ISP_ACQ_V_OFFS", "Vertical input offset", 0x0000040c, 0x00000000, 13, 0, "acq_v_offs", "Vertical sample offset in lines"}, + {"ISP_ACQ_V_SIZE", "Vertical input size", 0x00000414, 0x00000C00, 13, 0, "acq_v_size", "Vertical sample size in lines"}, + + {"ISP_ACQ_NR_FRAMES", "Number of frames to be captured", + 0x00000418, 0x00000000, 9, 0, "acq_nr_frames", "Number of input frames to be sampled (0 = continuous)"}, + + + {"ISP_AWB_PROP", "Auto white balance properties", + 0x00000510, 0x00000000, 31, 31, "awb_meas_mode","0: near white discrimination mode using YCbCr color space" LINE_PADDING_6TAB + "1: RGB based measurement mode"}, + {NULL, NULL, 0x00000510, 0x00000000, 2, 2, "awb_max_en", "0: disable; 1: enable. Not valid in RGB measurement mode."}, + {NULL, NULL, 0x00000510, 0x00000000, 1, 0, "awb_mode", "00: no measurement" LINE_PADDING_6TAB + "01: reserved" LINE_PADDING_6TAB + "10: measurement of YCbCr means (AWB_MEAS_MODE = 0)" LINE_PADDING_6TAB + " or RGB means (AWB_MEAS_MODE = 1)" LINE_PADDING_6TAB + "11: reserved"}, + + {"ISP_AWB_GAIN_G", "Auto white balance gain green", + 0x00000538, 0x01000100, 25, 16, "awb_gain_gr", "Gain value for green component in red line 100h = 1, " LINE_PADDING_6TAB + " Unsigned integer value, range 0 to 4 with 8 bit fractional part"}, + {NULL, NULL, 0x00000538, 0x01000100, 9, 0, "awb_gain_gb", "Gain value for green component in blue line 100h = 1, " LINE_PADDING_6TAB + " Unsigned integer value, range 0 to 4 with 8 bit fractional part"}, + + {"ISP_AWB_GAIN_RB", "Auto white balance gain red and blue", + 0x0000053c, 0x01000100, 25, 16, "awb_gain_r", "Gain value for red component in red line 100h = 1, " LINE_PADDING_6TAB + " Unsigned integer value, range 0 to 4 with 8 bit fractional part"}, + {NULL, NULL, 0x0000053c, 0x01000100, 9, 0, "awb_gain_b", "Gain value for blue component in blue line 100h = 1, " LINE_PADDING_6TAB + " Unsigned integer value, range 0 to 4 with 8 bit fractional part"}, + + {"ISP_OUT_H_OFFS", "Horizontal offset of output window", 0x00000594, 0x00000000, 13, 0, "isp_out_h_offs", "Horizontal pic offset in lines"}, + {"ISP_OUT_V_OFFS", "Vertical offset of output window", 0x00000598, 0x00000000, 13, 0, "isp_out_v_offs", "Vertical pic offset in lines"}, + {"ISP_OUT_H_SIZE", "Output horizontal picture size", 0x0000059C, 0x00000000, 14, 0, "isp_out_h_size", "Horizontal picture size in pixel if ISP_MODE is set to: ...[Refer doc]"}, + {"ISP_OUT_V_SIZE", "Output vertical picture size", 0x000005A0, 0x00000000, 13, 0, "isp_out_v_size", "Vertical picture size in lines"}, + + + {"ISP_DEMOSAIC", "Demosaic parameters", + 0x000005a4, 0x00000004, 10, 10, "demosaic_bypass", "0: normal operation for RGB Bayer Pattern input" LINE_PADDING_6TAB + "1: demosaicing bypass for Black&White input data"}, + {NULL, NULL, 0x000005a4, 0x00000004, 7, 0, "demosaic_th", "Threshold for Bayer demosaicing texture detection." LINE_PADDING_6TAB + " This value shifted left 4bit is compared with the" LINE_PADDING_6TAB + " difference of the vertical and horizontal 12-Bit wide" LINE_PADDING_6TAB + " texture indicators, to decide if the vertical or"LINE_PADDING_6TAB + " horizontal texture flag must be set." LINE_PADDING_6TAB + "0x00: maximum edge sensitivity" LINE_PADDING_6TAB + "0xFF: no texture detection"}, + + {"ISP_FLAGS_SHD", "Flags (current status) of certain signals and Shadow regs for enable signals", + 0x000005a8, 0x00000000, 31, 31, "s_hsync", "State of ISP input port s_hsync, for test purposes"}, + {NULL, NULL, 0x000005a8, 0x00000000, 30, 30, "s_vsync", "State of ISP input port s_vsync, for test purposes"}, + {NULL, NULL, 0x000005a8, 0x00000000, 27, 16, "s_data", "State of ISP input port s_data, for test purposes"}, + {NULL, NULL, 0x000005a8, 0x00000000, 2, 2, "inform_field", "Current field information (0=odd, 1=even)"}, + {NULL, NULL, 0x000005a8, 0x00000000, 1, 1, "inform_en_shd", "Input formatter enable shadow register"}, + {NULL, NULL, 0x000005a8, 0x00000000, 0, 0, "isp_on_shd", "ISP enable shadow register" LINE_PADDING_6TAB + " Shows if ISP currently outputs data (1) or not (0)"}, + + {"ISP_IMSC", "Interrupt mask", + 0x000005bc, 0x00000000, 26, 26, "imsc_sensor0_dataloss", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 25, 25, "imsc_sensor1_dataloss", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 24, 24, "imsc_sensor2_dataloss", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 23, 23, "imsc_sensor3_dataloss", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 22, 22, "imsc_ae2_dataloss", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 21, 21, "imsc_awb2_dataloss", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 20, 20, "imsc_tdnr", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 19, 19, "imsc_vsm_done", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 18, 18, "imsc_exp_end", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 17, 17, "imsc_fl_cap", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 16, 16, "imsc_tdnr1", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 15, 15, "imsc_hist_end", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 14, 14, "imsc_afm_fin", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 13, 13, "imsc_afm_lum_of", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 12, 12, "imsc_afm_sum_of", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 11, 11, "imsc_sh_off", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 10, 10, "imsc_sh_on", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 9, 9, "imsc_fl_off", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 8, 8, "imsc_fl_on", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 7, 7, "imsc_h_start", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 6, 6, "imsc_v_start", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 5, 5, "imsc_frame_in", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 4, 4, "imsc_awb_done", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 3, 3, "imsc_size_err", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 2, 2, "imsc_dataloss", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 1, 1, "imsc_frame", "0: mask out; 1: enable interrupt"}, + {NULL, NULL, 0x000005bc, 0x00000000, 0, 0, "imsc_isp_off", "0: mask out; 1: enable interrupt"}, + + + {"ISP_RIS", "Raw interrupt status", + 0x000005c0, 0x00000000, 26, 26, "ris_sensor0_dataloss", "sensor0 data loss"}, + {NULL, NULL, 0x000005c0, 0x00000000, 25, 25, "ris_sensor1_dataloss", "sensor1 data loss"}, + {NULL, NULL, 0x000005c0, 0x00000000, 24, 24, "ris_sensor2_dataloss", "sensor2 data loss"}, + {NULL, NULL, 0x000005c0, 0x00000000, 23, 23, "ris_sensor3_dataloss", "sensor3 data loss"}, + {NULL, NULL, 0x000005c0, 0x00000000, 22, 22, "ris_ae2_dataloss", "aev2 data loss"}, + {NULL, NULL, 0x000005c0, 0x00000000, 21, 21, "ris_awb2_dataloss", "awb2 data loss"}, + {NULL, NULL, 0x000005c0, 0x00000000, 20, 20, "ris_tdnr", "TDNR reference frame FIFO empty"}, + {NULL, NULL, 0x000005c0, 0x00000000, 19, 19, "ris_vsm_done", "VSM module complete"}, + {NULL, NULL, 0x000005c0, 0x00000000, 18, 18, "ris_exp_end", "Exposure measurement complete"}, + {NULL, NULL, 0x000005c0, 0x00000000, 17, 17, "ris_fl_cap", "Signaling captured frame"}, + {NULL, NULL, 0x000005c0, 0x00000000, 16, 16, "ris_tdnr1", "write cover read"}, + {NULL, NULL, 0x000005c0, 0x00000000, 15, 15, "ris_hist_end", "Histogram measurement ready." LINE_PADDING_6TAB + "(Old or new histogram measurement)"}, + {NULL, NULL, 0x000005c0, 0x00000000, 14, 14, "ris_afm_fin", "AF measurement finished: this interrupt is setwhen the first" LINE_PADDING_6TAB + "complete frame is calculated after enabling the AF measurement"}, + {NULL, NULL, 0x000005c0, 0x00000000, 13, 13, "ris_afm_lum_of", "Auto focus luminance overflow"}, + {NULL, NULL, 0x000005c0, 0x00000000, 12, 12, "ris_afm_sum_of", "Auto focus sum overflow"}, + {NULL, NULL, 0x000005c0, 0x00000000, 11, 11, "ris_sh_off", "Mechanical shutter is switched off"}, + {NULL, NULL, 0x000005c0, 0x00000000, 10, 10, "ris_sh_on", "Mechanical shutter is switched on"}, + {NULL, NULL, 0x000005c0, 0x00000000, 9, 9, "ris_fl_off", "Flash light is switched off"}, + {NULL, NULL, 0x000005c0, 0x00000000, 8, 8, "ris_fl_on", "Flash light is switched on"}, + {NULL, NULL, 0x000005c0, 0x00000000, 7, 7, "ris_h_start", "Start edge of h_sync"}, + {NULL, NULL, 0x000005c0, 0x00000000, 6, 6, "ris_v_start", "Start edge of v_sync"}, + {NULL, NULL, 0x000005c0, 0x00000000, 5, 5, "ris_frame_in", "Sampled input frame is complete"}, + {NULL, NULL, 0x000005c0, 0x00000000, 4, 4, "ris_awb_done", "White balancing measurement cycle is complete; results can be read out"}, + {NULL, NULL, 0x000005c0, 0x00000000, 3, 3, "ris_size_err", "Picture size violation occurred; incorrect programming"}, + {NULL, NULL, 0x000005c0, 0x00000000, 2, 2, "ris_dataloss", "Loss of data occurred within a line, processing failure"}, + {NULL, NULL, 0x000005c0, 0x00000000, 1, 1, "ris_frame", "Frame was completely put out"}, + {NULL, NULL, 0x000005c0, 0x00000000, 0, 0, "ris_isp_off", "ISP output was disabled (vsynced) due to f_cnt reached or manual"}, + + {"ISP_MIS", "Masked interrupt status", 0x000005c4, 0x00000000, 26, 26, "mis_sensor0_dataloss", "sensor0 data loss"}, + {NULL, NULL, 0x000005c4, 0x00000000, 25, 25, "mis_sensor1_dataloss", "sensor1 data loss"}, + {NULL, NULL, 0x000005c4, 0x00000000, 24, 24, "mis_sensor2_dataloss", "sensor2 data loss"}, + {NULL, NULL, 0x000005c4, 0x00000000, 23, 23, "mis_sensor3_dataloss", "sensor3 data loss"}, + {NULL, NULL, 0x000005c4, 0x00000000, 22, 22, "mis_ae2_dataloss", "aev2 data loss"}, + {NULL, NULL, 0x000005c4, 0x00000000, 21, 21, "mis_awb2_dataloss", "awb2 data loss"}, + {NULL, NULL, 0x000005c4, 0x00000000, 20, 20, "mis_tdnr", "TDNR reference frame FIFO empty"}, + {NULL, NULL, 0x000005c4, 0x00000000, 19, 19, "mis_vsm_done", "VSM module complete"}, + {NULL, NULL, 0x000005c4, 0x00000000, 18, 18, "mis_exp_end", "Exposure measurement complete"}, + {NULL, NULL, 0x000005c4, 0x00000000, 17, 17, "mis_fl_cap", "Signaling captured frame"}, + {NULL, NULL, 0x000005c4, 0x00000000, 16, 16, "mis_tdnr1", "write cover read"}, + {NULL, NULL, 0x000005c4, 0x00000000, 15, 15, "mis_hist_end", "Histogram measurement ready." LINE_PADDING_6TAB + "(Old or new histogram measurement)"}, + {NULL, NULL, 0x000005c4, 0x00000000, 14, 14, "mis_afm_fin", "AF measurement finished: this interrupt is set when the first" LINE_PADDING_6TAB + "complete frame is calculated after enabling the AF measurement"}, + {NULL, NULL, 0x000005c4, 0x00000000, 13, 13, "mis_afm_lum_of", "Auto focus luminance overflow"}, + {NULL, NULL, 0x000005c4, 0x00000000, 12, 12, "mis_afm_sum_of", "Auto focus sum overflow"}, + {NULL, NULL, 0x000005c4, 0x00000000, 11, 11, "mis_sh_off", "Mechanical shutter is switched off"}, + {NULL, NULL, 0x000005c4, 0x00000000, 10, 10, "mis_sh_on", "Mechanical shutter is switched on"}, + {NULL, NULL, 0x000005c4, 0x00000000, 9, 9, "mis_fl_off", "Flash light is switched off"}, + {NULL, NULL, 0x000005c4, 0x00000000, 8, 8, "mis_fl_on", "Flash light is switched on"}, + {NULL, NULL, 0x000005c4, 0x00000000, 7, 7, "mis_h_start", "Start edge of h_sync"}, + {NULL, NULL, 0x000005c4, 0x00000000, 6, 6, "mis_v_start", "Start edge of v_sync"}, + {NULL, NULL, 0x000005c4, 0x00000000, 5, 5, "mis_frame_in", "Sampled input frame is complete"}, + {NULL, NULL, 0x000005c4, 0x00000000, 4, 4, "mis_awb_done", "White balancing measurement cycle is complete; results can be read out"}, + {NULL, NULL, 0x000005c4, 0x00000000, 3, 3, "mis_size_err", "Picture size violation occurred; incorrect programming"}, + {NULL, NULL, 0x000005c4, 0x00000000, 2, 2, "mis_dataloss", "Loss of data occurred within a line, processing failure"}, + {NULL, NULL, 0x000005c4, 0x00000000, 1, 1, "mis_frame", "Frame was completely put out"}, + {NULL, NULL, 0x000005c4, 0x00000000, 0, 0, "mis_isp_off", "ISP output was disabled (vsynced) due to f_cnt reached or manual"}, + + {"ISP_ICR", "Interrupt clear register", + 0x000005c8, 0x00000000, 26, 26, "icr_sensor0_dataloss", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 25, 25, "icr_sensor1_dataloss", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 24, 24, "icr_sensor2_dataloss", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 23, 23, "icr_sensor3_dataloss", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 22, 22, "icr_ae2_dataloss", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 21, 21, "icr_awb2_dataloss", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 20, 20, "icr_tdnr", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 19, 19, "icr_vsm_done", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 18, 18, "icr_exp_end", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 17, 17, "icr_fl_cap", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 16, 16, "icr_tdnr1", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 15, 15, "icr_hist_end", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 14, 14, "icr_afm_fin", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 13, 13, "icr_afm_lum_of", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 12, 12, "icr_afm_sum_of", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 11, 11, "icr_sh_off", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 10, 10, "icr_sh_on", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 9, 9, "icr_fl_off", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 8, 8, "icr_fl_on", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 7, 7, "icr_h_start", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 6, 6, "icr_v_start", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 5, 5, "icr_frame_in", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 4, 4, "icr_awb_done", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 3, 3, "icr_size_err", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 2, 2, "icr_dataloss", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 1, 1, "icr_frame", "Clear interrupt"}, + {NULL, NULL, 0x000005c8, 0x00000000, 0, 0, "icr_isp_off", "Clear interrupt"}, + + {"ISP_ISR", "Interrupt set register", + 0x000005cc, 0x00000000, 26, 26, "isr_sensor0_dataloss", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 25, 25, "isr_sensor1_dataloss", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 24, 24, "isr_sensor2_dataloss", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 23, 23, "isr_sensor3_dataloss", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 22, 22, "isr_ae2_dataloss", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 21, 21, "isr_awb2_dataloss", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 20, 20, "isr_tdnr", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 19, 19, "isr_vsm_done", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 18, 18, "isr_exp_end", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 17, 17, "isr_fl_cap", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 16, 16, "isr_tdnr1", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 15, 15, "isr_hist_end", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 14, 14, "isr_afm_fin", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 13, 13, "isr_afm_lum_of", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 12, 12, "isr_afm_sum_of", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 11, 11, "isr_sh_off", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 10, 10, "isr_sh_on", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 9, 9, "isr_fl_off", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 8, 8, "isr_fl_on", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 7, 7, "isr_h_start", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 6, 6, "isr_v_start", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 5, 5, "isr_frame_in", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 4, 4, "isr_awb_done", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 3, 3, "isr_size_err", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 2, 2, "isr_dataloss", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 1, 1, "isr_frame", "Set interrupt"}, + {NULL, NULL, 0x000005cc, 0x00000000, 0, 0, "isr_isp_off", "Set interrupt"}, + + {"ISP_ERR", "ISP error register", + 0x0000063c, 0x00000000, 2, 2, "outform_size_err", "Size error is generated in outmux submodule"}, + {NULL, NULL, 0x0000063c, 0x00000000, 1, 1, "is_size_err", "Size error is generated in image stabilization submodule"}, + {NULL, NULL, 0x0000063c, 0x00000000, 0, 0, "inform_size_err", "Size error is generated in inform submodule"}, + + {"ISP_ERR_CLR", "ISP error clear register", + 0x00000640, 0x00000000, 2, 2, "outform_size_err_clr", "Size error is cleared"}, + {NULL, NULL, 0x00000640, 0x00000000, 1, 1, "is_size_err_clr", "Size error is cleared"}, + {NULL, NULL, 0x00000640, 0x00000000, 0, 0, "inform_size_err_clr", "Size error is cleared"}, + +}; + + + +int light_isp_isp_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_isp_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_isp_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_isp_dpf.c b/tools/reg_analyzer/vsi_isp8000/m5_isp_dpf.c new file mode 100644 index 0000000..1fe8abe --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_isp_dpf.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" +#define REG_BASE 0x2800 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_DPF_MODE", "Mode Control for De-noising Pre-Filter Block", + 0x00002800, 0x00000000, 9, 9, "use_nf_gain", "0: DPF_NF_GAINs will not be used. (Default)" LINE_PADDING_6TAB + "1: DPF_NF_GAINs will be used."}, + {NULL, NULL, 0x00002800, 0x00000000, 8, 8, "lsc_gain_en", "0: LSC gain will not be processed. Use LSC gain factor of 1. (Default)" LINE_PADDING_6TAB + "1: LSC gain will be processed"}, + {NULL, NULL, 0x00002800, 0x00000000, 7, 7, "awb_gain_en", "Only relevant when use_nf_gain==0 and ISP_CTRL::ISP_AWB_ENABLE==1" LINE_PADDING_6TAB + "0: ISP_AWB gains will not be processed. Use AWB gain factor of 1. (Default)" LINE_PADDING_6TAB + "1: ISP_AWB gains will be processed"}, + {NULL, NULL, 0x00002800, 0x00000000, 6, 6, "nll_equ_segm", "0: equidistant segmentation for NLL (Default)" LINE_PADDING_6TAB + "1: optimized logarithmic like segmentation for Noise Level Lookup (NLL)"}, + {NULL, NULL, 0x00002800, 0x00000000, 5, 5, "rb_filter_size9x9", "0: Wide Red and Blue filter kernel size of 13x9 (7x5 active) pixels (Default)" LINE_PADDING_6TAB + "1: Red and Blue filter kernel size of 9x9 (5x5 active) pixels"}, + {NULL, NULL, 0x00002800, 0x00000000, 4, 4, "r_filter_off", "0: filter R pixels (Default)" LINE_PADDING_6TAB + "1: disable filter processing for red pixels (R)"}, + {NULL, NULL, 0x00002800, 0x00000000, 3, 3, "gr_filter_off", "0: filter GB pixels (Default)" LINE_PADDING_6TAB + "1: disable filter processing for green pixels in green/blue lines (GB)"}, + {NULL, NULL, 0x00002800, 0x00000000, 2, 2, "gb_filter_off", "0: filter GB pixels (Default)" LINE_PADDING_6TAB + "1: disable filter processing for green pixels in green/blue lines (GB)"}, + {NULL, NULL, 0x00002800, 0x00000000, 1, 1, "b_filter_off", "0: filter B pixels (Default); 1: disable filter processing for blue pixels (B)"}, + {NULL, NULL, 0x00002800, 0x00000000, 0, 0, "cfg_dpf_enable", "De-noising pre-filter; 0: Bypass DPF (Default); 1: Enable DPF"}, +}; + + +int light_isp_dpf_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_dpf_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_dpf_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_isp_is.c b/tools/reg_analyzer/vsi_isp8000/m5_isp_is.c new file mode 100644 index 0000000..6a3a5ef --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_isp_is.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define MRV_IS_BASE 0x2300 +#define REG_BASE MRV_IS_BASE + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_IS_CTRL", "Image Stabilization Control Register", + 0x00002300, 0x00000000, 0, 0, "is_en", "Image stabilization state. 0: off ; 1: on"}, + + {"ISP_IS_RECENTER", "Image Stabilization Re-center Register", + 0x00002304, 0x00000000, 0, 0, "is_recenter", "0: re-center feature switched off; 1..7: re-centering by (cur_h/v_offs-H/V_OFFS)/2^RECENTER"}, + + {"ISP_IS_H_OFFS", "Horizontal Offset of Output Window", + 0x00002308, 0x00000000, 13, 0, "is_h_offs", "Horizontal picture offset in pixels"}, + + {"ISP_IS_V_OFFS", "Vertical Offset of Output Window", + 0x0000230C, 0x00000000, 13, 0, "is_v_offs", "Vertical picture offset in lines"}, + + {"ISP_IS_H_SIZE", "Horizontal Output Picture Size", + 0x00002310, 0x00001000, 13, 0, "is_h_size", "Horizontal picture size in pixels if ISP_MODE is set to: ..."}, + + {"ISP_IS_V_SIZE", "Vertical Output Picture Size", + 0x00002314, 0x00001000, 13, 0, "is_v_size", "Vertical picture size in lines"}, +}; + + +int light_isp_is_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_is_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_is_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_isp_shutter.c b/tools/reg_analyzer/vsi_isp8000/m5_isp_shutter.c new file mode 100644 index 0000000..7478bd5 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_isp_shutter.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x00000680 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"ISP_SH_CTRL", "Mechanical shutter control", + 0x00000680, 0x00000000, 4, 4, "sh_open_pol", "Shutter_open polarity. 0: high active; 1: low active"}, + {NULL, NULL, 0x00000680, 0x00000000, 3, 3, "sh_trig_pol", "Mechanical shutter trigger edge." LINE_PADDING_6TAB + "0: use negative edge of trigger signal" LINE_PADDING_6TAB + "1: use positive edge of trigger signal"}, + {NULL, NULL, 0x00000680, 0x00000000, 2, 2, "sh_trig_src", "Mechanical shutter trigger source." LINE_PADDING_6TAB + "0: use “vds_vsync” for trigger event" LINE_PADDING_6TAB + "1: use “shutter_trig” for trigger event"}, + {NULL, NULL, 0x00000680, 0x00000000, 1, 1, "sh_rep_en", "Mechanical shutter repetition enable." LINE_PADDING_6TAB + "0: shutter is opened only once" LINE_PADDING_6TAB + "1: shutter is opened with the repetition rate of the trigger signal"}, + {NULL, NULL, 0x00000680, 0x00000000, 0, 0, "sh_en", "Mechanical shutter. 0: disable; 1: enable"}, + +}; + + +int light_isp_shutter_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_shutter_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_shutter_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_main_control.c b/tools/reg_analyzer/vsi_isp8000/m5_main_control.c new file mode 100644 index 0000000..c84e923 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_main_control.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" +#define REG_BASE 0x0000 + +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + + {"VI_CCL", "Clock Control Register", + 0x00000000, 0x00000000, 2, 2, "vi_ccl_dis", "Clock Control Logic disable." LINE_PADDING_6TAB + " 0: processing/cfg-clocks for all sub modules enabled" LINE_PADDING_6TAB + " 1: processing/cfg-clocks for all sub modules disabled " LINE_PADDING_6TAB + " without access to ID and VI_CCL register"}, + {NULL, NULL, 0x00000000, 0x00000000, 1, 1, "vi_ccl_dis_status", "Status of vi_ccl[2] bit (copy of vi_ccl[2])"}, + + {"VI_ICCL", "Internal Clock Control Register", + 0x00000010, 0x000FFF7B, 19, 19, "stitch_3_clk_en", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 18, 18, "stitch_2_clk_en", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 17, 17, "reserved0", "reserved0"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 16, 16, "mcm_rd_clk_en", "MCM read clock enable; 0: power safe ; 1: processing mode"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 15, 15, "mcm_wr_clk_en", "0: power safe ; 1: processing mode"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 14, 14, "stitch_1_clk_en", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 13, 13, "stitch_0_clk_en", "stitch0 clock enable; 0: power safe ; 1: processing mode"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 12, 12, "vi_mipi2_clk_enable", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 11, 11, "vi_mipi_clk_enable", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 10, 10, "vi_smia_clk_enable", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 9, 9, "vi_simp_clk_enable", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 8, 8, "vi_ie_clk_enable", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 6, 6, "vi_mi_clk_enable", "Memory interface clock enable; 0: power safe ; 1: processing mode"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 5, 5, "vi_jpeg_clk_enable", "unused"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 4, 4, "vi_srsz_clk_enable", "Self-picture resize clock enable; 0: power safe ; 1: processing mode"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 3, 3, "vi_mrsz_clk_enable", "Main resize clock enable; 0: power safe; 1: processing mode"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 1, 1, "vi_cp_clk_enable", "CPROC processing clock enable; 0: power safe ; 1: processing mode"}, + {NULL, NULL, 0x00000010, 0x000FFF7B, 0, 0, "vi_isp_clk_enable", "ISP processing clock enable; 0: power safe ; 1: processing mode"}, + + {"VI_IRCL", "Internal Reset Control Register", + 0x00000014, 0x00000000, 20, 20, "soft_rst_mi_wrapper", "mi wrapper software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 19, 19, "soft_rst_stitch_3", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 18, 18, "soft_rst_stitch_2", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 17, 17, "soft_rst_fe", "0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 16, 16, "soft_rst_mcm_rd", "0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 15, 15, "soft_rst_mcm_wr", "MCM write software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 14, 14, "soft_rst_stitch_1", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 13, 13, "soft_rst_stitch_0", "stitch0 software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 12, 12, "vi_mipi2_soft_rst", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 11, 11, "vi_mipi_soft_rst", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 10, 10, "vi_smia_soft_rst", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 9, 9, "vi_simp_soft_rst", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 8, 8, "vi_ie_soft_rst", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 7, 7, "vi_marvin_rst", "Hardware reset of entire image signal processor; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 6, 6, "vi_mi_soft_rst", "Memory interface software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 5, 5, "vi_jpeg_soft_rst", "unused"}, + {NULL, NULL, 0x00000014, 0x00000000, 4, 4, "vi_srsz_soft_rst", "Self-picture resize software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 3, 3, "vi_mrsz_soft_rst", "Main-picture resize software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 2, 2, "vi_ycs_soft_rst", "Y/C splitter software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 1, 1, "vi_cp_soft_rst", "Color processing software reset; 0: Processing mode; 1: reset state"}, + {NULL, NULL, 0x00000014, 0x00000000, 0, 0, "vi_isp_soft_rst", "ISP software reset; 0: Processing mode; 1: reset state"}, + + {"VI_DPCL", "Data Path Control Register", + 0x00000018, 0x00000000, 27, 26, "if_select3", "unused"}, + {NULL, NULL, 0x00000018, 0x00000000, 25, 24, "if_select2", "unused"}, + {NULL, NULL, 0x00000018, 0x00000000, 23, 22, "next_sensor_id", "unused"}, + {NULL, NULL, 0x00000018, 0x00000000, 21, 20, "sensor_id", "Present frame id"}, + {NULL, NULL, 0x00000018, 0x00000000, 19, 19, "reserved2", "reserved2"}, + {NULL, NULL, 0x00000018, 0x00000000, 18, 18, "strm_mux", "1:raw out 0:yuv out"}, + {NULL, NULL, 0x00000018, 0x00000000, 17, 16, "if_select1", "unused"}, + {NULL, NULL, 0x00000018, 0x00000000, 15, 15, "reserved1", "unused"}, + {NULL, NULL, 0x00000018, 0x00000000, 14, 12, "vi_chan_mode", "Enable Main Path, Self Path 1, Self Path 2." LINE_PADDING_6TAB + "Note: More than one bit may be set to enable more than one path." LINE_PADDING_6TAB + "Bit 12: Enable Main Path; Bit 13: Enable Self Path 1; Bit 14: Enable Self Path 2"}, + {NULL, NULL, 0x00000018, 0x00000000, 11, 11, "vi_dma_spmux", "xml doc unused, but in code:" LINE_PADDING_6TAB + "0: data from camera interface to self resize" LINE_PADDING_6TAB + "1: data from DMA read port to self resize"}, + {NULL, NULL, 0x00000018, 0x00000000, 10, 10, "vi_dma_iemux", "xml doc unused, but in code:" LINE_PADDING_6TAB + "0: data from camera interface to image effects" LINE_PADDING_6TAB + "1: data from DMA read port to image effects"}, + {NULL, NULL, 0x00000018, 0x00000000, 9, 8, "if_select0", "Input interface for sensor0" LINE_PADDING_6TAB + "0: parallel interface; 1: SMIA-interface (Reserved); 2: Unused; 3: HDR Stitch output"}, + {NULL, NULL, 0x00000018, 0x00000000, 6, 4, "vi_dma_switch", "xml doc unused, but in code:" LINE_PADDING_6TAB + "0: path to SPMUX" LINE_PADDING_6TAB + "1: path to Superimpose" LINE_PADDING_6TAB + "2: path to Image Effects" LINE_PADDING_6TAB + "3: path to JPEG" LINE_PADDING_6TAB + "4: path to ISP"}, + {NULL, NULL, 0x00000018, 0x00000000, 3, 2, "reserved0", "unused"}, + {NULL, NULL, 0x00000018, 0x00000000, 1, 0, "vi_mp_mux", "xml doc unused, but in code:" LINE_PADDING_6TAB + "00: reserved (future: data from DMA read port to JPEG encoder)" LINE_PADDING_6TAB + "01: data from main resize to MI, uncompressed" LINE_PADDING_6TAB + " (now also used for RAW data bypass)" LINE_PADDING_6TAB + "10: data from main resize to JPEG encoder"}, +}; + + +int light_isp_main_control_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_main_control_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_main_control_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_main_resize.c b/tools/reg_analyzer/vsi_isp8000/m5_main_resize.c new file mode 100644 index 0000000..09228d0 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_main_resize.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x800 +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"MRSZ_CTRL", "Global control register", + 0x00000c00, 0x00000000, 10, 10, "auto_upd", "0: no update; 1: update shadow registers at frame end"}, + {NULL, NULL, 0x00000c00, 0x00000000, 9, 9, "cfg_upd", "Write 0: nothing happens; Write 1: update shadow registers; Read: Always 0"}, + {NULL, NULL, 0x00000c00, 0x00000000, 8, 8, "crop_enable", "0: Bypass crop ; 1: Enable picture crop"}, + {NULL, NULL, 0x00000c00, 0x00000000, 7, 7, "scale_vc_up", "0: Vertical chrominance downscaling selected ; 1: Vertical chrominance upscaling selected"}, + {NULL, NULL, 0x00000c00, 0x00000000, 6, 6, "scale_vy_up", "0: Vertical luminance downscaling selected ; 1: Vertical luminance upscaling selected"}, + {NULL, NULL, 0x00000c00, 0x00000000, 5, 5, "scale_hc_up", "0: Horizontal chrominance downscaling selected ; 1: Horizontal chrominance upscaling selected"}, + {NULL, NULL, 0x00000c00, 0x00000000, 4, 4, "scale_hy_up", "0: Horizontal luminance downscaling selected ; 1: Horizontal luminance upscaling selected"}, + {NULL, NULL, 0x00000c00, 0x00000000, 3, 3, "scale_vc_enable", "Vertical chrominance scaling unit; 0: Bypass; 1: enable"}, + {NULL, NULL, 0x00000c00, 0x00000000, 2, 2, "scale_vy_enable", "Vertical luminance scaling unit; 0: Bypass; 1: enable"}, + {NULL, NULL, 0x00000c00, 0x00000000, 1, 1, "scale_hc_enable", "Horizontal chrominance scaling unit; 0: Bypass; 1: enable"}, + {NULL, NULL, 0x00000c00, 0x00000000, 0, 0, "scale_hy_enable", "Horizontal luminance scaling unit ; 0: Bypass; 1: enable"}, + + + {"MRSZ_SCALE_HY", "Horizontal luminance scale factor register", + 0x00000c04, 0x00000000, 15, 0, "scale_hy", "This register is set to the horizontal luminance downscale factor" LINE_PADDING_6TAB + "or to the reciprocal of the horizontal luminance upscale factor."}, + + {"MRSZ_SCALE_HCB", "Horizontal Cb scale factor register", + 0x00000c08, 0x00000000, 15, 0, "scale_hcb", "This register is set to the horizontal Cb downscale factor " LINE_PADDING_6TAB + "or to the reciprocal of the horizontal Cb upscale factor."}, + + {"MRSZ_SCALE_HCR", "Horizontal Cr scale factor register", + 0x00000c0c, 0x00000000, 15, 0, "scale_hcr", "This register is set to the horizontal Cr downscale factor " LINE_PADDING_6TAB + "or to the reciprocal of the horizontal Cr upscale factor."}, + + {"MRSZ_SCALE_VY", "Vertical luminance scale factor register", + 0x00000c10, 0x00000000, 15, 0, "scale_vy", "This register is set to the vertical luminance downscale factor " LINE_PADDING_6TAB + "or to the reciprocal of the vertical luminance upscale factor."}, + + {"MRSZ_SCALE_VC", "Vertical chrominance scale factor register", + 0x00000c14, 0x00000000, 15, 0, "scale_vc", "This register is set to the vertical chrominance downscale factor" LINE_PADDING_6TAB + "or to the reciprocal of the vertical chrominance upscale factor."}, + + {"MRSZ_FORMAT_CONV_CTRL", "Format conversion control", + 0x00000c6c, 0x00000000, 10, 10, "rsz_pack_format", "0: YUV422/YUV420 planar; 1: YUV422/YUV420 semi_planar"}, + {NULL, NULL, 0x00000c6c, 0x00000000, 9, 9, "expand_8to10_method", "0: add two MSBs in two LSBs; 1: add zeros in two LSBs"}, + {NULL, NULL, 0x00000c6c, 0x00000000, 8, 8, "expand_8to10_enable", "0: disable 10 bit (add two zeros in two LSBs); 1: enable 10 bit"}, + {NULL, NULL, 0x00000c6c, 0x00000000, 7, 7, "cfg_422nocosited", "0: YCbCr422 data are co-sited (Y0 Cb0 and Cr0 are sampled at the same position)" LINE_PADDING_6TAB + "1: YCbCr422 data are non_co-sited (Cb and Cr samples are centered between Y samples)" LINE_PADDING_6TAB + " so modified interpolation is activated" LINE_PADDING_6TAB + "Note: the programmed value becomes effective immediately after this register is set." LINE_PADDING_6TAB + "Therefore, only write to this register if no picture data is sent to the Self Path."}, + {NULL, NULL, 0x00000c6c, 0x00000000, 6, 6, "cfg_cbcr_full", "0: CbCr has a compressed range of [16..240]" LINE_PADDING_6TAB + "1: CbCr has full range [0..255]" LINE_PADDING_6TAB + "Note: the programmed value becomes effective immediately after this register is set. " LINE_PADDING_6TAB + "Therefore, only write to this register if no picture data is sent to the Self Path."}, + {NULL, NULL, 0x00000c6c, 0x00000000, 5, 5, "cfg_y_full", "0: Y has a compressed range of [16..235]" LINE_PADDING_6TAB + "1: Y has full range [0..255]" LINE_PADDING_6TAB + "Note: the programmed value becomes effective immediately after this register is set." LINE_PADDING_6TAB + "Therefore, only write to this register if no picture data is sent to the Self Path."}, + {NULL, NULL, 0x00000c6c, 0x00000000, 4, 2, "rsz_output_format", "Main Resize output format"LINE_PADDING_6TAB + "000: YCbCr 4:0:0" LINE_PADDING_6TAB + "001: YCbCr 4:2:0" LINE_PADDING_6TAB + "010: YCbCr 4:2:2" LINE_PADDING_6TAB + "011: YCbCr 4:4:4" LINE_PADDING_6TAB + "100: RGB565" LINE_PADDING_6TAB + "101: RGB666" LINE_PADDING_6TAB + "110: RGB888" LINE_PADDING_6TAB + "Reserved"}, + {NULL, NULL, 0x00000c6c, 0x00000000, 1, 0, "rsz_input_format", "Main resize input format" LINE_PADDING_6TAB + "00: YCbCr 4:0:0" LINE_PADDING_6TAB + "01: YCbCr 4:2:0" LINE_PADDING_6TAB + "10: YCbCr 4:2:2" LINE_PADDING_6TAB + "11: YCbCr 4:4:4"}, +}; + +int light_isp_main_resize_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_main_resize_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_main_resize_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} + diff --git a/tools/reg_analyzer/vsi_isp8000/m5_mi.c b/tools/reg_analyzer/vsi_isp8000/m5_mi.c new file mode 100644 index 0000000..4db9b70 --- /dev/null +++ b/tools/reg_analyzer/vsi_isp8000/m5_mi.c @@ -0,0 +1,571 @@ +/* + * Copyright (C) 2021 Alibaba Group Holding Limited + * Author: LuChongzhi + * + * 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 +#include +#include + +#include "ra_common.h" + +#define REG_BASE 0x1300 +static const reg_field_s reg_desc[] = { + /* structure field order + reg_name, offset,reset_value,msb,lsb, field_name, field_desc */ + + {"MI_CTRL", "Global control register", + 0x00001300, 0x00000000, 24, 24, "sp2_raw2_continuous", "Enables continuous mode. If set to 1, the same frame is read back over and over."}, + {NULL, NULL, 0x00001300, 0x00000000, 23, 23, "sp2_raw2_start", "Enables DMA access."}, + {NULL, NULL, 0x00001300, 0x00000000, 22, 22, "pp_dma_continuous", "Enables continuous mode. If set to 1, the same frame is read back over and over."}, + {NULL, NULL, 0x00001300, 0x00000000, 21, 21, "pp_dma_start", "Enables DMA access."}, + {NULL, NULL, 0x00001300, 0x00000000, 20, 20, "sp2_raw2_write_path_enable", "Enables sp2_raw2_write path."}, + {NULL, NULL, 0x00001300, 0x00000000, 19, 19, "pp_write_path_enable", "Enables pp write path."}, + {NULL, NULL, 0x00001300, 0x00000000, 18, 18, "mcm_g2_raw1_path_enable", "Enables mcm_g2_raw1 path."}, + {NULL, NULL, 0x00001300, 0x00000000, 17, 17, "mcm_g2_raw0_path_enable", "Enables mcm_g2_raw0 path."}, + {NULL, NULL, 0x00001300, 0x00000000, 16, 16, "mcm_raw_rdma_start_con", "Enables continuous mode. If set to 1, ... [Refer to Doc]."}, + {NULL, NULL, 0x00001300, 0x00000000, 15, 15, "mcm_raw_rdma_start", "Enables DMA access."}, + {NULL, NULL, 0x00001300, 0x00000000, 14, 14, "mcm_raw_rdma_path_enable", "Enables mcm_raw_rdma path."}, + {NULL, NULL, 0x00001300, 0x00000000, 13, 13, "sp2_raw_rdma_start_con", "Enables continuous mode. If set to 1, the same frame is read back over and over.."}, + {NULL, NULL, 0x00001300, 0x00000000, 12, 12, "sp2_raw_rdma_start", "Enables DMA access."}, + {NULL, NULL, 0x00001300, 0x00000000, 11, 11, "sp2_raw_rdma_path_enable", "Enables sp2_raw_rdma path."}, + {NULL, NULL, 0x00001300, 0x00000000, 10, 10, "sp2_ycbcr_rdma_start_con", "Enables continuous mode. If set to 1, the same frame is read back over and over.."}, + {NULL, NULL, 0x00001300, 0x00000000, 9, 9, "sp2_ycbcr_rdma_start", "Enables DMA access."}, + {NULL, NULL, 0x00001300, 0x00000000, 8, 8, "sp2_ycbcr_rdma_path_enable", "Enables sp2_ycbcr_rdma path."}, + {NULL, NULL, 0x00001300, 0x00000000, 7, 7, "mcm_raw1_path_enable", "Enables mcm_raw1 path."}, + {NULL, NULL, 0x00001300, 0x00000000, 6, 6, "mcm_raw0_path_enable", "Enables mcm_raw0 path."}, + {NULL, NULL, 0x00001300, 0x00000000, 5, 5, "sp2_raw_path_enable", "Enables sp2_raw path."}, + {NULL, NULL, 0x00001300, 0x00000000, 4, 4, "sp2_ycbcr_path_enable", "Enables sp2_ycbcr path."}, + {NULL, NULL, 0x00001300, 0x00000000, 3, 3, "sp1_ycbcr_path_enable", "Enables sp1_ycbcr path."}, + {NULL, NULL, 0x00001300, 0x00000000, 2, 2, "mp_jdp_path_enable", "Enables mp_jdp path."}, + {NULL, NULL, 0x00001300, 0x00000000, 1, 1, "mp_raw_path_enable", "Enables mp_raw path."}, + {NULL, NULL, 0x00001300, 0x00000000, 0, 0, "mp_ycbcr_path_enable", "Enables mp_ycbcr path."}, + + {"MI_CTRL_SHD", "Global control internal shadow register", + 0x00001304, 0x00000000, 20, 20, "sp2_raw2_write_path_enable", "Enables sp2_raw2_write path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 19, 19, "pp_write_path_enable", "Enables pp write path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 18, 18, "mcm_g2_raw1_path_enable", "Enables mcm_raw1 path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 17, 17, "mcm_g2_raw0_path_enable", "Enables mcm_raw0 path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 16, 16, "mcm_raw_rdma_start_con", "Unused"}, + {NULL, NULL, 0x00001304, 0x00000000, 15, 15, "mcm_raw_rdma_start", "Unused"}, + {NULL, NULL, 0x00001304, 0x00000000, 14, 14, "mcm_raw_rdma_path_enable", "Unused"}, + {NULL, NULL, 0x00001304, 0x00000000, 13, 13, "sp2_raw_rdma_start_con", "Unused"}, + {NULL, NULL, 0x00001304, 0x00000000, 12, 12, "sp2_raw_rdma_start", "Unused"}, + {NULL, NULL, 0x00001304, 0x00000000, 11, 11, "sp2_raw_rdma_path_enable", "Unused"}, + {NULL, NULL, 0x00001304, 0x00000000, 10, 10, "sp2_ycbcr_rdma_start_con", "Unused"}, + {NULL, NULL, 0x00001304, 0x00000000, 9, 9, "mcm_raw1_path_enable", "Enables mcm_raw1 path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 8, 8, "mcm_raw0_path_enable", "Enables mcm_raw0 path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 5, 5, "sp2_raw_path_enable", "Enables sp2_raw path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 4, 4, "sp2_ycbcr_path_enable", "Enables sp2_ycbcr path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 3, 3, "sp1_ycbcr_path_enable", "Enables sp1_ycbcr path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 2, 2, "mp_jdp_path_enable", "Enables mp_jdp path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 1, 1, "mp_raw_path_enable", "Enables mp_raw path. 0: Disabled; 1: enabled"}, + {NULL, NULL, 0x00001304, 0x00000000, 0, 0, "mp_ycbcr_path_enable", "Enables mp_ycbcr path. 0: Disabled; 1: enabled"}, + + + + {"MI_QOS", "AXI Bus QOS value configuration", + 0x00001308, 0x00000000, 31, 28, "mcm_qos_rd", "QoS value of AXI bus for MCM read"}, + {NULL, NULL, 0x00001308, 0x00000000, 27, 24, "mcm_qos_wr", "QoS value of AXI bus for MCM write"}, + {NULL, NULL, 0x00001308, 0x00000000, 23, 20, "sp2_qos_rd", "QoS value of AXI bus bus for sp2 read"}, + {NULL, NULL, 0x00001308, 0x00000000, 19, 16, "sp2_qos_wr", "QoS value of AXI bus bus for sp2 write"}, + {NULL, NULL, 0x00001308, 0x00000000, 11, 8, "sp1_qos_wr", "QoS value of AXI bus bus for sp1 write"}, + {NULL, NULL, 0x00001308, 0x00000000, 3, 0, "mp_qos_wr", "QoS value of AXI bus bus for mp write"}, + + + {"MI_QOS2", "AXI Bus QOS value configuration", + 0x0000130C, 0x00000000, 7, 4, "rt_qos_rd", "QoS value of AXI bus for RT read"}, + {NULL, NULL, 0x0000130C, 0x00000000, 3, 0, "rt_qos_wr", "QoS value of AXI bus for RT write"}, + + + {"MI_MP_CTRL", "MP control register", + 0x00001310, 0x00000000, 5, 5, "mp_init_offset_en", "Enables updating of the offset counters shadow registers for" LINE_PADDING_6TAB + "main path to the programmed register init values." LINE_PADDING_6TAB + "MI_MP_Y/CB/CR_OFFS_CNT_INIT-> MI_MP_Y/CB/CR_OFFS_CNT_SHD" LINE_PADDING_6TAB + "The update will be executed either when a forced software " LINE_PADDING_6TAB + "update occurs (in register MI_MP_CTRL bit cfg_upd = 1) or " LINE_PADDING_6TAB + "when an automatic configuration update signal arrives at the MI input port. " LINE_PADDING_6TAB + "The latter is split into main and self picture, so only " LINE_PADDING_6TAB + "the corresponding main/self shadow registers are affected."}, + {NULL, NULL, 0x00001310, 0x00000000, 4, 4, "mp_init_base_en", "Enables updating of the base address and buffer size shadow " LINE_PADDING_6TAB + "registers for main picture to the programmed register init values." LINE_PADDING_6TAB + "MI_MP_Y/CB/CR_BASE_AD_INIT-> MI_MP_Y/CB/CR_OFFS_CNT_SHD" LINE_PADDING_6TAB + "MI_MP_Y/CB/CR_SIZE_INIT-> MI_MP_Y/CB/CR_SIZE_SHD" LINE_PADDING_6TAB + "The update will be executed either when a forced software " LINE_PADDING_6TAB + "update occurs (in register MI_MP_CTRL bit cfg_upd = 1) or " LINE_PADDING_6TAB + "when an automatic config update signal arrives at the MI input port. " LINE_PADDING_6TAB + "The latter is split into main and self picture. So only the " LINE_PADDING_6TAB + "corresponding main/self shadow registers are affected. " LINE_PADDING_6TAB + "After a picture skip has been performed init_offset_en " LINE_PADDING_6TAB + "selects between skip restart and skip init mode " LINE_PADDING_6TAB + "(see bit skip in register MI_MP_CTRL)."}, + {NULL, NULL, 0x00001310, 0x00000000, 3, 3, "mp_mi_cfg_upd", "Forced configuration update. Leads to an immediate update of the shadow " LINE_PADDING_6TAB + "registers. Depending on the two init enable bits in the MI_MP_CTRL register" LINE_PADDING_6TAB + "(init_offset_en and init_base_en) the offset counter, base address and" LINE_PADDING_6TAB + "buffer size shadow registers are also updated."}, + {NULL, NULL, 0x00001310, 0x00000000, 2, 2, "mp_mi_skip", "Skip of current or next starting main picture:" LINE_PADDING_6TAB + "Aborts writing of main picture image data of the current frame to RAM" LINE_PADDING_6TAB + " (after the current burst transmission has been completed). " LINE_PADDING_6TAB + " Further main picture data up to the end of the current frame are discarded." LINE_PADDING_6TAB + "No further macroblock line interrupt (mblk_line), no wrap around interrupt " LINE_PADDING_6TAB + " for main picture (wrap_mp_y/cb/cr) and no fill level interrupt (fill_mp_y) are generated." LINE_PADDING_6TAB + " Skip does not affect the generation of the main path frame end interrupt (mp_frame_end)." LINE_PADDING_6TAB + "Skip does not affect the processing of self picture and its corresponding interrupts " LINE_PADDING_6TAB + " namely the self path frame end interrupt (sp_frame_end)." LINE_PADDING_6TAB + "The byte counter (register MI_BYTE_CNT) is not affected. " LINE_PADDING_6TAB + " It produces the correct number of JPEG or RAW data bytes " LINE_PADDING_6TAB + " at the end of the current (skipped) frame." LINE_PADDING_6TAB + "After a skip has been performed, the offset counter for the main picture " LINE_PADDING_6TAB + " at the start of the following frame are set depending on the bit " LINE_PADDING_6TAB + "init_offset_en in register MI_MP_CTRL: " LINE_PADDING_6TAB + "- Skip restart mode (init_offset_en = 0)" LINE_PADDING_6TAB + " The offset counters of the main picture are restarted at the old start values of " LINE_PADDING_6TAB + " the previous skipped frame." LINE_PADDING_6TAB + "- Skip init mode (init_offset_en = 1)" LINE_PADDING_6TAB + " The offset counters of the main picture are initialized with the register " LINE_PADDING_6TAB + " contents of the offset counter init registers without any additional forced" LINE_PADDING_6TAB + " software update or automatic config update."}, + {NULL, NULL, 0x00001310, 0x00000000, 1, 1, "mp_auto_update", "Automatic update of configuration registers for main path at frame end."}, + {NULL, NULL, 0x00001310, 0x00000000, 0, 0, "mp_pingpong_enable", "Pingpong mode of configuration registers for main path at frame end."}, + + + {"MI_MP_FMT", "MI main path format", + 0x00001314, 0x00000000, 17, 17, "mp_wr_jdp_dp_bit", "0: 32bit; 1: 64bit;"}, + {NULL, NULL, 0x00001314, 0x00000000, 16, 16, "mp_wr_yuv_word_aligned_msb_en","0: 10bit yuv in LSB of 16bit; 1: 10bit yuv in MSB of 16bit;"}, + {NULL, NULL, 0x00001314, 0x00000000, 15, 15, "mp_wr_yuv_word_aligned", "0: disable; 1:enable"}, + {NULL, NULL, 0x00001314, 0x00000000, 14, 13, "mp_wr_yuv_nvy", "00: Put Y first => YC1C2; 01: Put Y second => C1YC2; 10: Put Y Third => C1C2Y"}, + {NULL, NULL, 0x00001314, 0x00000000, 12, 12, "mp_wr_yuv_nv21", "0: Put U before V; 1: Put V before U"}, + {NULL, NULL, 0x00001314, 0x00000000, 11, 10, "mp_wr_raw_aligned", "00: unaligned; 01: aligned mode0; 10: aligned mode1; 11: Reserved"}, + {NULL, NULL, 0x00001314, 0x00000000, 9, 9, "mp_wr_yuv_aligned", "0: unaligned; 1:aligned"}, + {NULL, NULL, 0x00001314, 0x00000000, 8, 6, "mp_wr_raw_bit", "000: RAW8; 001: RAW10; 010: RAW12; 011: RAW14; 100: RAW16; 101: RAW20, or Reserved."}, + {NULL, NULL, 0x00001314, 0x00000000, 5, 4, "mp_wr_yuv_str", "00: YUV/RGB SemiPlanar; 01: YUV Interleave, RGB Raster; 10: YUV/RGB Planar; 11: Y Only"}, + {NULL, NULL, 0x00001314, 0x00000000, 3, 2, "mp_wr_yuv_fmt", "00: YUV420; 01: YUV422; 10: YUV444; 11: Reserved"}, + {NULL, NULL, 0x00001314, 0x00000000, 1, 1, "mp_wr_yuv_bit", "0: 8 bit YUV/RGB; 1: 10 bit YUV/RGB"}, + {NULL, NULL, 0x00001314, 0x00000000, 0, 0, "mp_wr_jdp_fmt", "Output format. 0: DPCC; 1: JPEG"}, + + + {"MI_MP_BUS_CFG", "MP AXI Bus configuration", + 0x00001318, 0x00000000, 27, 24, "mp_wr_swap_jdp", "Same as mp_wr_swap_y"}, + {NULL, NULL, 0x00001318, 0x00000000, 23, 20, "mp_wr_swap_raw", "Same as mp_wr_swap_y"}, + {NULL, NULL, 0x00001318, 0x00000000, 19, 16, "mp_wr_swap_v", "Same as mp_wr_swap_y"}, + {NULL, NULL, 0x00001318, 0x00000000, 15, 12, "mp_wr_swap_u", "Same as mp_wr_swap_y"}, + {NULL, NULL, 0x00001318, 0x00000000, 11, 8, "mp_wr_swap_y", "Swap bits control for 16 byte data width on AXI bus;" LINE_PADDING_6TAB + "YUV interleave or RGB raster mode share the same bits." LINE_PADDING_6TAB + " Bit 0: to swap bytes" LINE_PADDING_6TAB + " Bit 1: to swap words" LINE_PADDING_6TAB + " Bit 2 to swap double words" LINE_PADDING_6TAB + " Bit 3 to swap four words"}, + {NULL, NULL, 0x00001318, 0x00000000, 7, 6, "mp_rd_issue_cap", "Unused"}, + {NULL, NULL, 0x00001318, 0x00000000, 5, 4, "mp_wr_issue_cap", "Maximum outstanding issue capability. 00:4; 01:8; 10:16; 11:32"}, + {NULL, NULL, 0x00001318, 0x00000000, 3, 2, "mp_rd_burst_len", "Unused"}, + {NULL, NULL, 0x00001318, 0x00000000, 1, 0, "mp_wr_burst_len", "Maximum burst length. 00:4; 01:8; 10:16; 11:32"}, + + + {"MI_MP_BUS_ID", "MP AXI Bus ID configuration", + 0x0000131c, 0x00000000, 25, 25, "mp_bus_sw_en", "Control whether BUS works, and set to 1’b1 before ISP works"}, + {NULL, NULL, 0x0000131c, 0x00000000, 24, 24, "mp_rd_id_en", "Unused"}, + {NULL, NULL, 0x0000131c, 0x00000000, 23, 16, "mp_rd_id_cfg", "Unused"}, + {NULL, NULL, 0x0000131c, 0x00000000, 8, 8, "mp_wr_id_en", "MP AXI ports write ID configuration enable"}, + {NULL, NULL, 0x0000131c, 0x00000000, 7, 0, "mp_wr_id_cfg", "MP AXI ports write ID configuration"}, + + {"MI_MP_BUS_TIMEO", "MP AXI Bus control register", + 0x00001320, 0x00000000, 31, 31, "mp_bus_timeo_en", "MP AXI bus time out waiting enable"}, + {NULL, NULL, 0x00001320, 0x00000000, 30, 0, "mp_bus_timeo", "MP AXI bus time out waiting clock cycle numbers"}, + + + {"MI_MP_Y_BASE_AD_INIT", "Base address for main picture Y component", + 0x00001324, 0x00000000, 31, 0, "mp_y_base_ad_init", "Base address of main picture Y component ring buffer." LINE_PADDING_6TAB + "Programmed value becomes effective (visible in corresponding shadow register)" LINE_PADDING_6TAB + "after a soft reset, a forced software update or an automatic configuration update."}, + + + {"MI_MP_Y_SIZE_INIT", "Size of main picture Y component in frame buffer(ring buffer)", + 0x00001328, 0x00000000, 28, 0, "mp_y_size_init", "Size of main picture Y component ring buffer." LINE_PADDING_6TAB + "Programmed value becomes effective (visible in corresponding shadow register)" LINE_PADDING_6TAB + "after a soft reset, a forced software update or an automatic configuration update."}, + + {"MI_MP_Y_OFFS_CNT_INIT", "Offset counter init value for main picture Y", + 0x0000132c, 0x00000000, 28, 0, "mp_y_offs_cnt_init", "Offset counter init value of main picture Y component ring buffer." LINE_PADDING_6TAB + "Programmed value becomes effective (visible in corresponding shadow register)" LINE_PADDING_6TAB + "after a soft reset, a forced software update or an automatic configuration update."}, + + {"MI_MP_Y_LLENGTH", "Line length of main picture Y", + 0x00001330, 0x00000000, 31, 0, "mp_y_llengh", "Line length of Main Path picture Y component or RGB picture in bytes, " LINE_PADDING_6TAB + "also known as line stride. [Refer doc]"}, + + {"MI_MP_Y_PIC_WIDTH", "Image width of the Y component in pixels for main path", + 0x00001334, 0x00000000, 31, 0, "mp_y_pic_width", "Image width of the main picture Y component or RGB picture in pixels.[Refer doc]"}, + + {"MI_MP_Y_PIC_HEIGHT", "Image height of the Y component in pixels for main path", + 0x00001338, 0x00000000, 31, 0, "mp_y_pic_height", "Image height of the y component or RGB picture in pixels.[Refer doc]"}, + + {"MI_MP_Y_PIC_SIZE", "Image memory size of the Y component in bytes for main path", + 0x0000133c, 0x00000000, 31, 0, "mp_y_pic_size", "Image size of the Y component or RGB picture in bytes.[Refer doc]"}, + + {"MI_MP_CB_BASE_AD_INIT", "Base address for main picture Cb component ring buffer", + 0x00001340, 0x00000000, 31, 0, "mp_cb_base_ad_init", "Base address of main picture Cb component ring buffer.[Refer doc]"}, + + + {"MI_MP_CB_SIZE_INIT", "Size of main picture Cb component ring buffer", + 0x00001344, 0x00000000, 27, 0, "mp_cb_size_init", "Size of main picture Cb component ring buffer.[Refer doc]"}, + + + {"MI_MP_CB_OFFS_CNT_INIT", "Offset counter init value for main picture Cb component ring buffer", + 0x00001348, 0x00000000, 27, 0, "mp_cb_offs_cnt_init", "Offset counter init value of main picture Cb component ring buffer.[Refer doc]"}, + + + {"MI_MP_CR_BASE_AD_INIT", "Base address for main picture Cr component ring buffer", + 0x0000134c, 0x00000000, 31, 0, "mp_cr_base_ad_init", "Base address of main picture Cr component ring buffer.[Refer doc]"}, + + {"MI_MP_CR_SIZE_INIT", "Size of main picture Cr component ring buffer", + REG_BASE+0x050, 0x00000000, 27, 0, "mp_cr_size_init", "Size of main picture Cr component ring buffer.[Refer doc]"}, + + {"MI_MP_CR_OFFS_CNT_INIT", "Offset counter init value for main picture Cr component ring buffer", + 0x00001354, 0x00000000, 27, 0, "mp_cr_offs_cnt_init", "Offset counter init value of main picture Cr component ring buffer.[Refer doc]"}, + + {"MI_MP_Y_BASE_AD_INIT2", "Base address 2 (ping pong) for main picture Y component", + 0x00001358, 0x00000000, 31, 0, "mp_y_base_ad_init2", "Second ping pong base address of main picture Y component buffer.[Refer doc]"}, + + {"MI_MP_CB_BASE_AD_INIT2", "Base address 2 (pingpong) for main picture Cb component ring buffer", + 0x0000135C, 0x00000000, 31, 0, "mp_cb_base_ad_init2", "Second ping pong base address of main picture Cb component buffer[Refer doc]"}, + + {"MI_MP_CR_BASE_AD_INIT2", "Base address 2 (pingpong) for main picture Cr component ring buffer", + 0x00001360, 0x00000000, 31, 0, "mp_cr_base_ad_init2", "Second ping pong base address of main picture Cr component buffer.[Refer doc]"}, + + {"MI_MP_Y_BASE_AD_SHD", "Base address shadow register for main picture Y component ring buffer", + 0x00001370, 0x00000000, 31, 0, "mp_y_base_ad", "Shadow Base address of main picture Y component ring buffer."}, + + {"MI_MP_RAW_BASE_AD_INIT","Follow Y", 0x00001394, 0x00000000, 31, 0, "mp_raw_base_ad_init", "Base address of main picture RAW component ring buffer.[Refer doc]"}, + {"MI_MP_RAW_SIZE_INIT", "Follow Y", 0x00001398, 0x00000000, 28, 0, "mp_raw_size_init", "Size of main picture RAW data ring buffer.[Refer doc]"}, + {"MI_MP_RAW_OFFS_CNT_INIT", "Follow Y", 0x0000139c, 0x00000000, 28, 0, "mp_raw_offs_cnt_init", "Offset counter initial value of main picture RAW data ring buffer.[Refer doc]"}, + {"MI_MP_RAW_LLENGTH", "Follow Y", 0x000013a0, 0x00000000, 31, 0, "mp_raw_llengh", "Line length of Main Path picture RAW data in bytes, also known as line stride. [Refer doc]"}, + {"MI_MP_RAW_PIC_WIDTH", "Follow Y", 0x000013a4, 0x00000000, 31, 0, "mp_raw_pic_width", "Image width of the Main Path picture RAW component or RGB picture in pixels.[Refer doc]"}, + {"MI_MP_RAW_PIC_HEIGHT", "Follow Y", 0x000013A8, 0x00000000, 14, 0, "mp_raw_pic_height", "Image height of Main Path picture RAW data in pixels[Refer doc]"}, + {"MI_MP_RAW_PIC_SIZE", "Follow Y", 0x000013AC, 0x00000000, 24, 0, "mp_raw_pic_size", "Image size of the RAW component in bytes[Refer doc]"}, + + {"MI_MP_JDP_BASE_AD_INIT", "Follow Y", 0x000013C0, 0x00000000, 31, 0, "mp_jdp_base_ad_init", "Base address of main picture jpeg or dpcc ring buffer.[Refer doc]"}, + {"MI_MP_JDP_SIZE_INIT", "Follow Y", 0x000013C4, 0x00000000, 28, 0, "mp_jdp_size_init", "Size of main picture jpeg or dpcc ring buffer.[Refer doc]"}, + {"MI_MP_JDP_OFFS_CNT_INIT", "Follow Y", 0x000013C8, 0x00000000, 28, 0, "mp_jdp_offs_cnt_init", "Offset counter init value of main picture jpeg or dpcc data ring buffer.[Refer doc]"}, + {"MI_MP_JDP_LLENGTH", "Follow Y", 0x000013CC, 0x00000000, 31, 0, "mp_jdp_llength", "Line length of mp picture jpeg data in pixels, also known as line stride.[Refer doc]"}, + {"MI_MP_JDP_PIC_WIDTH", "Follow Y", 0x000013D0, 0x00000000, 14, 0, "mp_jdp_pic_width", "Image width of the main picture JPEG component picture in pixels.[Refer doc]"}, + {"MI_MP_JDP_PIC_HEIGHT", "Follow Y", 0x000013D4, 0x00000000, 14, 0, "mp_jdp_pic_height", "Image height of the main picture JPEG component picture in pixels.[Refer doc]"}, + {"MI_MP_JDP_PIC_SIZE", "Follow Y", 0x000013D8, 0x00000000, 24, 0, "mp_jdp_pic_size", "Image size of the main picture JPEG component picture in bytes.[Refer doc]"}, + + + {"MI_MP_STATUS_CLR", "FIFO full clear", + 0x000013ec, 0x00000000, 4, 4, "mp_jdp_fifo_full", "Clear status of JDP FIFO full flag in Main path"}, + {NULL, NULL, 0x000013ec, 0x00000000, 3, 3, "mp_raw_fifo_full", "Clear status of RAW FIFO full flag in Main path"}, + {NULL, NULL, 0x000013ec, 0x00000000, 2, 2, "mp_cr_fifo_full", "Clear status of Cr FIFO full flag in Main path"}, + {NULL, NULL, 0x000013ec, 0x00000000, 1, 1, "mp_cb_fifo_full", "Clear status of Cb FIFO full flag in Main path"}, + {NULL, NULL, 0x000013ec, 0x00000000, 0, 0, "mp_y_fifo_full", "Clear status of Y FIFO full flag in Main path"}, + + + {"MI_MP_CTRL_STATUS", "FIFO Full STATUS, Y,U,V,RAW,JDP", + 0x000013f0, 0x00000000, 4, 4, "mp_jdp_fifo_full", "FIFO full flag of JDP FIFO in Main path asserted since last clear"}, + {NULL, NULL, 0x000013f0, 0x00000000, 3, 3, "mp_raw_fifo_full", "FIFO full flag of RAW FIFO in Main path asserted since last clear"}, + {NULL, NULL, 0x000013f0, 0x00000000, 2, 2, "mp_cr_fifo_full", "FIFO full flag of Cr FIFO in Main path asserted since last clear"}, + {NULL, NULL, 0x000013f0, 0x00000000, 1, 1, "mp_cb_fifo_full", "FIFO full flag of Cb FIFO in Main path asserted since last clear"}, + {NULL, NULL, 0x000013f0, 0x00000000, 0, 0, "mp_y_fifo_full", "FIFO full flag of Y FIFO in Main path asserted since last clear"}, + + {"MI_SP2_CTRL", "SP2 control register", + 0x000014e4, 0x00000000, 9, 9, "sp2_rd_raw_cfg_update", "Forced configuration update which leads to an immediate update of the shadow registers for this RAW read path."}, + {NULL, NULL, 0x000014e4, 0x00000000, 8, 8, "sp2_rd_raw_auto_update", "unused"}, + {NULL, NULL, 0x000014e4, 0x00000000, 7, 7, "sp2_rd_yuv_cfg_update", "unused"}, + {NULL, NULL, 0x000014e4, 0x00000000, 6, 6, "sp2_rd_yuv_auto_update", "unused"}, + {NULL, NULL, 0x000014e4, 0x00000000, 5, 5, "sp2_init_offset_en", "Enables updating of the offset counters shadow registers [Refer doc]"}, + {NULL, NULL, 0x000014e4, 0x00000000, 4, 4, "sp2_init_base_en", "Enables updating of the base address and buffer size shadow registers[Refer doc]"}, + {NULL, NULL, 0x000014e4, 0x00000000, 3, 3, "sp2_mi_cfg_upd", "Forced configuration update which leads to an immediate update of the shadow registers.[Refer doc]"}, + {NULL, NULL, 0x000014e4, 0x00000000, 2, 2, "sp2_mi_skip", "Skip of current or next starting main picture."}, + {NULL, NULL, 0x000014e4, 0x00000000, 1, 1, "sp2_auto_update", "Automatic update of configuration registers for Self Path 2 at frame end. 0: disabled; 1: enabled"}, + {NULL, NULL, 0x000014e4, 0x00000000, 0, 0, "sp2_pingpong_enable", "Ping-pong mode of configuration registers for Self Path 2 at frame end. 0: disabled; 1: enabled"}, + + + {"MI_SP2_FMT", "SP2 pixel format control register", + 0x000014e8, 0x00000000, 29, 29, "sp2_wr_yuv_word_aligned_msb_en","0: 10bit yuv in LSB of 16bit; 1: 10bit yuv in MSB of 16bit;"}, + {NULL, NULL, 0x000014e8, 0x00000000, 28, 28, "sp2_wr_yuv_word_aligned", "0: disable; 1:enable"}, + {NULL, NULL, 0x000014e8, 0x00000000, 27, 26, "sp2_rd_yuv_nvy", "00: Y channel in the first position; 01: Y in the second; 10: Y in the third; 11: Reserved" LINE_PADDING_6TAB + " When in YUV444 or RGB888 interleave: " LINE_PADDING_6TAB + " 00: Y channel in the first and third position; 01: Y channel in the second and fourth position"}, + {NULL, NULL, 0x000014e8, 0x00000000, 25, 25, "sp2_rd_yuv_nv21", "0: No swap; 1: Swap Cr and Cb channel for semi-planar and YUV444 or RGB interleave and YUV422 interleave"}, + {NULL, NULL, 0x000014e8, 0x00000000, 24, 23, "sp2_rd_raw_aligned", "00: Unaligned; 01: Aligned mode0; 10: Aligned mode1; 11: Reserved"}, + {NULL, NULL, 0x000014e8, 0x00000000, 22, 22, "sp2_rd_yuv_aligned", "0: Unaligned; 1: Aligned"}, + {NULL, NULL, 0x000014e8, 0x00000000, 21, 19, "sp2_rd_raw_bit", "000: RAW8; 001: RAW10; 010: RAW12; 011: RAW14; 100: RAW16; 101: RAW20, or Reserved"}, + {NULL, NULL, 0x000014e8, 0x00000000, 18, 17, "sp2_rd_yuv_str", "00: YUV/RGB Semi-Planar; 01: YUV Interleave, RGB Raster; 10: YUV/RGB Planar; 11: Reserved"}, + {NULL, NULL, 0x000014e8, 0x00000000, 16, 15, "sp2_rd_yuv_fmt", "00: YUV420; 01: YUV422; 10: YUV444; 11: Reserved"}, + {NULL, NULL, 0x000014e8, 0x00000000, 14, 14, "sp2_rd_yuv_bit", "0: 8 bit YUV/RGB; 1: 10 bit YUV/RGB"}, + {NULL, NULL, 0x000014e8, 0x00000000, 13, 12, "sp2_wr_yuv_nvy", "00: Y channel in the first position; 01: Y in the second; 10: Y in the third; 11: Reserved" LINE_PADDING_6TAB + " When in YUV444 or RGB888 interleave: 00:Y channel in 1st and 3rd position; 01:Y channel in the 2nd and 4th position"}, + {NULL, NULL, 0x000014e8, 0x00000000, 11, 11, "sp2_wr_yuv_nv21", "0: No swap; 1: Swap Cr and Cb channel for semi-planar and YUV444 or RGB interleave and YUV422 interleave"}, + {NULL, NULL, 0x000014e8, 0x00000000, 10, 9, "sp2_wr_raw_aligned", "00: Unaligned; 01: Aligned mode0; 10: Aligned mode1; 11: Reserved"}, + {NULL, NULL, 0x000014e8, 0x00000000, 8, 8, "sp2_wr_yuv_aligned", "0: Unaligned; 1:Aligned"}, + {NULL, NULL, 0x000014e8, 0x00000000, 7, 5, "sp2_wr_raw_bit", "000: RAW8; 001: RAW10; 010: RAW12; 011: RAW14; 100: RAW16; 101: RAW20, or Reserved"}, + {NULL, NULL, 0x000014e8, 0x00000000, 4, 3, "sp2_wr_yuv_str", "00: YUV/RGB SemiPlanar; 01: YUV Interleave, RGB Raster; 10: YUV/RGB Planar; 11: Y Only"}, + {NULL, NULL, 0x000014e8, 0x00000000, 2, 1, "sp2_wr_yuv_fmt", "00: YUV420; 01: YUV422; 10: YUV444; 11: Reserved"}, + {NULL, NULL, 0x000014e8, 0x00000000, 0, 0, "sp2_wr_yuv_bit", "0: 8 bit YUV/RGB; 1: 10 bit YUV/RGB"}, + + {"MI_SP2_RAW_BASE_AD_INIT", "Follow main path RAW", + 0x00001568, 0x00000000, 31, 0, "sp2_raw_base_ad_init", "Base address of Self Path 2 picture RAW component ring buffer[Refer doc]"}, + {"MI_SP2_DMA_RAW_PIC_START_AD", "RAW component image start address", + 0x000015bc, 0x00000000, 31, 0, "sp2_dma_raw_pic_start_ad", "Image start address of the RAW component"}, + + {"MI_SP2_DMA_RAW_PIC_WIDTH", "RAW component image width", + 0x000015c0, 0x00000000, 14, 0, "sp2_dma_raw_pic_width", "Image width of the RAW component in pixels."}, + + {"MI_SP2_DMA_RAW_STATUS", "DMA raw status", 0x000015e0, 0x00000000, 0, 0, "sp2_dma_raw_active", "If set, DMA RAW access is active."}, + + {"MI_MCM_CTRL", "MCM Path MI control register", + 0x00001600, 0x00000000, 6, 6, "mcm_rd_cfg_upd", "Forced configuration update which leads to an immediate " LINE_PADDING_6TAB + "update of the shadow registers for the MCM read path."}, + {NULL, NULL, 0x00001600, 0x00000000, 5, 5, "mcm_rd_auto_update", "unused"}, + {NULL, NULL, 0x00001600, 0x00000000, 4, 4, "mcm_init_offset_en", "Enables updating of the offset counters shadow registers " LINE_PADDING_6TAB + "for MCM path to the programmed register init values.[Refer doc]"}, + {NULL, NULL, 0x00001600, 0x00000000, 3, 3, "mcm_init_base_en", "Enables updating of the base address and buffer size shadow registers" LINE_PADDING_6TAB + "for main picture to the programmed register init values. [Refer doc]"}, + {NULL, NULL, 0x00001600, 0x00000000, 2, 2, "mcm_wr_cfg_upd", "Forced configuration update which leads to an immediate " LINE_PADDING_6TAB + "update of the shadow registers. [Refer doc]"}, + {NULL, NULL, 0x00001600, 0x00000000, 1, 1, "mcm_wr_skip", "Skip of current or next starting MCM picture."}, + {NULL, NULL, 0x00001600, 0x00000000, 0, 0, "mcm_wr_auto_update", "Automatic update of configuration registers for Self Path 1 " LINE_PADDING_6TAB + "at frame end. 0: Disabled; 1: Enabled"}, + + + + {"MI_MCM_FMT", "MCM pixel format control register", + 0x00001604, 0x00000000, 17, 16, "mcm_wr1_fmt_aligned", "00: unaligned, 01: aligned mode0, 10: aligned mode1, 11: Reserved"}, + {NULL, NULL, 0x00001604, 0x00000000, 15, 14, "mcm_wr0_fmt_aligned", "00: unaligned, 01: aligned mode0, 10: aligned mode1, 11: Reserved"}, + {NULL, NULL, 0x00001604, 0x00000000, 13, 12, "mcm_rd_fmt_aligned", "00: unaligned, 01: aligned mode0, 10: aligned mode1, 11: Reserved"}, + {NULL, NULL, 0x00001604, 0x00000000, 11, 8, "mcm_wr1_raw_bit", "000: RAW8, 001: RAW10, 010: RAW12, 011: RAW14, 100: RAW16, 101: RAW20 or Reserved"}, + {NULL, NULL, 0x00001604, 0x00000000, 7, 4, "mcm_wr0_raw_bit", "000: RAW8, 001: RAW10, 010: RAW12, 011: RAW14, 100: RAW16, 101: RAW20 or Reserved"}, + {NULL, NULL, 0x00001604, 0x00000000, 3, 0, "mcm_rd_raw_bit", "000: RAW8, 001: RAW10, 010: RAW12, 011: RAW14, 100: RAW16, 101: RAW20 or Reserved"}, + + + {"MI_MCM_BUS_CFG", "MCM AXI Bus cfg", + 0x00001608, 0x00000000, 19, 16, "mcm_rd_swap_raw", "Swap bits control for 16 byte data width on AXI bus; " LINE_PADDING_6TAB + "YUV interleave and RGB raster mode share the same bits." LINE_PADDING_6TAB + "Bit 0 to swap bytes; Bit 1 to swap words; Bit 2 to swap double words; Bit 3 to swap four words"}, + {NULL, NULL, 0x00001608, 0x00000000, 15, 12, "mcm_wr0_swap_raw", "Same as field: mcm_rd_swap_raw"}, + {NULL, NULL, 0x00001608, 0x00000000, 11, 8, "mcm_wr1_swap_raw", "Same as field: mcm_rd_swap_raw"}, + {NULL, NULL, 0x00001608, 0x00000000, 7, 6, "mcm_rd_issue_cap", "Maximum outstanding issue capability. 00: 4; 01: 8; 10: 16; 11: 32"}, + {NULL, NULL, 0x00001608, 0x00000000, 5, 4, "mcm_wr_issue_cap", "Maximum outstanding issue capability. 00: 4; 01: 8; 10: 16; 11: 32"}, + {NULL, NULL, 0x00001608, 0x00000000, 3, 2, "mcm_rd_burst_len", "Maximum burst length. 00:4; 01:8; 10:16, 11:Reserved"}, + {NULL, NULL, 0x00001608, 0x00000000, 1, 0, "mcm_wr_burst_len", "Maximum burst length. 00:4; 01:8; 10:16, 11:Reserved"}, + + {"MI_MCM_RAW0_BASE_AD_INIT", "Follow Main Path RAW", 0x00001614, 0x00000000, 31, 0, "mcm_raw0_base_ad_init","Base address of MCM Path picture RAW0 component ring buffer[Refer doc]"}, + {"MI_MCM_RAW0_SIZE_INIT", "Follow Main Path RAW", 0x00001618, 0x00000000, 28, 0, "mcm_raw0_size_init", "Size of MCM Path picture RAW0 data ring buffer.[Refer doc]"}, + + {"MI_MCM_BUS_ID", "MCM AXI Bus ID configuration", + 0x0000160C, 0x00000000, 27, 27, "mcm_bus_sw_en", "Control whether BUS works, and set to 1’b1 before ISP works"}, + {NULL, NULL, 0x0000160C, 0x00000000, 26, 26, "mcm_rd_id_en", "MCM AXI ports read ID configuration enable"}, + {NULL, NULL, 0x0000160C, 0x00000000, 25, 18, "mcm_rd_id_cfg", "MCM AXI ports read ID configuration"}, + {NULL, NULL, 0x0000160C, 0x00000000, 8, 8, "mcm_wr1_id_en", "MCM AXI ports write1 ID configuration enable"}, + {NULL, NULL, 0x0000160C, 0x00000000, 7, 0, "mcm_wr1_id_cfg", "MCM AXI ports write1 ID configuration"}, + + {"MI_MCM_RAW0_LLENGTH", "Follow Main Path RAW", 0x00001620, 0x00000000, 31, 0, "mcm_raw0_llength", "Line length of MCM Path picture RAW0 data in bytes, also known as line stride[Refer doc]"}, + {"MI_MCM_RAW0_PIC_WIDTH", "Follow Main Path RAW", 0x00001624, 0x00000000, 14, 0, "mcm_raw0_pic_width", "Image width of the MCM Path picture RAW component in pixels.[Refer doc]"}, + {"MI_MCM_RAW0_PIC_HEIGHT", "Follow Main Path RAW", 0x00001628, 0x00000000, 14, 0, "mcm_raw0_pic_height", "Image height of the RAW0 component in pixels.[Refer doc]"}, + {"MI_MCM_RAW0_PIC_SIZE", "Follow Main Path RAW", 0x0000162c, 0x00000000, 24, 0, "mcm_raw0_pic_size", "Image size of the RAW0 component in bytes(mcm_raw0_llength * mcm_raw0_pic_height).[Refer doc]"}, + + {"MI_MCM_RAW1_BASE_AD_INIT", "Follow Main Path RAW", 0x00001640, 0x00000000, 31, 0, "mcm_raw1_base_ad_init","Base address of MCM Path picture RAW1 component ring buffer"}, + {"MI_MCM_RAW1_SIZE_INIT", "Follow Main Path RAW", 0x00001644, 0x00000000, 28, 0, "mcm_raw1_size_init", "Size of MCM Path picture RAW1 data ring buffer."}, + + {"MI_MCM_RAW1_LLENGTH", "Follow Main Path RAW", 0x0000164c, 0x00000000, 31, 0, "mcm_raw1_llength", "Line length of MCM Path picture RAW1 data in bytes, also known as line stride[Refer doc]"}, + {"MI_MCM_RAW1_PIC_WIDTH", "Follow Main Path RAW", 0x00001650, 0x00000000, 14, 0, "mcm_raw1_pic_width", "Image width of the MCM Path picture RAW1 component in pixels.[Refer doc]"}, + {"MI_MCM_RAW1_PIC_HEIGHT", "Follow Main Path RAW", 0x00001654, 0x00000000, 14, 0, "mcm_raw1_pic_height", "Image height of the RAW1 component in pixels.[Refer doc]"}, + {"MI_MCM_RAW1_PIC_SIZE", "Follow Main Path RAW", 0x00001658, 0x00000000, 24, 0, "mcm_raw1_pic_size", "Image size of the RAW1 component in bytes(mcm_raw1_llength * mcm_raw1_pic_height).[Refer doc]"}, + + {"MI_MCM_DMA_RAW_PIC_START_AD", "RAW component image start address", 0x0000166c, 0x00000000, 31, 0, "mcm_dma_raw_pic_start_ad", "Image start address of the RAW component."}, + {"MI_MCM_DMA_RAW_PIC_WIDTH", "RAW component image width", 0x00001670, 0x00000000, 14, 0, "mcm_dma_raw_pic_width", "Image width of the RAW component in pixels."}, + {"MI_MCM_DMA_RAW_PIC_LLENGTH", "RAW component original line length", 0x00001674, 0x00000000, 31, 0, "mcm_dma_raw_pic_llength", "Line length of the RAW component in bytes of " LINE_PADDING_6TAB + "the original image in memory.For an uncropped image, " LINE_PADDING_6TAB + "where lines follow each other without offset" LINE_PADDING_6TAB + "(no line stride), line length must match image width."}, + {"MI_MCM_DMA_RAW_PIC_SIZE", "RAW component image memory size in bytes", 0x00001678, 0x00000000, 27, 0, "mcm_dma_raw_pic_size", "Image size of the RAW component in bytes which has to be" LINE_PADDING_6TAB + " the RAW line length multiplied by the RAW image height" LINE_PADDING_6TAB + "(dma_raw_llength * dma_raw_pic_height)."}, + + {"MI_MCM_DMA_STATUS", "MCM_DMA status register", 0x0000168c, 0x00000000, 0, 0, "mcm_dma_active", "0: MCM DMA access is not active; 1: MCM DMA access is active"}, + {"MI_MCM_DMA_RAW_PIC_LVAL", "MCM_DMA RAW Component line valid bytes number, 128 bit Alignment.", + 0x00001690, 0x00000000, 15, 0, "mcm_dma_raw_width_bytes", "Sizes occupied by valid data of a line; " LINE_PADDING_6TAB + "should be a multiple of 16" LINE_PADDING_6TAB + "Note: bus width=16 bytes"}, + + {"MI_IMSC", "Interrupt Mask", + 0x000016c0, 0x00000000, 27, 27, "fill_mp_y", "Mask bit for fill level interrupt of main picture Y, JPEG or RAW data"}, + {NULL, NULL, 0x000016c0, 0x00000000, 26, 26, "mblk_line", "Mask bit for macroblock line interrupt of main picture " LINE_PADDING_6TAB + "(16 lines of Y, 8 lines of Cb and 8 lines of Cr are written into RAM)"}, + {NULL, NULL, 0x000016c0, 0x00000000, 25, 25, "mp_handshk_int", "Mask bit for handshake interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 24, 24, "mcm_dma_raw_ready", "Mask bit for mcm_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 23, 23, "sp2_dma_raw_ready", "Mask bit for sp2_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 22, 22, "sp2_dma_ycbcr_ready", "Mask bit for sp2_dma YCbCr ready interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 21, 21, "wrap_mcm_raw1", "Mask bit for MCM RAW1 address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 20, 20, "wrap_mcm_raw0", "Mask bit for MCM RAW0 address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 19, 19, "wrap_sp2_raw", "Mask bit for Self Path 2 RAW address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 18, 18, "wrap_sp2_cr", "Mask bit for Self Path 2 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 17, 17, "wrap_sp2_cb", "Mask bit for Self Path 2 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 16, 16, "wrap_sp2_y", "Mask bit for Self Path 2 Y address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 15, 15, "wrap_sp1_cr", "Mask bit for Self Path 1 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 14, 14, "wrap_sp1_cb", "Mask bit for Self Path 1 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 13, 13, "wrap_sp1_y", "Mask bit for Self Path 1 Y address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 12, 12, "wrap_mp_jdp", "Mask bit for Main Path JDP address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 11, 11, "wrap_mp_raw", "Mask bit for Main Path RAW address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 10, 10, "wrap_mp_cr", "Mask bit for Main Path Cr address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 9, 9, "wrap_mp_cb", "Mask bit for Main Path Cb address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 8, 8, "wrap_mp_y", "Mask bit for Main Path Y address wrap interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 7, 7, "mcm_raw1_frame_end", "Mask bit for MCM RAW1 end of frame interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 6, 6, "mcm_raw0_frame_end", "Mask bit for MCM RAW0 end of frame interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 5, 5, "sp2_raw_frame_end", "Mask bit for Self Path 2 RAW end of frame interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 4, 4, "sp2_ycbcr_frame_end", "Mask bit for Self Path 2 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 3, 3, "sp1_ycbcr_frame_end", "Mask bit for Self Path 1 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 2, 2, "mp_jdp_frame_end", "Mask bit for Main Path JDP end of frame interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 1, 1, "mp_raw_frame_end", "Mask bit for Main Path RAW end of frame interrupt"}, + {NULL, NULL, 0x000016c0, 0x00000000, 0, 0, "mp_ycbcr_frame_end", "Mask bit for Main Path YCbCr end of frame interrupt." LINE_PADDING_6TAB + "0: Interrupt masked; 1: Interrupt active"}, + + {"MI_MIS", "Masked Interrupt Status", + 0x000016d0, 0x00000000, 27, 27, "fill_mp_y", "Masked status of fill level interrupt of main picture Y, JPEG or RAW data"}, + {NULL, NULL, 0x000016d0, 0x00000000, 26, 26, "mblk_line", "Masked status of macroblock line interrupt of main picture" LINE_PADDING_6TAB + "(16 lines of Y, 8 lines of Cb and 8 lines of Cr are written into RAM)"}, + {NULL, NULL, 0x000016d0, 0x00000000, 25, 25, "mp_handshk_int", "Masked status of handshake interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 24, 24, "mcm_dma_raw_ready", "Masked status of mcm_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 23, 23, "sp2_dma_raw_ready", "Masked status of sp2_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 22, 22, "sp2_dma_ycbcr_ready", "Masked status of sp2_dma YCbCr ready interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 21, 21, "wrap_mcm_raw1", "Masked status of MCM RAW1 address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 20, 20, "wrap_mcm_raw0", "Masked status of MCM RAW0 address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 19, 19, "wrap_sp2_raw", "Masked status of Self Path2 RAW address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 18, 18, "wrap_sp2_cr", "Masked status of Self Path2 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 17, 17, "wrap_sp2_cb", "Masked status of Self Path2 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 16, 16, "wrap_sp2_y", "Masked status of Self Path2 y address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 15, 15, "wrap_sp1_cr", "Masked status of Self Path1 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 14, 14, "wrap_sp1_cb", "Masked status of Self Path1 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 13, 13, "wrap_sp1_y", "Masked status of Self Path1 y address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 12, 12, "wrap_mp_jdp", "Masked status of Main Path JDP address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 11, 11, "wrap_mp_raw", "Masked status of Main Path RAW address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 10, 10, "wrap_mp_cr", "Masked status of Main Path Cr address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 9, 9, "wrap_mp_cb", "Masked status of Main Path Cb address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 8, 8, "wrap_mp_y", "Masked status of Main Path Y address wrap interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 7, 7, "mcm_raw1_frame_end", "Masked status of MCM RAW1 end of frame interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 6, 6, "mcm_raw0_frame_end", "Masked status of MCM RAW0 end of frame interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 5, 5, "sp2_raw_frame_end", "Masked status of Self Path2 RAW end of frame interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 4, 4, "sp2_ycbcr_frame_end", "Masked status of Self Path2 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 3, 3, "sp1_ycbcr_frame_end", "Masked status of Self Path1 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 2, 2, "mp_jdp_frame_end", "Masked status of Main Path JDP end of frame interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 1, 1, "mp_raw_frame_end", "Masked status of Main Path RAW end of frame interrupt"}, + {NULL, NULL, 0x000016d0, 0x00000000, 0, 0, "mp_ycbcr_frame_end", "Masked status of Main Path YCbCr end of frame interrupt"}, + + {"MI_ICR", "Interrupt Clear Register", + 0x000016d8, 0x00000000, 27, 27, "fill_mp_y", "Clear fill level interrupt of main picture Y, JPEG or RAW data"}, + {NULL, NULL, 0x000016d8, 0x00000000, 26, 26, "mblk_line", "Clear macroblock line interrupt of main picture " LINE_PADDING_6TAB + " (16 lines of Y, 8 lines of Cb and 8 lines of Cr are written into RAM)"}, + {NULL, NULL, 0x000016d8, 0x00000000, 25, 25, "mp_handshk_int", "Clear handshake interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 24, 24, "mcm_dma_raw_ready", "Clear mcm_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 23, 23, "sp2_dma_raw_ready", "Clear sp2_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 22, 22, "sp2_dma_ycbcr_ready", "Clear sp2_dma YCbCr ready interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 21, 21, "wrap_mcm_raw1", "Clear MCM RAW1 address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 20, 20, "wrap_mcm_raw0", "Clear MCM RAW0 address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 19, 19, "wrap_sp2_raw", "Clear Self Path2 RAW address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 18, 18, "wrap_sp2_cr", "Clear Self Path2 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 17, 17, "wrap_sp2_cb", "Clear Self Path2 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 16, 16, "wrap_sp2_y", "Clear Self Path2 y address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 15, 15, "wrap_sp1_cr", "Clear Self Path1 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 14, 14, "wrap_sp1_cb", "Clear Self Path1 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 13, 13, "wrap_sp1_y", "Clear Self Path1 Y address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 12, 12, "wrap_mp_jdp", "Clear Main Path JDP address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 11, 11, "wrap_mp_raw", "Clear Main Path RAW address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 10, 10, "wrap_mp_cr", "Clear Main Path Cr address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 9, 9, "wrap_mp_cb", "Clear Main Path Cb address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 8, 8, "wrap_mp_y", "Clear Main Path Y address wrap interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 7, 7, "mcm_raw1_frame_end", "Clear MCM RAW1 end of frame interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 6, 6, "mcm_raw0_frame_end", "Clear MCM RAW0 end of frame interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 5, 5, "sp2_raw_frame_end", "Clear Self Path2 RAW end of frame interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 4, 4, "sp2_ycbcr_frame_end", "Clear Self Path2 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 3, 3, "sp1_ycbcr_frame_end", "Clear Self Path1 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 2, 2, "mp_jdp_frame_end", "Clear Main Path JDP end of frame interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 1, 1, "mp_raw_frame_end", "Clear Main Path RAW end of frame interrupt"}, + {NULL, NULL, 0x000016d8, 0x00000000, 0, 0, "mp_ycbcr_frame_end", "Clear Main Path YCbCr end of frame interrupt"}, + + + {"MI_RIS", "Interrupt Set Register", + 0x000016e0, 0x00000000, 27, 27, "fill_mp_y", "RAW status of fill level interrupt of main picture Y, JPEG or RAW data"}, + {NULL, NULL, 0x000016e0, 0x00000000, 26, 26, "mblk_line", "RAW status of macroblock line interrupt of main picture " LINE_PADDING_6TAB + "(16 lines of Y, 8 lines of Cb and 8 lines of Cr are written into RAM)"}, + {NULL, NULL, 0x000016e0, 0x00000000, 25, 25, "mp_handshk_int", "RAW status of handshake interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 24, 24, "mcm_dma_raw_ready", "RAW status of mcm_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 23, 23, "sp2_dma_raw_ready", "RAW status of sp2_dma RAW ready interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 22, 22, "sp2_dma_ycbcr_ready", "RAW status of sp2_dma YCbCr ready interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 21, 21, "wrap_mcm_raw1", "RAW status of MCM RAW1 address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 20, 20, "wrap_mcm_raw0", "RAW status of MCM RAW0 address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 19, 19, "wrap_sp2_raw", "RAW status of Self Path2 RAW address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 18, 18, "wrap_sp2_cr", "RAW status of Self Path2 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 17, 17, "wrap_sp2_cb", "RAW status of Self Path2 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 16, 16, "wrap_sp2_y", "RAW status of Self Path2 Y address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 15, 15, "wrap_sp1_cr", "RAW status of Self Path1 Cr address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 14, 14, "wrap_sp1_cb", "RAW status of Self Path1 Cb address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 13, 13, "wrap_sp1_y", "RAW status of Self Path1 Y address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 12, 12, "wrap_mp_jdp", "RAW status of Main Path JDP address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 11, 11, "wrap_mp_raw", "RAW status of Main Path RAW address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 10, 10, "wrap_mp_cr", "RAW status of Main Path Cr address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 9, 9, "wrap_mp_cb", "RAW status of Main Path Cb address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 8, 8, "wrap_mp_y", "RAW status of Main Path Y address wrap interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 7, 7, "mcm_raw1_frame_end", "RAW status of MCM RAW1 end of frame interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 6, 6, "mcm_raw0_frame_end", "RAW status of MCM RAW0 end of frame interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 5, 5, "sp2_raw_frame_end", "RAW status of Self Path2 RAW end of frame interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 4, 4, "sp2_ycbcr_frame_end", "RAW status of Self Path2 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 3, 3, "sp1_ycbcr_frame_end", "RAW status of Self Path1 YCbCr end of frame interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 2, 2, "mp_jdp_frame_end", "RAW status of Main Path JDP end of frame interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 1, 1, "mp_raw_frame_end", "RAW status of Main Path RAW end of frame interrupt"}, + {NULL, NULL, 0x000016e0, 0x00000000, 0, 0, "mp_ycbcr_frame_end", "RAW status of Main Path YCbCr end of frame interrupt"}, + + + {"MI_MIS2", "Interrupt Set Register", + 0x000016f0, 0x00000000, 26, 26, "ppw_y_buf_full", "status of ppw y buf full ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 25, 25, "ppw_u_buf_full", "status of ppw u buf full ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 24, 24, "ppw_v_buf_full", "status of ppw v buf full ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 23, 23, "ppr_y_buf_full", "status of ppr y buf full ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 22, 22, "sp2_raw2_w_buf_full", "status of spw_raw2 wr buf full interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 21, 21, "sp2_raw2_r_buf_full", "status of spw_raw2 rd buf full interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 20, 20, "hdr_w_buf_full", "status of mi hdr wr buf full interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 19, 19, "hdr_r_buf_full", "status of mi hdr rd buf full interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 18, 18, "sp2_raw2_dma_ready", "status of spw_raw2 ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 17, 17, "ppr_dma_ready", "status of pp_dma yuv ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 16, 16, "wrap_sp2_raw", "status of sp2_raw2 address wrap interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 15, 15, "wrap_ppw_cr", "status of ppw_cr address wrap interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 14, 14, "wrap_ppw_cb", "status of ppw_cb address wrap interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 13, 13, "wrap_ppw_y", "status of ppw_y address wrap interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 12, 12, "sp2_raw2_frame_end", "status of spp2_raw2 end of frame interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 11, 11, "ppw_frame_end", "status of ppw end of frame interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 10, 10, "hdr_vs_dma_ready", "status of hdr_vs ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 9, 9, "hdr_s_dma_ready", "status of hdr_s ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 8, 8, "hdr_l_dma_ready", "status of hdr_l ready interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 7, 7, "wrap_hdr_vs", "status of hdr_vs address wrap interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 6, 6, "wrap_hdr_s", "status of hdr_s address wrap interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 5, 5, "wrap_hdr_l", "status of hdr_l address wrap interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 4, 4, "hdr_vs_frame_end", "status of hdr_vs end of frame interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 3, 3, "hdr_s_frame_end", "status of hdr_s end of frame interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 2, 2, "hdr_l_frame_end", "status of hdr_l end of frame interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 1, 1, "mi_rt_bus_buserr", "status of Memory Interface RT Path bus buserr interrupt"}, + {NULL, NULL, 0x000016f0, 0x00000000, 0, 0, "mi_rt_bus_timeo", "status of Memory Interface RT Path bus timeout interrupt"}, +}; + +int light_isp_mi_reg_dump(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_fields(ra_info, reg_desc, count); +} + +int light_isp_mi_reg_define(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_define(ra_info, reg_desc, count); +} + +int light_isp_mi_reg_find(reg_analyzer_info_s *ra_info) +{ + uint32_t count = sizeof(reg_desc) / sizeof(reg_desc[0]); + return ra_dump_reg_find(ra_info, reg_desc, count); +} +