From: Guosong Zhou Date: Mon, 15 Apr 2019 06:56:09 +0000 (-0400) Subject: camera: add mipi csi driver for sm1 [1/1] X-Git-Tag: khadas-vims-v0.9.6-release~512 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd10e8bcdc52c5e3e815564db17e8dff6651af16;p=platform%2Fkernel%2Flinux-amlogic.git camera: add mipi csi driver for sm1 [1/1] PD#SWPL-5388 Problem: sm1 board camera need add mipi csi module Solution: add mipi csi module Verify: verified on SM1 AC200 Change-Id: I819f2f74aa8da7d725cb59e5636e790185964f79 Signed-off-by: Guosong Zhou --- diff --git a/MAINTAINERS b/MAINTAINERS index de6a4cf..9c2fb06 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14817,3 +14817,24 @@ F: arch/arm64/boot/dts/amlogic/g12a_s905x2_u212.dts F: arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_1g.dts F: arch/arm/boot/dts/amlogic/sm1_s905x3_ac213.dts F: arch/arm64/boot/dts/amlogic/sm1_s905x3_ac213.dts + +AMLOGIC SM1 MIPI CSI DRIVER +M: Guosong Zhou +F: arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts +F: arch/arm/boot/dts/amlogic/mesonsm1.dtsi +F: arch/arm/configs/meson64_a32_defconfig +F: arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts +F: arch/arm64/boot/dts/amlogic/mesonsm1.dtsi +F: arch/arm64/configs/meson64_defconfig +F: drivers/amlogic/clk/g12a/g12a.h +F: include/dt-bindings/clock/amlogic,g12a-clkc.h +F: drivers/amlogic/clk/sm1/sm1.c +F: drivers/amlogic/media/camera/Makefile +F: drivers/amlogic/media/camera/common/cam_prober.c +F: drivers/amlogic/media/vin/tvin/Kconfig +F: drivers/amlogic/media/vin/tvin/Makefile +F: include/linux/amlogic/media/camera/aml_cam_info.h +F: drivers/amlogic/media/camera/ov5640.c +F: drivers/amlogic/media/camera/ov5640_firmware.h +F: drivers/amlogic/media/vin/tvin/csi/* +F: include/linux/amlogic/media/mipi/* diff --git a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi index 2fbee00..05a4166 100644 --- a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi +++ b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi @@ -2136,6 +2136,15 @@ }; }; + i2c2_master_pins3:i2c2_pins3 { + mux { + groups = "i2c2_sda_z10", + "i2c2_sck_z11"; + function = "i2c2"; + drive-strength = <2>; + }; + }; + i2c3_master_pins1:i2c3_pins1 { mux { groups = "i2c3_sda_h", diff --git a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts index 6f4b918..02ae91d 100644 --- a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts +++ b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts @@ -310,7 +310,7 @@ compatible = "amlogic, vm"; memory-region = <&vm0_cma_reserved>; dev_name = "vm0"; - status = "disabled"; + status = "okay"; vm_id = <0>; }; @@ -333,28 +333,45 @@ aml_cams { compatible = "amlogic, cams_prober"; - status = "disabled"; + status = "okay"; pinctrl-names="default"; - pinctrl-0=<&cam_dvp_pins &gen_clk_ee_z>; + pinctrl-0=<&gen_clk_ee_z>; clocks = <&clkc CLKID_GEN_CLK>; clock-names = "g12a_24m"; cam_0{ - cam_name = "gc2145"; + cam_name = "ov5640"; front_back = <0>; - /*u200 i2c2 gpio conflict with ethmac*/ camera-i2c-bus = <&i2c2>; - gpio_pwdn-gpios = <&gpio GPIOZ_2 GPIO_ACTIVE_HIGH>; + camvdd-gpios = <&gpio GPIOZ_5 GPIO_ACTIVE_HIGH>; + gpio_pwdn-gpios = <&gpio GPIOZ_6 GPIO_ACTIVE_HIGH>; gpio_rst-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH>; mirror_flip = <1>; vertical_flip = <1>; spread_spectrum = <0>; - bt_path = "gpio"; + bt_path = "csi"; + interface = "mipi"; + clk_channel = "a"; bt_path_count = <1>; - vdin_path = <0>; status = "okay"; }; }; + amvdec_csi { + compatible = "amlogic, amvdec_csi"; + status = "okay"; + csi_id = <0>; + reg = <0xff650000 0x00000100>, + <0xffe0c000 0x00000100>, + <0xffe0d000 0x00000100>; + reg-names = "csi_phy", "csi_host", "csi_adapt"; + clocks = <&clkc CLKID_CSI_ADAPT_CLK_COMP>, + <&clkc CLKID_MIPI_CSI_PHY_CLK_COMP>; + clock-names = "cts_csi_adapt_clk_composite", + "cts_csi_phy_clk_composite"; + interrupts = <0 1 0>; + interrupt-names = "csi_phy"; + }; + gpio_keypad{ compatible = "amlogic, gpio_keypad"; status = "okay"; @@ -1049,9 +1066,9 @@ }; &i2c2 { - status = "disabled"; + status = "okay"; pinctrl-names="default"; - pinctrl-0=<&i2c2_master_pins2>; + pinctrl-0=<&i2c2_master_pins3>; clock-frequency = <100000>; }; diff --git a/arch/arm/configs/meson64_a32_defconfig b/arch/arm/configs/meson64_a32_defconfig index a096265..8753a0f 100644 --- a/arch/arm/configs/meson64_a32_defconfig +++ b/arch/arm/configs/meson64_a32_defconfig @@ -316,6 +316,7 @@ CONFIG_AMLOGIC_MEDIA_TVIN_HDMI=y CONFIG_AMLOGIC_MEDIA_TVIN_AFE=y CONFIG_AMLOGIC_MEDIA_TVIN_VBI=y CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT=y +CONFIG_AMLOGIC_MEDIA_TVIN_CSI=y CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR=y CONFIG_AMLOGIC_V4L_VIDEO=y CONFIG_AMLOGIC_V4L_VIDEO2=y @@ -333,6 +334,7 @@ CONFIG_AMLOGIC_MEDIA_GDC=y CONFIG_AMLOGIC_VIDEO_CAPTURE=y CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER=y CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145=y +CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5640=y CONFIG_AMLOGIC_DTV_DEMOD=y CONFIG_AMLOGIC_MMC=y CONFIG_AMLOGIC_NAND=y diff --git a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi index d8a9ac4..2e74571 100644 --- a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi @@ -2135,6 +2135,15 @@ }; }; + i2c2_master_pins3:i2c2_pins3 { + mux { + groups = "i2c2_sda_z10", + "i2c2_sck_z11"; + function = "i2c2"; + drive-strength = <2>; + }; + }; + i2c3_master_pins1:i2c3_pins1 { mux { groups = "i2c3_sda_h", diff --git a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts index bdd41af..88e043f 100644 --- a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts +++ b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts @@ -333,26 +333,43 @@ compatible = "amlogic, cams_prober"; status = "disabled"; pinctrl-names="default"; - pinctrl-0=<&cam_dvp_pins &gen_clk_ee_z>; + pinctrl-0=<&gen_clk_ee_z>; clocks = <&clkc CLKID_GEN_CLK>; clock-names = "g12a_24m"; cam_0{ - cam_name = "gc2145"; + cam_name = "ov5640"; front_back = <0>; - /*u200 i2c2 gpio conflict with ethmac*/ camera-i2c-bus = <&i2c2>; - gpio_pwdn-gpios = <&gpio GPIOZ_2 GPIO_ACTIVE_HIGH>; + camvdd-gpios = <&gpio GPIOZ_5 GPIO_ACTIVE_HIGH>; + gpio_pwdn-gpios = <&gpio GPIOZ_6 GPIO_ACTIVE_HIGH>; gpio_rst-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH>; mirror_flip = <1>; vertical_flip = <1>; spread_spectrum = <0>; - bt_path = "gpio"; + bt_path = "csi"; + interface = "mipi"; + clk_channel = "a"; bt_path_count = <1>; - vdin_path = <0>; status = "okay"; }; }; + amvdec_csi { + compatible = "amlogic, amvdec_csi"; + status = "disabled"; + csi_id = <0>; + reg = <0x0 0xff650000 0x0 0x00000100>, + <0x0 0xffe0c000 0x0 0x00000100>, + <0x0 0xffe0d000 0x0 0x00000100>; + reg-names = "csi_phy", "csi_host", "csi_adapt"; + clocks = <&clkc CLKID_CSI_ADAPT_CLK_COMP>, + <&clkc CLKID_MIPI_CSI_PHY_CLK_COMP>; + clock-names = "cts_csi_adapt_clk_composite", + "cts_csi_phy_clk_composite"; + interrupts = <0 1 0>; + interrupt-names = "csi_phy"; + }; + gpio_keypad{ compatible = "amlogic, gpio_keypad"; status = "okay"; @@ -1050,7 +1067,7 @@ &i2c2 { status = "disabled"; pinctrl-names="default"; - pinctrl-0=<&i2c2_master_pins2>; + pinctrl-0=<&i2c2_master_pins3>; clock-frequency = <100000>; }; diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index a11ba1b..03d9fcf 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -310,6 +310,7 @@ CONFIG_AMLOGIC_MEDIA_TVIN_HDMI=y CONFIG_AMLOGIC_MEDIA_TVIN_AFE=y CONFIG_AMLOGIC_MEDIA_TVIN_VBI=y CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT=y +CONFIG_AMLOGIC_MEDIA_TVIN_CSI=y CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR=y CONFIG_AMLOGIC_V4L_VIDEO=y CONFIG_AMLOGIC_V4L_VIDEO2=y @@ -327,6 +328,7 @@ CONFIG_AMLOGIC_MEDIA_GDC=y CONFIG_AMLOGIC_VIDEO_CAPTURE=y CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER=y CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145=y +CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5640=y CONFIG_AMLOGIC_DTV_DEMOD=y CONFIG_AMLOGIC_MMC=y CONFIG_AMLOGIC_NAND=y diff --git a/drivers/amlogic/clk/g12a/g12a.h b/drivers/amlogic/clk/g12a/g12a.h index 5a2f0b5..508017c 100644 --- a/drivers/amlogic/clk/g12a/g12a.h +++ b/drivers/amlogic/clk/g12a/g12a.h @@ -117,6 +117,11 @@ #define HHI_SYS1_PLL_CNTL5 0x394 /* 0xe5 offset in data sheet */ #define HHI_SYS1_PLL_CNTL6 0x398 /* 0xe6 offset in data sheet */ /*****************/ + +/* For SM1 only */ +#define HHI_CSI2_ADAPT_CLK_CNTL 0x3c0 /* 0xf0 offset in data sheet */ +/*****************/ + #define HHI_BT656_CLK_CNTL 0x3d4 /* 0xf5 offset in data sheet */ #define HHI_SPICC_CLK_CNTL 0x3dc /* 0xf7 offset in data sheet */ /* AO registers*/ diff --git a/drivers/amlogic/clk/sm1/sm1.c b/drivers/amlogic/clk/sm1/sm1.c index 9b985ab..2f8acf3 100644 --- a/drivers/amlogic/clk/sm1/sm1.c +++ b/drivers/amlogic/clk/sm1/sm1.c @@ -140,6 +140,99 @@ static struct clk_gate cts_vipnanoq_axi_clk_gate = { .flags = CLK_GET_RATE_NOCACHE, }, }; + +static const char * const media_parent_names_mipi[] = { "xtal", + "gp0_pll", "mpll1", "mpll2", "fclk_div3", "fclk_div4", + "fclk_div5", "fclk_div7" +}; + +static struct clk_mux cts_mipi_csi_phy_clk_mux = { + .reg = (void *)HHI_MIPI_CSI_PHY_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cts_mipi_csi_phy_clk_mux", + .ops = &clk_mux_ops, + .parent_names = media_parent_names_mipi, + .num_parents = 8, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_divider cts_mipi_csi_phy_clk_div = { + .reg = (void *)HHI_MIPI_CSI_PHY_CLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cts_mipi_csi_phy_clk_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "cts_mipi_csi_phy_clk_mux" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_gate cts_mipi_csi_phy_clk_gate = { + .reg = (void *)HHI_MIPI_CSI_PHY_CLK_CNTL, + .bit_idx = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "cts_mipi_csi_phy_clk_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "cts_mipi_csi_phy_clk_div" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static const char * const media_parent_names_adapt[] = { "xtal", + "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", + "mpll3", "gp0_pll" +}; + +static struct clk_mux cts_csi_adapt_clk_mux = { + .reg = (void *)HHI_CSI2_ADAPT_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cts_csi_adapt_clk_mux", + .ops = &clk_mux_ops, + .parent_names = media_parent_names_adapt, + .num_parents = 8, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_divider cts_csi_adapt_clk_div = { + .reg = (void *)HHI_CSI2_ADAPT_CLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cts_csi_adapt_clk_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "cts_csi_adapt_clk_mux" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_gate cts_csi_adapt_clk_gate = { + .reg = (void *)HHI_CSI2_ADAPT_CLK_CNTL, + .bit_idx = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "cts_csi_adapt_clk_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "cts_csi_adapt_clk_div" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + static struct clk_mux sm1_dsu_pre_src_clk_mux0 = { .reg = (void *)HHI_SYS_CPU_CLK_CNTL5, .mask = 0x3, @@ -373,6 +466,20 @@ static void __init sm1_clkc_init(struct device_node *np) + (unsigned long)(cts_vipnanoq_axi_clk_gate.reg); cts_vipnanoq_axi_clk_div.reg = clk_base + (unsigned long)(cts_vipnanoq_axi_clk_div.reg); + + cts_mipi_csi_phy_clk_mux.reg = clk_base + + (unsigned long)(cts_mipi_csi_phy_clk_mux.reg); + cts_mipi_csi_phy_clk_div.reg = clk_base + + (unsigned long)(cts_mipi_csi_phy_clk_div.reg); + cts_mipi_csi_phy_clk_gate.reg = clk_base + + (unsigned long)(cts_mipi_csi_phy_clk_gate.reg); + cts_csi_adapt_clk_mux.reg = clk_base + + (unsigned long)(cts_csi_adapt_clk_mux.reg); + cts_csi_adapt_clk_div.reg = clk_base + + (unsigned long)(cts_csi_adapt_clk_div.reg); + cts_csi_adapt_clk_gate.reg = clk_base + + (unsigned long)(cts_csi_adapt_clk_gate.reg); + /* Populate base address for gates */ for (i = 0; i < ARRAY_SIZE(sm1_clk_gates); i++) sm1_clk_gates[i]->reg = clk_base + @@ -426,6 +533,33 @@ static void __init sm1_clkc_init(struct device_node *np) if (IS_ERR(clks[CLKID_VNANOQ_AXI_CLK_COMP])) panic("%s: %d register cts_vipnanoq_axi_clk_composite error\n", __func__, __LINE__); + + clks[CLKID_MIPI_CSI_PHY_CLK_COMP] = clk_register_composite(NULL, + "cts_csi_phy_clk_composite", + media_parent_names_mipi, 8, + &cts_mipi_csi_phy_clk_mux.hw, + &clk_mux_ops, + &cts_mipi_csi_phy_clk_div.hw, + &clk_divider_ops, + &cts_mipi_csi_phy_clk_gate.hw, + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_MIPI_CSI_PHY_CLK_COMP])) + panic("%s: %d register cts_csi_phy_clk_composite error\n", + __func__, __LINE__); + + clks[CLKID_CSI_ADAPT_CLK_COMP] = clk_register_composite(NULL, + "cts_csi_adapt_clk_composite", + media_parent_names_adapt, 8, + &cts_csi_adapt_clk_mux.hw, + &clk_mux_ops, + &cts_csi_adapt_clk_div.hw, + &clk_divider_ops, + &cts_csi_adapt_clk_gate.hw, + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_CSI_ADAPT_CLK_COMP])) + panic("%s: %d register cts_csi_adapt_clk_composite error\n", + __func__, __LINE__); + if (clks[CLKID_CPU_CLK]) { if (!of_property_read_bool(np, "own-dsu-clk")) return; diff --git a/drivers/amlogic/media/camera/Makefile b/drivers/amlogic/media/camera/Makefile index 04fb18c..70236db2 100644 --- a/drivers/amlogic/media/camera/Makefile +++ b/drivers/amlogic/media/camera/Makefile @@ -7,9 +7,11 @@ amlcamera-objs := common/plat_ctrl.o amlvm-objs := common/vm.o cam_prober-objs := common/cam_prober.o common/config_parser.o gc2145dri-objs := gc2145.o +ov5640dri-objs := ov5640.o obj-y += amlflash.o obj-y += amlvm.o obj-y += amlcamera.o obj-y += cam_prober.o obj-$(CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145) += gc2145dri.o +obj-$(CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5640) += ov5640dri.o \ No newline at end of file diff --git a/drivers/amlogic/media/camera/common/cam_prober.c b/drivers/amlogic/media/camera/common/cam_prober.c index 98fe531..d1a45f3 100644 --- a/drivers/amlogic/media/camera/common/cam_prober.c +++ b/drivers/amlogic/media/camera/common/cam_prober.c @@ -33,6 +33,7 @@ #include #include #include +#include #define CONFIG_ARCH_MESON8 @@ -1049,7 +1050,8 @@ void aml_cam_init(struct aml_cam_info_s *cam_dev) if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) GXBB_cam_enable_clk(); else if ((get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B)) + (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B) || + (is_meson_sm1_cpu())) GX12_cam_enable_clk(); else cam_enable_clk(cam_dev->mclk, cam_dev->spread_spectrum); @@ -1109,7 +1111,8 @@ void aml_cam_uninit(struct aml_cam_info_s *cam_dev) if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) GXBB_cam_disable_clk(cam_dev->spread_spectrum); else if ((get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B)) + (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B) || + (is_meson_sm1_cpu())) GX12_cam_disable_clk(cam_dev->spread_spectrum); else cam_disable_clk(cam_dev->spread_spectrum); @@ -1196,6 +1199,15 @@ static int fill_cam_dev(struct device_node *p_node, goto err_out; } + cam_dev->cam_vdd = of_get_named_gpio(p_node, "camvdd-gpios", 0); + pr_info("cam_dev->cam_vdd = %d\n", cam_dev->cam_vdd); + if (cam_dev->cam_vdd == 0) + pr_info("%s: failed to map gpio_cam_vdd !\n", cam_dev->name); + ret = gpio_request(cam_dev->cam_vdd, "camera"); + if (ret < 0) + pr_info("aml_cam_init cam_vdd request failed\n"); + gpio_direction_output(cam_dev->cam_vdd, 0); + cam_dev->pwdn_pin = of_get_named_gpio(p_node, "gpio_pwdn-gpios", 0); if (cam_dev->pwdn_pin == 0) { pr_info("%s: failed to map gpio_pwdn !\n", cam_dev->name); diff --git a/drivers/amlogic/media/camera/ov5640.c b/drivers/amlogic/media/camera/ov5640.c new file mode 100644 index 0000000..e58387a --- /dev/null +++ b/drivers/amlogic/media/camera/ov5640.c @@ -0,0 +1,3346 @@ +/* + * drivers/amlogic/media/camera/ov5640.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_WAKELOCK +#include +#endif +#include +#include +#include +#include +#include +#include "common/plat_ctrl.h" +#include +#include +#include +#include "common/vm.h" +#include "ov5640_firmware.h" + +#define OV5640_CAMERA_MODULE_NAME "ov5640" + +#define WAKE_NUMERATOR 30 +#define WAKE_DENOMINATOR 1001 +#define BUFFER_TIMEOUT msecs_to_jiffies(500) + +#define MAGIC_RE_MEM 0x123039dc +#define OV5640_RES0_CANVAS_INDEX 0x4e + +#define OV5640_CAMERA_MAJOR_VERSION 0 +#define OV5640_CAMERA_MINOR_VERSION 7 +#define OV5640_CAMERA_RELEASE 0 +#define OV5640_CAMERA_VERSION \ + KERNEL_VERSION(OV5640_CAMERA_MAJOR_VERSION, \ + OV5640_CAMERA_MINOR_VERSION, \ + OV5640_CAMERA_RELEASE) + +MODULE_DESCRIPTION("ov5640 On Board"); +MODULE_AUTHOR("amlogic-sh"); +MODULE_LICENSE("GPL v2"); + +#define OV5640_DRIVER_VERSION "OV5640-COMMON-01-140717" + +static unsigned int video_nr = -1; + +static unsigned int debug; + +static unsigned int vid_limit = 32; + +static int ov5640_have_opened; + +static void do_download(struct work_struct *work); +static DECLARE_DELAYED_WORK(dl_work, do_download); + +static struct vdin_v4l2_ops_s *vops; + +static bool bDoingAutoFocusMode; +static int temp_frame = -1; +static struct v4l2_fract ov5640_frmintervals_active = { + .numerator = 1, + .denominator = 15, +}; + +static struct v4l2_frmivalenum ov5640_frmivalenum[] = { + { + .index = 0, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 640, + .height = 480, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 30, + } + } + }, { + .index = 0, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 1024, + .height = 768, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 30, + } + } + }, { + .index = 0, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 1280, + .height = 720, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 30, + } + } + }, { + .index = 0, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 1920, + .height = 1080, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 30, + } + } + }, { + .index = 1, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 1600, + .height = 1200, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 5, + } + } + }, { + .index = 1, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 2048, + .height = 1536, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 5, + } + } + }, { + .index = 1, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 2592, + .height = 1944, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 5, + } + } + }, +}; + +static struct v4l2_queryctrl ov5640_qctrl[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0x10, + .maximum = 0x60, + .step = 0xa, + .default_value = 0x30, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "flip on horizontal", + .minimum = 0, + .maximum = 1, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "flip on vertical", + .minimum = 0, + .maximum = 1, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "white balance", + .minimum = 0, + .maximum = 6, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "exposure", + .minimum = 0, + .maximum = 8, + .step = 0x1, + .default_value = 4, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_COLORFX, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "effect", + .minimum = 0, + .maximum = 6, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_WHITENESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "banding", + .minimum = 0, + .maximum = 1, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_FOCUS_AUTO, + .type = V4L2_CTRL_TYPE_MENU, + .name = "auto focus", + .minimum = CAM_FOCUS_MODE_RELEASE, + .maximum = CAM_FOCUS_MODE_CONTI_PIC, + .step = 0x1, + .default_value = CAM_FOCUS_MODE_CONTI_PIC, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_BACKLIGHT_COMPENSATION, + .type = V4L2_CTRL_TYPE_MENU, + .name = "flash", + .minimum = FLASHLIGHT_ON, + .maximum = FLASHLIGHT_TORCH, + .step = 0x1, + .default_value = FLASHLIGHT_OFF, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Zoom, Absolute", + .minimum = 100, + .maximum = 300, + .step = 20, + .default_value = 100, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_ROTATE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Rotate", + .minimum = 0, + .maximum = 270, + .step = 90, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_AUTO_FOCUS_STATUS, + .type = 8, + .name = "focus status", + .minimum = 0, + .maximum = ~3, + .step = 0x1, + .default_value = V4L2_AUTO_FOCUS_STATUS_IDLE, + .flags = V4L2_CTRL_FLAG_READ_ONLY, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "focus center", + .minimum = 0, + .maximum = ((2000) << 16) | 2000, + .step = 1, + .default_value = (1000 << 16) | 1000, + .flags = V4L2_CTRL_FLAG_SLIDER, + } +}; + +struct v4l2_querymenu ov5640_qmenu_autofocus[] = { + { + .id = V4L2_CID_FOCUS_AUTO, + .index = CAM_FOCUS_MODE_INFINITY, + .name = "infinity", + .reserved = 0, + }, { + .id = V4L2_CID_FOCUS_AUTO, + .index = CAM_FOCUS_MODE_AUTO, + .name = "auto", + .reserved = 0, + }, { + .id = V4L2_CID_FOCUS_AUTO, + .index = CAM_FOCUS_MODE_CONTI_VID, + .name = "continuous-video", + .reserved = 0, + }, { + .id = V4L2_CID_FOCUS_AUTO, + .index = CAM_FOCUS_MODE_CONTI_PIC, + .name = "continuous-picture", + .reserved = 0, + } +}; + +struct v4l2_querymenu ov5640_qmenu_flashmode[] = { + { + .id = V4L2_CID_BACKLIGHT_COMPENSATION, + .index = FLASHLIGHT_ON, + .name = "on", + .reserved = 0, + }, { + .id = V4L2_CID_BACKLIGHT_COMPENSATION, + .index = FLASHLIGHT_OFF, + .name = "off", + .reserved = 0, + }, { + .id = V4L2_CID_BACKLIGHT_COMPENSATION, + .index = FLASHLIGHT_TORCH, + .name = "torch", + .reserved = 0, + } +}; + +struct v4l2_querymenu ov5640_qmenu_wbmode[] = { + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_AUTO, + .name = "auto", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_CLOUD, + .name = "cloudy-daylight", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_INCANDESCENCE, + .name = "incandescent", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_DAYLIGHT, + .name = "daylight", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_FLUORESCENT, + .name = "fluorescent", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_FLUORESCENT, + .name = "warm-fluorescent", + .reserved = 0, + }, +}; + +struct ov5640_qmenu_s { + __u32 id; + int num; + struct v4l2_querymenu *ov5640_qmenu; +}; + +struct ov5640_qmenu_s ov5640_qmenu_set[] = { + { + .id = V4L2_CID_FOCUS_AUTO, + .num = ARRAY_SIZE(ov5640_qmenu_autofocus), + .ov5640_qmenu = ov5640_qmenu_autofocus, + }, { + .id = V4L2_CID_BACKLIGHT_COMPENSATION, + .num = ARRAY_SIZE(ov5640_qmenu_flashmode), + .ov5640_qmenu = ov5640_qmenu_flashmode, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .num = ARRAY_SIZE(ov5640_qmenu_wbmode), + .ov5640_qmenu = ov5640_qmenu_wbmode, + } +}; + +#define dprintk(dev, level, fmt, arg...) \ + v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) + + +struct ov5640_fmt { + char *name; + u32 fourcc; + int depth; +}; + +static struct ov5640_fmt formats[] = { + { + .name = "RGB565 (BE)", + .fourcc = V4L2_PIX_FMT_RGB565X, + .depth = 16, + }, { + .name = "RGB888 (24)", + .fourcc = V4L2_PIX_FMT_RGB24, + .depth = 24, + }, { + .name = "BGR888 (24)", + .fourcc = V4L2_PIX_FMT_BGR24, + .depth = 24, + }, { + .name = "12 Y/CbCr 4:2:0SP", + .fourcc = V4L2_PIX_FMT_NV12, + .depth = 12, + }, { + .name = "12 Y/CbCr 4:2:0SP", + .fourcc = V4L2_PIX_FMT_NV21, + .depth = 12, + }, { + .name = "YUV420P", + .fourcc = V4L2_PIX_FMT_YUV420, + .depth = 12, + }, { + .name = "YVU420P", + .fourcc = V4L2_PIX_FMT_YVU420, + .depth = 12, + } +}; + +static struct ov5640_fmt *get_format(struct v4l2_format *f) +{ + struct ov5640_fmt *fmt; + unsigned int k; + + for (k = 0; k < ARRAY_SIZE(formats); k++) { + fmt = &formats[k]; + if (fmt->fourcc == f->fmt.pix.pixelformat) + break; + } + + if (k == ARRAY_SIZE(formats)) + return NULL; + + return &formats[k]; +} + +struct sg_to_addr { + int pos; + struct scatterlist *sg; +}; + + +struct ov5640_buffer { + struct videobuf_buffer vb; + struct ov5640_fmt *fmt; + unsigned int canvas_id; +}; + +struct ov5640_dmaqueue { + struct list_head active; + struct task_struct *kthread; + wait_queue_head_t wq; + int frame; + int ini_jiffies; +}; + +struct resolution_param { + struct v4l2_frmsize_discrete frmsize; + struct v4l2_frmsize_discrete active_frmsize; + int active_fps; + int lanes; + int bps; + enum resolution_size size_type; + struct aml_camera_i2c_fig_s *reg_script; +}; + +static LIST_HEAD(ov5640_devicelist); + +struct ov5640_device { + struct list_head ov5640_devicelist; + struct v4l2_subdev sd; + struct v4l2_device v4l2_dev; + + spinlock_t slock; + struct mutex mutex; + + int users; + + struct video_device *vdev; + + struct ov5640_dmaqueue vidq; + + unsigned long jiffies; + + int input; + + struct aml_cam_info_s cam_info; + + int qctl_regs[ARRAY_SIZE(ov5640_qctrl)]; + + struct resolution_param *cur_resolution_param; + +#ifdef CONFIG_HAS_WAKELOCK + struct wake_lock wake_lock; +#endif + + struct work_struct dl_work; + + int firmware_ready; + + struct vm_init_s vminfo; +}; + +static DEFINE_MUTEX(firmware_mutex); + +static inline struct ov5640_device *to_dev(struct v4l2_subdev *sd) +{ + return container_of(sd, struct ov5640_device, sd); +} + +struct ov5640_fh { + struct ov5640_device *dev; + + struct ov5640_fmt *fmt; + unsigned int width, height; + struct videobuf_queue vb_vidq; + + struct videobuf_res_privdata res; + + enum v4l2_buf_type type; + int input; + int stream_on; + unsigned int f_flags; +}; + +static struct aml_camera_i2c_fig_s OV5640_script[] = { + {0xffff, 0xff} +}; + +static struct aml_camera_i2c_fig_s OV5640_preview_720P_script[] = { + {0x3103, 0x11}, + {0x3008, 0x82}, + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0x00}, + {0x3018, 0x00}, + {0x3034, 0x18}, + {0x3035, 0x11}, + {0x3036, 0x54}, + {0x3037, 0x13}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x07}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0xfa}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x06}, + {0x3807, 0xa9}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x02}, + {0x380b, 0xd0}, + {0x380c, 0x07}, + {0x380d, 0x64}, + {0x380e, 0x02}, + {0x380f, 0xe4}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x04}, + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3708, 0x66}, + {0x3709, 0x12}, + {0x370c, 0x03}, + {0x3a02, 0x02}, + {0x3a03, 0xe4}, + {0x3a08, 0x01}, + {0x3a09, 0xbc}, + {0x3a0a, 0x01}, + {0x3a0b, 0x72}, + {0x3a0e, 0x01}, + {0x3a0d, 0x02}, + {0x3a14, 0x02}, + {0x3a15, 0xe4}, + {0x4001, 0x02}, + {0x4004, 0x02}, + {0x4050, 0x6e}, + {0x4051, 0x8f}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x45}, + {0x302e, 0x08}, + {0x4300, 0x32}, + {0x501f, 0x00}, + {0x5684, 0x05}, + {0x5685, 0x20}, + {0x5686, 0x02}, + {0x5687, 0xd8}, + {0x4713, 0x02}, + {0x4407, 0x04}, + {0x440e, 0x00}, + {0x460b, 0x37}, + {0x460c, 0x20}, + {0x4827, 0x16}, + {0x3824, 0x04}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {0xffff, 0xff} +}; + +static struct aml_camera_i2c_fig_s OV5640_preview_1080P_script[] = { + {0x3103, 0x11}, + {0x3008, 0x82}, + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0x00}, + {0x3018, 0x00}, + {0x3034, 0x18}, + {0x3035, 0x11}, + {0x3036, 0x54}, + {0x3037, 0x13}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x07}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3800, 0x01}, + {0x3801, 0x50}, + {0x3802, 0x01}, + {0x3803, 0xb2}, + {0x3804, 0x08}, + {0x3805, 0xef}, + {0x3806, 0x05}, + {0x3807, 0xf1}, + {0x3808, 0x07}, + {0x3809, 0x80}, + {0x380a, 0x04}, + {0x380b, 0x38}, + {0x380c, 0x09}, + {0x380d, 0xc4}, + {0x380e, 0x04}, + {0x380f, 0x60}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3708, 0x63}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x04}, + {0x3a03, 0x60}, + {0x3a08, 0x01}, + {0x3a09, 0x50}, + {0x3a0a, 0x01}, + {0x3a0b, 0x18}, + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x04}, + {0x3a15, 0x60}, + {0x4001, 0x02}, + {0x4004, 0x06}, + {0x4050, 0x6e}, + {0x4051, 0x8f}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x45}, + {0x302e, 0x08}, + {0x4300, 0x32}, + {0x501f, 0x00}, + {0x5684, 0x07}, + {0x5685, 0xa0}, + {0x5686, 0x04}, + {0x5687, 0x40}, + {0x4713, 0x02}, + {0x4407, 0x04}, + {0x440e, 0x00}, + {0x460b, 0x37}, + {0x460c, 0x20}, + {0x4837, 0x0a}, + {0x3824, 0x04}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {0xffff, 0xff} +}; + +static struct aml_camera_i2c_fig_s OV5640_capture_5M_script[] = { + {0x3103, 0x11}, + {0x3008, 0x82}, + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0x00}, + {0x3018, 0x00}, + {0x3034, 0x18}, + {0x3035, 0x11}, + {0x3036, 0x54}, + {0x3037, 0x13}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x07}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9f}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3708, 0x63}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a08, 0x01}, + {0x3a09, 0x27}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4001, 0x02}, + {0x4004, 0x06}, + {0x4050, 0x6e}, + {0x4051, 0x8f}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x45}, + {0x302e, 0x08}, + {0x4300, 0x32}, + {0x4837, 0x0a}, + {0x501f, 0x00}, + {0x5684, 0x0a}, + {0x5685, 0x20}, + {0x5686, 0x07}, + {0x5687, 0x98}, + {0x440e, 0x00}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {0xffff, 0xff} +}; + +/*mipi lane bps : M*/ +static struct resolution_param prev_resolution_array[] = { + { + .frmsize = {1920, 1080}, + .active_frmsize = {1920, 1080}, + .active_fps = 30, + .lanes = 2, + .bps = 672, + .size_type = SIZE_1920X1080, + .reg_script = OV5640_preview_1080P_script, + }, { + .frmsize = {1280, 720}, + .active_frmsize = {1280, 720}, + .active_fps = 60, + .lanes = 2, + .bps = 672, + .size_type = SIZE_1280X720, + .reg_script = OV5640_preview_720P_script, + }, +}; + +static struct resolution_param capture_resolution_array[] = { + { + .frmsize = {2592, 1944}, + .active_frmsize = {2592, 1944}, + .active_fps = 15, + .lanes = 2, + .bps = 672, + .size_type = SIZE_2592X1944, + .reg_script = OV5640_capture_5M_script, + }, +}; + +int OV5640_download_firmware(struct ov5640_device *dev) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int i = 0; + + while (1 && ov5640_have_opened) { + if (OV5640_AF_firmware[i].val == 0xff && + OV5640_AF_firmware[i].addr == 0xffff) { + pr_info("download firmware success in initial OV5640.\n"); + break; + } + if ((i2c_put_byte(client, OV5640_AF_firmware[i].addr, + OV5640_AF_firmware[i].val)) < 0) { + pr_info("fail in download firmware OV5640. i=%d\n", i); + break; + } + i++; + } + return 0; +} + +static enum camera_focus_mode_e start_focus_mode = CAM_FOCUS_MODE_RELEASE; +static int OV5640_AutoFocus(struct ov5640_device *dev, int focus_mode); + +static void do_download(struct work_struct *work) +{ + struct ov5640_device *dev = + container_of(work, struct ov5640_device, dl_work); + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int ret; + int i = 10; + + mutex_lock(&firmware_mutex); + if (ov5640_have_opened) { + if (OV5640_download_firmware(dev) >= 0) { + while (i-- && ov5640_have_opened) { + ret = i2c_get_byte(client, 0x3029); + if (ret == 0x70) + break; + else if (ret == -1) + continue; + msleep(20); + } + } + } + dev->firmware_ready = 1; + mutex_unlock(&firmware_mutex); + if (start_focus_mode) { + OV5640_AutoFocus(dev, (int)start_focus_mode); + start_focus_mode = CAM_FOCUS_MODE_RELEASE; + } +} + +void OV5640_init_regs(struct ov5640_device *dev) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int i = 0; + + while (1) { + if (OV5640_script[i].val == 0xff && + OV5640_script[i].addr == 0xffff) { + pr_info("success in initial OV5640\n"); + break; + } + if ((i2c_put_byte(client, OV5640_script[i].addr, + OV5640_script[i].val)) < 0) { + pr_info("fail in initial OV5640\n"); + return; + } + i++; + } + +} + +static unsigned long ov5640_preview_exposure; +static unsigned long ov5640_preview_extra_lines; +static unsigned long ov5640_gain; +static unsigned long ov5640_preview_maxlines; + +static int Get_preview_exposure_gain(struct ov5640_device *dev) +{ + int rc = 0; + unsigned int ret_l, ret_m, ret_h; + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + ret_h = ret_m = ret_l = 0; + ret_h = i2c_get_byte(client, 0x350c); + ret_l = i2c_get_byte(client, 0x350d); + ov5640_preview_extra_lines = ((ret_h << 8) + ret_l); + i2c_put_byte(client, 0x3503, 0x07); + ret_h = ret_m = ret_l = 0; + ov5640_preview_exposure = 0; + ret_h = i2c_get_byte(client, 0x3500); + ret_m = i2c_get_byte(client, 0x3501); + ret_l = i2c_get_byte(client, 0x3502); + ov5640_preview_exposure = (ret_h << 12) + (ret_m << 4) + (ret_l >> 4); + ret_h = ret_m = ret_l = 0; + ov5640_preview_exposure = + ov5640_preview_exposure + (ov5640_preview_extra_lines) / 16; + ret_h = ret_m = ret_l = 0; + ov5640_preview_maxlines = 0; + ret_h = i2c_get_byte(client, 0x380e); + ret_l = i2c_get_byte(client, 0x380f); + ov5640_preview_maxlines = (ret_h << 8) + ret_l; + ov5640_gain = 0; + ov5640_gain = i2c_get_byte(client, 0x350b); + + return rc; +} + +static int cal_exposure(struct ov5640_device *dev, int pre_fps, int cap_fps) +{ + int rc = 0; + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + unsigned char ExposureLow, ExposureMid, ExposureHigh; + unsigned char Capture_MaxLines_High, Capture_MaxLines_Low; + unsigned int ret_l, ret_m, ret_h, Lines_10ms; + unsigned short ulCapture_Exposure, iCapture_Gain; + unsigned int ulCapture_Exposure_Gain, Capture_MaxLines; + + ret_h = ret_m = ret_l = 0; + ret_h = i2c_get_byte(client, 0x380e); + ret_l = i2c_get_byte(client, 0x380f); + Capture_MaxLines = (ret_h << 8) + ret_l; + Capture_MaxLines = Capture_MaxLines + (ov5640_preview_extra_lines) / 16; + dprintk(dev, 3, "Capture_MaxLines=%d\n", Capture_MaxLines); + if (ov5640_qctrl[7].default_value == CAM_BANDING_60HZ) + Lines_10ms = cap_fps * Capture_MaxLines / 12000; + else + Lines_10ms = cap_fps * Capture_MaxLines / 10000; + + if (ov5640_preview_maxlines == 0) + ov5640_preview_maxlines = 1; + + ulCapture_Exposure = + (ov5640_preview_exposure * (cap_fps) * (Capture_MaxLines)) / + (((ov5640_preview_maxlines) * (pre_fps))); + iCapture_Gain = ov5640_gain; + ulCapture_Exposure_Gain = ulCapture_Exposure * iCapture_Gain; + if (ulCapture_Exposure_Gain < Capture_MaxLines * 16) { + ulCapture_Exposure = ulCapture_Exposure_Gain / 16; + if (ulCapture_Exposure > Lines_10ms) { + ulCapture_Exposure /= Lines_10ms; + ulCapture_Exposure *= Lines_10ms; + } + } else { + ulCapture_Exposure = Capture_MaxLines; + } + if (ulCapture_Exposure == 0) + ulCapture_Exposure = 1; + + iCapture_Gain = (ulCapture_Exposure_Gain * 2 / + ulCapture_Exposure + 1) / 2; + ExposureLow = ((unsigned char)ulCapture_Exposure) << 4; + ExposureMid = (unsigned char)(ulCapture_Exposure >> 4) & 0xff; + ExposureHigh = (unsigned char)(ulCapture_Exposure >> 12); + Capture_MaxLines_Low = (unsigned char)(Capture_MaxLines & 0xff); + Capture_MaxLines_High = (unsigned char)(Capture_MaxLines >> 8); + i2c_put_byte(client, 0x380e, Capture_MaxLines_High); + i2c_put_byte(client, 0x380f, Capture_MaxLines_Low); + i2c_put_byte(client, 0x350b, iCapture_Gain); + i2c_put_byte(client, 0x3502, ExposureLow); + i2c_put_byte(client, 0x3501, ExposureMid); + i2c_put_byte(client, 0x3500, ExposureHigh); + dprintk(dev, 3, "iCapture_Gain=%d\n", iCapture_Gain); + dprintk(dev, 3, "ExposureLow=%d\n", ExposureLow); + dprintk(dev, 3, "ExposureMid=%d\n", ExposureMid); + dprintk(dev, 3, "ExposureHigh=%d\n", ExposureHigh); + + return rc; +} + +void OV5640_set_param_wb(struct ov5640_device *dev, + enum camera_wb_flip_e para) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + switch (para) { + case CAM_WB_AUTO: + i2c_put_byte(client, 0x3212, 0x03); + i2c_put_byte(client, 0x3406, 0x00); + i2c_put_byte(client, 0x3400, 0x04); + i2c_put_byte(client, 0x3401, 0x00); + i2c_put_byte(client, 0x3402, 0x04); + i2c_put_byte(client, 0x3403, 0x00); + i2c_put_byte(client, 0x3404, 0x04); + i2c_put_byte(client, 0x3405, 0x00); + i2c_put_byte(client, 0x3212, 0x13); + i2c_put_byte(client, 0x3212, 0xa3); + + break; + + case CAM_WB_CLOUD: + i2c_put_byte(client, 0x3212, 0x03); + i2c_put_byte(client, 0x3406, 0x01); + i2c_put_byte(client, 0x3400, 0x06); + i2c_put_byte(client, 0x3401, 0x48); + i2c_put_byte(client, 0x3402, 0x04); + i2c_put_byte(client, 0x3403, 0x00); + i2c_put_byte(client, 0x3404, 0x04); + i2c_put_byte(client, 0x3405, 0xd3); + i2c_put_byte(client, 0x3212, 0x13); + i2c_put_byte(client, 0x3212, 0xa3); + + break; + + case CAM_WB_DAYLIGHT: + i2c_put_byte(client, 0x3212, 0x03); + i2c_put_byte(client, 0x3406, 0x01); + i2c_put_byte(client, 0x3400, 0x06); + i2c_put_byte(client, 0x3401, 0x1c); + i2c_put_byte(client, 0x3402, 0x04); + i2c_put_byte(client, 0x3403, 0x00); + i2c_put_byte(client, 0x3404, 0x04); + i2c_put_byte(client, 0x3405, 0xf3); + i2c_put_byte(client, 0x3212, 0x13); + i2c_put_byte(client, 0x3212, 0xa3); + + break; + + case CAM_WB_INCANDESCENCE: + i2c_put_byte(client, 0x3212, 0x03); + i2c_put_byte(client, 0x3406, 0x01); + i2c_put_byte(client, 0x3400, 0x04); + i2c_put_byte(client, 0x3401, 0x10); + i2c_put_byte(client, 0x3402, 0x04); + i2c_put_byte(client, 0x3403, 0x00); + i2c_put_byte(client, 0x3404, 0x08); + i2c_put_byte(client, 0x3405, 0x40); + i2c_put_byte(client, 0x3212, 0x13); + i2c_put_byte(client, 0x3212, 0xa3); + + break; + + case CAM_WB_TUNGSTEN: + i2c_put_byte(client, 0x3212, 0x03); + i2c_put_byte(client, 0x3406, 0x01); + i2c_put_byte(client, 0x3400, 0x04); + i2c_put_byte(client, 0x3401, 0x10); + i2c_put_byte(client, 0x3402, 0x04); + i2c_put_byte(client, 0x3403, 0x00); + i2c_put_byte(client, 0x3404, 0x08); + i2c_put_byte(client, 0x3405, 0x40); + i2c_put_byte(client, 0x3212, 0x13); + i2c_put_byte(client, 0x3212, 0xa3); + + break; + + case CAM_WB_FLUORESCENT: + i2c_put_byte(client, 0x3212, 0x03); + i2c_put_byte(client, 0x3406, 0x01); + i2c_put_byte(client, 0x3400, 0x05); + i2c_put_byte(client, 0x3401, 0x48); + i2c_put_byte(client, 0x3402, 0x04); + i2c_put_byte(client, 0x3403, 0x00); + i2c_put_byte(client, 0x3404, 0x07); + i2c_put_byte(client, 0x3405, 0xcf); + i2c_put_byte(client, 0x3212, 0x13); + i2c_put_byte(client, 0x3212, 0xa3); + break; + + case CAM_WB_MANUAL: + break; + default: + break; + } +} + +void OV5640_set_param_exposure(struct ov5640_device *dev, + enum camera_exposure_e para) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + switch (para) { + case EXPOSURE_N4_STEP: + i2c_put_byte(client, 0x3a0f, 0x10); + i2c_put_byte(client, 0x3a10, 0x08); + i2c_put_byte(client, 0x3a1b, 0x10); + i2c_put_byte(client, 0x3a1e, 0x08); + i2c_put_byte(client, 0x3a11, 0x20); + i2c_put_byte(client, 0x3a1f, 0x10); + break; + + case EXPOSURE_N3_STEP: + i2c_put_byte(client, 0x3a0f, 0x18); + i2c_put_byte(client, 0x3a10, 0x10); + i2c_put_byte(client, 0x3a1b, 0x18); + i2c_put_byte(client, 0x3a1e, 0x10); + i2c_put_byte(client, 0x3a11, 0x30); + i2c_put_byte(client, 0x3a1f, 0x10); + break; + + case EXPOSURE_N2_STEP: + i2c_put_byte(client, 0x3a0f, 0x20); + i2c_put_byte(client, 0x3a10, 0x18); + i2c_put_byte(client, 0x3a11, 0x41); + i2c_put_byte(client, 0x3a1b, 0x20); + i2c_put_byte(client, 0x3a1e, 0x18); + i2c_put_byte(client, 0x3a1f, 0x10); + break; + + case EXPOSURE_N1_STEP: + i2c_put_byte(client, 0x3a0f, 0x28); + i2c_put_byte(client, 0x3a10, 0x20); + i2c_put_byte(client, 0x3a11, 0x51); + i2c_put_byte(client, 0x3a1b, 0x28); + i2c_put_byte(client, 0x3a1e, 0x20); + i2c_put_byte(client, 0x3a1f, 0x10); + break; + + case EXPOSURE_0_STEP: + i2c_put_byte(client, 0x3a0f, 0x38); + i2c_put_byte(client, 0x3a10, 0x30); + i2c_put_byte(client, 0x3a11, 0x61); + i2c_put_byte(client, 0x3a1b, 0x38); + i2c_put_byte(client, 0x3a1e, 0x30); + i2c_put_byte(client, 0x3a1f, 0x10); + break; + + case EXPOSURE_P1_STEP: + i2c_put_byte(client, 0x3a0f, 0x48); + i2c_put_byte(client, 0x3a10, 0x40); + i2c_put_byte(client, 0x3a11, 0x80); + i2c_put_byte(client, 0x3a1b, 0x48); + i2c_put_byte(client, 0x3a1e, 0x40); + i2c_put_byte(client, 0x3a1f, 0x20); + break; + + case EXPOSURE_P2_STEP: + i2c_put_byte(client, 0x3a0f, 0x50); + i2c_put_byte(client, 0x3a10, 0x48); + i2c_put_byte(client, 0x3a11, 0x90); + i2c_put_byte(client, 0x3a1b, 0x50); + i2c_put_byte(client, 0x3a1e, 0x48); + i2c_put_byte(client, 0x3a1f, 0x20); + break; + + case EXPOSURE_P3_STEP: + i2c_put_byte(client, 0x3a0f, 0x58); + i2c_put_byte(client, 0x3a10, 0x50); + i2c_put_byte(client, 0x3a11, 0x91); + i2c_put_byte(client, 0x3a1b, 0x58); + i2c_put_byte(client, 0x3a1e, 0x50); + i2c_put_byte(client, 0x3a1f, 0x20); + break; + + case EXPOSURE_P4_STEP: + i2c_put_byte(client, 0x3a0f, 0x60); + i2c_put_byte(client, 0x3a10, 0x58); + i2c_put_byte(client, 0x3a11, 0xa0); + i2c_put_byte(client, 0x3a1b, 0x60); + i2c_put_byte(client, 0x3a1e, 0x58); + i2c_put_byte(client, 0x3a1f, 0x20); + break; + + default: + i2c_put_byte(client, 0x3a0f, 0x38); + i2c_put_byte(client, 0x3a10, 0x30); + i2c_put_byte(client, 0x3a11, 0x61); + i2c_put_byte(client, 0x3a1b, 0x38); + i2c_put_byte(client, 0x3a1e, 0x30); + i2c_put_byte(client, 0x3a1f, 0x10); + break; + } +} + +void OV5640_set_param_effect(struct ov5640_device *dev, + enum camera_effect_flip_e para) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + switch (para) { + case CAM_EFFECT_ENC_NORMAL: + i2c_put_byte(client, 0x5001, 0x03); + break; + + case CAM_EFFECT_ENC_GRAYSCALE: + i2c_put_byte(client, 0x5001, 0x83); + i2c_put_byte(client, 0x5580, 0x20); + break; + + case CAM_EFFECT_ENC_SEPIA: + break; + + case CAM_EFFECT_ENC_SEPIAGREEN: + break; + + case CAM_EFFECT_ENC_SEPIABLUE: + break; + + case CAM_EFFECT_ENC_COLORINV: + i2c_put_byte(client, 0x5001, 0x83); + i2c_put_byte(client, 0x5580, 0x40); + break; + + default: + break; + } +} + +static void OV5640_set_param_banding(struct ov5640_device *dev, + enum camera_banding_flip_e banding) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + switch (banding) { + case CAM_BANDING_60HZ: + pr_info("set banding 60Hz\n"); + i2c_put_byte(client, 0x3c00, 0x00); + break; + case CAM_BANDING_50HZ: + pr_info("set banding 50Hz\n"); + i2c_put_byte(client, 0x3c00, 0x04); + break; + default: + break; + } +} + +static int OV5640_AutoFocus(struct ov5640_device *dev, int focus_mode) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int ret = 0; + + switch (focus_mode) { + case CAM_FOCUS_MODE_AUTO: + i2c_put_byte(client, 0x3023, 0x1); + i2c_put_byte(client, 0x3022, 0x3); + bDoingAutoFocusMode = true; + pr_info("auto mode start\n"); + break; + + case CAM_FOCUS_MODE_CONTI_VID: + case CAM_FOCUS_MODE_CONTI_PIC: + i2c_put_byte(client, 0x3022, 0x4); + i2c_put_byte(client, 0x3023, 0x1); + pr_info("start continuous focus\n"); + break; + + case CAM_FOCUS_MODE_RELEASE: + case CAM_FOCUS_MODE_FIXED: + default: + i2c_put_byte(client, 0x3023, 0x1); + i2c_put_byte(client, 0x3022, 0x8); + pr_info("release focus to infinit\n"); + break; + } + return ret; + +} + +static int OV5640_FlashCtrl(struct ov5640_device *dev, int flash_mode) +{ + int ret = 0; + + switch (flash_mode) { + case FLASHLIGHT_ON: + case FLASHLIGHT_AUTO: + if (dev->cam_info.torch_support) + aml_cam_torch(&dev->cam_info, 1); + aml_cam_flash(&dev->cam_info, 1); + break; + case FLASHLIGHT_TORCH: + if (dev->cam_info.torch_support) { + aml_cam_torch(&dev->cam_info, 1); + aml_cam_flash(&dev->cam_info, 0); + } else + aml_cam_torch(&dev->cam_info, 1); + break; + case FLASHLIGHT_OFF: + aml_cam_flash(&dev->cam_info, 0); + if (dev->cam_info.torch_support) + aml_cam_torch(&dev->cam_info, 0); + break; + default: + pr_info("this flash mode not support yet\n"); + break; + } + return ret; +} + +static enum resolution_size get_size_type(int width, int height) +{ + enum resolution_size rv = SIZE_NULL; + + if (width * height >= 2500 * 1900) + rv = SIZE_2592X1944; + else if (width * height >= 2000 * 1500) + rv = SIZE_2048X1536; + else if (width * height >= 1920 * 1080) + rv = SIZE_1920X1080; + else if (width * height >= 1600 * 1200) + rv = SIZE_1600X1200; + else if (width * height >= 1280 * 960) + rv = SIZE_1280X960; + else if (width * height >= 1280 * 720) + rv = SIZE_1280X720; + else if (width * height >= 1024 * 768) + rv = SIZE_1024X768; + else if (width * height >= 800 * 600) + rv = SIZE_800X600; + else if (width * height >= 600 * 400) + rv = SIZE_640X480; + else if (width * height >= 352 * 288) + rv = SIZE_352X288; + else if (width * height >= 300 * 200) + rv = SIZE_320X240; + else if (width * height >= 170 * 140) + rv = SIZE_176X144; + return rv; +} + +static int set_flip(struct ov5640_device *dev) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + unsigned char temp; + + temp = i2c_get_byte(client, 0x3821); + temp &= 0xf9; + temp |= dev->cam_info.m_flip << 1 | dev->cam_info.m_flip << 2; + if ((i2c_put_byte(client, 0x3821, temp)) < 0) { + pr_info("fail in setting sensor orientation\n"); + return -1; + } + temp = i2c_get_byte(client, 0x3820); + temp &= 0xf9; + temp |= dev->cam_info.v_flip << 1 | dev->cam_info.v_flip << 2; + if ((i2c_put_byte(client, 0x3820, temp)) < 0) { + pr_info("fail in setting sensor orientation\n"); + return -1; + } + + return 0; +} + +static struct resolution_param *get_resolution_param( + struct ov5640_device *dev, + int is_capture, int width, int height) +{ + int i = 0; + int arry_size = 0; + struct resolution_param *tmp_resolution_param = NULL; + enum resolution_size res_type = SIZE_NULL; + + res_type = get_size_type(width, height); + if (res_type == SIZE_NULL) + return NULL; + if (is_capture) { + tmp_resolution_param = capture_resolution_array; + arry_size = sizeof(capture_resolution_array)/ + sizeof(capture_resolution_array[0]); + } else { + tmp_resolution_param = prev_resolution_array; + arry_size = sizeof(prev_resolution_array)/ + sizeof(prev_resolution_array[0]); + ov5640_frmintervals_active.denominator = 23; + ov5640_frmintervals_active.numerator = 1; + } + + for (i = 0; i < arry_size; i++) { + if (tmp_resolution_param[i].size_type == res_type) { + ov5640_frmintervals_active.denominator = + tmp_resolution_param[i].active_fps; + ov5640_frmintervals_active.numerator = 1; + return &tmp_resolution_param[i]; + } + } + return NULL; +} + +static int set_resolution_param(struct ov5640_device *dev, + struct resolution_param *res_param) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int i = 0; + + if (!res_param->reg_script) { + pr_info("error, resolution reg script is NULL\n"); + return -1; + } + + pr_info("res_para->size_type = %d, res_param->frmsize.width = %d, height = %d\n", + res_param->size_type, res_param->frmsize.width, + res_param->frmsize.height); + + while (1) { + if (res_param->reg_script[i].val == 0xff && + res_param->reg_script[i].addr == 0xffff) { + pr_info("setting resolutin param complete\n"); + break; + } + if ((i2c_put_byte(client, res_param->reg_script[i].addr, + res_param->reg_script[i].val)) < 0) { + pr_info("fail in setting resolution param.i=%d\n", i); + break; + } + i++; + } + dev->cur_resolution_param = res_param; + set_flip(dev); + + return 0; +} + +static int set_focus_zone(struct ov5640_device *dev, int value) +{ + int xc, yc; + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int retry_count = 10; + int ret = -1; + + xc = ((value >> 16) & 0xffff) * 80 / 2000; + yc = (value & 0xffff) * 60 / 2000; + pr_info("xc = %d, yc = %d\n", xc, yc); + i2c_put_byte(client, CMD_PARA0, xc); + i2c_put_byte(client, CMD_PARA1, yc); + i2c_put_byte(client, CMD_ACK, 0x01); + i2c_put_byte(client, CMD_MAIN, 0x81); + + do { + msleep(20); + pr_info("waiting for focus zone to be set\n"); + } while (i2c_get_byte(client, CMD_ACK) && retry_count--); + + if (retry_count) + ret = 0; + return ret; +} + +unsigned char v4l_2_ov5640(int val) +{ + int ret = val / 0x20; + + if (ret < 4) + return ret * 0x20 + 0x80; + else if (ret < 8) + return ret * 0x20 + 0x20; + else + return 0; +} + +static int convert_canvas_index(unsigned int v4l2_format, + unsigned int start_canvas) +{ + int canvas = start_canvas; + + switch (v4l2_format) { + case V4L2_PIX_FMT_RGB565X: + case V4L2_PIX_FMT_VYUY: + canvas = start_canvas; + break; + case V4L2_PIX_FMT_YUV444: + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + canvas = start_canvas; + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + canvas = start_canvas | ((start_canvas+1)<<8); + break; + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YUV420: + if (v4l2_format == V4L2_PIX_FMT_YUV420) + canvas = + start_canvas | + ((start_canvas + 1) << 8) | + ((start_canvas + 2) << 16); + else + canvas = + start_canvas | + ((start_canvas + 2) << 8) | + ((start_canvas + 1) << 16); + break; + default: + break; + } + return canvas; +} + +static int ov5640_setting(struct ov5640_device *dev, int PROP_ID, int value) +{ + int ret = 0; + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + switch (PROP_ID) { + case V4L2_CID_BRIGHTNESS: + mutex_lock(&firmware_mutex); + dprintk(dev, 1, "setting brightned:%d\n", v4l_2_ov5640(value)); + ret = i2c_put_byte(client, 0x0201, v4l_2_ov5640(value)); + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_CONTRAST: + mutex_lock(&firmware_mutex); + ret = i2c_put_byte(client, 0x0200, value); + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_SATURATION: + mutex_lock(&firmware_mutex); + ret = i2c_put_byte(client, 0x0202, value); + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_HFLIP: + value = value & 0x3; + if (ov5640_qctrl[2].default_value != value) { + ov5640_qctrl[2].default_value = value; + dprintk(dev, 3, "set camera h filp =%d\n", value); + } + break; + case V4L2_CID_VFLIP: + break; + case V4L2_CID_DO_WHITE_BALANCE: + mutex_lock(&firmware_mutex); + if (ov5640_qctrl[4].default_value != value) { + ov5640_qctrl[4].default_value = value; + OV5640_set_param_wb(dev, value); + dprintk(dev, 3, "set camera white_balance=%d\n", value); + } + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_EXPOSURE: + mutex_lock(&firmware_mutex); + if (ov5640_qctrl[5].default_value != value) { + ov5640_qctrl[5].default_value = value; + OV5640_set_param_exposure(dev, value); + dprintk(dev, 3, "set camera exposure=%d\n", value); + } + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_COLORFX: + mutex_lock(&firmware_mutex); + if (ov5640_qctrl[6].default_value != value) { + ov5640_qctrl[6].default_value = value; + OV5640_set_param_effect(dev, value); + dprintk(dev, 3, "set camera effect=%d\n", value); + } + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_WHITENESS: + mutex_lock(&firmware_mutex); + if (ov5640_qctrl[7].default_value != value) { + ov5640_qctrl[7].default_value = value; + OV5640_set_param_banding(dev, value); + dprintk(dev, 3, "set camera banding=%d\n", value); + } + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_FOCUS_AUTO: + mutex_lock(&firmware_mutex); + if (ov5640_have_opened) { + if (dev->firmware_ready) + ret = OV5640_AutoFocus(dev, value); + else if (value == CAM_FOCUS_MODE_CONTI_VID || + value == CAM_FOCUS_MODE_CONTI_PIC) + start_focus_mode = value; + else + ret = -1; + } + mutex_unlock(&firmware_mutex); + break; + case V4L2_CID_BACKLIGHT_COMPENSATION: + if (dev->cam_info.flash_support) + ret = OV5640_FlashCtrl(dev, value); + else + ret = -1; + break; + case V4L2_CID_ZOOM_ABSOLUTE: + if (ov5640_qctrl[10].default_value != value) + ov5640_qctrl[10].default_value = value; + break; + case V4L2_CID_ROTATE: + if (ov5640_qctrl[11].default_value != value) { + ov5640_qctrl[11].default_value = value; + dprintk(dev, 3, "set camera rotate =%d\n", value); + } + break; + case V4L2_CID_FOCUS_ABSOLUTE: + if (ov5640_qctrl[12].default_value != value) { + ov5640_qctrl[12].default_value = value; + dprintk(dev, 3, "set camera focus zone =%d\n", value); + set_focus_zone(dev, value); + } + break; + default: + ret = -1; + break; + } + return ret; + +} + +static void power_down_ov5640(struct ov5640_device *dev) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + i2c_put_byte(client, 0x3022, 0x8); + i2c_put_byte(client, 0x3008, 0x42); +} + + +#define TSTAMP_MIN_Y 24 +#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15) +#define TSTAMP_INPUT_X 10 +#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) + +static void ov5640_fillbuff(struct ov5640_fh *fh, struct ov5640_buffer *buf) +{ + int ret; + struct ov5640_device *dev = fh->dev; + void *vbuf = (void *)videobuf_to_res(&buf->vb); + struct vm_output_para para = {0}; + + dprintk(dev, 1, "%s\n", __func__); + if (!vbuf) + return; + + if (buf->canvas_id == 0) + buf->canvas_id = convert_canvas_index(fh->fmt->fourcc, + OV5640_RES0_CANVAS_INDEX + buf->vb.i * 3); + + para.mirror = ov5640_qctrl[2].default_value & 3; + para.v4l2_format = fh->fmt->fourcc; + para.v4l2_memory = MAGIC_RE_MEM; + para.zoom = ov5640_qctrl[10].default_value; + para.angle = ov5640_qctrl[11].default_value; + para.vaddr = (uintptr_t)vbuf; + para.ext_canvas = 0; + para.width = buf->vb.width; + para.height = + (buf->vb.height == 1080) ? 1088 : buf->vb.height; + dev->vminfo.vdin_id = dev->cam_info.vdin_path; + ret = vm_fill_this_buffer(&buf->vb, ¶, &dev->vminfo); + if (ret == -2) + msleep(40); + buf->vb.state = VIDEOBUF_DONE; +} + +static void ov5640_thread_tick(struct ov5640_fh *fh) +{ + struct ov5640_buffer *buf; + struct ov5640_device *dev = fh->dev; + struct ov5640_dmaqueue *dma_q = &dev->vidq; + + unsigned long flags = 0; + + dprintk(dev, 1, "Thread tick\n"); + if (!fh->stream_on) { + dprintk(dev, 1, "sensor doesn't stream on\n"); + return; + } + + spin_lock_irqsave(&dev->slock, flags); + if (list_empty(&dma_q->active)) { + dprintk(dev, 1, "No active queue to serve\n"); + goto unlock; + } + + buf = list_entry(dma_q->active.next, + struct ov5640_buffer, vb.queue); + dprintk(dev, 1, "%s\n", __func__); + dprintk(dev, 1, "list entry get buf is %p\n", buf); + + if (!(fh->f_flags & O_NONBLOCK)) { + /* Nobody is waiting on this buffer, return */ + if (!waitqueue_active(&buf->vb.done)) + goto unlock; + } + buf->vb.state = VIDEOBUF_ACTIVE; + + list_del(&buf->vb.queue); + + do_gettimeofday(&buf->vb.ts); + + spin_unlock_irqrestore(&dev->slock, flags); + ov5640_fillbuff(fh, buf); + dprintk(dev, 1, "filled buffer %p\n", buf); + + wake_up(&buf->vb.done); + dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); + return; +unlock: + spin_unlock_irqrestore(&dev->slock, flags); +} + +static void ov5640_sleep(struct ov5640_fh *fh) +{ + struct ov5640_device *dev = fh->dev; + struct ov5640_dmaqueue *dma_q = &dev->vidq; + + DECLARE_WAITQUEUE(wait, current); + + dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__, + (unsigned long)dma_q); + + add_wait_queue(&dma_q->wq, &wait); + if (kthread_should_stop()) + goto stop_task; + + ov5640_thread_tick(fh); + + schedule_timeout_interruptible(1); + +stop_task: + remove_wait_queue(&dma_q->wq, &wait); + try_to_freeze(); +} + +static int ov5640_thread(void *data) +{ + struct ov5640_fh *fh = data; + struct ov5640_device *dev = fh->dev; + + dprintk(dev, 1, "thread started\n"); + + set_freezable(); + + for (;;) { + ov5640_sleep(fh); + + if (kthread_should_stop()) + break; + } + dprintk(dev, 1, "thread: exit\n"); + return 0; +} + +static int ov5640_start_thread(struct ov5640_fh *fh) +{ + struct ov5640_device *dev = fh->dev; + struct ov5640_dmaqueue *dma_q = &dev->vidq; + + dma_q->frame = 0; + dma_q->ini_jiffies = jiffies; + + dprintk(dev, 1, "%s\n", __func__); + + dma_q->kthread = kthread_run(ov5640_thread, fh, "ov5640"); + + if (IS_ERR(dma_q->kthread)) { + v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); + return PTR_ERR(dma_q->kthread); + } + + wake_up_interruptible(&dma_q->wq); + + dprintk(dev, 1, "returning from %s\n", __func__); + return 0; +} + +static void ov5640_stop_thread(struct ov5640_dmaqueue *dma_q) +{ + struct ov5640_device *dev = + container_of(dma_q, struct ov5640_device, vidq); + + dprintk(dev, 1, "%s\n", __func__); + + if (dma_q->kthread) { + kthread_stop(dma_q->kthread); + dma_q->kthread = NULL; + } +} + +static int +buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) +{ + struct videobuf_res_privdata *res = vq->priv_data; + struct ov5640_fh *fh = container_of(res, struct ov5640_fh, res); + struct ov5640_device *dev = fh->dev; + int height = fh->height; + + if (height == 1080) + height = 1088; + *size = (fh->width * height * fh->fmt->depth) >> 3; + if (*count == 0) + *count = 32; + + while (*size * *count > vid_limit * 1024 * 1024) + (*count)--; + + dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, + *count, *size); + + return 0; +} + +static void free_buffer(struct videobuf_queue *vq, struct ov5640_buffer *buf) +{ + struct videobuf_res_privdata *res = vq->priv_data; + struct ov5640_fh *fh = container_of(res, struct ov5640_fh, res); + struct ov5640_device *dev = fh->dev; + + dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); + videobuf_waiton(vq, &buf->vb, 0, 0); + + if (in_interrupt()) + WARN_ON(1); + + videobuf_res_free(vq, &buf->vb); + dprintk(dev, 1, "free_buffer: freed\n"); + buf->vb.state = VIDEOBUF_NEEDS_INIT; +} + +#define norm_maxw() 3000 +#define norm_maxh() 3000 +static int +buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct videobuf_res_privdata *res = vq->priv_data; + struct ov5640_fh *fh = container_of(res, struct ov5640_fh, res); + struct ov5640_device *dev = fh->dev; + struct ov5640_buffer *buf = container_of(vb, struct ov5640_buffer, vb); + int rc; + + dprintk(dev, 1, "%s, field=%d\n", __func__, field); + + WARN_ON(fh->fmt == NULL); + + if (fh->width < 48 || fh->width > norm_maxw() || + fh->height < 32 || fh->height > norm_maxh()) + return -EINVAL; + + buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; + if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) + return -EINVAL; + + buf->fmt = fh->fmt; + buf->vb.width = fh->width; + buf->vb.height = fh->height; + buf->vb.field = field; + + if (buf->vb.state == VIDEOBUF_NEEDS_INIT) { + rc = videobuf_iolock(vq, &buf->vb, NULL); + if (rc < 0) + goto fail; + } + + buf->vb.state = VIDEOBUF_PREPARED; + + return 0; + +fail: + free_buffer(vq, buf); + return rc; +} + +static void +buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +{ + struct ov5640_buffer *buf = + container_of(vb, struct ov5640_buffer, vb); + struct videobuf_res_privdata *res = vq->priv_data; + struct ov5640_fh *fh = container_of(res, struct ov5640_fh, res); + struct ov5640_device *dev = fh->dev; + struct ov5640_dmaqueue *vidq = &dev->vidq; + + dprintk(dev, 1, "%s\n", __func__); + buf->vb.state = VIDEOBUF_QUEUED; + list_add_tail(&buf->vb.queue, &vidq->active); +} + +static void buffer_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct ov5640_buffer *buf = + container_of(vb, struct ov5640_buffer, vb); + struct videobuf_res_privdata *res = vq->priv_data; + struct ov5640_fh *fh = container_of(res, struct ov5640_fh, res); + struct ov5640_device *dev = (struct ov5640_device *)fh->dev; + + dprintk(dev, 1, "%s\n", __func__); + + free_buffer(vq, buf); +} + +static struct videobuf_queue_ops ov5640_video_qops = { + .buf_setup = buffer_setup, + .buf_prepare = buffer_prepare, + .buf_queue = buffer_queue, + .buf_release = buffer_release, +}; + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + + strcpy(cap->driver, "ov5640"); + strcpy(cap->card, "ov5640.canvas"); + if (dev->cam_info.front_back == 0) + strcat(cap->card, "back"); + else + strcat(cap->card, "front"); + + strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); + cap->version = OV5640_CAMERA_VERSION; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING + | V4L2_CAP_READWRITE; + + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; +} + +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct ov5640_fmt *fmt; + + if (f->index >= ARRAY_SIZE(formats)) + return -EINVAL; + + fmt = &formats[f->index]; + + strlcpy(f->description, fmt->name, sizeof(f->description)); + f->pixelformat = fmt->fourcc; + return 0; +} + +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct ov5640_fh *fh = priv; + + pr_info("%s, fh->width =%d,fh->height=%d\n", + __func__, fh->width, fh->height); + f->fmt.pix.width = fh->width; + f->fmt.pix.height = fh->height; + f->fmt.pix.field = fh->vb_vidq.field; + f->fmt.pix.pixelformat = fh->fmt->fourcc; + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fh->fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + + return 0; +} + +static int vidioc_enum_frameintervals(struct file *file, void *priv, + struct v4l2_frmivalenum *fival) +{ + unsigned int k; + + if (fival->index > ARRAY_SIZE(ov5640_frmivalenum)) + return -EINVAL; + + for (k = 0; k < ARRAY_SIZE(ov5640_frmivalenum); k++) { + if ((fival->index == ov5640_frmivalenum[k].index) && + (fival->pixel_format == + ov5640_frmivalenum[k].pixel_format) && + (fival->width == ov5640_frmivalenum[k].width) && + (fival->height == ov5640_frmivalenum[k].height)) { + memcpy(fival, &ov5640_frmivalenum[k], + sizeof(struct v4l2_frmivalenum)); + return 0; + } + } + + return -EINVAL; +} + +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + struct ov5640_fmt *fmt; + enum v4l2_field field; + unsigned int maxw, maxh; + + fmt = get_format(f); + if (!fmt) { + dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n", + f->fmt.pix.pixelformat); + return -EINVAL; + } + + field = f->fmt.pix.field; + + if (field == V4L2_FIELD_ANY) { + field = V4L2_FIELD_INTERLACED; + } else if (field != V4L2_FIELD_INTERLACED) { + dprintk(dev, 1, "Field type invalid.\n"); + return -EINVAL; + } + + maxw = norm_maxw(); + maxh = norm_maxh(); + + f->fmt.pix.field = field; + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + + return 0; +} + +static struct resolution_param *prev_res; + +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct ov5640_fh *fh = priv; + struct videobuf_queue *q = &fh->vb_vidq; + struct ov5640_device *dev = fh->dev; + struct resolution_param *res_param = NULL; + int ret; + int cap_fps, pre_fps; + + f->fmt.pix.width = (f->fmt.pix.width + (CANVAS_WIDTH_ALIGN - 1)) & + (~(CANVAS_WIDTH_ALIGN - 1)); + if ((f->fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) || + (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)) { + f->fmt.pix.width = + (f->fmt.pix.width + (CANVAS_WIDTH_ALIGN * 2 - 1)) & + (~(CANVAS_WIDTH_ALIGN * 2 - 1)); + } + ret = vidioc_try_fmt_vid_cap(file, fh, f); + if (ret < 0) + return ret; + + mutex_lock(&q->vb_lock); + + if (videobuf_queue_is_busy(&fh->vb_vidq)) { + dprintk(fh->dev, 1, "%s queue busy\n", __func__); + ret = -EBUSY; + goto out; + } + + fh->fmt = get_format(f); + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; + fh->vb_vidq.field = f->fmt.pix.field; + fh->type = f->type; + dprintk(dev, 3, + "system aquire ...fh->height=%d, fh->width= %d\n", + fh->height, fh->width); + + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) { + res_param = get_resolution_param(dev, 1, fh->width, fh->height); + if (!res_param) { + pr_err("error, resolution param not get\n"); + goto out; + } + + Get_preview_exposure_gain(dev); + set_resolution_param(dev, res_param); + + if (prev_res && (prev_res->size_type == SIZE_1280X960 + || prev_res->size_type == SIZE_1024X768)) { + pre_fps = 1500; + } else if (prev_res && prev_res->size_type == SIZE_1280X720) { + pre_fps = 3000; + } else { + pre_fps = 1500; + } + cap_fps = 500; + cal_exposure(dev, pre_fps, cap_fps); + dprintk(dev, 3, "pre_fps=%d,cap_fps=%d\n", pre_fps, cap_fps); + } else { + res_param = get_resolution_param(dev, 0, fh->width, fh->height); + if (!res_param) { + pr_err("error, resolution param not get\n"); + goto out; + } + set_resolution_param(dev, res_param); + prev_res = res_param; + } + + ret = 0; +out: + mutex_unlock(&q->vb_lock); + + return ret; +} + +static int vidioc_g_parm(struct file *file, void *priv, + struct v4l2_streamparm *parms) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + struct v4l2_captureparm *cp = &parms->parm.capture; + + dprintk(dev, 3, "vidioc_g_parm\n"); + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(cp, 0, sizeof(struct v4l2_captureparm)); + cp->capability = V4L2_CAP_TIMEPERFRAME; + + cp->timeperframe = ov5640_frmintervals_active; + pr_info("g_parm,deno=%d, numerator=%d\n", cp->timeperframe.denominator, + cp->timeperframe.numerator); + return 0; +} + +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct ov5640_fh *fh = priv; + + return videobuf_reqbufs(&fh->vb_vidq, p); +} + +static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct ov5640_fh *fh = priv; + int ret = videobuf_querybuf(&fh->vb_vidq, p); + + if (get_cpu_type() == MESON_CPU_MAJOR_ID_M8) { + if (ret == 0) { + p->reserved = + convert_canvas_index(fh->fmt->fourcc, + OV5640_RES0_CANVAS_INDEX + p->index * 3); + } else { + p->reserved = 0; + } + } + + return ret; +} + +static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct ov5640_fh *fh = priv; + + return videobuf_qbuf(&fh->vb_vidq, p); +} + +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct ov5640_fh *fh = priv; + + return (videobuf_dqbuf(&fh->vb_vidq, p, + file->f_flags & O_NONBLOCK)); +} + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) +{ + struct ov5640_fh *fh = priv; + + return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); +} +#endif + +static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + struct vdin_parm_s para; + unsigned int vdin_path; + int ret = 0; + + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (i != fh->type) + return -EINVAL; + + memset(¶, 0, sizeof(para)); + para.port = TVIN_PORT_MIPI; + para.fmt = TVIN_SIG_FMT_MAX; + if (fh->dev->cur_resolution_param) { + para.frame_rate = + ov5640_frmintervals_active.denominator; + para.h_active = + fh->dev->cur_resolution_param->active_frmsize.width; + para.v_active = + fh->dev->cur_resolution_param->active_frmsize.height; + para.hs_bp = 0; + para.vs_bp = 2; + para.scan_mode = TVIN_SCAN_MODE_PROGRESSIVE; + } else + pr_info("error, cur_resolution_param is NULL\n"); + + vdin_path = fh->dev->cam_info.vdin_path; + + pr_info("%s: h_active=%d; v_active=%d, frame_rate=%d,vdin_path=%d\n", + __func__, para.h_active, para.v_active, + para.frame_rate, vdin_path); + if (temp_frame < 0) { + temp_frame = para.frame_rate; + para.skip_count = 2; + } else { + temp_frame = para.frame_rate; + para.skip_count = 5; + } + para.cfmt = TVIN_YUV422; + para.dfmt = TVIN_NV21; + para.hsync_phase = 1; + para.vsync_phase = 1; + para.bt_path = dev->cam_info.bt_path; + /*config mipi parameter*/ + para.csi_hw_info.settle = fh->dev->cur_resolution_param->bps; + para.csi_hw_info.lanes = fh->dev->cur_resolution_param->lanes; + + pr_info("ov5640 stream on.\n"); + ret = videobuf_streamon(&fh->vb_vidq); + if (ret == 0) { + pr_info("ov5640 start tvin service.\n"); + vops->start_tvin_service(vdin_path, ¶); + fh->stream_on = 1; + } + OV5640_set_param_wb(dev, ov5640_qctrl[4].default_value); + return ret; +} + +static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct ov5640_fh *fh = priv; + int ret = 0; + + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (i != fh->type) + return -EINVAL; + ret = videobuf_streamoff(&fh->vb_vidq); + if (ret == 0) { + vops->stop_tvin_service(0); + fh->stream_on = 0; + } + return ret; +} + +static int vidioc_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + int ret = 0, i = 0; + struct ov5640_fmt *fmt = NULL; + struct v4l2_frmsize_discrete *frmsize = NULL; + + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (formats[i].fourcc == fsize->pixel_format) { + fmt = &formats[i]; + break; + } + } + if (fmt == NULL) + return -EINVAL; + if ((fmt->fourcc == V4L2_PIX_FMT_NV21) + || (fmt->fourcc == V4L2_PIX_FMT_NV12) + || (fmt->fourcc == V4L2_PIX_FMT_YUV420) + || (fmt->fourcc == V4L2_PIX_FMT_YVU420)) { + if (fsize->index >= ARRAY_SIZE(prev_resolution_array)) + return -EINVAL; + frmsize = &prev_resolution_array[fsize->index].frmsize; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = frmsize->width; + fsize->discrete.height = frmsize->height; + } else if (fmt->fourcc == V4L2_PIX_FMT_RGB24) { + if (fsize->index >= ARRAY_SIZE(capture_resolution_array)) + return -EINVAL; + frmsize = + &capture_resolution_array[fsize->index].frmsize; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = frmsize->width; + fsize->discrete.height = frmsize->height; + } + return ret; +} + +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i) +{ + return 0; +} + +static int vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_525_60; + sprintf(inp->name, "Camera %u", inp->index); + + return 0; +} + +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + + *i = dev->input; + + return 0; +} + +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + + dev->input = i; + + return 0; +} + +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + + if (!dev->cam_info.flash_support + && qc->id == V4L2_CID_BACKLIGHT_COMPENSATION) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(ov5640_qctrl); i++) + if (qc->id && qc->id == ov5640_qctrl[i].id) { + memcpy(qc, &(ov5640_qctrl[i]), + sizeof(*qc)); + if (ov5640_qctrl[i].type == V4L2_CTRL_TYPE_MENU) + return ov5640_qctrl[i].maximum + 1; + else + return 0; + } + + return -EINVAL; +} + +static int vidioc_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *a) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(ov5640_qmenu_set); i++) + if (a->id && a->id == ov5640_qmenu_set[i].id) { + for (j = 0; j < ov5640_qmenu_set[i].num; j++) + if (a->index == + ov5640_qmenu_set[i].ov5640_qmenu[j].index) { + memcpy(a, + &(ov5640_qmenu_set[i].ov5640_qmenu[j]), + sizeof(*a)); + return 0; + } + } + + return -EINVAL; +} + +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int i; + int i2cret = -1; + + for (i = 0; i < ARRAY_SIZE(ov5640_qctrl); i++) + if (ctrl->id == ov5640_qctrl[i].id) { + if ((ctrl->id == V4L2_CID_FOCUS_AUTO) + && bDoingAutoFocusMode) { + if (i2c_get_byte(client, 0x3023)) + return -EBUSY; + bDoingAutoFocusMode = false; + if (i2c_get_byte(client, 0x3028) == 0) { + dprintk(dev, 3, + "auto mode failed!\n"); + return -EAGAIN; + } + i2c_put_byte(client, + 0x3022, 0x6); + i2c_put_byte(client, + 0x3023, 0x1); + dprintk(dev, 3, + "pause auto focus\n"); + } else if (ctrl->id == V4L2_CID_AUTO_FOCUS_STATUS) { + i2cret = i2c_get_byte(client, 0x3029); + if (i2cret == 0x00) { + ctrl->value = + V4L2_AUTO_FOCUS_STATUS_BUSY; + } else if (i2cret == 0x10) { + ctrl->value = + V4L2_AUTO_FOCUS_STATUS_REACHED; + } else if (i2cret == 0x20) { + ctrl->value = + V4L2_AUTO_FOCUS_STATUS_IDLE; + } else { + dprintk(dev, 3, + "should resart focus\n"); + ctrl->value = + V4L2_AUTO_FOCUS_STATUS_FAILED; + } + return 0; + } + ctrl->value = dev->qctl_regs[i]; + return 0; + } + + return -EINVAL; +} + +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct ov5640_fh *fh = priv; + struct ov5640_device *dev = fh->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(ov5640_qctrl); i++) + if (ctrl->id == ov5640_qctrl[i].id) { + if (ctrl->value < ov5640_qctrl[i].minimum || + ctrl->value > ov5640_qctrl[i].maximum || + ov5640_setting(dev, ctrl->id, ctrl->value) < 0) { + return -ERANGE; + } + dev->qctl_regs[i] = ctrl->value; + return 0; + } + return -EINVAL; +} + +static int ov5640_open(struct file *file) +{ + struct ov5640_device *dev = video_drvdata(file); + struct ov5640_fh *fh = NULL; + int retval = 0; + + dev->vminfo.vdin_id = dev->cam_info.vdin_path; + dev->vminfo.bt_path_count = dev->cam_info.bt_path_count; + +#ifdef CONFIG_CMA + retval = vm_init_resource(24 * SZ_1M, &dev->vminfo); + if (retval < 0) { + pr_err("error: no cma memory\n"); + return -1; + } +#endif + mutex_lock(&firmware_mutex); + ov5640_have_opened = 1; + mutex_unlock(&firmware_mutex); + + aml_cam_init(&dev->cam_info); + + OV5640_init_regs(dev); + + msleep(20); + + mutex_lock(&dev->mutex); + dev->users++; + if (dev->users > 1) { + dev->users--; + mutex_unlock(&dev->mutex); + return -EBUSY; + } + + dprintk(dev, 1, "open %s type=%s users=%d\n", + video_device_node_name(dev->vdev), + v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); + + INIT_LIST_HEAD(&dev->vidq.active); + init_waitqueue_head(&dev->vidq.wq); + spin_lock_init(&dev->slock); + + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (fh == NULL) { + dev->users--; + retval = -ENOMEM; + } + mutex_unlock(&dev->mutex); + + if (retval) + return retval; + +#ifdef CONFIG_HAS_WAKELOCK + wake_lock(&(dev->wake_lock)); +#endif + + file->private_data = fh; + fh->dev = dev; + + fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fh->fmt = &formats[0]; + fh->width = 640; + fh->height = 480; + fh->stream_on = 0; + fh->f_flags = file->f_flags; + + dev->jiffies = jiffies; + + if (dev->vminfo.mem_alloc_succeed) { + fh->res.start = dev->vminfo.buffer_start; + fh->res.end = dev->vminfo.buffer_start + + dev->vminfo.vm_buf_size - 1; + fh->res.magic = MAGIC_RE_MEM; + fh->res.priv = NULL; + videobuf_queue_res_init(&fh->vb_vidq, &ov5640_video_qops, + NULL, &dev->slock, fh->type, + V4L2_FIELD_INTERLACED, + sizeof(struct ov5640_buffer), + (void *)&fh->res, NULL); + } + + bDoingAutoFocusMode = false; + ov5640_start_thread(fh); + return 0; +} + +static ssize_t +ov5640_read(struct file *file, char __user *data, size_t count, loff_t *ppos) +{ + struct ov5640_fh *fh = file->private_data; + + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0, + file->f_flags & O_NONBLOCK); + } + return 0; +} + +static unsigned int +ov5640_poll(struct file *file, struct poll_table_struct *wait) +{ + struct ov5640_fh *fh = file->private_data; + struct ov5640_device *dev = fh->dev; + struct videobuf_queue *q = &fh->vb_vidq; + + dprintk(dev, 1, "%s\n", __func__); + + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return POLLERR; + + return videobuf_poll_stream(file, q, wait); +} + +static int ov5640_close(struct file *file) +{ + struct ov5640_fh *fh = file->private_data; + struct ov5640_device *dev = fh->dev; + struct ov5640_dmaqueue *vidq = &dev->vidq; + struct video_device *vdev = video_devdata(file); + unsigned int vdin_path; + + vdin_path = fh->dev->cam_info.vdin_path; + mutex_lock(&firmware_mutex); + ov5640_have_opened = 0; + dev->firmware_ready = 0; + mutex_unlock(&firmware_mutex); + ov5640_stop_thread(vidq); + videobuf_stop(&fh->vb_vidq); + if (fh->stream_on) { + pr_info("%s, vdin_path = %d\n", + __func__, vdin_path); + vops->stop_tvin_service(vdin_path); + } + + videobuf_mmap_free(&fh->vb_vidq); + + kfree(fh); + + mutex_lock(&dev->mutex); + dev->users--; + mutex_unlock(&dev->mutex); + + dprintk(dev, 1, "close called (dev=%s, users=%d)\n", + video_device_node_name(vdev), dev->users); + + ov5640_qctrl[4].default_value = 0; + ov5640_qctrl[5].default_value = 4; + ov5640_qctrl[6].default_value = 0; + ov5640_qctrl[2].default_value = 0; + ov5640_qctrl[10].default_value = 100; + ov5640_qctrl[11].default_value = 0; + temp_frame = -1; + power_down_ov5640(dev); + ov5640_frmintervals_active.numerator = 1; + ov5640_frmintervals_active.denominator = 25; + + aml_cam_uninit(&dev->cam_info); +#ifdef CONFIG_HAS_WAKELOCK + wake_unlock(&(dev->wake_lock)); +#endif +#ifdef CONFIG_CMA + vm_deinit_resource(&dev->vminfo); +#endif + return 0; +} + +static int ov5640_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct ov5640_fh *fh = file->private_data; + struct ov5640_device *dev = fh->dev; + int ret; + + dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); + + ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); + + dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", + (unsigned long)vma->vm_start, + (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, + ret); + + return ret; +} + +static const struct v4l2_file_operations ov5640_fops = { + .owner = THIS_MODULE, + .open = ov5640_open, + .release = ov5640_close, + .read = ov5640_read, + .poll = ov5640_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = ov5640_mmap, +}; + +static const struct v4l2_ioctl_ops ov5640_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_s_std = vidioc_s_std, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_querymenu = vidioc_querymenu, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, + .vidioc_enum_framesizes = vidioc_enum_framesizes, + .vidioc_g_parm = vidioc_g_parm, + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = vidiocgmbuf, +#endif +}; + +static struct video_device ov5640_template = { + .name = "ov5640_v4l", + .fops = &ov5640_fops, + .ioctl_ops = &ov5640_ioctl_ops, + .release = video_device_release, + .tvnorms = V4L2_STD_525_60, +}; + +static const struct v4l2_subdev_core_ops ov5640_core_ops = { +}; + +static const struct v4l2_subdev_ops ov5640_ops = { + .core = &ov5640_core_ops, +}; + +static int ov5640_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct aml_cam_info_s *plat_dat; + int err; + int ret; + struct ov5640_device *t; + struct v4l2_subdev *sd; + + vops = get_vdin_v4l2_ops(); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + t = kzalloc(sizeof(*t), GFP_KERNEL); + if (t == NULL) { + pr_err("ov5640 probe kzalloc failed.\n"); + return -ENOMEM; + } + + client->addr = 0x3c; + snprintf(t->v4l2_dev.name, sizeof(t->v4l2_dev.name), + "%s-%03d", "ov5640", 0); + ret = v4l2_device_register(NULL, &t->v4l2_dev); + if (ret) { + pr_info("%s, v4l2 device register failed", __func__); + kfree(t); + return ret; + } + + sd = &t->sd; + v4l2_i2c_subdev_init(sd, client, &ov5640_ops); + mutex_init(&t->mutex); + memset(&t->vminfo, 0, sizeof(struct vm_init_s)); + + t->vdev = video_device_alloc(); + if (t->vdev == NULL) { + kfree(t); + return -ENOMEM; + } + memcpy(t->vdev, &ov5640_template, sizeof(*t->vdev)); + t->vdev->v4l2_dev = &t->v4l2_dev; + video_set_drvdata(t->vdev, t); + +#ifdef CONFIG_HAS_WAKELOCK + wake_lock_init(&(t->wake_lock), WAKE_LOCK_SUSPEND, "ov5640"); +#endif + + plat_dat = (struct aml_cam_info_s *)client->dev.platform_data; + if (plat_dat) { + memcpy(&t->cam_info, plat_dat, sizeof(struct aml_cam_info_s)); + pr_info("%s, front_back = %d\n", + __func__, plat_dat->front_back); + video_nr = plat_dat->front_back; + } else { + pr_err("camera ov5640: have no platform data\n"); + video_device_release(t->vdev); + kfree(t); + return -1; + } + + t->cam_info.version = OV5640_DRIVER_VERSION; + if (aml_cam_info_reg(&t->cam_info) < 0) + pr_err("reg caminfo error\n"); + + pr_info("t->vdev = %p, video_nr = %d\n", t->vdev, video_nr); + err = video_register_device(t->vdev, VFL_TYPE_GRABBER, video_nr); + if (err < 0) { + video_device_release(t->vdev); + kfree(t); + return err; + } + + pr_info("ov5640_probe successful.\n"); + + return 0; +} + +static int ov5640_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov5640_device *t = to_dev(sd); + + video_unregister_device(t->vdev); + v4l2_device_unregister_subdev(sd); +#ifdef CONFIG_HAS_WAKELOCK + wake_lock_destroy(&(t->wake_lock)); +#endif + aml_cam_info_unreg(&t->cam_info); + kfree(t); + return 0; +} + +static const struct i2c_device_id ov5640_id[] = { + { "ov5640", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ov5640_id); + +static struct i2c_driver ov5640_i2c_driver = { + .driver = { + .name = "ov5640", + }, + .probe = ov5640_probe, + .remove = ov5640_remove, + .id_table = ov5640_id, +}; + +module_i2c_driver(ov5640_i2c_driver); + diff --git a/drivers/amlogic/media/camera/ov5640_firmware.h b/drivers/amlogic/media/camera/ov5640_firmware.h new file mode 100644 index 0000000..a3967ac --- /dev/null +++ b/drivers/amlogic/media/camera/ov5640_firmware.h @@ -0,0 +1,4121 @@ +/* + * drivers/amlogic/media/camera/ov5640_firmware.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef OV5640_FIRMWARE_H +#define OV5640_FIRMWARE_H + +#define CMD_MAIN 0x3022 +#define CMD_ACK 0x3023 +#define CMD_PARA0 0x3024 +#define CMD_PARA1 0x3025 +#define CMD_PARA2 0x3026 +#define CMD_PARA3 0x3027 +#define CMD_PARA4 0x3028 +#define FW_STATUS 0x3029 + +struct aml_camera_i2c_fig_s OV5640_AF_firmware[] = { + {0x3000, 0x20}, + {0x8000, 0x02}, + {0x8001, 0x0f}, + {0x8002, 0xd6}, + {0x8003, 0x02}, + {0x8004, 0x0a}, + {0x8005, 0x39}, + {0x8006, 0xc2}, + {0x8007, 0x01}, + {0x8008, 0x22}, + {0x8009, 0x22}, + {0x800a, 0x00}, + {0x800b, 0x02}, + {0x800c, 0x0f}, + {0x800d, 0xb2}, + {0x800e, 0xe5}, + {0x800f, 0x1f}, + {0x8010, 0x70}, + {0x8011, 0x72}, + {0x8012, 0xf5}, + {0x8013, 0x1e}, + {0x8014, 0xd2}, + {0x8015, 0x35}, + {0x8016, 0xff}, + {0x8017, 0xef}, + {0x8018, 0x25}, + {0x8019, 0xe0}, + {0x801a, 0x24}, + {0x801b, 0x4e}, + {0x801c, 0xf8}, + {0x801d, 0xe4}, + {0x801e, 0xf6}, + {0x801f, 0x08}, + {0x8020, 0xf6}, + {0x8021, 0x0f}, + {0x8022, 0xbf}, + {0x8023, 0x34}, + {0x8024, 0xf2}, + {0x8025, 0x90}, + {0x8026, 0x0e}, + {0x8027, 0x93}, + {0x8028, 0xe4}, + {0x8029, 0x93}, + {0x802a, 0xff}, + {0x802b, 0xe5}, + {0x802c, 0x4b}, + {0x802d, 0xc3}, + {0x802e, 0x9f}, + {0x802f, 0x50}, + {0x8030, 0x04}, + {0x8031, 0x7f}, + {0x8032, 0x05}, + {0x8033, 0x80}, + {0x8034, 0x02}, + {0x8035, 0x7f}, + {0x8036, 0xfb}, + {0x8037, 0x78}, + {0x8038, 0xbd}, + {0x8039, 0xa6}, + {0x803a, 0x07}, + {0x803b, 0x12}, + {0x803c, 0x0f}, + {0x803d, 0x04}, + {0x803e, 0x40}, + {0x803f, 0x04}, + {0x8040, 0x7f}, + {0x8041, 0x03}, + {0x8042, 0x80}, + {0x8043, 0x02}, + {0x8044, 0x7f}, + {0x8045, 0x30}, + {0x8046, 0x78}, + {0x8047, 0xbc}, + {0x8048, 0xa6}, + {0x8049, 0x07}, + {0x804a, 0xe6}, + {0x804b, 0x18}, + {0x804c, 0xf6}, + {0x804d, 0x08}, + {0x804e, 0xe6}, + {0x804f, 0x78}, + {0x8050, 0xb9}, + {0x8051, 0xf6}, + {0x8052, 0x78}, + {0x8053, 0xbc}, + {0x8054, 0xe6}, + {0x8055, 0x78}, + {0x8056, 0xba}, + {0x8057, 0xf6}, + {0x8058, 0x78}, + {0x8059, 0xbf}, + {0x805a, 0x76}, + {0x805b, 0x33}, + {0x805c, 0xe4}, + {0x805d, 0x08}, + {0x805e, 0xf6}, + {0x805f, 0x78}, + {0x8060, 0xb8}, + {0x8061, 0x76}, + {0x8062, 0x01}, + {0x8063, 0x75}, + {0x8064, 0x4a}, + {0x8065, 0x02}, + {0x8066, 0x78}, + {0x8067, 0xb6}, + {0x8068, 0xf6}, + {0x8069, 0x08}, + {0x806a, 0xf6}, + {0x806b, 0x74}, + {0x806c, 0xff}, + {0x806d, 0x78}, + {0x806e, 0xc1}, + {0x806f, 0xf6}, + {0x8070, 0x08}, + {0x8071, 0xf6}, + {0x8072, 0x75}, + {0x8073, 0x1f}, + {0x8074, 0x01}, + {0x8075, 0x78}, + {0x8076, 0xbc}, + {0x8077, 0xe6}, + {0x8078, 0x75}, + {0x8079, 0xf0}, + {0x807a, 0x05}, + {0x807b, 0xa4}, + {0x807c, 0xf5}, + {0x807d, 0x4b}, + {0x807e, 0x12}, + {0x807f, 0x0a}, + {0x8080, 0xff}, + {0x8081, 0xc2}, + {0x8082, 0x37}, + {0x8083, 0x22}, + {0x8084, 0x78}, + {0x8085, 0xb8}, + {0x8086, 0xe6}, + {0x8087, 0xd3}, + {0x8088, 0x94}, + {0x8089, 0x00}, + {0x808a, 0x40}, + {0x808b, 0x02}, + {0x808c, 0x16}, + {0x808d, 0x22}, + {0x808e, 0xe5}, + {0x808f, 0x1f}, + {0x8090, 0xb4}, + {0x8091, 0x05}, + {0x8092, 0x23}, + {0x8093, 0xe4}, + {0x8094, 0xf5}, + {0x8095, 0x1f}, + {0x8096, 0xc2}, + {0x8097, 0x01}, + {0x8098, 0x78}, + {0x8099, 0xb6}, + {0x809a, 0xe6}, + {0x809b, 0xfe}, + {0x809c, 0x08}, + {0x809d, 0xe6}, + {0x809e, 0xff}, + {0x809f, 0x78}, + {0x80a0, 0x4e}, + {0x80a1, 0xa6}, + {0x80a2, 0x06}, + {0x80a3, 0x08}, + {0x80a4, 0xa6}, + {0x80a5, 0x07}, + {0x80a6, 0xa2}, + {0x80a7, 0x37}, + {0x80a8, 0xe4}, + {0x80a9, 0x33}, + {0x80aa, 0xf5}, + {0x80ab, 0x3c}, + {0x80ac, 0x90}, + {0x80ad, 0x30}, + {0x80ae, 0x28}, + {0x80af, 0xf0}, + {0x80b0, 0x75}, + {0x80b1, 0x1e}, + {0x80b2, 0x10}, + {0x80b3, 0xd2}, + {0x80b4, 0x35}, + {0x80b5, 0x22}, + {0x80b6, 0xe5}, + {0x80b7, 0x4b}, + {0x80b8, 0x75}, + {0x80b9, 0xf0}, + {0x80ba, 0x05}, + {0x80bb, 0x84}, + {0x80bc, 0x78}, + {0x80bd, 0xbc}, + {0x80be, 0xf6}, + {0x80bf, 0x90}, + {0x80c0, 0x0e}, + {0x80c1, 0x8c}, + {0x80c2, 0xe4}, + {0x80c3, 0x93}, + {0x80c4, 0xff}, + {0x80c5, 0x25}, + {0x80c6, 0xe0}, + {0x80c7, 0x24}, + {0x80c8, 0x0a}, + {0x80c9, 0xf8}, + {0x80ca, 0xe6}, + {0x80cb, 0xfc}, + {0x80cc, 0x08}, + {0x80cd, 0xe6}, + {0x80ce, 0xfd}, + {0x80cf, 0x78}, + {0x80d0, 0xbc}, + {0x80d1, 0xe6}, + {0x80d2, 0x25}, + {0x80d3, 0xe0}, + {0x80d4, 0x24}, + {0x80d5, 0x4e}, + {0x80d6, 0xf8}, + {0x80d7, 0xa6}, + {0x80d8, 0x04}, + {0x80d9, 0x08}, + {0x80da, 0xa6}, + {0x80db, 0x05}, + {0x80dc, 0xef}, + {0x80dd, 0x12}, + {0x80de, 0x0f}, + {0x80df, 0x0b}, + {0x80e0, 0xd3}, + {0x80e1, 0x78}, + {0x80e2, 0xb7}, + {0x80e3, 0x96}, + {0x80e4, 0xee}, + {0x80e5, 0x18}, + {0x80e6, 0x96}, + {0x80e7, 0x40}, + {0x80e8, 0x0d}, + {0x80e9, 0x78}, + {0x80ea, 0xbc}, + {0x80eb, 0xe6}, + {0x80ec, 0x78}, + {0x80ed, 0xb9}, + {0x80ee, 0xf6}, + {0x80ef, 0x78}, + {0x80f0, 0xb6}, + {0x80f1, 0xa6}, + {0x80f2, 0x06}, + {0x80f3, 0x08}, + {0x80f4, 0xa6}, + {0x80f5, 0x07}, + {0x80f6, 0x90}, + {0x80f7, 0x0e}, + {0x80f8, 0x8c}, + {0x80f9, 0xe4}, + {0x80fa, 0x93}, + {0x80fb, 0x12}, + {0x80fc, 0x0f}, + {0x80fd, 0x0b}, + {0x80fe, 0xc3}, + {0x80ff, 0x78}, + {0x8100, 0xc2}, + {0x8101, 0x96}, + {0x8102, 0xee}, + {0x8103, 0x18}, + {0x8104, 0x96}, + {0x8105, 0x50}, + {0x8106, 0x0d}, + {0x8107, 0x78}, + {0x8108, 0xbc}, + {0x8109, 0xe6}, + {0x810a, 0x78}, + {0x810b, 0xba}, + {0x810c, 0xf6}, + {0x810d, 0x78}, + {0x810e, 0xc1}, + {0x810f, 0xa6}, + {0x8110, 0x06}, + {0x8111, 0x08}, + {0x8112, 0xa6}, + {0x8113, 0x07}, + {0x8114, 0x78}, + {0x8115, 0xb6}, + {0x8116, 0xe6}, + {0x8117, 0xfe}, + {0x8118, 0x08}, + {0x8119, 0xe6}, + {0x811a, 0xc3}, + {0x811b, 0x78}, + {0x811c, 0xc2}, + {0x811d, 0x96}, + {0x811e, 0xff}, + {0x811f, 0xee}, + {0x8120, 0x18}, + {0x8121, 0x96}, + {0x8122, 0x78}, + {0x8123, 0xc3}, + {0x8124, 0xf6}, + {0x8125, 0x08}, + {0x8126, 0xa6}, + {0x8127, 0x07}, + {0x8128, 0x90}, + {0x8129, 0x0e}, + {0x812a, 0x95}, + {0x812b, 0xe4}, + {0x812c, 0x18}, + {0x812d, 0x12}, + {0x812e, 0x0e}, + {0x812f, 0xe9}, + {0x8130, 0x40}, + {0x8131, 0x02}, + {0x8132, 0xd2}, + {0x8133, 0x37}, + {0x8134, 0x78}, + {0x8135, 0xbc}, + {0x8136, 0xe6}, + {0x8137, 0x08}, + {0x8138, 0x26}, + {0x8139, 0x08}, + {0x813a, 0xf6}, + {0x813b, 0xe5}, + {0x813c, 0x1f}, + {0x813d, 0x64}, + {0x813e, 0x01}, + {0x813f, 0x70}, + {0x8140, 0x4a}, + {0x8141, 0xe6}, + {0x8142, 0xc3}, + {0x8143, 0x78}, + {0x8144, 0xc0}, + {0x8145, 0x12}, + {0x8146, 0x0e}, + {0x8147, 0xdf}, + {0x8148, 0x40}, + {0x8149, 0x05}, + {0x814a, 0x12}, + {0x814b, 0x0e}, + {0x814c, 0xda}, + {0x814d, 0x40}, + {0x814e, 0x39}, + {0x814f, 0x12}, + {0x8150, 0x0f}, + {0x8151, 0x02}, + {0x8152, 0x40}, + {0x8153, 0x04}, + {0x8154, 0x7f}, + {0x8155, 0xfe}, + {0x8156, 0x80}, + {0x8157, 0x02}, + {0x8158, 0x7f}, + {0x8159, 0x02}, + {0x815a, 0x78}, + {0x815b, 0xbd}, + {0x815c, 0xa6}, + {0x815d, 0x07}, + {0x815e, 0x78}, + {0x815f, 0xb9}, + {0x8160, 0xe6}, + {0x8161, 0x24}, + {0x8162, 0x03}, + {0x8163, 0x78}, + {0x8164, 0xbf}, + {0x8165, 0xf6}, + {0x8166, 0x78}, + {0x8167, 0xb9}, + {0x8168, 0xe6}, + {0x8169, 0x24}, + {0x816a, 0xfd}, + {0x816b, 0x78}, + {0x816c, 0xc0}, + {0x816d, 0xf6}, + {0x816e, 0x12}, + {0x816f, 0x0f}, + {0x8170, 0x02}, + {0x8171, 0x40}, + {0x8172, 0x06}, + {0x8173, 0x78}, + {0x8174, 0xc0}, + {0x8175, 0xe6}, + {0x8176, 0xff}, + {0x8177, 0x80}, + {0x8178, 0x04}, + {0x8179, 0x78}, + {0x817a, 0xbf}, + {0x817b, 0xe6}, + {0x817c, 0xff}, + {0x817d, 0x78}, + {0x817e, 0xbe}, + {0x817f, 0xa6}, + {0x8180, 0x07}, + {0x8181, 0x75}, + {0x8182, 0x1f}, + {0x8183, 0x02}, + {0x8184, 0x78}, + {0x8185, 0xb8}, + {0x8186, 0x76}, + {0x8187, 0x01}, + {0x8188, 0x02}, + {0x8189, 0x02}, + {0x818a, 0x4a}, + {0x818b, 0xe5}, + {0x818c, 0x1f}, + {0x818d, 0x64}, + {0x818e, 0x02}, + {0x818f, 0x60}, + {0x8190, 0x03}, + {0x8191, 0x02}, + {0x8192, 0x02}, + {0x8193, 0x2a}, + {0x8194, 0x78}, + {0x8195, 0xbe}, + {0x8196, 0xe6}, + {0x8197, 0xff}, + {0x8198, 0xc3}, + {0x8199, 0x78}, + {0x819a, 0xc0}, + {0x819b, 0x12}, + {0x819c, 0x0e}, + {0x819d, 0xe0}, + {0x819e, 0x40}, + {0x819f, 0x08}, + {0x81a0, 0x12}, + {0x81a1, 0x0e}, + {0x81a2, 0xda}, + {0x81a3, 0x50}, + {0x81a4, 0x03}, + {0x81a5, 0x02}, + {0x81a6, 0x02}, + {0x81a7, 0x28}, + {0x81a8, 0x12}, + {0x81a9, 0x0f}, + {0x81aa, 0x02}, + {0x81ab, 0x40}, + {0x81ac, 0x04}, + {0x81ad, 0x7f}, + {0x81ae, 0xff}, + {0x81af, 0x80}, + {0x81b0, 0x02}, + {0x81b1, 0x7f}, + {0x81b2, 0x01}, + {0x81b3, 0x78}, + {0x81b4, 0xbd}, + {0x81b5, 0xa6}, + {0x81b6, 0x07}, + {0x81b7, 0x78}, + {0x81b8, 0xb9}, + {0x81b9, 0xe6}, + {0x81ba, 0x04}, + {0x81bb, 0x78}, + {0x81bc, 0xbf}, + {0x81bd, 0xf6}, + {0x81be, 0x78}, + {0x81bf, 0xb9}, + {0x81c0, 0xe6}, + {0x81c1, 0x14}, + {0x81c2, 0x78}, + {0x81c3, 0xc0}, + {0x81c4, 0xf6}, + {0x81c5, 0x18}, + {0x81c6, 0x12}, + {0x81c7, 0x0f}, + {0x81c8, 0x04}, + {0x81c9, 0x40}, + {0x81ca, 0x04}, + {0x81cb, 0xe6}, + {0x81cc, 0xff}, + {0x81cd, 0x80}, + {0x81ce, 0x02}, + {0x81cf, 0x7f}, + {0x81d0, 0x00}, + {0x81d1, 0x78}, + {0x81d2, 0xbf}, + {0x81d3, 0xa6}, + {0x81d4, 0x07}, + {0x81d5, 0xd3}, + {0x81d6, 0x08}, + {0x81d7, 0xe6}, + {0x81d8, 0x64}, + {0x81d9, 0x80}, + {0x81da, 0x94}, + {0x81db, 0x80}, + {0x81dc, 0x40}, + {0x81dd, 0x04}, + {0x81de, 0xe6}, + {0x81df, 0xff}, + {0x81e0, 0x80}, + {0x81e1, 0x02}, + {0x81e2, 0x7f}, + {0x81e3, 0x00}, + {0x81e4, 0x78}, + {0x81e5, 0xc0}, + {0x81e6, 0xa6}, + {0x81e7, 0x07}, + {0x81e8, 0xc3}, + {0x81e9, 0x18}, + {0x81ea, 0xe6}, + {0x81eb, 0x64}, + {0x81ec, 0x80}, + {0x81ed, 0x94}, + {0x81ee, 0xb3}, + {0x81ef, 0x50}, + {0x81f0, 0x04}, + {0x81f1, 0xe6}, + {0x81f2, 0xff}, + {0x81f3, 0x80}, + {0x81f4, 0x02}, + {0x81f5, 0x7f}, + {0x81f6, 0x33}, + {0x81f7, 0x78}, + {0x81f8, 0xbf}, + {0x81f9, 0xa6}, + {0x81fa, 0x07}, + {0x81fb, 0xc3}, + {0x81fc, 0x08}, + {0x81fd, 0xe6}, + {0x81fe, 0x64}, + {0x81ff, 0x80}, + {0x8200, 0x94}, + {0x8201, 0xb3}, + {0x8202, 0x50}, + {0x8203, 0x04}, + {0x8204, 0xe6}, + {0x8205, 0xff}, + {0x8206, 0x80}, + {0x8207, 0x02}, + {0x8208, 0x7f}, + {0x8209, 0x33}, + {0x820a, 0x78}, + {0x820b, 0xc0}, + {0x820c, 0xa6}, + {0x820d, 0x07}, + {0x820e, 0x12}, + {0x820f, 0x0f}, + {0x8210, 0x02}, + {0x8211, 0x40}, + {0x8212, 0x06}, + {0x8213, 0x78}, + {0x8214, 0xc0}, + {0x8215, 0xe6}, + {0x8216, 0xff}, + {0x8217, 0x80}, + {0x8218, 0x04}, + {0x8219, 0x78}, + {0x821a, 0xbf}, + {0x821b, 0xe6}, + {0x821c, 0xff}, + {0x821d, 0x78}, + {0x821e, 0xbe}, + {0x821f, 0xa6}, + {0x8220, 0x07}, + {0x8221, 0x75}, + {0x8222, 0x1f}, + {0x8223, 0x03}, + {0x8224, 0x78}, + {0x8225, 0xb8}, + {0x8226, 0x76}, + {0x8227, 0x01}, + {0x8228, 0x80}, + {0x8229, 0x20}, + {0x822a, 0xe5}, + {0x822b, 0x1f}, + {0x822c, 0x64}, + {0x822d, 0x03}, + {0x822e, 0x70}, + {0x822f, 0x26}, + {0x8230, 0x78}, + {0x8231, 0xbe}, + {0x8232, 0xe6}, + {0x8233, 0xff}, + {0x8234, 0xc3}, + {0x8235, 0x78}, + {0x8236, 0xc0}, + {0x8237, 0x12}, + {0x8238, 0x0e}, + {0x8239, 0xe0}, + {0x823a, 0x40}, + {0x823b, 0x05}, + {0x823c, 0x12}, + {0x823d, 0x0e}, + {0x823e, 0xda}, + {0x823f, 0x40}, + {0x8240, 0x09}, + {0x8241, 0x78}, + {0x8242, 0xb9}, + {0x8243, 0xe6}, + {0x8244, 0x78}, + {0x8245, 0xbe}, + {0x8246, 0xf6}, + {0x8247, 0x75}, + {0x8248, 0x1f}, + {0x8249, 0x04}, + {0x824a, 0x78}, + {0x824b, 0xbe}, + {0x824c, 0xe6}, + {0x824d, 0x75}, + {0x824e, 0xf0}, + {0x824f, 0x05}, + {0x8250, 0xa4}, + {0x8251, 0xf5}, + {0x8252, 0x4b}, + {0x8253, 0x02}, + {0x8254, 0x0a}, + {0x8255, 0xff}, + {0x8256, 0xe5}, + {0x8257, 0x1f}, + {0x8258, 0xb4}, + {0x8259, 0x04}, + {0x825a, 0x10}, + {0x825b, 0x90}, + {0x825c, 0x0e}, + {0x825d, 0x94}, + {0x825e, 0xe4}, + {0x825f, 0x78}, + {0x8260, 0xc3}, + {0x8261, 0x12}, + {0x8262, 0x0e}, + {0x8263, 0xe9}, + {0x8264, 0x40}, + {0x8265, 0x02}, + {0x8266, 0xd2}, + {0x8267, 0x37}, + {0x8268, 0x75}, + {0x8269, 0x1f}, + {0x826a, 0x05}, + {0x826b, 0x22}, + {0x826c, 0x30}, + {0x826d, 0x01}, + {0x826e, 0x03}, + {0x826f, 0x02}, + {0x8270, 0x04}, + {0x8271, 0xc0}, + {0x8272, 0x30}, + {0x8273, 0x02}, + {0x8274, 0x03}, + {0x8275, 0x02}, + {0x8276, 0x04}, + {0x8277, 0xc0}, + {0x8278, 0x90}, + {0x8279, 0x51}, + {0x827a, 0xa5}, + {0x827b, 0xe0}, + {0x827c, 0x78}, + {0x827d, 0x93}, + {0x827e, 0xf6}, + {0x827f, 0xa3}, + {0x8280, 0xe0}, + {0x8281, 0x08}, + {0x8282, 0xf6}, + {0x8283, 0xa3}, + {0x8284, 0xe0}, + {0x8285, 0x08}, + {0x8286, 0xf6}, + {0x8287, 0xe5}, + {0x8288, 0x1f}, + {0x8289, 0x70}, + {0x828a, 0x3c}, + {0x828b, 0x75}, + {0x828c, 0x1e}, + {0x828d, 0x20}, + {0x828e, 0xd2}, + {0x828f, 0x35}, + {0x8290, 0x12}, + {0x8291, 0x0c}, + {0x8292, 0x7a}, + {0x8293, 0x78}, + {0x8294, 0x7e}, + {0x8295, 0xa6}, + {0x8296, 0x06}, + {0x8297, 0x08}, + {0x8298, 0xa6}, + {0x8299, 0x07}, + {0x829a, 0x78}, + {0x829b, 0x8b}, + {0x829c, 0xa6}, + {0x829d, 0x09}, + {0x829e, 0x18}, + {0x829f, 0x76}, + {0x82a0, 0x01}, + {0x82a1, 0x12}, + {0x82a2, 0x0c}, + {0x82a3, 0x5b}, + {0x82a4, 0x78}, + {0x82a5, 0x4e}, + {0x82a6, 0xa6}, + {0x82a7, 0x06}, + {0x82a8, 0x08}, + {0x82a9, 0xa6}, + {0x82aa, 0x07}, + {0x82ab, 0x78}, + {0x82ac, 0x8b}, + {0x82ad, 0xe6}, + {0x82ae, 0x78}, + {0x82af, 0x6e}, + {0x82b0, 0xf6}, + {0x82b1, 0x75}, + {0x82b2, 0x1f}, + {0x82b3, 0x01}, + {0x82b4, 0x78}, + {0x82b5, 0x93}, + {0x82b6, 0xe6}, + {0x82b7, 0x78}, + {0x82b8, 0x90}, + {0x82b9, 0xf6}, + {0x82ba, 0x78}, + {0x82bb, 0x94}, + {0x82bc, 0xe6}, + {0x82bd, 0x78}, + {0x82be, 0x91}, + {0x82bf, 0xf6}, + {0x82c0, 0x78}, + {0x82c1, 0x95}, + {0x82c2, 0xe6}, + {0x82c3, 0x78}, + {0x82c4, 0x92}, + {0x82c5, 0xf6}, + {0x82c6, 0x22}, + {0x82c7, 0x79}, + {0x82c8, 0x90}, + {0x82c9, 0xe7}, + {0x82ca, 0xd3}, + {0x82cb, 0x78}, + {0x82cc, 0x93}, + {0x82cd, 0x96}, + {0x82ce, 0x40}, + {0x82cf, 0x05}, + {0x82d0, 0xe7}, + {0x82d1, 0x96}, + {0x82d2, 0xff}, + {0x82d3, 0x80}, + {0x82d4, 0x08}, + {0x82d5, 0xc3}, + {0x82d6, 0x79}, + {0x82d7, 0x93}, + {0x82d8, 0xe7}, + {0x82d9, 0x78}, + {0x82da, 0x90}, + {0x82db, 0x96}, + {0x82dc, 0xff}, + {0x82dd, 0x78}, + {0x82de, 0x88}, + {0x82df, 0x76}, + {0x82e0, 0x00}, + {0x82e1, 0x08}, + {0x82e2, 0xa6}, + {0x82e3, 0x07}, + {0x82e4, 0x79}, + {0x82e5, 0x91}, + {0x82e6, 0xe7}, + {0x82e7, 0xd3}, + {0x82e8, 0x78}, + {0x82e9, 0x94}, + {0x82ea, 0x96}, + {0x82eb, 0x40}, + {0x82ec, 0x05}, + {0x82ed, 0xe7}, + {0x82ee, 0x96}, + {0x82ef, 0xff}, + {0x82f0, 0x80}, + {0x82f1, 0x08}, + {0x82f2, 0xc3}, + {0x82f3, 0x79}, + {0x82f4, 0x94}, + {0x82f5, 0xe7}, + {0x82f6, 0x78}, + {0x82f7, 0x91}, + {0x82f8, 0x96}, + {0x82f9, 0xff}, + {0x82fa, 0x12}, + {0x82fb, 0x0c}, + {0x82fc, 0x8e}, + {0x82fd, 0x79}, + {0x82fe, 0x92}, + {0x82ff, 0xe7}, + {0x8300, 0xd3}, + {0x8301, 0x78}, + {0x8302, 0x95}, + {0x8303, 0x96}, + {0x8304, 0x40}, + {0x8305, 0x05}, + {0x8306, 0xe7}, + {0x8307, 0x96}, + {0x8308, 0xff}, + {0x8309, 0x80}, + {0x830a, 0x08}, + {0x830b, 0xc3}, + {0x830c, 0x79}, + {0x830d, 0x95}, + {0x830e, 0xe7}, + {0x830f, 0x78}, + {0x8310, 0x92}, + {0x8311, 0x96}, + {0x8312, 0xff}, + {0x8313, 0x12}, + {0x8314, 0x0c}, + {0x8315, 0x8e}, + {0x8316, 0x12}, + {0x8317, 0x0c}, + {0x8318, 0x5b}, + {0x8319, 0x78}, + {0x831a, 0x8a}, + {0x831b, 0xe6}, + {0x831c, 0x25}, + {0x831d, 0xe0}, + {0x831e, 0x24}, + {0x831f, 0x4e}, + {0x8320, 0xf8}, + {0x8321, 0xa6}, + {0x8322, 0x06}, + {0x8323, 0x08}, + {0x8324, 0xa6}, + {0x8325, 0x07}, + {0x8326, 0x78}, + {0x8327, 0x8a}, + {0x8328, 0xe6}, + {0x8329, 0x24}, + {0x832a, 0x6e}, + {0x832b, 0xf8}, + {0x832c, 0xa6}, + {0x832d, 0x09}, + {0x832e, 0x78}, + {0x832f, 0x8a}, + {0x8330, 0xe6}, + {0x8331, 0x24}, + {0x8332, 0x01}, + {0x8333, 0xff}, + {0x8334, 0xe4}, + {0x8335, 0x33}, + {0x8336, 0xfe}, + {0x8337, 0xd3}, + {0x8338, 0xef}, + {0x8339, 0x94}, + {0x833a, 0x0f}, + {0x833b, 0xee}, + {0x833c, 0x64}, + {0x833d, 0x80}, + {0x833e, 0x94}, + {0x833f, 0x80}, + {0x8340, 0x40}, + {0x8341, 0x04}, + {0x8342, 0x7f}, + {0x8343, 0x00}, + {0x8344, 0x80}, + {0x8345, 0x05}, + {0x8346, 0x78}, + {0x8347, 0x8a}, + {0x8348, 0xe6}, + {0x8349, 0x04}, + {0x834a, 0xff}, + {0x834b, 0x78}, + {0x834c, 0x8a}, + {0x834d, 0xa6}, + {0x834e, 0x07}, + {0x834f, 0xe5}, + {0x8350, 0x1f}, + {0x8351, 0xb4}, + {0x8352, 0x01}, + {0x8353, 0x0a}, + {0x8354, 0xe6}, + {0x8355, 0x60}, + {0x8356, 0x03}, + {0x8357, 0x02}, + {0x8358, 0x04}, + {0x8359, 0xc0}, + {0x835a, 0x75}, + {0x835b, 0x1f}, + {0x835c, 0x02}, + {0x835d, 0x22}, + {0x835e, 0x12}, + {0x835f, 0x0c}, + {0x8360, 0x7a}, + {0x8361, 0x78}, + {0x8362, 0x80}, + {0x8363, 0xa6}, + {0x8364, 0x06}, + {0x8365, 0x08}, + {0x8366, 0xa6}, + {0x8367, 0x07}, + {0x8368, 0x12}, + {0x8369, 0x0c}, + {0x836a, 0x7a}, + {0x836b, 0x78}, + {0x836c, 0x82}, + {0x836d, 0xa6}, + {0x836e, 0x06}, + {0x836f, 0x08}, + {0x8370, 0xa6}, + {0x8371, 0x07}, + {0x8372, 0x78}, + {0x8373, 0x6e}, + {0x8374, 0xe6}, + {0x8375, 0x78}, + {0x8376, 0x8c}, + {0x8377, 0xf6}, + {0x8378, 0x78}, + {0x8379, 0x6e}, + {0x837a, 0xe6}, + {0x837b, 0x78}, + {0x837c, 0x8d}, + {0x837d, 0xf6}, + {0x837e, 0x7f}, + {0x837f, 0x01}, + {0x8380, 0xef}, + {0x8381, 0x25}, + {0x8382, 0xe0}, + {0x8383, 0x24}, + {0x8384, 0x4f}, + {0x8385, 0xf9}, + {0x8386, 0xc3}, + {0x8387, 0x78}, + {0x8388, 0x81}, + {0x8389, 0xe6}, + {0x838a, 0x97}, + {0x838b, 0x18}, + {0x838c, 0xe6}, + {0x838d, 0x19}, + {0x838e, 0x97}, + {0x838f, 0x50}, + {0x8390, 0x0a}, + {0x8391, 0x12}, + {0x8392, 0x0c}, + {0x8393, 0x82}, + {0x8394, 0x78}, + {0x8395, 0x80}, + {0x8396, 0xa6}, + {0x8397, 0x04}, + {0x8398, 0x08}, + {0x8399, 0xa6}, + {0x839a, 0x05}, + {0x839b, 0x74}, + {0x839c, 0x6e}, + {0x839d, 0x2f}, + {0x839e, 0xf9}, + {0x839f, 0x78}, + {0x83a0, 0x8c}, + {0x83a1, 0xe6}, + {0x83a2, 0xc3}, + {0x83a3, 0x97}, + {0x83a4, 0x50}, + {0x83a5, 0x08}, + {0x83a6, 0x74}, + {0x83a7, 0x6e}, + {0x83a8, 0x2f}, + {0x83a9, 0xf8}, + {0x83aa, 0xe6}, + {0x83ab, 0x78}, + {0x83ac, 0x8c}, + {0x83ad, 0xf6}, + {0x83ae, 0xef}, + {0x83af, 0x25}, + {0x83b0, 0xe0}, + {0x83b1, 0x24}, + {0x83b2, 0x4f}, + {0x83b3, 0xf9}, + {0x83b4, 0xd3}, + {0x83b5, 0x78}, + {0x83b6, 0x83}, + {0x83b7, 0xe6}, + {0x83b8, 0x97}, + {0x83b9, 0x18}, + {0x83ba, 0xe6}, + {0x83bb, 0x19}, + {0x83bc, 0x97}, + {0x83bd, 0x40}, + {0x83be, 0x0a}, + {0x83bf, 0x12}, + {0x83c0, 0x0c}, + {0x83c1, 0x82}, + {0x83c2, 0x78}, + {0x83c3, 0x82}, + {0x83c4, 0xa6}, + {0x83c5, 0x04}, + {0x83c6, 0x08}, + {0x83c7, 0xa6}, + {0x83c8, 0x05}, + {0x83c9, 0x74}, + {0x83ca, 0x6e}, + {0x83cb, 0x2f}, + {0x83cc, 0xf9}, + {0x83cd, 0x78}, + {0x83ce, 0x8d}, + {0x83cf, 0xe6}, + {0x83d0, 0xd3}, + {0x83d1, 0x97}, + {0x83d2, 0x40}, + {0x83d3, 0x08}, + {0x83d4, 0x74}, + {0x83d5, 0x6e}, + {0x83d6, 0x2f}, + {0x83d7, 0xf8}, + {0x83d8, 0xe6}, + {0x83d9, 0x78}, + {0x83da, 0x8d}, + {0x83db, 0xf6}, + {0x83dc, 0x0f}, + {0x83dd, 0xef}, + {0x83de, 0x64}, + {0x83df, 0x10}, + {0x83e0, 0x70}, + {0x83e1, 0x9e}, + {0x83e2, 0xc3}, + {0x83e3, 0x79}, + {0x83e4, 0x81}, + {0x83e5, 0xe7}, + {0x83e6, 0x78}, + {0x83e7, 0x83}, + {0x83e8, 0x96}, + {0x83e9, 0xff}, + {0x83ea, 0x19}, + {0x83eb, 0xe7}, + {0x83ec, 0x18}, + {0x83ed, 0x96}, + {0x83ee, 0x78}, + {0x83ef, 0x84}, + {0x83f0, 0xf6}, + {0x83f1, 0x08}, + {0x83f2, 0xa6}, + {0x83f3, 0x07}, + {0x83f4, 0xc3}, + {0x83f5, 0x79}, + {0x83f6, 0x8c}, + {0x83f7, 0xe7}, + {0x83f8, 0x78}, + {0x83f9, 0x8d}, + {0x83fa, 0x96}, + {0x83fb, 0x08}, + {0x83fc, 0xf6}, + {0x83fd, 0xd3}, + {0x83fe, 0x79}, + {0x83ff, 0x81}, + {0x8400, 0xe7}, + {0x8401, 0x78}, + {0x8402, 0x7f}, + {0x8403, 0x96}, + {0x8404, 0x19}, + {0x8405, 0xe7}, + {0x8406, 0x18}, + {0x8407, 0x96}, + {0x8408, 0x40}, + {0x8409, 0x05}, + {0x840a, 0x09}, + {0x840b, 0xe7}, + {0x840c, 0x08}, + {0x840d, 0x80}, + {0x840e, 0x06}, + {0x840f, 0xc3}, + {0x8410, 0x79}, + {0x8411, 0x7f}, + {0x8412, 0xe7}, + {0x8413, 0x78}, + {0x8414, 0x81}, + {0x8415, 0x96}, + {0x8416, 0xff}, + {0x8417, 0x19}, + {0x8418, 0xe7}, + {0x8419, 0x18}, + {0x841a, 0x96}, + {0x841b, 0xfe}, + {0x841c, 0x78}, + {0x841d, 0x86}, + {0x841e, 0xa6}, + {0x841f, 0x06}, + {0x8420, 0x08}, + {0x8421, 0xa6}, + {0x8422, 0x07}, + {0x8423, 0x79}, + {0x8424, 0x8c}, + {0x8425, 0xe7}, + {0x8426, 0xd3}, + {0x8427, 0x78}, + {0x8428, 0x8b}, + {0x8429, 0x96}, + {0x842a, 0x40}, + {0x842b, 0x05}, + {0x842c, 0xe7}, + {0x842d, 0x96}, + {0x842e, 0xff}, + {0x842f, 0x80}, + {0x8430, 0x08}, + {0x8431, 0xc3}, + {0x8432, 0x79}, + {0x8433, 0x8b}, + {0x8434, 0xe7}, + {0x8435, 0x78}, + {0x8436, 0x8c}, + {0x8437, 0x96}, + {0x8438, 0xff}, + {0x8439, 0x78}, + {0x843a, 0x8f}, + {0x843b, 0xa6}, + {0x843c, 0x07}, + {0x843d, 0xe5}, + {0x843e, 0x1f}, + {0x843f, 0x64}, + {0x8440, 0x02}, + {0x8441, 0x70}, + {0x8442, 0x69}, + {0x8443, 0x90}, + {0x8444, 0x0e}, + {0x8445, 0x91}, + {0x8446, 0x93}, + {0x8447, 0xff}, + {0x8448, 0x18}, + {0x8449, 0xe6}, + {0x844a, 0xc3}, + {0x844b, 0x9f}, + {0x844c, 0x50}, + {0x844d, 0x72}, + {0x844e, 0x12}, + {0x844f, 0x0c}, + {0x8450, 0x4a}, + {0x8451, 0x12}, + {0x8452, 0x0c}, + {0x8453, 0x2f}, + {0x8454, 0x90}, + {0x8455, 0x0e}, + {0x8456, 0x8e}, + {0x8457, 0x12}, + {0x8458, 0x0c}, + {0x8459, 0x38}, + {0x845a, 0x78}, + {0x845b, 0x80}, + {0x845c, 0x12}, + {0x845d, 0x0c}, + {0x845e, 0x6b}, + {0x845f, 0x7b}, + {0x8460, 0x04}, + {0x8461, 0x12}, + {0x8462, 0x0c}, + {0x8463, 0x1d}, + {0x8464, 0xc3}, + {0x8465, 0x12}, + {0x8466, 0x06}, + {0x8467, 0x45}, + {0x8468, 0x50}, + {0x8469, 0x56}, + {0x846a, 0x90}, + {0x846b, 0x0e}, + {0x846c, 0x92}, + {0x846d, 0xe4}, + {0x846e, 0x93}, + {0x846f, 0xff}, + {0x8470, 0x78}, + {0x8471, 0x8f}, + {0x8472, 0xe6}, + {0x8473, 0x9f}, + {0x8474, 0x40}, + {0x8475, 0x02}, + {0x8476, 0x80}, + {0x8477, 0x11}, + {0x8478, 0x90}, + {0x8479, 0x0e}, + {0x847a, 0x90}, + {0x847b, 0xe4}, + {0x847c, 0x93}, + {0x847d, 0xff}, + {0x847e, 0xd3}, + {0x847f, 0x78}, + {0x8480, 0x89}, + {0x8481, 0xe6}, + {0x8482, 0x9f}, + {0x8483, 0x18}, + {0x8484, 0xe6}, + {0x8485, 0x94}, + {0x8486, 0x00}, + {0x8487, 0x40}, + {0x8488, 0x03}, + {0x8489, 0x75}, + {0x848a, 0x1f}, + {0x848b, 0x05}, + {0x848c, 0x12}, + {0x848d, 0x0c}, + {0x848e, 0x4a}, + {0x848f, 0x12}, + {0x8490, 0x0c}, + {0x8491, 0x2f}, + {0x8492, 0x90}, + {0x8493, 0x0e}, + {0x8494, 0x8f}, + {0x8495, 0x12}, + {0x8496, 0x0c}, + {0x8497, 0x38}, + {0x8498, 0x78}, + {0x8499, 0x7e}, + {0x849a, 0x12}, + {0x849b, 0x0c}, + {0x849c, 0x6b}, + {0x849d, 0x7b}, + {0x849e, 0x40}, + {0x849f, 0x12}, + {0x84a0, 0x0c}, + {0x84a1, 0x1d}, + {0x84a2, 0xd3}, + {0x84a3, 0x12}, + {0x84a4, 0x06}, + {0x84a5, 0x45}, + {0x84a6, 0x40}, + {0x84a7, 0x18}, + {0x84a8, 0x75}, + {0x84a9, 0x1f}, + {0x84aa, 0x05}, + {0x84ab, 0x22}, + {0x84ac, 0xe5}, + {0x84ad, 0x1f}, + {0x84ae, 0xb4}, + {0x84af, 0x05}, + {0x84b0, 0x0f}, + {0x84b1, 0xd2}, + {0x84b2, 0x01}, + {0x84b3, 0xc2}, + {0x84b4, 0x02}, + {0x84b5, 0xe4}, + {0x84b6, 0xf5}, + {0x84b7, 0x1f}, + {0x84b8, 0xf5}, + {0x84b9, 0x1e}, + {0x84ba, 0xd2}, + {0x84bb, 0x35}, + {0x84bc, 0xd2}, + {0x84bd, 0x33}, + {0x84be, 0xd2}, + {0x84bf, 0x36}, + {0x84c0, 0x22}, + {0x84c1, 0xef}, + {0x84c2, 0x8d}, + {0x84c3, 0xf0}, + {0x84c4, 0xa4}, + {0x84c5, 0xa8}, + {0x84c6, 0xf0}, + {0x84c7, 0xcf}, + {0x84c8, 0x8c}, + {0x84c9, 0xf0}, + {0x84ca, 0xa4}, + {0x84cb, 0x28}, + {0x84cc, 0xce}, + {0x84cd, 0x8d}, + {0x84ce, 0xf0}, + {0x84cf, 0xa4}, + {0x84d0, 0x2e}, + {0x84d1, 0xfe}, + {0x84d2, 0x22}, + {0x84d3, 0xbc}, + {0x84d4, 0x00}, + {0x84d5, 0x0b}, + {0x84d6, 0xbe}, + {0x84d7, 0x00}, + {0x84d8, 0x29}, + {0x84d9, 0xef}, + {0x84da, 0x8d}, + {0x84db, 0xf0}, + {0x84dc, 0x84}, + {0x84dd, 0xff}, + {0x84de, 0xad}, + {0x84df, 0xf0}, + {0x84e0, 0x22}, + {0x84e1, 0xe4}, + {0x84e2, 0xcc}, + {0x84e3, 0xf8}, + {0x84e4, 0x75}, + {0x84e5, 0xf0}, + {0x84e6, 0x08}, + {0x84e7, 0xef}, + {0x84e8, 0x2f}, + {0x84e9, 0xff}, + {0x84ea, 0xee}, + {0x84eb, 0x33}, + {0x84ec, 0xfe}, + {0x84ed, 0xec}, + {0x84ee, 0x33}, + {0x84ef, 0xfc}, + {0x84f0, 0xee}, + {0x84f1, 0x9d}, + {0x84f2, 0xec}, + {0x84f3, 0x98}, + {0x84f4, 0x40}, + {0x84f5, 0x05}, + {0x84f6, 0xfc}, + {0x84f7, 0xee}, + {0x84f8, 0x9d}, + {0x84f9, 0xfe}, + {0x84fa, 0x0f}, + {0x84fb, 0xd5}, + {0x84fc, 0xf0}, + {0x84fd, 0xe9}, + {0x84fe, 0xe4}, + {0x84ff, 0xce}, + {0x8500, 0xfd}, + {0x8501, 0x22}, + {0x8502, 0xed}, + {0x8503, 0xf8}, + {0x8504, 0xf5}, + {0x8505, 0xf0}, + {0x8506, 0xee}, + {0x8507, 0x84}, + {0x8508, 0x20}, + {0x8509, 0xd2}, + {0x850a, 0x1c}, + {0x850b, 0xfe}, + {0x850c, 0xad}, + {0x850d, 0xf0}, + {0x850e, 0x75}, + {0x850f, 0xf0}, + {0x8510, 0x08}, + {0x8511, 0xef}, + {0x8512, 0x2f}, + {0x8513, 0xff}, + {0x8514, 0xed}, + {0x8515, 0x33}, + {0x8516, 0xfd}, + {0x8517, 0x40}, + {0x8518, 0x07}, + {0x8519, 0x98}, + {0x851a, 0x50}, + {0x851b, 0x06}, + {0x851c, 0xd5}, + {0x851d, 0xf0}, + {0x851e, 0xf2}, + {0x851f, 0x22}, + {0x8520, 0xc3}, + {0x8521, 0x98}, + {0x8522, 0xfd}, + {0x8523, 0x0f}, + {0x8524, 0xd5}, + {0x8525, 0xf0}, + {0x8526, 0xea}, + {0x8527, 0x22}, + {0x8528, 0xe8}, + {0x8529, 0x8f}, + {0x852a, 0xf0}, + {0x852b, 0xa4}, + {0x852c, 0xcc}, + {0x852d, 0x8b}, + {0x852e, 0xf0}, + {0x852f, 0xa4}, + {0x8530, 0x2c}, + {0x8531, 0xfc}, + {0x8532, 0xe9}, + {0x8533, 0x8e}, + {0x8534, 0xf0}, + {0x8535, 0xa4}, + {0x8536, 0x2c}, + {0x8537, 0xfc}, + {0x8538, 0x8a}, + {0x8539, 0xf0}, + {0x853a, 0xed}, + {0x853b, 0xa4}, + {0x853c, 0x2c}, + {0x853d, 0xfc}, + {0x853e, 0xea}, + {0x853f, 0x8e}, + {0x8540, 0xf0}, + {0x8541, 0xa4}, + {0x8542, 0xcd}, + {0x8543, 0xa8}, + {0x8544, 0xf0}, + {0x8545, 0x8b}, + {0x8546, 0xf0}, + {0x8547, 0xa4}, + {0x8548, 0x2d}, + {0x8549, 0xcc}, + {0x854a, 0x38}, + {0x854b, 0x25}, + {0x854c, 0xf0}, + {0x854d, 0xfd}, + {0x854e, 0xe9}, + {0x854f, 0x8f}, + {0x8550, 0xf0}, + {0x8551, 0xa4}, + {0x8552, 0x2c}, + {0x8553, 0xcd}, + {0x8554, 0x35}, + {0x8555, 0xf0}, + {0x8556, 0xfc}, + {0x8557, 0xeb}, + {0x8558, 0x8e}, + {0x8559, 0xf0}, + {0x855a, 0xa4}, + {0x855b, 0xfe}, + {0x855c, 0xa9}, + {0x855d, 0xf0}, + {0x855e, 0xeb}, + {0x855f, 0x8f}, + {0x8560, 0xf0}, + {0x8561, 0xa4}, + {0x8562, 0xcf}, + {0x8563, 0xc5}, + {0x8564, 0xf0}, + {0x8565, 0x2e}, + {0x8566, 0xcd}, + {0x8567, 0x39}, + {0x8568, 0xfe}, + {0x8569, 0xe4}, + {0x856a, 0x3c}, + {0x856b, 0xfc}, + {0x856c, 0xea}, + {0x856d, 0xa4}, + {0x856e, 0x2d}, + {0x856f, 0xce}, + {0x8570, 0x35}, + {0x8571, 0xf0}, + {0x8572, 0xfd}, + {0x8573, 0xe4}, + {0x8574, 0x3c}, + {0x8575, 0xfc}, + {0x8576, 0x22}, + {0x8577, 0x75}, + {0x8578, 0xf0}, + {0x8579, 0x08}, + {0x857a, 0x75}, + {0x857b, 0x82}, + {0x857c, 0x00}, + {0x857d, 0xef}, + {0x857e, 0x2f}, + {0x857f, 0xff}, + {0x8580, 0xee}, + {0x8581, 0x33}, + {0x8582, 0xfe}, + {0x8583, 0xcd}, + {0x8584, 0x33}, + {0x8585, 0xcd}, + {0x8586, 0xcc}, + {0x8587, 0x33}, + {0x8588, 0xcc}, + {0x8589, 0xc5}, + {0x858a, 0x82}, + {0x858b, 0x33}, + {0x858c, 0xc5}, + {0x858d, 0x82}, + {0x858e, 0x9b}, + {0x858f, 0xed}, + {0x8590, 0x9a}, + {0x8591, 0xec}, + {0x8592, 0x99}, + {0x8593, 0xe5}, + {0x8594, 0x82}, + {0x8595, 0x98}, + {0x8596, 0x40}, + {0x8597, 0x0c}, + {0x8598, 0xf5}, + {0x8599, 0x82}, + {0x859a, 0xee}, + {0x859b, 0x9b}, + {0x859c, 0xfe}, + {0x859d, 0xed}, + {0x859e, 0x9a}, + {0x859f, 0xfd}, + {0x85a0, 0xec}, + {0x85a1, 0x99}, + {0x85a2, 0xfc}, + {0x85a3, 0x0f}, + {0x85a4, 0xd5}, + {0x85a5, 0xf0}, + {0x85a6, 0xd6}, + {0x85a7, 0xe4}, + {0x85a8, 0xce}, + {0x85a9, 0xfb}, + {0x85aa, 0xe4}, + {0x85ab, 0xcd}, + {0x85ac, 0xfa}, + {0x85ad, 0xe4}, + {0x85ae, 0xcc}, + {0x85af, 0xf9}, + {0x85b0, 0xa8}, + {0x85b1, 0x82}, + {0x85b2, 0x22}, + {0x85b3, 0xb8}, + {0x85b4, 0x00}, + {0x85b5, 0xc1}, + {0x85b6, 0xb9}, + {0x85b7, 0x00}, + {0x85b8, 0x59}, + {0x85b9, 0xba}, + {0x85ba, 0x00}, + {0x85bb, 0x2d}, + {0x85bc, 0xec}, + {0x85bd, 0x8b}, + {0x85be, 0xf0}, + {0x85bf, 0x84}, + {0x85c0, 0xcf}, + {0x85c1, 0xce}, + {0x85c2, 0xcd}, + {0x85c3, 0xfc}, + {0x85c4, 0xe5}, + {0x85c5, 0xf0}, + {0x85c6, 0xcb}, + {0x85c7, 0xf9}, + {0x85c8, 0x78}, + {0x85c9, 0x18}, + {0x85ca, 0xef}, + {0x85cb, 0x2f}, + {0x85cc, 0xff}, + {0x85cd, 0xee}, + {0x85ce, 0x33}, + {0x85cf, 0xfe}, + {0x85d0, 0xed}, + {0x85d1, 0x33}, + {0x85d2, 0xfd}, + {0x85d3, 0xec}, + {0x85d4, 0x33}, + {0x85d5, 0xfc}, + {0x85d6, 0xeb}, + {0x85d7, 0x33}, + {0x85d8, 0xfb}, + {0x85d9, 0x10}, + {0x85da, 0xd7}, + {0x85db, 0x03}, + {0x85dc, 0x99}, + {0x85dd, 0x40}, + {0x85de, 0x04}, + {0x85df, 0xeb}, + {0x85e0, 0x99}, + {0x85e1, 0xfb}, + {0x85e2, 0x0f}, + {0x85e3, 0xd8}, + {0x85e4, 0xe5}, + {0x85e5, 0xe4}, + {0x85e6, 0xf9}, + {0x85e7, 0xfa}, + {0x85e8, 0x22}, + {0x85e9, 0x78}, + {0x85ea, 0x18}, + {0x85eb, 0xef}, + {0x85ec, 0x2f}, + {0x85ed, 0xff}, + {0x85ee, 0xee}, + {0x85ef, 0x33}, + {0x85f0, 0xfe}, + {0x85f1, 0xed}, + {0x85f2, 0x33}, + {0x85f3, 0xfd}, + {0x85f4, 0xec}, + {0x85f5, 0x33}, + {0x85f6, 0xfc}, + {0x85f7, 0xc9}, + {0x85f8, 0x33}, + {0x85f9, 0xc9}, + {0x85fa, 0x10}, + {0x85fb, 0xd7}, + {0x85fc, 0x05}, + {0x85fd, 0x9b}, + {0x85fe, 0xe9}, + {0x85ff, 0x9a}, + {0x8600, 0x40}, + {0x8601, 0x07}, + {0x8602, 0xec}, + {0x8603, 0x9b}, + {0x8604, 0xfc}, + {0x8605, 0xe9}, + {0x8606, 0x9a}, + {0x8607, 0xf9}, + {0x8608, 0x0f}, + {0x8609, 0xd8}, + {0x860a, 0xe0}, + {0x860b, 0xe4}, + {0x860c, 0xc9}, + {0x860d, 0xfa}, + {0x860e, 0xe4}, + {0x860f, 0xcc}, + {0x8610, 0xfb}, + {0x8611, 0x22}, + {0x8612, 0x75}, + {0x8613, 0xf0}, + {0x8614, 0x10}, + {0x8615, 0xef}, + {0x8616, 0x2f}, + {0x8617, 0xff}, + {0x8618, 0xee}, + {0x8619, 0x33}, + {0x861a, 0xfe}, + {0x861b, 0xed}, + {0x861c, 0x33}, + {0x861d, 0xfd}, + {0x861e, 0xcc}, + {0x861f, 0x33}, + {0x8620, 0xcc}, + {0x8621, 0xc8}, + {0x8622, 0x33}, + {0x8623, 0xc8}, + {0x8624, 0x10}, + {0x8625, 0xd7}, + {0x8626, 0x07}, + {0x8627, 0x9b}, + {0x8628, 0xec}, + {0x8629, 0x9a}, + {0x862a, 0xe8}, + {0x862b, 0x99}, + {0x862c, 0x40}, + {0x862d, 0x0a}, + {0x862e, 0xed}, + {0x862f, 0x9b}, + {0x8630, 0xfd}, + {0x8631, 0xec}, + {0x8632, 0x9a}, + {0x8633, 0xfc}, + {0x8634, 0xe8}, + {0x8635, 0x99}, + {0x8636, 0xf8}, + {0x8637, 0x0f}, + {0x8638, 0xd5}, + {0x8639, 0xf0}, + {0x863a, 0xda}, + {0x863b, 0xe4}, + {0x863c, 0xcd}, + {0x863d, 0xfb}, + {0x863e, 0xe4}, + {0x863f, 0xcc}, + {0x8640, 0xfa}, + {0x8641, 0xe4}, + {0x8642, 0xc8}, + {0x8643, 0xf9}, + {0x8644, 0x22}, + {0x8645, 0xeb}, + {0x8646, 0x9f}, + {0x8647, 0xf5}, + {0x8648, 0xf0}, + {0x8649, 0xea}, + {0x864a, 0x9e}, + {0x864b, 0x42}, + {0x864c, 0xf0}, + {0x864d, 0xe9}, + {0x864e, 0x9d}, + {0x864f, 0x42}, + {0x8650, 0xf0}, + {0x8651, 0xe8}, + {0x8652, 0x9c}, + {0x8653, 0x45}, + {0x8654, 0xf0}, + {0x8655, 0x22}, + {0x8656, 0xe8}, + {0x8657, 0x60}, + {0x8658, 0x0f}, + {0x8659, 0xec}, + {0x865a, 0xc3}, + {0x865b, 0x13}, + {0x865c, 0xfc}, + {0x865d, 0xed}, + {0x865e, 0x13}, + {0x865f, 0xfd}, + {0x8660, 0xee}, + {0x8661, 0x13}, + {0x8662, 0xfe}, + {0x8663, 0xef}, + {0x8664, 0x13}, + {0x8665, 0xff}, + {0x8666, 0xd8}, + {0x8667, 0xf1}, + {0x8668, 0x22}, + {0x8669, 0xe8}, + {0x866a, 0x60}, + {0x866b, 0x0f}, + {0x866c, 0xef}, + {0x866d, 0xc3}, + {0x866e, 0x33}, + {0x866f, 0xff}, + {0x8670, 0xee}, + {0x8671, 0x33}, + {0x8672, 0xfe}, + {0x8673, 0xed}, + {0x8674, 0x33}, + {0x8675, 0xfd}, + {0x8676, 0xec}, + {0x8677, 0x33}, + {0x8678, 0xfc}, + {0x8679, 0xd8}, + {0x867a, 0xf1}, + {0x867b, 0x22}, + {0x867c, 0xe4}, + {0x867d, 0x93}, + {0x867e, 0xfc}, + {0x867f, 0x74}, + {0x8680, 0x01}, + {0x8681, 0x93}, + {0x8682, 0xfd}, + {0x8683, 0x74}, + {0x8684, 0x02}, + {0x8685, 0x93}, + {0x8686, 0xfe}, + {0x8687, 0x74}, + {0x8688, 0x03}, + {0x8689, 0x93}, + {0x868a, 0xff}, + {0x868b, 0x22}, + {0x868c, 0xe6}, + {0x868d, 0xfb}, + {0x868e, 0x08}, + {0x868f, 0xe6}, + {0x8690, 0xf9}, + {0x8691, 0x08}, + {0x8692, 0xe6}, + {0x8693, 0xfa}, + {0x8694, 0x08}, + {0x8695, 0xe6}, + {0x8696, 0xcb}, + {0x8697, 0xf8}, + {0x8698, 0x22}, + {0x8699, 0xec}, + {0x869a, 0xf6}, + {0x869b, 0x08}, + {0x869c, 0xed}, + {0x869d, 0xf6}, + {0x869e, 0x08}, + {0x869f, 0xee}, + {0x86a0, 0xf6}, + {0x86a1, 0x08}, + {0x86a2, 0xef}, + {0x86a3, 0xf6}, + {0x86a4, 0x22}, + {0x86a5, 0xa4}, + {0x86a6, 0x25}, + {0x86a7, 0x82}, + {0x86a8, 0xf5}, + {0x86a9, 0x82}, + {0x86aa, 0xe5}, + {0x86ab, 0xf0}, + {0x86ac, 0x35}, + {0x86ad, 0x83}, + {0x86ae, 0xf5}, + {0x86af, 0x83}, + {0x86b0, 0x22}, + {0x86b1, 0xd0}, + {0x86b2, 0x83}, + {0x86b3, 0xd0}, + {0x86b4, 0x82}, + {0x86b5, 0xf8}, + {0x86b6, 0xe4}, + {0x86b7, 0x93}, + {0x86b8, 0x70}, + {0x86b9, 0x12}, + {0x86ba, 0x74}, + {0x86bb, 0x01}, + {0x86bc, 0x93}, + {0x86bd, 0x70}, + {0x86be, 0x0d}, + {0x86bf, 0xa3}, + {0x86c0, 0xa3}, + {0x86c1, 0x93}, + {0x86c2, 0xf8}, + {0x86c3, 0x74}, + {0x86c4, 0x01}, + {0x86c5, 0x93}, + {0x86c6, 0xf5}, + {0x86c7, 0x82}, + {0x86c8, 0x88}, + {0x86c9, 0x83}, + {0x86ca, 0xe4}, + {0x86cb, 0x73}, + {0x86cc, 0x74}, + {0x86cd, 0x02}, + {0x86ce, 0x93}, + {0x86cf, 0x68}, + {0x86d0, 0x60}, + {0x86d1, 0xef}, + {0x86d2, 0xa3}, + {0x86d3, 0xa3}, + {0x86d4, 0xa3}, + {0x86d5, 0x80}, + {0x86d6, 0xdf}, + {0x86d7, 0x90}, + {0x86d8, 0x38}, + {0x86d9, 0x04}, + {0x86da, 0x78}, + {0x86db, 0x52}, + {0x86dc, 0x12}, + {0x86dd, 0x0b}, + {0x86de, 0xfd}, + {0x86df, 0x90}, + {0x86e0, 0x38}, + {0x86e1, 0x00}, + {0x86e2, 0xe0}, + {0x86e3, 0xfe}, + {0x86e4, 0xa3}, + {0x86e5, 0xe0}, + {0x86e6, 0xfd}, + {0x86e7, 0xed}, + {0x86e8, 0xff}, + {0x86e9, 0xc3}, + {0x86ea, 0x12}, + {0x86eb, 0x0b}, + {0x86ec, 0x9e}, + {0x86ed, 0x90}, + {0x86ee, 0x38}, + {0x86ef, 0x10}, + {0x86f0, 0x12}, + {0x86f1, 0x0b}, + {0x86f2, 0x92}, + {0x86f3, 0x90}, + {0x86f4, 0x38}, + {0x86f5, 0x06}, + {0x86f6, 0x78}, + {0x86f7, 0x54}, + {0x86f8, 0x12}, + {0x86f9, 0x0b}, + {0x86fa, 0xfd}, + {0x86fb, 0x90}, + {0x86fc, 0x38}, + {0x86fd, 0x02}, + {0x86fe, 0xe0}, + {0x86ff, 0xfe}, + {0x8700, 0xa3}, + {0x8701, 0xe0}, + {0x8702, 0xfd}, + {0x8703, 0xed}, + {0x8704, 0xff}, + {0x8705, 0xc3}, + {0x8706, 0x12}, + {0x8707, 0x0b}, + {0x8708, 0x9e}, + {0x8709, 0x90}, + {0x870a, 0x38}, + {0x870b, 0x12}, + {0x870c, 0x12}, + {0x870d, 0x0b}, + {0x870e, 0x92}, + {0x870f, 0xa3}, + {0x8710, 0xe0}, + {0x8711, 0xb4}, + {0x8712, 0x31}, + {0x8713, 0x07}, + {0x8714, 0x78}, + {0x8715, 0x52}, + {0x8716, 0x79}, + {0x8717, 0x52}, + {0x8718, 0x12}, + {0x8719, 0x0c}, + {0x871a, 0x13}, + {0x871b, 0x90}, + {0x871c, 0x38}, + {0x871d, 0x14}, + {0x871e, 0xe0}, + {0x871f, 0xb4}, + {0x8720, 0x71}, + {0x8721, 0x15}, + {0x8722, 0x78}, + {0x8723, 0x52}, + {0x8724, 0xe6}, + {0x8725, 0xfe}, + {0x8726, 0x08}, + {0x8727, 0xe6}, + {0x8728, 0x78}, + {0x8729, 0x02}, + {0x872a, 0xce}, + {0x872b, 0xc3}, + {0x872c, 0x13}, + {0x872d, 0xce}, + {0x872e, 0x13}, + {0x872f, 0xd8}, + {0x8730, 0xf9}, + {0x8731, 0x79}, + {0x8732, 0x53}, + {0x8733, 0xf7}, + {0x8734, 0xee}, + {0x8735, 0x19}, + {0x8736, 0xf7}, + {0x8737, 0x90}, + {0x8738, 0x38}, + {0x8739, 0x15}, + {0x873a, 0xe0}, + {0x873b, 0xb4}, + {0x873c, 0x31}, + {0x873d, 0x07}, + {0x873e, 0x78}, + {0x873f, 0x54}, + {0x8740, 0x79}, + {0x8741, 0x54}, + {0x8742, 0x12}, + {0x8743, 0x0c}, + {0x8744, 0x13}, + {0x8745, 0x90}, + {0x8746, 0x38}, + {0x8747, 0x15}, + {0x8748, 0xe0}, + {0x8749, 0xb4}, + {0x874a, 0x71}, + {0x874b, 0x15}, + {0x874c, 0x78}, + {0x874d, 0x54}, + {0x874e, 0xe6}, + {0x874f, 0xfe}, + {0x8750, 0x08}, + {0x8751, 0xe6}, + {0x8752, 0x78}, + {0x8753, 0x02}, + {0x8754, 0xce}, + {0x8755, 0xc3}, + {0x8756, 0x13}, + {0x8757, 0xce}, + {0x8758, 0x13}, + {0x8759, 0xd8}, + {0x875a, 0xf9}, + {0x875b, 0x79}, + {0x875c, 0x55}, + {0x875d, 0xf7}, + {0x875e, 0xee}, + {0x875f, 0x19}, + {0x8760, 0xf7}, + {0x8761, 0x79}, + {0x8762, 0x52}, + {0x8763, 0x12}, + {0x8764, 0x0b}, + {0x8765, 0xd9}, + {0x8766, 0x09}, + {0x8767, 0x12}, + {0x8768, 0x0b}, + {0x8769, 0xd9}, + {0x876a, 0xaf}, + {0x876b, 0x47}, + {0x876c, 0x12}, + {0x876d, 0x0b}, + {0x876e, 0xb2}, + {0x876f, 0xe5}, + {0x8770, 0x44}, + {0x8771, 0xfb}, + {0x8772, 0x7a}, + {0x8773, 0x00}, + {0x8774, 0xfd}, + {0x8775, 0x7c}, + {0x8776, 0x00}, + {0x8777, 0x12}, + {0x8778, 0x04}, + {0x8779, 0xd3}, + {0x877a, 0x78}, + {0x877b, 0x5a}, + {0x877c, 0xa6}, + {0x877d, 0x06}, + {0x877e, 0x08}, + {0x877f, 0xa6}, + {0x8780, 0x07}, + {0x8781, 0xaf}, + {0x8782, 0x45}, + {0x8783, 0x12}, + {0x8784, 0x0b}, + {0x8785, 0xb2}, + {0x8786, 0xad}, + {0x8787, 0x03}, + {0x8788, 0x7c}, + {0x8789, 0x00}, + {0x878a, 0x12}, + {0x878b, 0x04}, + {0x878c, 0xd3}, + {0x878d, 0x78}, + {0x878e, 0x56}, + {0x878f, 0xa6}, + {0x8790, 0x06}, + {0x8791, 0x08}, + {0x8792, 0xa6}, + {0x8793, 0x07}, + {0x8794, 0xaf}, + {0x8795, 0x48}, + {0x8796, 0x78}, + {0x8797, 0x54}, + {0x8798, 0x12}, + {0x8799, 0x0b}, + {0x879a, 0xb4}, + {0x879b, 0xe5}, + {0x879c, 0x43}, + {0x879d, 0xfb}, + {0x879e, 0xfd}, + {0x879f, 0x7c}, + {0x87a0, 0x00}, + {0x87a1, 0x12}, + {0x87a2, 0x04}, + {0x87a3, 0xd3}, + {0x87a4, 0x78}, + {0x87a5, 0x5c}, + {0x87a6, 0xa6}, + {0x87a7, 0x06}, + {0x87a8, 0x08}, + {0x87a9, 0xa6}, + {0x87aa, 0x07}, + {0x87ab, 0xaf}, + {0x87ac, 0x46}, + {0x87ad, 0x7e}, + {0x87ae, 0x00}, + {0x87af, 0x78}, + {0x87b0, 0x54}, + {0x87b1, 0x12}, + {0x87b2, 0x0b}, + {0x87b3, 0xb6}, + {0x87b4, 0xad}, + {0x87b5, 0x03}, + {0x87b6, 0x7c}, + {0x87b7, 0x00}, + {0x87b8, 0x12}, + {0x87b9, 0x04}, + {0x87ba, 0xd3}, + {0x87bb, 0x78}, + {0x87bc, 0x58}, + {0x87bd, 0xa6}, + {0x87be, 0x06}, + {0x87bf, 0x08}, + {0x87c0, 0xa6}, + {0x87c1, 0x07}, + {0x87c2, 0xc3}, + {0x87c3, 0x78}, + {0x87c4, 0x5b}, + {0x87c5, 0xe6}, + {0x87c6, 0x94}, + {0x87c7, 0x08}, + {0x87c8, 0x18}, + {0x87c9, 0xe6}, + {0x87ca, 0x94}, + {0x87cb, 0x00}, + {0x87cc, 0x50}, + {0x87cd, 0x05}, + {0x87ce, 0x76}, + {0x87cf, 0x00}, + {0x87d0, 0x08}, + {0x87d1, 0x76}, + {0x87d2, 0x08}, + {0x87d3, 0xc3}, + {0x87d4, 0x78}, + {0x87d5, 0x5d}, + {0x87d6, 0xe6}, + {0x87d7, 0x94}, + {0x87d8, 0x08}, + {0x87d9, 0x18}, + {0x87da, 0xe6}, + {0x87db, 0x94}, + {0x87dc, 0x00}, + {0x87dd, 0x50}, + {0x87de, 0x05}, + {0x87df, 0x76}, + {0x87e0, 0x00}, + {0x87e1, 0x08}, + {0x87e2, 0x76}, + {0x87e3, 0x08}, + {0x87e4, 0x78}, + {0x87e5, 0x5a}, + {0x87e6, 0x12}, + {0x87e7, 0x0b}, + {0x87e8, 0xc6}, + {0x87e9, 0xff}, + {0x87ea, 0xd3}, + {0x87eb, 0x78}, + {0x87ec, 0x57}, + {0x87ed, 0xe6}, + {0x87ee, 0x9f}, + {0x87ef, 0x18}, + {0x87f0, 0xe6}, + {0x87f1, 0x9e}, + {0x87f2, 0x40}, + {0x87f3, 0x0e}, + {0x87f4, 0x78}, + {0x87f5, 0x5a}, + {0x87f6, 0xe6}, + {0x87f7, 0x13}, + {0x87f8, 0xfe}, + {0x87f9, 0x08}, + {0x87fa, 0xe6}, + {0x87fb, 0x78}, + {0x87fc, 0x57}, + {0x87fd, 0x12}, + {0x87fe, 0x0c}, + {0x87ff, 0x08}, + {0x8800, 0x80}, + {0x8801, 0x04}, + {0x8802, 0x7e}, + {0x8803, 0x00}, + {0x8804, 0x7f}, + {0x8805, 0x00}, + {0x8806, 0x78}, + {0x8807, 0x5e}, + {0x8808, 0x12}, + {0x8809, 0x0b}, + {0x880a, 0xbe}, + {0x880b, 0xff}, + {0x880c, 0xd3}, + {0x880d, 0x78}, + {0x880e, 0x59}, + {0x880f, 0xe6}, + {0x8810, 0x9f}, + {0x8811, 0x18}, + {0x8812, 0xe6}, + {0x8813, 0x9e}, + {0x8814, 0x40}, + {0x8815, 0x0e}, + {0x8816, 0x78}, + {0x8817, 0x5c}, + {0x8818, 0xe6}, + {0x8819, 0x13}, + {0x881a, 0xfe}, + {0x881b, 0x08}, + {0x881c, 0xe6}, + {0x881d, 0x78}, + {0x881e, 0x59}, + {0x881f, 0x12}, + {0x8820, 0x0c}, + {0x8821, 0x08}, + {0x8822, 0x80}, + {0x8823, 0x04}, + {0x8824, 0x7e}, + {0x8825, 0x00}, + {0x8826, 0x7f}, + {0x8827, 0x00}, + {0x8828, 0xe4}, + {0x8829, 0xfc}, + {0x882a, 0xfd}, + {0x882b, 0x78}, + {0x882c, 0x62}, + {0x882d, 0x12}, + {0x882e, 0x06}, + {0x882f, 0x99}, + {0x8830, 0x78}, + {0x8831, 0x5a}, + {0x8832, 0x12}, + {0x8833, 0x0b}, + {0x8834, 0xc6}, + {0x8835, 0x78}, + {0x8836, 0x57}, + {0x8837, 0x26}, + {0x8838, 0xff}, + {0x8839, 0xee}, + {0x883a, 0x18}, + {0x883b, 0x36}, + {0x883c, 0xfe}, + {0x883d, 0x78}, + {0x883e, 0x66}, + {0x883f, 0x12}, + {0x8840, 0x0b}, + {0x8841, 0xbe}, + {0x8842, 0x78}, + {0x8843, 0x59}, + {0x8844, 0x26}, + {0x8845, 0xff}, + {0x8846, 0xee}, + {0x8847, 0x18}, + {0x8848, 0x36}, + {0x8849, 0xfe}, + {0x884a, 0xe4}, + {0x884b, 0xfc}, + {0x884c, 0xfd}, + {0x884d, 0x78}, + {0x884e, 0x6a}, + {0x884f, 0x12}, + {0x8850, 0x06}, + {0x8851, 0x99}, + {0x8852, 0x12}, + {0x8853, 0x0b}, + {0x8854, 0xce}, + {0x8855, 0x78}, + {0x8856, 0x66}, + {0x8857, 0x12}, + {0x8858, 0x06}, + {0x8859, 0x8c}, + {0x885a, 0xd3}, + {0x885b, 0x12}, + {0x885c, 0x06}, + {0x885d, 0x45}, + {0x885e, 0x40}, + {0x885f, 0x08}, + {0x8860, 0x12}, + {0x8861, 0x0b}, + {0x8862, 0xce}, + {0x8863, 0x78}, + {0x8864, 0x66}, + {0x8865, 0x12}, + {0x8866, 0x06}, + {0x8867, 0x99}, + {0x8868, 0x78}, + {0x8869, 0x54}, + {0x886a, 0x12}, + {0x886b, 0x0b}, + {0x886c, 0xd0}, + {0x886d, 0x78}, + {0x886e, 0x6a}, + {0x886f, 0x12}, + {0x8870, 0x06}, + {0x8871, 0x8c}, + {0x8872, 0xd3}, + {0x8873, 0x12}, + {0x8874, 0x06}, + {0x8875, 0x45}, + {0x8876, 0x40}, + {0x8877, 0x0a}, + {0x8878, 0x78}, + {0x8879, 0x54}, + {0x887a, 0x12}, + {0x887b, 0x0b}, + {0x887c, 0xd0}, + {0x887d, 0x78}, + {0x887e, 0x6a}, + {0x887f, 0x12}, + {0x8880, 0x06}, + {0x8881, 0x99}, + {0x8882, 0x78}, + {0x8883, 0x61}, + {0x8884, 0xe6}, + {0x8885, 0x90}, + {0x8886, 0x60}, + {0x8887, 0x01}, + {0x8888, 0xf0}, + {0x8889, 0x78}, + {0x888a, 0x65}, + {0x888b, 0xe6}, + {0x888c, 0xa3}, + {0x888d, 0xf0}, + {0x888e, 0x78}, + {0x888f, 0x69}, + {0x8890, 0xe6}, + {0x8891, 0xa3}, + {0x8892, 0xf0}, + {0x8893, 0x78}, + {0x8894, 0x55}, + {0x8895, 0xe6}, + {0x8896, 0xa3}, + {0x8897, 0xf0}, + {0x8898, 0x7d}, + {0x8899, 0x01}, + {0x889a, 0x78}, + {0x889b, 0x61}, + {0x889c, 0x12}, + {0x889d, 0x0b}, + {0x889e, 0xe9}, + {0x889f, 0x24}, + {0x88a0, 0x01}, + {0x88a1, 0x12}, + {0x88a2, 0x0b}, + {0x88a3, 0xa6}, + {0x88a4, 0x78}, + {0x88a5, 0x65}, + {0x88a6, 0x12}, + {0x88a7, 0x0b}, + {0x88a8, 0xe9}, + {0x88a9, 0x24}, + {0x88aa, 0x02}, + {0x88ab, 0x12}, + {0x88ac, 0x0b}, + {0x88ad, 0xa6}, + {0x88ae, 0x78}, + {0x88af, 0x69}, + {0x88b0, 0x12}, + {0x88b1, 0x0b}, + {0x88b2, 0xe9}, + {0x88b3, 0x24}, + {0x88b4, 0x03}, + {0x88b5, 0x12}, + {0x88b6, 0x0b}, + {0x88b7, 0xa6}, + {0x88b8, 0x78}, + {0x88b9, 0x6d}, + {0x88ba, 0x12}, + {0x88bb, 0x0b}, + {0x88bc, 0xe9}, + {0x88bd, 0x24}, + {0x88be, 0x04}, + {0x88bf, 0x12}, + {0x88c0, 0x0b}, + {0x88c1, 0xa6}, + {0x88c2, 0x0d}, + {0x88c3, 0xbd}, + {0x88c4, 0x05}, + {0x88c5, 0xd4}, + {0x88c6, 0xc2}, + {0x88c7, 0x0e}, + {0x88c8, 0xc2}, + {0x88c9, 0x06}, + {0x88ca, 0x22}, + {0x88cb, 0x85}, + {0x88cc, 0x08}, + {0x88cd, 0x41}, + {0x88ce, 0x90}, + {0x88cf, 0x30}, + {0x88d0, 0x24}, + {0x88d1, 0xe0}, + {0x88d2, 0xf5}, + {0x88d3, 0x3d}, + {0x88d4, 0xa3}, + {0x88d5, 0xe0}, + {0x88d6, 0xf5}, + {0x88d7, 0x3e}, + {0x88d8, 0xa3}, + {0x88d9, 0xe0}, + {0x88da, 0xf5}, + {0x88db, 0x3f}, + {0x88dc, 0xa3}, + {0x88dd, 0xe0}, + {0x88de, 0xf5}, + {0x88df, 0x40}, + {0x88e0, 0xa3}, + {0x88e1, 0xe0}, + {0x88e2, 0xf5}, + {0x88e3, 0x3c}, + {0x88e4, 0xd2}, + {0x88e5, 0x34}, + {0x88e6, 0xe5}, + {0x88e7, 0x41}, + {0x88e8, 0x12}, + {0x88e9, 0x06}, + {0x88ea, 0xb1}, + {0x88eb, 0x09}, + {0x88ec, 0x31}, + {0x88ed, 0x03}, + {0x88ee, 0x09}, + {0x88ef, 0x35}, + {0x88f0, 0x04}, + {0x88f1, 0x09}, + {0x88f2, 0x3b}, + {0x88f3, 0x05}, + {0x88f4, 0x09}, + {0x88f5, 0x3e}, + {0x88f6, 0x06}, + {0x88f7, 0x09}, + {0x88f8, 0x41}, + {0x88f9, 0x07}, + {0x88fa, 0x09}, + {0x88fb, 0x4a}, + {0x88fc, 0x08}, + {0x88fd, 0x09}, + {0x88fe, 0x5b}, + {0x88ff, 0x12}, + {0x8900, 0x09}, + {0x8901, 0x73}, + {0x8902, 0x18}, + {0x8903, 0x09}, + {0x8904, 0x89}, + {0x8905, 0x19}, + {0x8906, 0x09}, + {0x8907, 0x5e}, + {0x8908, 0x1a}, + {0x8909, 0x09}, + {0x890a, 0x6a}, + {0x890b, 0x1b}, + {0x890c, 0x09}, + {0x890d, 0xad}, + {0x890e, 0x80}, + {0x890f, 0x09}, + {0x8910, 0xb2}, + {0x8911, 0x81}, + {0x8912, 0x0a}, + {0x8913, 0x1d}, + {0x8914, 0x8f}, + {0x8915, 0x0a}, + {0x8916, 0x09}, + {0x8917, 0x90}, + {0x8918, 0x0a}, + {0x8919, 0x1d}, + {0x891a, 0x91}, + {0x891b, 0x0a}, + {0x891c, 0x1d}, + {0x891d, 0x92}, + {0x891e, 0x0a}, + {0x891f, 0x1d}, + {0x8920, 0x93}, + {0x8921, 0x0a}, + {0x8922, 0x1d}, + {0x8923, 0x94}, + {0x8924, 0x0a}, + {0x8925, 0x1d}, + {0x8926, 0x98}, + {0x8927, 0x0a}, + {0x8928, 0x17}, + {0x8929, 0x9f}, + {0x892a, 0x0a}, + {0x892b, 0x1a}, + {0x892c, 0xec}, + {0x892d, 0x00}, + {0x892e, 0x00}, + {0x892f, 0x0a}, + {0x8930, 0x38}, + {0x8931, 0x12}, + {0x8932, 0x0f}, + {0x8933, 0x74}, + {0x8934, 0x22}, + {0x8935, 0x12}, + {0x8936, 0x0f}, + {0x8937, 0x74}, + {0x8938, 0xd2}, + {0x8939, 0x03}, + {0x893a, 0x22}, + {0x893b, 0xd2}, + {0x893c, 0x03}, + {0x893d, 0x22}, + {0x893e, 0xc2}, + {0x893f, 0x03}, + {0x8940, 0x22}, + {0x8941, 0xa2}, + {0x8942, 0x37}, + {0x8943, 0xe4}, + {0x8944, 0x33}, + {0x8945, 0xf5}, + {0x8946, 0x3c}, + {0x8947, 0x02}, + {0x8948, 0x0a}, + {0x8949, 0x1d}, + {0x894a, 0xc2}, + {0x894b, 0x01}, + {0x894c, 0xc2}, + {0x894d, 0x02}, + {0x894e, 0xc2}, + {0x894f, 0x03}, + {0x8950, 0x12}, + {0x8951, 0x0d}, + {0x8952, 0x0d}, + {0x8953, 0x75}, + {0x8954, 0x1e}, + {0x8955, 0x70}, + {0x8956, 0xd2}, + {0x8957, 0x35}, + {0x8958, 0x02}, + {0x8959, 0x0a}, + {0x895a, 0x1d}, + {0x895b, 0x02}, + {0x895c, 0x0a}, + {0x895d, 0x04}, + {0x895e, 0x85}, + {0x895f, 0x40}, + {0x8960, 0x4a}, + {0x8961, 0x85}, + {0x8962, 0x3c}, + {0x8963, 0x4b}, + {0x8964, 0x12}, + {0x8965, 0x0a}, + {0x8966, 0xff}, + {0x8967, 0x02}, + {0x8968, 0x0a}, + {0x8969, 0x1d}, + {0x896a, 0x85}, + {0x896b, 0x4a}, + {0x896c, 0x40}, + {0x896d, 0x85}, + {0x896e, 0x4b}, + {0x896f, 0x3c}, + {0x8970, 0x02}, + {0x8971, 0x0a}, + {0x8972, 0x1d}, + {0x8973, 0xe4}, + {0x8974, 0xf5}, + {0x8975, 0x22}, + {0x8976, 0xf5}, + {0x8977, 0x23}, + {0x8978, 0x85}, + {0x8979, 0x40}, + {0x897a, 0x31}, + {0x897b, 0x85}, + {0x897c, 0x3f}, + {0x897d, 0x30}, + {0x897e, 0x85}, + {0x897f, 0x3e}, + {0x8980, 0x2f}, + {0x8981, 0x85}, + {0x8982, 0x3d}, + {0x8983, 0x2e}, + {0x8984, 0x12}, + {0x8985, 0x0f}, + {0x8986, 0x46}, + {0x8987, 0x80}, + {0x8988, 0x1f}, + {0x8989, 0x75}, + {0x898a, 0x22}, + {0x898b, 0x00}, + {0x898c, 0x75}, + {0x898d, 0x23}, + {0x898e, 0x01}, + {0x898f, 0x74}, + {0x8990, 0xff}, + {0x8991, 0xf5}, + {0x8992, 0x2d}, + {0x8993, 0xf5}, + {0x8994, 0x2c}, + {0x8995, 0xf5}, + {0x8996, 0x2b}, + {0x8997, 0xf5}, + {0x8998, 0x2a}, + {0x8999, 0x12}, + {0x899a, 0x0f}, + {0x899b, 0x46}, + {0x899c, 0x85}, + {0x899d, 0x2d}, + {0x899e, 0x40}, + {0x899f, 0x85}, + {0x89a0, 0x2c}, + {0x89a1, 0x3f}, + {0x89a2, 0x85}, + {0x89a3, 0x2b}, + {0x89a4, 0x3e}, + {0x89a5, 0x85}, + {0x89a6, 0x2a}, + {0x89a7, 0x3d}, + {0x89a8, 0xe4}, + {0x89a9, 0xf5}, + {0x89aa, 0x3c}, + {0x89ab, 0x80}, + {0x89ac, 0x70}, + {0x89ad, 0x12}, + {0x89ae, 0x0f}, + {0x89af, 0x16}, + {0x89b0, 0x80}, + {0x89b1, 0x6b}, + {0x89b2, 0x85}, + {0x89b3, 0x3d}, + {0x89b4, 0x45}, + {0x89b5, 0x85}, + {0x89b6, 0x3e}, + {0x89b7, 0x46}, + {0x89b8, 0xe5}, + {0x89b9, 0x47}, + {0x89ba, 0xc3}, + {0x89bb, 0x13}, + {0x89bc, 0xff}, + {0x89bd, 0xe5}, + {0x89be, 0x45}, + {0x89bf, 0xc3}, + {0x89c0, 0x9f}, + {0x89c1, 0x50}, + {0x89c2, 0x02}, + {0x89c3, 0x8f}, + {0x89c4, 0x45}, + {0x89c5, 0xe5}, + {0x89c6, 0x48}, + {0x89c7, 0xc3}, + {0x89c8, 0x13}, + {0x89c9, 0xff}, + {0x89ca, 0xe5}, + {0x89cb, 0x46}, + {0x89cc, 0xc3}, + {0x89cd, 0x9f}, + {0x89ce, 0x50}, + {0x89cf, 0x02}, + {0x89d0, 0x8f}, + {0x89d1, 0x46}, + {0x89d2, 0xe5}, + {0x89d3, 0x47}, + {0x89d4, 0xc3}, + {0x89d5, 0x13}, + {0x89d6, 0xff}, + {0x89d7, 0xfd}, + {0x89d8, 0xe5}, + {0x89d9, 0x45}, + {0x89da, 0x2d}, + {0x89db, 0xfd}, + {0x89dc, 0xe4}, + {0x89dd, 0x33}, + {0x89de, 0xfc}, + {0x89df, 0xe5}, + {0x89e0, 0x44}, + {0x89e1, 0x12}, + {0x89e2, 0x0f}, + {0x89e3, 0x90}, + {0x89e4, 0x40}, + {0x89e5, 0x05}, + {0x89e6, 0xe5}, + {0x89e7, 0x44}, + {0x89e8, 0x9f}, + {0x89e9, 0xf5}, + {0x89ea, 0x45}, + {0x89eb, 0xe5}, + {0x89ec, 0x48}, + {0x89ed, 0xc3}, + {0x89ee, 0x13}, + {0x89ef, 0xff}, + {0x89f0, 0xfd}, + {0x89f1, 0xe5}, + {0x89f2, 0x46}, + {0x89f3, 0x2d}, + {0x89f4, 0xfd}, + {0x89f5, 0xe4}, + {0x89f6, 0x33}, + {0x89f7, 0xfc}, + {0x89f8, 0xe5}, + {0x89f9, 0x43}, + {0x89fa, 0x12}, + {0x89fb, 0x0f}, + {0x89fc, 0x90}, + {0x89fd, 0x40}, + {0x89fe, 0x05}, + {0x89ff, 0xe5}, + {0x8a00, 0x43}, + {0x8a01, 0x9f}, + {0x8a02, 0xf5}, + {0x8a03, 0x46}, + {0x8a04, 0x12}, + {0x8a05, 0x06}, + {0x8a06, 0xd7}, + {0x8a07, 0x80}, + {0x8a08, 0x14}, + {0x8a09, 0x85}, + {0x8a0a, 0x40}, + {0x8a0b, 0x48}, + {0x8a0c, 0x85}, + {0x8a0d, 0x3f}, + {0x8a0e, 0x47}, + {0x8a0f, 0x85}, + {0x8a10, 0x3e}, + {0x8a11, 0x46}, + {0x8a12, 0x85}, + {0x8a13, 0x3d}, + {0x8a14, 0x45}, + {0x8a15, 0x80}, + {0x8a16, 0x06}, + {0x8a17, 0x02}, + {0x8a18, 0x06}, + {0x8a19, 0xd7}, + {0x8a1a, 0x12}, + {0x8a1b, 0x0d}, + {0x8a1c, 0x7e}, + {0x8a1d, 0x90}, + {0x8a1e, 0x30}, + {0x8a1f, 0x24}, + {0x8a20, 0xe5}, + {0x8a21, 0x3d}, + {0x8a22, 0xf0}, + {0x8a23, 0xa3}, + {0x8a24, 0xe5}, + {0x8a25, 0x3e}, + {0x8a26, 0xf0}, + {0x8a27, 0xa3}, + {0x8a28, 0xe5}, + {0x8a29, 0x3f}, + {0x8a2a, 0xf0}, + {0x8a2b, 0xa3}, + {0x8a2c, 0xe5}, + {0x8a2d, 0x40}, + {0x8a2e, 0xf0}, + {0x8a2f, 0xa3}, + {0x8a30, 0xe5}, + {0x8a31, 0x3c}, + {0x8a32, 0xf0}, + {0x8a33, 0x90}, + {0x8a34, 0x30}, + {0x8a35, 0x23}, + {0x8a36, 0xe4}, + {0x8a37, 0xf0}, + {0x8a38, 0x22}, + {0x8a39, 0xc0}, + {0x8a3a, 0xe0}, + {0x8a3b, 0xc0}, + {0x8a3c, 0x83}, + {0x8a3d, 0xc0}, + {0x8a3e, 0x82}, + {0x8a3f, 0xc0}, + {0x8a40, 0xd0}, + {0x8a41, 0x90}, + {0x8a42, 0x3f}, + {0x8a43, 0x0c}, + {0x8a44, 0xe0}, + {0x8a45, 0xf5}, + {0x8a46, 0x32}, + {0x8a47, 0xe5}, + {0x8a48, 0x32}, + {0x8a49, 0x30}, + {0x8a4a, 0xe3}, + {0x8a4b, 0x74}, + {0x8a4c, 0x30}, + {0x8a4d, 0x36}, + {0x8a4e, 0x66}, + {0x8a4f, 0x90}, + {0x8a50, 0x60}, + {0x8a51, 0x19}, + {0x8a52, 0xe0}, + {0x8a53, 0xf5}, + {0x8a54, 0x0a}, + {0x8a55, 0xa3}, + {0x8a56, 0xe0}, + {0x8a57, 0xf5}, + {0x8a58, 0x0b}, + {0x8a59, 0x90}, + {0x8a5a, 0x60}, + {0x8a5b, 0x1d}, + {0x8a5c, 0xe0}, + {0x8a5d, 0xf5}, + {0x8a5e, 0x14}, + {0x8a5f, 0xa3}, + {0x8a60, 0xe0}, + {0x8a61, 0xf5}, + {0x8a62, 0x15}, + {0x8a63, 0x90}, + {0x8a64, 0x60}, + {0x8a65, 0x21}, + {0x8a66, 0xe0}, + {0x8a67, 0xf5}, + {0x8a68, 0x0c}, + {0x8a69, 0xa3}, + {0x8a6a, 0xe0}, + {0x8a6b, 0xf5}, + {0x8a6c, 0x0d}, + {0x8a6d, 0x90}, + {0x8a6e, 0x60}, + {0x8a6f, 0x29}, + {0x8a70, 0xe0}, + {0x8a71, 0xf5}, + {0x8a72, 0x0e}, + {0x8a73, 0xa3}, + {0x8a74, 0xe0}, + {0x8a75, 0xf5}, + {0x8a76, 0x0f}, + {0x8a77, 0x90}, + {0x8a78, 0x60}, + {0x8a79, 0x31}, + {0x8a7a, 0xe0}, + {0x8a7b, 0xf5}, + {0x8a7c, 0x10}, + {0x8a7d, 0xa3}, + {0x8a7e, 0xe0}, + {0x8a7f, 0xf5}, + {0x8a80, 0x11}, + {0x8a81, 0x90}, + {0x8a82, 0x60}, + {0x8a83, 0x39}, + {0x8a84, 0xe0}, + {0x8a85, 0xf5}, + {0x8a86, 0x12}, + {0x8a87, 0xa3}, + {0x8a88, 0xe0}, + {0x8a89, 0xf5}, + {0x8a8a, 0x13}, + {0x8a8b, 0x30}, + {0x8a8c, 0x01}, + {0x8a8d, 0x06}, + {0x8a8e, 0x30}, + {0x8a8f, 0x33}, + {0x8a90, 0x03}, + {0x8a91, 0xd3}, + {0x8a92, 0x80}, + {0x8a93, 0x01}, + {0x8a94, 0xc3}, + {0x8a95, 0x92}, + {0x8a96, 0x09}, + {0x8a97, 0x30}, + {0x8a98, 0x02}, + {0x8a99, 0x06}, + {0x8a9a, 0x30}, + {0x8a9b, 0x33}, + {0x8a9c, 0x03}, + {0x8a9d, 0xd3}, + {0x8a9e, 0x80}, + {0x8a9f, 0x01}, + {0x8aa0, 0xc3}, + {0x8aa1, 0x92}, + {0x8aa2, 0x0a}, + {0x8aa3, 0x30}, + {0x8aa4, 0x33}, + {0x8aa5, 0x0c}, + {0x8aa6, 0x30}, + {0x8aa7, 0x03}, + {0x8aa8, 0x09}, + {0x8aa9, 0x20}, + {0x8aaa, 0x02}, + {0x8aab, 0x06}, + {0x8aac, 0x20}, + {0x8aad, 0x01}, + {0x8aae, 0x03}, + {0x8aaf, 0xd3}, + {0x8ab0, 0x80}, + {0x8ab1, 0x01}, + {0x8ab2, 0xc3}, + {0x8ab3, 0x92}, + {0x8ab4, 0x0b}, + {0x8ab5, 0x90}, + {0x8ab6, 0x30}, + {0x8ab7, 0x01}, + {0x8ab8, 0xe0}, + {0x8ab9, 0x44}, + {0x8aba, 0x40}, + {0x8abb, 0xf0}, + {0x8abc, 0xe0}, + {0x8abd, 0x54}, + {0x8abe, 0xbf}, + {0x8abf, 0xf0}, + {0x8ac0, 0xe5}, + {0x8ac1, 0x32}, + {0x8ac2, 0x30}, + {0x8ac3, 0xe1}, + {0x8ac4, 0x14}, + {0x8ac5, 0x30}, + {0x8ac6, 0x34}, + {0x8ac7, 0x11}, + {0x8ac8, 0x90}, + {0x8ac9, 0x30}, + {0x8aca, 0x22}, + {0x8acb, 0xe0}, + {0x8acc, 0xf5}, + {0x8acd, 0x08}, + {0x8ace, 0xe4}, + {0x8acf, 0xf0}, + {0x8ad0, 0x30}, + {0x8ad1, 0x00}, + {0x8ad2, 0x03}, + {0x8ad3, 0xd3}, + {0x8ad4, 0x80}, + {0x8ad5, 0x01}, + {0x8ad6, 0xc3}, + {0x8ad7, 0x92}, + {0x8ad8, 0x08}, + {0x8ad9, 0xe5}, + {0x8ada, 0x32}, + {0x8adb, 0x30}, + {0x8adc, 0xe5}, + {0x8add, 0x12}, + {0x8ade, 0x90}, + {0x8adf, 0x56}, + {0x8ae0, 0xa1}, + {0x8ae1, 0xe0}, + {0x8ae2, 0xf5}, + {0x8ae3, 0x09}, + {0x8ae4, 0x30}, + {0x8ae5, 0x31}, + {0x8ae6, 0x09}, + {0x8ae7, 0x30}, + {0x8ae8, 0x05}, + {0x8ae9, 0x03}, + {0x8aea, 0xd3}, + {0x8aeb, 0x80}, + {0x8aec, 0x01}, + {0x8aed, 0xc3}, + {0x8aee, 0x92}, + {0x8aef, 0x0d}, + {0x8af0, 0x90}, + {0x8af1, 0x3f}, + {0x8af2, 0x0c}, + {0x8af3, 0xe5}, + {0x8af4, 0x32}, + {0x8af5, 0xf0}, + {0x8af6, 0xd0}, + {0x8af7, 0xd0}, + {0x8af8, 0xd0}, + {0x8af9, 0x82}, + {0x8afa, 0xd0}, + {0x8afb, 0x83}, + {0x8afc, 0xd0}, + {0x8afd, 0xe0}, + {0x8afe, 0x32}, + {0x8aff, 0x90}, + {0x8b00, 0x0e}, + {0x8b01, 0x7e}, + {0x8b02, 0xe4}, + {0x8b03, 0x93}, + {0x8b04, 0xfe}, + {0x8b05, 0x74}, + {0x8b06, 0x01}, + {0x8b07, 0x93}, + {0x8b08, 0xff}, + {0x8b09, 0xc3}, + {0x8b0a, 0x90}, + {0x8b0b, 0x0e}, + {0x8b0c, 0x7c}, + {0x8b0d, 0x74}, + {0x8b0e, 0x01}, + {0x8b0f, 0x93}, + {0x8b10, 0x9f}, + {0x8b11, 0xff}, + {0x8b12, 0xe4}, + {0x8b13, 0x93}, + {0x8b14, 0x9e}, + {0x8b15, 0xfe}, + {0x8b16, 0xe4}, + {0x8b17, 0x8f}, + {0x8b18, 0x3b}, + {0x8b19, 0x8e}, + {0x8b1a, 0x3a}, + {0x8b1b, 0xf5}, + {0x8b1c, 0x39}, + {0x8b1d, 0xf5}, + {0x8b1e, 0x38}, + {0x8b1f, 0xab}, + {0x8b20, 0x3b}, + {0x8b21, 0xaa}, + {0x8b22, 0x3a}, + {0x8b23, 0xa9}, + {0x8b24, 0x39}, + {0x8b25, 0xa8}, + {0x8b26, 0x38}, + {0x8b27, 0xaf}, + {0x8b28, 0x4b}, + {0x8b29, 0xfc}, + {0x8b2a, 0xfd}, + {0x8b2b, 0xfe}, + {0x8b2c, 0x12}, + {0x8b2d, 0x05}, + {0x8b2e, 0x28}, + {0x8b2f, 0x12}, + {0x8b30, 0x0d}, + {0x8b31, 0xe1}, + {0x8b32, 0xe4}, + {0x8b33, 0x7b}, + {0x8b34, 0xff}, + {0x8b35, 0xfa}, + {0x8b36, 0xf9}, + {0x8b37, 0xf8}, + {0x8b38, 0x12}, + {0x8b39, 0x05}, + {0x8b3a, 0xb3}, + {0x8b3b, 0x12}, + {0x8b3c, 0x0d}, + {0x8b3d, 0xe1}, + {0x8b3e, 0x90}, + {0x8b3f, 0x0e}, + {0x8b40, 0x69}, + {0x8b41, 0xe4}, + {0x8b42, 0x12}, + {0x8b43, 0x0d}, + {0x8b44, 0xf6}, + {0x8b45, 0x12}, + {0x8b46, 0x0d}, + {0x8b47, 0xe1}, + {0x8b48, 0xe4}, + {0x8b49, 0x85}, + {0x8b4a, 0x4a}, + {0x8b4b, 0x37}, + {0x8b4c, 0xf5}, + {0x8b4d, 0x36}, + {0x8b4e, 0xf5}, + {0x8b4f, 0x35}, + {0x8b50, 0xf5}, + {0x8b51, 0x34}, + {0x8b52, 0xaf}, + {0x8b53, 0x37}, + {0x8b54, 0xae}, + {0x8b55, 0x36}, + {0x8b56, 0xad}, + {0x8b57, 0x35}, + {0x8b58, 0xac}, + {0x8b59, 0x34}, + {0x8b5a, 0xa3}, + {0x8b5b, 0x12}, + {0x8b5c, 0x0d}, + {0x8b5d, 0xf6}, + {0x8b5e, 0x8f}, + {0x8b5f, 0x37}, + {0x8b60, 0x8e}, + {0x8b61, 0x36}, + {0x8b62, 0x8d}, + {0x8b63, 0x35}, + {0x8b64, 0x8c}, + {0x8b65, 0x34}, + {0x8b66, 0xe5}, + {0x8b67, 0x3b}, + {0x8b68, 0x45}, + {0x8b69, 0x37}, + {0x8b6a, 0xf5}, + {0x8b6b, 0x3b}, + {0x8b6c, 0xe5}, + {0x8b6d, 0x3a}, + {0x8b6e, 0x45}, + {0x8b6f, 0x36}, + {0x8b70, 0xf5}, + {0x8b71, 0x3a}, + {0x8b72, 0xe5}, + {0x8b73, 0x39}, + {0x8b74, 0x45}, + {0x8b75, 0x35}, + {0x8b76, 0xf5}, + {0x8b77, 0x39}, + {0x8b78, 0xe5}, + {0x8b79, 0x38}, + {0x8b7a, 0x45}, + {0x8b7b, 0x34}, + {0x8b7c, 0xf5}, + {0x8b7d, 0x38}, + {0x8b7e, 0xe4}, + {0x8b7f, 0xf5}, + {0x8b80, 0x22}, + {0x8b81, 0xf5}, + {0x8b82, 0x23}, + {0x8b83, 0x85}, + {0x8b84, 0x3b}, + {0x8b85, 0x31}, + {0x8b86, 0x85}, + {0x8b87, 0x3a}, + {0x8b88, 0x30}, + {0x8b89, 0x85}, + {0x8b8a, 0x39}, + {0x8b8b, 0x2f}, + {0x8b8c, 0x85}, + {0x8b8d, 0x38}, + {0x8b8e, 0x2e}, + {0x8b8f, 0x02}, + {0x8b90, 0x0f}, + {0x8b91, 0x46}, + {0x8b92, 0xe0}, + {0x8b93, 0xa3}, + {0x8b94, 0xe0}, + {0x8b95, 0x75}, + {0x8b96, 0xf0}, + {0x8b97, 0x02}, + {0x8b98, 0xa4}, + {0x8b99, 0xff}, + {0x8b9a, 0xae}, + {0x8b9b, 0xf0}, + {0x8b9c, 0xc3}, + {0x8b9d, 0x08}, + {0x8b9e, 0xe6}, + {0x8b9f, 0x9f}, + {0x8ba0, 0xf6}, + {0x8ba1, 0x18}, + {0x8ba2, 0xe6}, + {0x8ba3, 0x9e}, + {0x8ba4, 0xf6}, + {0x8ba5, 0x22}, + {0x8ba6, 0xff}, + {0x8ba7, 0xe5}, + {0x8ba8, 0xf0}, + {0x8ba9, 0x34}, + {0x8baa, 0x60}, + {0x8bab, 0x8f}, + {0x8bac, 0x82}, + {0x8bad, 0xf5}, + {0x8bae, 0x83}, + {0x8baf, 0xec}, + {0x8bb0, 0xf0}, + {0x8bb1, 0x22}, + {0x8bb2, 0x78}, + {0x8bb3, 0x52}, + {0x8bb4, 0x7e}, + {0x8bb5, 0x00}, + {0x8bb6, 0xe6}, + {0x8bb7, 0xfc}, + {0x8bb8, 0x08}, + {0x8bb9, 0xe6}, + {0x8bba, 0xfd}, + {0x8bbb, 0x02}, + {0x8bbc, 0x04}, + {0x8bbd, 0xc1}, + {0x8bbe, 0xe4}, + {0x8bbf, 0xfc}, + {0x8bc0, 0xfd}, + {0x8bc1, 0x12}, + {0x8bc2, 0x06}, + {0x8bc3, 0x99}, + {0x8bc4, 0x78}, + {0x8bc5, 0x5c}, + {0x8bc6, 0xe6}, + {0x8bc7, 0xc3}, + {0x8bc8, 0x13}, + {0x8bc9, 0xfe}, + {0x8bca, 0x08}, + {0x8bcb, 0xe6}, + {0x8bcc, 0x13}, + {0x8bcd, 0x22}, + {0x8bce, 0x78}, + {0x8bcf, 0x52}, + {0x8bd0, 0xe6}, + {0x8bd1, 0xfe}, + {0x8bd2, 0x08}, + {0x8bd3, 0xe6}, + {0x8bd4, 0xff}, + {0x8bd5, 0xe4}, + {0x8bd6, 0xfc}, + {0x8bd7, 0xfd}, + {0x8bd8, 0x22}, + {0x8bd9, 0xe7}, + {0x8bda, 0xc4}, + {0x8bdb, 0xf8}, + {0x8bdc, 0x54}, + {0x8bdd, 0xf0}, + {0x8bde, 0xc8}, + {0x8bdf, 0x68}, + {0x8be0, 0xf7}, + {0x8be1, 0x09}, + {0x8be2, 0xe7}, + {0x8be3, 0xc4}, + {0x8be4, 0x54}, + {0x8be5, 0x0f}, + {0x8be6, 0x48}, + {0x8be7, 0xf7}, + {0x8be8, 0x22}, + {0x8be9, 0xe6}, + {0x8bea, 0xfc}, + {0x8beb, 0xed}, + {0x8bec, 0x75}, + {0x8bed, 0xf0}, + {0x8bee, 0x04}, + {0x8bef, 0xa4}, + {0x8bf0, 0x22}, + {0x8bf1, 0x12}, + {0x8bf2, 0x06}, + {0x8bf3, 0x7c}, + {0x8bf4, 0x8f}, + {0x8bf5, 0x48}, + {0x8bf6, 0x8e}, + {0x8bf7, 0x47}, + {0x8bf8, 0x8d}, + {0x8bf9, 0x46}, + {0x8bfa, 0x8c}, + {0x8bfb, 0x45}, + {0x8bfc, 0x22}, + {0x8bfd, 0xe0}, + {0x8bfe, 0xfe}, + {0x8bff, 0xa3}, + {0x8c00, 0xe0}, + {0x8c01, 0xfd}, + {0x8c02, 0xee}, + {0x8c03, 0xf6}, + {0x8c04, 0xed}, + {0x8c05, 0x08}, + {0x8c06, 0xf6}, + {0x8c07, 0x22}, + {0x8c08, 0x13}, + {0x8c09, 0xff}, + {0x8c0a, 0xc3}, + {0x8c0b, 0xe6}, + {0x8c0c, 0x9f}, + {0x8c0d, 0xff}, + {0x8c0e, 0x18}, + {0x8c0f, 0xe6}, + {0x8c10, 0x9e}, + {0x8c11, 0xfe}, + {0x8c12, 0x22}, + {0x8c13, 0xe6}, + {0x8c14, 0xc3}, + {0x8c15, 0x13}, + {0x8c16, 0xf7}, + {0x8c17, 0x08}, + {0x8c18, 0xe6}, + {0x8c19, 0x13}, + {0x8c1a, 0x09}, + {0x8c1b, 0xf7}, + {0x8c1c, 0x22}, + {0x8c1d, 0xad}, + {0x8c1e, 0x39}, + {0x8c1f, 0xac}, + {0x8c20, 0x38}, + {0x8c21, 0xfa}, + {0x8c22, 0xf9}, + {0x8c23, 0xf8}, + {0x8c24, 0x12}, + {0x8c25, 0x05}, + {0x8c26, 0x28}, + {0x8c27, 0x8f}, + {0x8c28, 0x3b}, + {0x8c29, 0x8e}, + {0x8c2a, 0x3a}, + {0x8c2b, 0x8d}, + {0x8c2c, 0x39}, + {0x8c2d, 0x8c}, + {0x8c2e, 0x38}, + {0x8c2f, 0xab}, + {0x8c30, 0x37}, + {0x8c31, 0xaa}, + {0x8c32, 0x36}, + {0x8c33, 0xa9}, + {0x8c34, 0x35}, + {0x8c35, 0xa8}, + {0x8c36, 0x34}, + {0x8c37, 0x22}, + {0x8c38, 0x93}, + {0x8c39, 0xff}, + {0x8c3a, 0xe4}, + {0x8c3b, 0xfc}, + {0x8c3c, 0xfd}, + {0x8c3d, 0xfe}, + {0x8c3e, 0x12}, + {0x8c3f, 0x05}, + {0x8c40, 0x28}, + {0x8c41, 0x8f}, + {0x8c42, 0x37}, + {0x8c43, 0x8e}, + {0x8c44, 0x36}, + {0x8c45, 0x8d}, + {0x8c46, 0x35}, + {0x8c47, 0x8c}, + {0x8c48, 0x34}, + {0x8c49, 0x22}, + {0x8c4a, 0x78}, + {0x8c4b, 0x84}, + {0x8c4c, 0xe6}, + {0x8c4d, 0xfe}, + {0x8c4e, 0x08}, + {0x8c4f, 0xe6}, + {0x8c50, 0xff}, + {0x8c51, 0xe4}, + {0x8c52, 0x8f}, + {0x8c53, 0x37}, + {0x8c54, 0x8e}, + {0x8c55, 0x36}, + {0x8c56, 0xf5}, + {0x8c57, 0x35}, + {0x8c58, 0xf5}, + {0x8c59, 0x34}, + {0x8c5a, 0x22}, + {0x8c5b, 0x90}, + {0x8c5c, 0x0e}, + {0x8c5d, 0x8c}, + {0x8c5e, 0xe4}, + {0x8c5f, 0x93}, + {0x8c60, 0x25}, + {0x8c61, 0xe0}, + {0x8c62, 0x24}, + {0x8c63, 0x0a}, + {0x8c64, 0xf8}, + {0x8c65, 0xe6}, + {0x8c66, 0xfe}, + {0x8c67, 0x08}, + {0x8c68, 0xe6}, + {0x8c69, 0xff}, + {0x8c6a, 0x22}, + {0x8c6b, 0xe6}, + {0x8c6c, 0xfe}, + {0x8c6d, 0x08}, + {0x8c6e, 0xe6}, + {0x8c6f, 0xff}, + {0x8c70, 0xe4}, + {0x8c71, 0x8f}, + {0x8c72, 0x3b}, + {0x8c73, 0x8e}, + {0x8c74, 0x3a}, + {0x8c75, 0xf5}, + {0x8c76, 0x39}, + {0x8c77, 0xf5}, + {0x8c78, 0x38}, + {0x8c79, 0x22}, + {0x8c7a, 0x78}, + {0x8c7b, 0x4e}, + {0x8c7c, 0xe6}, + {0x8c7d, 0xfe}, + {0x8c7e, 0x08}, + {0x8c7f, 0xe6}, + {0x8c80, 0xff}, + {0x8c81, 0x22}, + {0x8c82, 0xef}, + {0x8c83, 0x25}, + {0x8c84, 0xe0}, + {0x8c85, 0x24}, + {0x8c86, 0x4e}, + {0x8c87, 0xf8}, + {0x8c88, 0xe6}, + {0x8c89, 0xfc}, + {0x8c8a, 0x08}, + {0x8c8b, 0xe6}, + {0x8c8c, 0xfd}, + {0x8c8d, 0x22}, + {0x8c8e, 0x78}, + {0x8c8f, 0x89}, + {0x8c90, 0xef}, + {0x8c91, 0x26}, + {0x8c92, 0xf6}, + {0x8c93, 0x18}, + {0x8c94, 0xe4}, + {0x8c95, 0x36}, + {0x8c96, 0xf6}, + {0x8c97, 0x22}, + {0x8c98, 0x75}, + {0x8c99, 0x89}, + {0x8c9a, 0x03}, + {0x8c9b, 0x75}, + {0x8c9c, 0xa8}, + {0x8c9d, 0x01}, + {0x8c9e, 0x75}, + {0x8c9f, 0xb8}, + {0x8ca0, 0x04}, + {0x8ca1, 0x75}, + {0x8ca2, 0x34}, + {0x8ca3, 0xff}, + {0x8ca4, 0x75}, + {0x8ca5, 0x35}, + {0x8ca6, 0x0e}, + {0x8ca7, 0x75}, + {0x8ca8, 0x36}, + {0x8ca9, 0x15}, + {0x8caa, 0x75}, + {0x8cab, 0x37}, + {0x8cac, 0x0d}, + {0x8cad, 0x12}, + {0x8cae, 0x0e}, + {0x8caf, 0x9a}, + {0x8cb0, 0x12}, + {0x8cb1, 0x00}, + {0x8cb2, 0x09}, + {0x8cb3, 0x12}, + {0x8cb4, 0x0f}, + {0x8cb5, 0x16}, + {0x8cb6, 0x12}, + {0x8cb7, 0x00}, + {0x8cb8, 0x06}, + {0x8cb9, 0xd2}, + {0x8cba, 0x00}, + {0x8cbb, 0xd2}, + {0x8cbc, 0x34}, + {0x8cbd, 0xd2}, + {0x8cbe, 0xaf}, + {0x8cbf, 0x75}, + {0x8cc0, 0x34}, + {0x8cc1, 0xff}, + {0x8cc2, 0x75}, + {0x8cc3, 0x35}, + {0x8cc4, 0x0e}, + {0x8cc5, 0x75}, + {0x8cc6, 0x36}, + {0x8cc7, 0x49}, + {0x8cc8, 0x75}, + {0x8cc9, 0x37}, + {0x8cca, 0x03}, + {0x8ccb, 0x12}, + {0x8ccc, 0x0e}, + {0x8ccd, 0x9a}, + {0x8cce, 0x30}, + {0x8ccf, 0x08}, + {0x8cd0, 0x09}, + {0x8cd1, 0xc2}, + {0x8cd2, 0x34}, + {0x8cd3, 0x12}, + {0x8cd4, 0x08}, + {0x8cd5, 0xcb}, + {0x8cd6, 0xc2}, + {0x8cd7, 0x08}, + {0x8cd8, 0xd2}, + {0x8cd9, 0x34}, + {0x8cda, 0x30}, + {0x8cdb, 0x0b}, + {0x8cdc, 0x09}, + {0x8cdd, 0xc2}, + {0x8cde, 0x36}, + {0x8cdf, 0x12}, + {0x8ce0, 0x02}, + {0x8ce1, 0x6c}, + {0x8ce2, 0xc2}, + {0x8ce3, 0x0b}, + {0x8ce4, 0xd2}, + {0x8ce5, 0x36}, + {0x8ce6, 0x30}, + {0x8ce7, 0x09}, + {0x8ce8, 0x09}, + {0x8ce9, 0xc2}, + {0x8cea, 0x36}, + {0x8ceb, 0x12}, + {0x8cec, 0x00}, + {0x8ced, 0x0e}, + {0x8cee, 0xc2}, + {0x8cef, 0x09}, + {0x8cf0, 0xd2}, + {0x8cf1, 0x36}, + {0x8cf2, 0x30}, + {0x8cf3, 0x0e}, + {0x8cf4, 0x03}, + {0x8cf5, 0x12}, + {0x8cf6, 0x06}, + {0x8cf7, 0xd7}, + {0x8cf8, 0x30}, + {0x8cf9, 0x35}, + {0x8cfa, 0xd3}, + {0x8cfb, 0x90}, + {0x8cfc, 0x30}, + {0x8cfd, 0x29}, + {0x8cfe, 0xe5}, + {0x8cff, 0x1e}, + {0x8d00, 0xf0}, + {0x8d01, 0xb4}, + {0x8d02, 0x10}, + {0x8d03, 0x05}, + {0x8d04, 0x90}, + {0x8d05, 0x30}, + {0x8d06, 0x23}, + {0x8d07, 0xe4}, + {0x8d08, 0xf0}, + {0x8d09, 0xc2}, + {0x8d0a, 0x35}, + {0x8d0b, 0x80}, + {0x8d0c, 0xc1}, + {0x8d0d, 0xe4}, + {0x8d0e, 0xf5}, + {0x8d0f, 0x4b}, + {0x8d10, 0x90}, + {0x8d11, 0x0e}, + {0x8d12, 0x7a}, + {0x8d13, 0x93}, + {0x8d14, 0xff}, + {0x8d15, 0xe4}, + {0x8d16, 0x8f}, + {0x8d17, 0x37}, + {0x8d18, 0xf5}, + {0x8d19, 0x36}, + {0x8d1a, 0xf5}, + {0x8d1b, 0x35}, + {0x8d1c, 0xf5}, + {0x8d1d, 0x34}, + {0x8d1e, 0xaf}, + {0x8d1f, 0x37}, + {0x8d20, 0xae}, + {0x8d21, 0x36}, + {0x8d22, 0xad}, + {0x8d23, 0x35}, + {0x8d24, 0xac}, + {0x8d25, 0x34}, + {0x8d26, 0x90}, + {0x8d27, 0x0e}, + {0x8d28, 0x6a}, + {0x8d29, 0x12}, + {0x8d2a, 0x0d}, + {0x8d2b, 0xf6}, + {0x8d2c, 0x8f}, + {0x8d2d, 0x37}, + {0x8d2e, 0x8e}, + {0x8d2f, 0x36}, + {0x8d30, 0x8d}, + {0x8d31, 0x35}, + {0x8d32, 0x8c}, + {0x8d33, 0x34}, + {0x8d34, 0x90}, + {0x8d35, 0x0e}, + {0x8d36, 0x72}, + {0x8d37, 0x12}, + {0x8d38, 0x06}, + {0x8d39, 0x7c}, + {0x8d3a, 0xef}, + {0x8d3b, 0x45}, + {0x8d3c, 0x37}, + {0x8d3d, 0xf5}, + {0x8d3e, 0x37}, + {0x8d3f, 0xee}, + {0x8d40, 0x45}, + {0x8d41, 0x36}, + {0x8d42, 0xf5}, + {0x8d43, 0x36}, + {0x8d44, 0xed}, + {0x8d45, 0x45}, + {0x8d46, 0x35}, + {0x8d47, 0xf5}, + {0x8d48, 0x35}, + {0x8d49, 0xec}, + {0x8d4a, 0x45}, + {0x8d4b, 0x34}, + {0x8d4c, 0xf5}, + {0x8d4d, 0x34}, + {0x8d4e, 0xe4}, + {0x8d4f, 0xf5}, + {0x8d50, 0x22}, + {0x8d51, 0xf5}, + {0x8d52, 0x23}, + {0x8d53, 0x85}, + {0x8d54, 0x37}, + {0x8d55, 0x31}, + {0x8d56, 0x85}, + {0x8d57, 0x36}, + {0x8d58, 0x30}, + {0x8d59, 0x85}, + {0x8d5a, 0x35}, + {0x8d5b, 0x2f}, + {0x8d5c, 0x85}, + {0x8d5d, 0x34}, + {0x8d5e, 0x2e}, + {0x8d5f, 0x12}, + {0x8d60, 0x0f}, + {0x8d61, 0x46}, + {0x8d62, 0xe4}, + {0x8d63, 0xf5}, + {0x8d64, 0x22}, + {0x8d65, 0xf5}, + {0x8d66, 0x23}, + {0x8d67, 0x90}, + {0x8d68, 0x0e}, + {0x8d69, 0x72}, + {0x8d6a, 0x12}, + {0x8d6b, 0x0d}, + {0x8d6c, 0xea}, + {0x8d6d, 0x12}, + {0x8d6e, 0x0f}, + {0x8d6f, 0x46}, + {0x8d70, 0xe4}, + {0x8d71, 0xf5}, + {0x8d72, 0x22}, + {0x8d73, 0xf5}, + {0x8d74, 0x23}, + {0x8d75, 0x90}, + {0x8d76, 0x0e}, + {0x8d77, 0x6e}, + {0x8d78, 0x12}, + {0x8d79, 0x0d}, + {0x8d7a, 0xea}, + {0x8d7b, 0x02}, + {0x8d7c, 0x0f}, + {0x8d7d, 0x46}, + {0x8d7e, 0xe5}, + {0x8d7f, 0x40}, + {0x8d80, 0x24}, + {0x8d81, 0xf2}, + {0x8d82, 0xf5}, + {0x8d83, 0x37}, + {0x8d84, 0xe5}, + {0x8d85, 0x3f}, + {0x8d86, 0x34}, + {0x8d87, 0x43}, + {0x8d88, 0xf5}, + {0x8d89, 0x36}, + {0x8d8a, 0xe5}, + {0x8d8b, 0x3e}, + {0x8d8c, 0x34}, + {0x8d8d, 0xa2}, + {0x8d8e, 0xf5}, + {0x8d8f, 0x35}, + {0x8d90, 0xe5}, + {0x8d91, 0x3d}, + {0x8d92, 0x34}, + {0x8d93, 0x28}, + {0x8d94, 0xf5}, + {0x8d95, 0x34}, + {0x8d96, 0xe5}, + {0x8d97, 0x37}, + {0x8d98, 0xff}, + {0x8d99, 0xe4}, + {0x8d9a, 0xfe}, + {0x8d9b, 0xfd}, + {0x8d9c, 0xfc}, + {0x8d9d, 0x78}, + {0x8d9e, 0x18}, + {0x8d9f, 0x12}, + {0x8da0, 0x06}, + {0x8da1, 0x69}, + {0x8da2, 0x8f}, + {0x8da3, 0x40}, + {0x8da4, 0x8e}, + {0x8da5, 0x3f}, + {0x8da6, 0x8d}, + {0x8da7, 0x3e}, + {0x8da8, 0x8c}, + {0x8da9, 0x3d}, + {0x8daa, 0xe5}, + {0x8dab, 0x37}, + {0x8dac, 0x54}, + {0x8dad, 0xa0}, + {0x8dae, 0xff}, + {0x8daf, 0xe5}, + {0x8db0, 0x36}, + {0x8db1, 0xfe}, + {0x8db2, 0xe4}, + {0x8db3, 0xfd}, + {0x8db4, 0xfc}, + {0x8db5, 0x78}, + {0x8db6, 0x07}, + {0x8db7, 0x12}, + {0x8db8, 0x06}, + {0x8db9, 0x56}, + {0x8dba, 0x78}, + {0x8dbb, 0x10}, + {0x8dbc, 0x12}, + {0x8dbd, 0x0f}, + {0x8dbe, 0x9a}, + {0x8dbf, 0xe4}, + {0x8dc0, 0xff}, + {0x8dc1, 0xfe}, + {0x8dc2, 0xe5}, + {0x8dc3, 0x35}, + {0x8dc4, 0xfd}, + {0x8dc5, 0xe4}, + {0x8dc6, 0xfc}, + {0x8dc7, 0x78}, + {0x8dc8, 0x0e}, + {0x8dc9, 0x12}, + {0x8dca, 0x06}, + {0x8dcb, 0x56}, + {0x8dcc, 0x12}, + {0x8dcd, 0x0f}, + {0x8dce, 0x9d}, + {0x8dcf, 0xe4}, + {0x8dd0, 0xff}, + {0x8dd1, 0xfe}, + {0x8dd2, 0xfd}, + {0x8dd3, 0xe5}, + {0x8dd4, 0x34}, + {0x8dd5, 0xfc}, + {0x8dd6, 0x78}, + {0x8dd7, 0x18}, + {0x8dd8, 0x12}, + {0x8dd9, 0x06}, + {0x8dda, 0x56}, + {0x8ddb, 0x78}, + {0x8ddc, 0x08}, + {0x8ddd, 0x12}, + {0x8dde, 0x0f}, + {0x8ddf, 0x9a}, + {0x8de0, 0x22}, + {0x8de1, 0x8f}, + {0x8de2, 0x3b}, + {0x8de3, 0x8e}, + {0x8de4, 0x3a}, + {0x8de5, 0x8d}, + {0x8de6, 0x39}, + {0x8de7, 0x8c}, + {0x8de8, 0x38}, + {0x8de9, 0x22}, + {0x8dea, 0x12}, + {0x8deb, 0x06}, + {0x8dec, 0x7c}, + {0x8ded, 0x8f}, + {0x8dee, 0x31}, + {0x8def, 0x8e}, + {0x8df0, 0x30}, + {0x8df1, 0x8d}, + {0x8df2, 0x2f}, + {0x8df3, 0x8c}, + {0x8df4, 0x2e}, + {0x8df5, 0x22}, + {0x8df6, 0x93}, + {0x8df7, 0xf9}, + {0x8df8, 0xf8}, + {0x8df9, 0x02}, + {0x8dfa, 0x06}, + {0x8dfb, 0x69}, + {0x8dfc, 0x00}, + {0x8dfd, 0x00}, + {0x8dfe, 0x00}, + {0x8dff, 0x00}, + {0x8e00, 0x12}, + {0x8e01, 0x01}, + {0x8e02, 0x17}, + {0x8e03, 0x08}, + {0x8e04, 0x31}, + {0x8e05, 0x15}, + {0x8e06, 0x53}, + {0x8e07, 0x54}, + {0x8e08, 0x44}, + {0x8e09, 0x20}, + {0x8e0a, 0x20}, + {0x8e0b, 0x20}, + {0x8e0c, 0x20}, + {0x8e0d, 0x20}, + {0x8e0e, 0x13}, + {0x8e0f, 0x01}, + {0x8e10, 0x10}, + {0x8e11, 0x01}, + {0x8e12, 0x56}, + {0x8e13, 0x40}, + {0x8e14, 0x1a}, + {0x8e15, 0x30}, + {0x8e16, 0x29}, + {0x8e17, 0x7e}, + {0x8e18, 0x00}, + {0x8e19, 0x30}, + {0x8e1a, 0x04}, + {0x8e1b, 0x20}, + {0x8e1c, 0xdf}, + {0x8e1d, 0x30}, + {0x8e1e, 0x05}, + {0x8e1f, 0x40}, + {0x8e20, 0xbf}, + {0x8e21, 0x50}, + {0x8e22, 0x03}, + {0x8e23, 0x00}, + {0x8e24, 0xfd}, + {0x8e25, 0x50}, + {0x8e26, 0x27}, + {0x8e27, 0x01}, + {0x8e28, 0xfe}, + {0x8e29, 0x60}, + {0x8e2a, 0x00}, + {0x8e2b, 0x11}, + {0x8e2c, 0x00}, + {0x8e2d, 0x3f}, + {0x8e2e, 0x05}, + {0x8e2f, 0x30}, + {0x8e30, 0x00}, + {0x8e31, 0x3f}, + {0x8e32, 0x06}, + {0x8e33, 0x22}, + {0x8e34, 0x00}, + {0x8e35, 0x3f}, + {0x8e36, 0x01}, + {0x8e37, 0x2a}, + {0x8e38, 0x00}, + {0x8e39, 0x3f}, + {0x8e3a, 0x02}, + {0x8e3b, 0x00}, + {0x8e3c, 0x00}, + {0x8e3d, 0x36}, + {0x8e3e, 0x06}, + {0x8e3f, 0x07}, + {0x8e40, 0x00}, + {0x8e41, 0x3f}, + {0x8e42, 0x0b}, + {0x8e43, 0x0f}, + {0x8e44, 0xf0}, + {0x8e45, 0x00}, + {0x8e46, 0x00}, + {0x8e47, 0x00}, + {0x8e48, 0x00}, + {0x8e49, 0x30}, + {0x8e4a, 0x01}, + {0x8e4b, 0x40}, + {0x8e4c, 0xbf}, + {0x8e4d, 0x30}, + {0x8e4e, 0x01}, + {0x8e4f, 0x00}, + {0x8e50, 0xbf}, + {0x8e51, 0x30}, + {0x8e52, 0x29}, + {0x8e53, 0x70}, + {0x8e54, 0x00}, + {0x8e55, 0x3a}, + {0x8e56, 0x00}, + {0x8e57, 0x00}, + {0x8e58, 0xff}, + {0x8e59, 0x3a}, + {0x8e5a, 0x00}, + {0x8e5b, 0x00}, + {0x8e5c, 0xff}, + {0x8e5d, 0x36}, + {0x8e5e, 0x03}, + {0x8e5f, 0x36}, + {0x8e60, 0x02}, + {0x8e61, 0x41}, + {0x8e62, 0x44}, + {0x8e63, 0x58}, + {0x8e64, 0x20}, + {0x8e65, 0x18}, + {0x8e66, 0x10}, + {0x8e67, 0x0a}, + {0x8e68, 0x04}, + {0x8e69, 0x04}, + {0x8e6a, 0x00}, + {0x8e6b, 0x03}, + {0x8e6c, 0xff}, + {0x8e6d, 0x64}, + {0x8e6e, 0x00}, + {0x8e6f, 0x00}, + {0x8e70, 0x80}, + {0x8e71, 0x00}, + {0x8e72, 0x00}, + {0x8e73, 0x00}, + {0x8e74, 0x00}, + {0x8e75, 0x00}, + {0x8e76, 0x00}, + {0x8e77, 0x02}, + {0x8e78, 0x04}, + {0x8e79, 0x06}, + {0x8e7a, 0x06}, + {0x8e7b, 0x00}, + {0x8e7c, 0x03}, + {0x8e7d, 0x51}, + {0x8e7e, 0x00}, + {0x8e7f, 0x7a}, + {0x8e80, 0x50}, + {0x8e81, 0x3c}, + {0x8e82, 0x28}, + {0x8e83, 0x1e}, + {0x8e84, 0x10}, + {0x8e85, 0x10}, + {0x8e86, 0x50}, + {0x8e87, 0x2d}, + {0x8e88, 0x28}, + {0x8e89, 0x16}, + {0x8e8a, 0x10}, + {0x8e8b, 0x10}, + {0x8e8c, 0x02}, + {0x8e8d, 0x00}, + {0x8e8e, 0x10}, + {0x8e8f, 0x0c}, + {0x8e90, 0x10}, + {0x8e91, 0x04}, + {0x8e92, 0x0c}, + {0x8e93, 0x6e}, + {0x8e94, 0x06}, + {0x8e95, 0x05}, + {0x8e96, 0x00}, + {0x8e97, 0xa5}, + {0x8e98, 0x5a}, + {0x8e99, 0x00}, + {0x8e9a, 0xae}, + {0x8e9b, 0x35}, + {0x8e9c, 0xaf}, + {0x8e9d, 0x36}, + {0x8e9e, 0xe4}, + {0x8e9f, 0xfd}, + {0x8ea0, 0xed}, + {0x8ea1, 0xc3}, + {0x8ea2, 0x95}, + {0x8ea3, 0x37}, + {0x8ea4, 0x50}, + {0x8ea5, 0x33}, + {0x8ea6, 0x12}, + {0x8ea7, 0x0f}, + {0x8ea8, 0xe2}, + {0x8ea9, 0xe4}, + {0x8eaa, 0x93}, + {0x8eab, 0xf5}, + {0x8eac, 0x38}, + {0x8ead, 0x74}, + {0x8eae, 0x01}, + {0x8eaf, 0x93}, + {0x8eb0, 0xf5}, + {0x8eb1, 0x39}, + {0x8eb2, 0x45}, + {0x8eb3, 0x38}, + {0x8eb4, 0x60}, + {0x8eb5, 0x23}, + {0x8eb6, 0x85}, + {0x8eb7, 0x39}, + {0x8eb8, 0x82}, + {0x8eb9, 0x85}, + {0x8eba, 0x38}, + {0x8ebb, 0x83}, + {0x8ebc, 0xe0}, + {0x8ebd, 0xfc}, + {0x8ebe, 0x12}, + {0x8ebf, 0x0f}, + {0x8ec0, 0xe2}, + {0x8ec1, 0x74}, + {0x8ec2, 0x03}, + {0x8ec3, 0x93}, + {0x8ec4, 0x52}, + {0x8ec5, 0x04}, + {0x8ec6, 0x12}, + {0x8ec7, 0x0f}, + {0x8ec8, 0xe2}, + {0x8ec9, 0x74}, + {0x8eca, 0x02}, + {0x8ecb, 0x93}, + {0x8ecc, 0x42}, + {0x8ecd, 0x04}, + {0x8ece, 0x85}, + {0x8ecf, 0x39}, + {0x8ed0, 0x82}, + {0x8ed1, 0x85}, + {0x8ed2, 0x38}, + {0x8ed3, 0x83}, + {0x8ed4, 0xec}, + {0x8ed5, 0xf0}, + {0x8ed6, 0x0d}, + {0x8ed7, 0x80}, + {0x8ed8, 0xc7}, + {0x8ed9, 0x22}, + {0x8eda, 0x78}, + {0x8edb, 0xbe}, + {0x8edc, 0xe6}, + {0x8edd, 0xd3}, + {0x8ede, 0x08}, + {0x8edf, 0xff}, + {0x8ee0, 0xe6}, + {0x8ee1, 0x64}, + {0x8ee2, 0x80}, + {0x8ee3, 0xf8}, + {0x8ee4, 0xef}, + {0x8ee5, 0x64}, + {0x8ee6, 0x80}, + {0x8ee7, 0x98}, + {0x8ee8, 0x22}, + {0x8ee9, 0x93}, + {0x8eea, 0xff}, + {0x8eeb, 0x7e}, + {0x8eec, 0x00}, + {0x8eed, 0xe6}, + {0x8eee, 0xfc}, + {0x8eef, 0x08}, + {0x8ef0, 0xe6}, + {0x8ef1, 0xfd}, + {0x8ef2, 0x12}, + {0x8ef3, 0x04}, + {0x8ef4, 0xc1}, + {0x8ef5, 0x78}, + {0x8ef6, 0xc1}, + {0x8ef7, 0xe6}, + {0x8ef8, 0xfc}, + {0x8ef9, 0x08}, + {0x8efa, 0xe6}, + {0x8efb, 0xfd}, + {0x8efc, 0xd3}, + {0x8efd, 0xef}, + {0x8efe, 0x9d}, + {0x8eff, 0xee}, + {0x8f00, 0x9c}, + {0x8f01, 0x22}, + {0x8f02, 0x78}, + {0x8f03, 0xbd}, + {0x8f04, 0xd3}, + {0x8f05, 0xe6}, + {0x8f06, 0x64}, + {0x8f07, 0x80}, + {0x8f08, 0x94}, + {0x8f09, 0x80}, + {0x8f0a, 0x22}, + {0x8f0b, 0x25}, + {0x8f0c, 0xe0}, + {0x8f0d, 0x24}, + {0x8f0e, 0x0a}, + {0x8f0f, 0xf8}, + {0x8f10, 0xe6}, + {0x8f11, 0xfe}, + {0x8f12, 0x08}, + {0x8f13, 0xe6}, + {0x8f14, 0xff}, + {0x8f15, 0x22}, + {0x8f16, 0xe5}, + {0x8f17, 0x3c}, + {0x8f18, 0xd3}, + {0x8f19, 0x94}, + {0x8f1a, 0x00}, + {0x8f1b, 0x40}, + {0x8f1c, 0x0b}, + {0x8f1d, 0x90}, + {0x8f1e, 0x0e}, + {0x8f1f, 0x88}, + {0x8f20, 0x12}, + {0x8f21, 0x0b}, + {0x8f22, 0xf1}, + {0x8f23, 0x90}, + {0x8f24, 0x0e}, + {0x8f25, 0x86}, + {0x8f26, 0x80}, + {0x8f27, 0x09}, + {0x8f28, 0x90}, + {0x8f29, 0x0e}, + {0x8f2a, 0x82}, + {0x8f2b, 0x12}, + {0x8f2c, 0x0b}, + {0x8f2d, 0xf1}, + {0x8f2e, 0x90}, + {0x8f2f, 0x0e}, + {0x8f30, 0x80}, + {0x8f31, 0xe4}, + {0x8f32, 0x93}, + {0x8f33, 0xf5}, + {0x8f34, 0x44}, + {0x8f35, 0xa3}, + {0x8f36, 0xe4}, + {0x8f37, 0x93}, + {0x8f38, 0xf5}, + {0x8f39, 0x43}, + {0x8f3a, 0xd2}, + {0x8f3b, 0x06}, + {0x8f3c, 0x30}, + {0x8f3d, 0x06}, + {0x8f3e, 0x03}, + {0x8f3f, 0xd3}, + {0x8f40, 0x80}, + {0x8f41, 0x01}, + {0x8f42, 0xc3}, + {0x8f43, 0x92}, + {0x8f44, 0x0e}, + {0x8f45, 0x22}, + {0x8f46, 0xa2}, + {0x8f47, 0xaf}, + {0x8f48, 0x92}, + {0x8f49, 0x32}, + {0x8f4a, 0xc2}, + {0x8f4b, 0xaf}, + {0x8f4c, 0xe5}, + {0x8f4d, 0x23}, + {0x8f4e, 0x45}, + {0x8f4f, 0x22}, + {0x8f50, 0x90}, + {0x8f51, 0x0e}, + {0x8f52, 0x5d}, + {0x8f53, 0x60}, + {0x8f54, 0x0e}, + {0x8f55, 0x12}, + {0x8f56, 0x0f}, + {0x8f57, 0xcb}, + {0x8f58, 0xe0}, + {0x8f59, 0xf5}, + {0x8f5a, 0x2c}, + {0x8f5b, 0x12}, + {0x8f5c, 0x0f}, + {0x8f5d, 0xc8}, + {0x8f5e, 0xe0}, + {0x8f5f, 0xf5}, + {0x8f60, 0x2d}, + {0x8f61, 0x80}, + {0x8f62, 0x0c}, + {0x8f63, 0x12}, + {0x8f64, 0x0f}, + {0x8f65, 0xcb}, + {0x8f66, 0xe5}, + {0x8f67, 0x30}, + {0x8f68, 0xf0}, + {0x8f69, 0x12}, + {0x8f6a, 0x0f}, + {0x8f6b, 0xc8}, + {0x8f6c, 0xe5}, + {0x8f6d, 0x31}, + {0x8f6e, 0xf0}, + {0x8f6f, 0xa2}, + {0x8f70, 0x32}, + {0x8f71, 0x92}, + {0x8f72, 0xaf}, + {0x8f73, 0x22}, + {0x8f74, 0xd2}, + {0x8f75, 0x01}, + {0x8f76, 0xc2}, + {0x8f77, 0x02}, + {0x8f78, 0xe4}, + {0x8f79, 0xf5}, + {0x8f7a, 0x1f}, + {0x8f7b, 0xf5}, + {0x8f7c, 0x1e}, + {0x8f7d, 0xd2}, + {0x8f7e, 0x35}, + {0x8f7f, 0xd2}, + {0x8f80, 0x33}, + {0x8f81, 0xd2}, + {0x8f82, 0x36}, + {0x8f83, 0xd2}, + {0x8f84, 0x01}, + {0x8f85, 0xc2}, + {0x8f86, 0x02}, + {0x8f87, 0xf5}, + {0x8f88, 0x1f}, + {0x8f89, 0xf5}, + {0x8f8a, 0x1e}, + {0x8f8b, 0xd2}, + {0x8f8c, 0x35}, + {0x8f8d, 0xd2}, + {0x8f8e, 0x33}, + {0x8f8f, 0x22}, + {0x8f90, 0xfb}, + {0x8f91, 0xd3}, + {0x8f92, 0xed}, + {0x8f93, 0x9b}, + {0x8f94, 0x74}, + {0x8f95, 0x80}, + {0x8f96, 0xf8}, + {0x8f97, 0x6c}, + {0x8f98, 0x98}, + {0x8f99, 0x22}, + {0x8f9a, 0x12}, + {0x8f9b, 0x06}, + {0x8f9c, 0x69}, + {0x8f9d, 0xe5}, + {0x8f9e, 0x40}, + {0x8f9f, 0x2f}, + {0x8fa0, 0xf5}, + {0x8fa1, 0x40}, + {0x8fa2, 0xe5}, + {0x8fa3, 0x3f}, + {0x8fa4, 0x3e}, + {0x8fa5, 0xf5}, + {0x8fa6, 0x3f}, + {0x8fa7, 0xe5}, + {0x8fa8, 0x3e}, + {0x8fa9, 0x3d}, + {0x8faa, 0xf5}, + {0x8fab, 0x3e}, + {0x8fac, 0xe5}, + {0x8fad, 0x3d}, + {0x8fae, 0x3c}, + {0x8faf, 0xf5}, + {0x8fb0, 0x3d}, + {0x8fb1, 0x22}, + {0x8fb2, 0xc0}, + {0x8fb3, 0xe0}, + {0x8fb4, 0xc0}, + {0x8fb5, 0x83}, + {0x8fb6, 0xc0}, + {0x8fb7, 0x82}, + {0x8fb8, 0x90}, + {0x8fb9, 0x3f}, + {0x8fba, 0x0d}, + {0x8fbb, 0xe0}, + {0x8fbc, 0xf5}, + {0x8fbd, 0x33}, + {0x8fbe, 0xe5}, + {0x8fbf, 0x33}, + {0x8fc0, 0xf0}, + {0x8fc1, 0xd0}, + {0x8fc2, 0x82}, + {0x8fc3, 0xd0}, + {0x8fc4, 0x83}, + {0x8fc5, 0xd0}, + {0x8fc6, 0xe0}, + {0x8fc7, 0x32}, + {0x8fc8, 0x90}, + {0x8fc9, 0x0e}, + {0x8fca, 0x5f}, + {0x8fcb, 0xe4}, + {0x8fcc, 0x93}, + {0x8fcd, 0xfe}, + {0x8fce, 0x74}, + {0x8fcf, 0x01}, + {0x8fd0, 0x93}, + {0x8fd1, 0xf5}, + {0x8fd2, 0x82}, + {0x8fd3, 0x8e}, + {0x8fd4, 0x83}, + {0x8fd5, 0x22}, + {0x8fd6, 0x78}, + {0x8fd7, 0x7f}, + {0x8fd8, 0xe4}, + {0x8fd9, 0xf6}, + {0x8fda, 0xd8}, + {0x8fdb, 0xfd}, + {0x8fdc, 0x75}, + {0x8fdd, 0x81}, + {0x8fde, 0xcd}, + {0x8fdf, 0x02}, + {0x8fe0, 0x0c}, + {0x8fe1, 0x98}, + {0x8fe2, 0x8f}, + {0x8fe3, 0x82}, + {0x8fe4, 0x8e}, + {0x8fe5, 0x83}, + {0x8fe6, 0x75}, + {0x8fe7, 0xf0}, + {0x8fe8, 0x04}, + {0x8fe9, 0xed}, + {0x8fea, 0x02}, + {0x8feb, 0x06}, + {0x8fec, 0xa5}, + {0x3022, 0x00}, + {0x3023, 0x00}, + {0x3024, 0x00}, + {0x3025, 0x00}, + {0x3026, 0x00}, + {0x3027, 0x00}, + {0x3028, 0x00}, + {0x3029, 0x7F}, + {0x3000, 0x00}, + {0xffff, 0xff} +}; + +#endif diff --git a/drivers/amlogic/media/vin/tvin/Kconfig b/drivers/amlogic/media/vin/tvin/Kconfig index ed5558c..b684f4e 100644 --- a/drivers/amlogic/media/vin/tvin/Kconfig +++ b/drivers/amlogic/media/vin/tvin/Kconfig @@ -21,4 +21,5 @@ source "drivers/amlogic/media/vin/tvin/bt656/Kconfig" source "drivers/amlogic/media/vin/tvin/hdmirx_ext/Kconfig" source "drivers/amlogic/media/vin/tvin/hdmirx/Kconfig" source "drivers/amlogic/media/vin/tvin/tvafe/Kconfig" +source "drivers/amlogic/media/vin/tvin/csi/Kconfig" endif diff --git a/drivers/amlogic/media/vin/tvin/Makefile b/drivers/amlogic/media/vin/tvin/Makefile index d89aa4e..4b40fa1 100644 --- a/drivers/amlogic/media/vin/tvin/Makefile +++ b/drivers/amlogic/media/vin/tvin/Makefile @@ -13,4 +13,5 @@ obj-$(CONFIG_AMLOGIC_MEDIA_TVIN_BT656) += bt656/ obj-$(CONFIG_AMLOGIC_MEDIA_TVIN_HDMI_EXT) += hdmirx_ext/ obj-$(CONFIG_AMLOGIC_MEDIA_TVIN_HDMI) += hdmirx/ obj-$(CONFIG_AMLOGIC_MEDIA_TVIN_AFE) += tvafe/ +obj-$(CONFIG_AMLOGIC_MEDIA_TVIN_CSI) += csi/ diff --git a/drivers/amlogic/media/vin/tvin/csi/Kconfig b/drivers/amlogic/media/vin/tvin/csi/Kconfig new file mode 100644 index 0000000..4f9d374 --- /dev/null +++ b/drivers/amlogic/media/vin/tvin/csi/Kconfig @@ -0,0 +1,11 @@ +# +# CSI Device Driver Configuration +# + + +config AMLOGIC_MEDIA_TVIN_CSI + tristate "Amlogic CSI device driver" + default n + help + CSI device driver. + diff --git a/drivers/amlogic/media/vin/tvin/csi/Makefile b/drivers/amlogic/media/vin/tvin/csi/Makefile new file mode 100644 index 0000000..83ee818 --- /dev/null +++ b/drivers/amlogic/media/vin/tvin/csi/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_AMLOGIC_MEDIA_TVIN_CSI) += tvin_csi.o +tvin_csi-objs := csi.o mipi_hw.o diff --git a/drivers/amlogic/media/vin/tvin/csi/csi.c b/drivers/amlogic/media/vin/tvin/csi/csi.c new file mode 100644 index 0000000..dbaedc2 --- /dev/null +++ b/drivers/amlogic/media/vin/tvin/csi/csi.c @@ -0,0 +1,558 @@ +/* + * drivers/amlogic/media/vin/tvin/csi/csi.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../tvin_global.h" +#include "../vdin/vdin_regs.h" +#include "../vdin/vdin_drv.h" +#include "../vdin/vdin_ctl.h" +#include "../tvin_format_table.h" +#include "../tvin_frontend.h" +#include "csi.h" + +#define DEV_NAME "amvdec_csi" +#define DRV_NAME "amvdec_csi" +#define CLS_NAME "amvdec_csi" +#define MOD_NAME "amvdec_csi" + +#define CSI_MAX_DEVS 1 +#define WDG_STEP_JIFFIES 10 + +static dev_t amcsi_devno; +static struct class *amcsi_clsp; + +static void init_csi_dec_parameter(struct amcsi_dev_s *devp) +{ + enum tvin_sig_fmt_e fmt; + const struct tvin_format_s *fmt_info_p; + + pr_info("init_csi_dec_parameter.\n"); + fmt = devp->para.fmt; + fmt_info_p = + (struct tvin_format_s *)tvin_get_fmt_info(fmt); + devp->para.v_active = 1080; + devp->para.h_active = 1920; + devp->para.hsync_phase = 0; + devp->para.vsync_phase = 0; + devp->para.hs_bp = 0; + devp->para.vs_bp = 0; + devp->para.csi_hw_info.lanes = 2; +} + +static void reset_btcsi_module(void) +{ + DPRINT("%s, %d\n", __func__, __LINE__); +} + +static void reinit_csi_dec(struct amcsi_dev_s *devp) +{ + DPRINT("%s, %d\n", __func__, __LINE__); +} + +static void start_amvdec_csi(struct amcsi_dev_s *devp) +{ + enum tvin_port_e port = devp->para.port; + + pr_info("start_amvdec_csi.\n"); + + if (devp->dec_status & TVIN_AMCSI_RUNNING) { + pr_info("%s csi have started alreadly.\n", + __func__); + return; + } + devp->dec_status = TVIN_AMCSI_RUNNING; + pr_info("start_amvdec_csi port = %x\n", port); + if (port == TVIN_PORT_MIPI) { + init_csi_dec_parameter(devp); + reinit_csi_dec(devp); + } else { + devp->para.fmt = TVIN_SIG_FMT_NULL; + devp->para.port = TVIN_PORT_NULL; + DPRINT("%s: input is not selected, please try again\n", + __func__); + return; + } + devp->dec_status = TVIN_AMCSI_RUNNING; +} + +static void stop_amvdec_csi(struct amcsi_dev_s *devp) +{ + if (devp->dec_status & TVIN_AMCSI_RUNNING) { + reset_btcsi_module(); + devp->dec_status = TVIN_AMCSI_STOP; + } else + DPRINT("%s device is not started yet\n", __func__); +} + +static bool amcsi_check_skip_frame(struct tvin_frontend_s *fe) +{ + struct amcsi_dev_s *devp = + container_of(fe, struct amcsi_dev_s, frontend); + + if (devp->csi_parm.skip_frames > 0) { + devp->csi_parm.skip_frames--; + return true; + } else + return false; +} + +int amcsi_support(struct tvin_frontend_s *fe, enum tvin_port_e port) +{ + if (port != TVIN_PORT_MIPI) { + DPRINT("this is not MIPI port\n"); + return -1; + } else { + return 0; + } +} + +static int amcsi_open(struct inode *node, struct file *file) +{ + struct amcsi_dev_s *csi_devp; + + csi_devp = container_of(node->i_cdev, struct amcsi_dev_s, cdev); + file->private_data = csi_devp; + + return 0; +} + +static int amcsi_release(struct inode *node, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +static const struct file_operations amcsi_fops = { + .owner = THIS_MODULE, + .open = amcsi_open, + .release = amcsi_release, +}; + +void amcsi_start(struct tvin_frontend_s *fe, enum tvin_sig_fmt_e fmt) +{ + struct amcsi_dev_s *csi_devp; + + csi_devp = container_of(fe, struct amcsi_dev_s, frontend); + start_amvdec_csi(csi_devp); +} + +static void amcsi_stop(struct tvin_frontend_s *fe, enum tvin_port_e port) +{ + struct amcsi_dev_s *devp = + container_of(fe, struct amcsi_dev_s, frontend); + + if (port != TVIN_PORT_MIPI) { + DPRINT("%s:invaild port %d.\n", __func__, port); + return; + } + stop_amvdec_csi(devp); +} + +void amcsi_get_sig_property(struct tvin_frontend_s *fe, + struct tvin_sig_property_s *prop) +{ + struct amcsi_dev_s *devp = + container_of(fe, struct amcsi_dev_s, frontend); + + prop->color_format = devp->para.cfmt; + prop->dest_cfmt = devp->para.dfmt; + pr_info("devp->para.cfmt=%d, devp->para.dfmt=%d\n", + devp->para.cfmt, devp->para.dfmt); + prop->decimation_ratio = 0; +} + +int amcsi_isr(struct tvin_frontend_s *fe, unsigned int hcnt) +{ + struct amcsi_dev_s *devp = + container_of(fe, struct amcsi_dev_s, frontend); + unsigned int data1 = 0; + struct am_csi2_frame_s frame; + + frame.w = READ_CSI_ADPT_REG_BIT(CSI2_PIC_SIZE_STAT, 0, 16); + frame.h = READ_CSI_ADPT_REG_BIT(CSI2_PIC_SIZE_STAT, 16, 16); + frame.err = READ_CSI_ADPT_REG(CSI2_ERR_STAT0); + data1 = READ_CSI_ADPT_REG(CSI2_GEN_STAT0); + + if (frame.err) { + DPRINT("%s,error---pixel cnt:%d, line cnt:%d\n", + __func__, frame.w, frame.h); + DPRINT("error state:0x%x.,status:0x%x\n", + frame.err, data1); + devp->overflow_cnt++; + WRITE_CSI_ADPT_REG(CSI2_ERR_STAT0, 0); + } + if (devp->overflow_cnt > 4) { + DPRINT("should reset mipi\n"); + devp->overflow_cnt = 0; + return 0; + } + + devp->reset = 0; + + return 0; +} + +static ssize_t csi_attr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t len = 0; + struct amcsi_dev_s *csi_devp; + int i; + + csi_devp = dev_get_drvdata(dev); + if (csi_devp->dec_status != TVIN_AMCSI_RUNNING) { + len += sprintf(buf+len, "csi does not start\n"); + return len; + } + + len += sprintf(buf+len, "csi parameters below\n"); + len += + sprintf(buf+len, "\tlanes=%d, channel=%d\n" + "\tclk_channel=%d\n" + "\tmode=%d, clock_lane_mode=%d, active_pixel=%d\n" + "\tactive_line=%d, frame_size=%d, ui_val=%dns\n" + "\ths_freq=%dhz, urgent=%d\n", + csi_devp->csi_parm.lanes, + csi_devp->csi_parm.channel, + csi_devp->csi_parm.clk_channel, + csi_devp->csi_parm.mode, + csi_devp->csi_parm.clock_lane_mode, + csi_devp->csi_parm.active_pixel, + csi_devp->csi_parm.active_line, + csi_devp->csi_parm.frame_size, + csi_devp->csi_parm.ui_val, + csi_devp->csi_parm.hs_freq, + csi_devp->csi_parm.urgent); + + len += sprintf(buf+len, "csi adapter register below\n"); + for (i = CSI_ADPT_START_REG; i <= CSI_ADPT_END_REG; i++) { + len += sprintf(buf+len, "\t[0x%04x]=0x%08x\n", + i - CSI_ADPT_START_REG, READ_CSI_ADPT_REG(i)); + } + + len += sprintf(buf+len, "csi phy register below\n"); + for (i = CSI_PHY_START_REG; i <= CSI_PHY_END_REG; i++) { + len += sprintf(buf+len, "\t[0x%04x]=0x%08x\n", + i, READ_CSI_PHY_REG(i)); + } + + len += sprintf(buf+len, "csi host register below\n"); + for (i = CSI_HST_START_REG; i <= CSI_HST_END_REG; i++) { + len += sprintf(buf+len, "\t[0x%04x]=0x%08x\n", + i << 2, READ_CSI_HST_REG(i)); + } + + return len; +} + +static ssize_t csi_attr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct amcsi_dev_s *csi_devp; + + unsigned int n = 0; + + char *buf_orig, *ps, *token; + char *parm[6] = {NULL}; + + if (!buf) + return len; + buf_orig = kstrdup(buf, GFP_KERNEL); + csi_devp = dev_get_drvdata(dev); + + ps = buf_orig; + while (1) { + if (n >= ARRAY_SIZE(parm)) { + pr_info("parm array overflow, n=%d\n", n); + kfree(buf_orig); + return len; + } + token = strsep(&ps, "\n"); + if (token == NULL) + break; + if (*token == '\0') + continue; + parm[n++] = token; + } + + if (strcmp(parm[0], "reset") == 0) { + pr_info("reset\n"); + am_mipi_csi2_init(&csi_devp->csi_parm); + } else if (strcmp(parm[0], "init") == 0) { + pr_info("init mipi measure clock\n"); + init_am_mipi_csi2_clock(); + } else if (strcmp(parm[0], "min") == 0) { + csi_devp->min_frmrate = + kstrtol(parm[1], 16, NULL); + if ((csi_devp->min_frmrate * WDG_STEP_JIFFIES) < HZ) + csi_devp->min_frmrate = HZ/WDG_STEP_JIFFIES; + pr_info("min_frmrate=%d\n", csi_devp->min_frmrate); + } + + kfree(buf_orig); + return len; +} + +static DEVICE_ATTR(hw_info, 0664, csi_attr_show, csi_attr_store); + +static int amcsi_feopen(struct tvin_frontend_s *fe, enum tvin_port_e port) +{ + struct amcsi_dev_s *csi_devp = + container_of(fe, struct amcsi_dev_s, frontend); + struct vdin_parm_s *parm = fe->private_data; + + if (port != TVIN_PORT_MIPI) { + DPRINT("[mipi..]%s:invaild port %d.\n", __func__, port); + return -1; + } + + if (!memcpy(&csi_devp->para, parm, + sizeof(struct vdin_parm_s))) { + DPRINT("[mipi..]%s memcpy error.\n", __func__); + return -1; + } + + init_am_mipi_csi2_clock(); + + csi_devp->para.port = port; + + memcpy(&csi_devp->csi_parm, + &parm->csi_hw_info, sizeof(struct csi_parm_s)); + csi_devp->csi_parm.skip_frames = parm->skip_count; + + csi_devp->reset = 0; + csi_devp->reset_count = 0; + + cal_csi_para(&csi_devp->csi_parm); + am_mipi_csi2_init(&csi_devp->csi_parm); + + return 0; +} + +static void amcsi_feclose(struct tvin_frontend_s *fe) +{ + struct amcsi_dev_s *devp = + container_of(fe, struct amcsi_dev_s, frontend); + enum tvin_port_e port = devp->para.port; + + if (port != TVIN_PORT_MIPI) { + DPRINT("[mipi..]%s:invaild port %d.\n", __func__, port); + return; + } + + devp->reset = 0; + devp->reset_count = 0; + + am_mipi_csi2_uninit(); + + memset(&devp->para, 0, sizeof(struct vdin_parm_s)); +} + +static struct tvin_state_machine_ops_s amcsi_machine_ops = { + .nosig = NULL, + .fmt_changed = NULL, + .get_fmt = NULL, + .fmt_config = NULL, + .adc_cal = NULL, + .pll_lock = NULL, + .get_sig_property = amcsi_get_sig_property, + .vga_set_param = NULL, + .vga_get_param = NULL, + .check_frame_skip = amcsi_check_skip_frame, +}; + +static struct tvin_decoder_ops_s amcsi_decoder_ops_s = { + .support = amcsi_support, + .open = amcsi_feopen, + .start = amcsi_start, + .stop = amcsi_stop, + .close = amcsi_feclose, + .decode_isr = amcsi_isr, +}; + +static int csi_add_cdev(struct cdev *cdevp, + const struct file_operations *fops, int minor) +{ + int ret; + dev_t devno = MKDEV(MAJOR(amcsi_devno), minor); + + cdev_init(cdevp, fops); + cdevp->owner = THIS_MODULE; + ret = cdev_add(cdevp, devno, 1); + return ret; +} + +static void csi_delete_device(int minor) +{ + dev_t devno = MKDEV(MAJOR(amcsi_devno), minor); + + device_destroy(amcsi_clsp, devno); +} + +static int amvdec_csi_probe(struct platform_device *pdev) +{ + int ret = 0; + int id = 0; + struct amcsi_dev_s *devp = NULL; + + devp = kmalloc(sizeof(struct amcsi_dev_s), GFP_KERNEL); + if (!devp) { + ret = -1; + goto fail_kmalloc_dev; + } + memset(devp, 0, sizeof(struct amcsi_dev_s)); + + ret = csi_add_cdev(&devp->cdev, &amcsi_fops, 0); + if (ret != 0) { + pr_err("%s: failed to add cdev\n", __func__); + goto fail_add_cdev; + } + + ret = of_property_read_u32(pdev->dev.of_node, "csi_id", &id); + if (ret != 0) { + pr_err("%s: don't find csi_id.\n", __func__); + goto fail_add_cdev; + } + pdev->id = id; + + sprintf(devp->frontend.name, "%s", DEV_NAME); + tvin_frontend_init(&devp->frontend, &amcsi_decoder_ops_s, + &amcsi_machine_ops, pdev->id); + tvin_reg_frontend(&devp->frontend); + devp->pdev = pdev; + + platform_set_drvdata(pdev, devp); + + am_mipi_csi2_para_init(pdev); + + pr_info("amvdec_csi probe ok.\n"); + return ret; + +fail_add_cdev: + kfree(devp); +fail_kmalloc_dev: + return ret; +} + +static int amvdec_csi_remove(struct platform_device *pdev) +{ + struct amcsi_dev_s *devp; + + devp = (struct amcsi_dev_s *)platform_get_drvdata(pdev); + + tvin_unreg_frontend(&devp->frontend); + device_remove_file(devp->dev, &dev_attr_hw_info); + deinit_am_mipi_csi2_clock(); + csi_delete_device(pdev->id); + cdev_del(&devp->cdev); + dev_set_drvdata(devp->dev, NULL); + platform_set_drvdata(pdev, NULL); + kfree(devp); + return 0; +} + +static const struct of_device_id csi_dt_match[] = { + { + .compatible = "amlogic, amvdec_csi", + }, + {}, +}; + +static struct platform_driver amvdec_csi_driver = { + .probe = amvdec_csi_probe, + .remove = amvdec_csi_remove, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = csi_dt_match, + } +}; + +static int __init amvdec_csi_init_module(void) +{ + int ret = 0; + + pr_info("amvdec_csi module: init.\n"); + ret = alloc_chrdev_region(&amcsi_devno, 0, + CSI_MAX_DEVS, DEV_NAME); + if (ret != 0) { + pr_err("%s:failed to alloc major number\n", + __func__); + goto fail_alloc_cdev_region; + } + + pr_info("%s:major %d\n", __func__, MAJOR(amcsi_devno)); + + amcsi_clsp = class_create(THIS_MODULE, CLS_NAME); + if (IS_ERR(amcsi_clsp)) { + ret = PTR_ERR(amcsi_clsp); + pr_err("%s:failed to create class\n", __func__); + goto fail_class_create; + } + + ret = platform_driver_register(&amvdec_csi_driver); + if (ret) { + pr_err("failed to register amvdec_csi driver\n"); + goto fail_pdrv_register; + } + + pr_info("amvdec_csi module: init. ok\n"); + return 0; + +fail_pdrv_register: + class_destroy(amcsi_clsp); +fail_class_create: + unregister_chrdev_region(amcsi_devno, CSI_MAX_DEVS); +fail_alloc_cdev_region: + pr_err("amvdec_csi module: init failed, ret=%d\n", ret); + + return ret; +} + +static void __exit amvdec_csi_exit_module(void) +{ + pr_info("amvdec_csi module remove.\n"); + DPRINT("%s, %d\n", __func__, __LINE__); + class_destroy(amcsi_clsp); + unregister_chrdev_region(amcsi_devno, CSI_MAX_DEVS); + platform_driver_unregister(&amvdec_csi_driver); +} + +module_init(amvdec_csi_init_module); +module_exit(amvdec_csi_exit_module); + +MODULE_DESCRIPTION("AMLOGIC CSI input driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0.0"); diff --git a/drivers/amlogic/media/vin/tvin/csi/csi.h b/drivers/amlogic/media/vin/tvin/csi/csi.h new file mode 100644 index 0000000..7c9b597 --- /dev/null +++ b/drivers/amlogic/media/vin/tvin/csi/csi.h @@ -0,0 +1,134 @@ +/* + * drivers/amlogic/media/vin/tvin/csi/csi.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __CSI_INPUT_H +#define __CSI_INPUT_H +#include +#include +#include +#include "../tvin_frontend.h" +#include "../tvin_global.h" +#ifdef PRINT_DEBUG_INFO +#define DPRINT(...) printk(__VA_ARGS__) +#else +#define DPRINT(...) +#endif + +#define CSI2_CFG_USE_NULL_PACKET 0 +#define CSI2_CFG_BUFFER_PIC_SIZE 1 +#define CSI2_CFG_422TO444_MODE 1 +#define CSI2_CFG_INV_FIELD 0 +#define CSI2_CFG_INTERLACE_EN 0 +#define CSI2_CFG_COLOR_EXPAND 0 +#define CSI2_CFG_ALL_TO_MEM 0 + + +/*mipi-csi2 phy registers*/ +#define MIPI_PHY_CTRL 0x00 +#define MIPI_PHY_CLK_LANE_CTRL 0x04 +#define MIPI_PHY_DATA_LANE_CTRL 0x08 +#define MIPI_PHY_DATA_LANE_CTRL1 0x0C +#define MIPI_PHY_TCLK_MISS 0x10 +#define MIPI_PHY_TCLK_SETTLE 0x14 +#define MIPI_PHY_THS_EXIT 0x18 +#define MIPI_PHY_THS_SKIP 0x1C +#define MIPI_PHY_THS_SETTLE 0x20 +#define MIPI_PHY_TINIT 0x24 +#define MIPI_PHY_TULPS_C 0x28 +#define MIPI_PHY_TULPS_S 0x2C +#define MIPI_PHY_TMBIAS 0x30 +#define MIPI_PHY_TLP_EN_W 0x34 +#define MIPI_PHY_TLPOK 0x38 +#define MIPI_PHY_TWD_INIT 0x3C +#define MIPI_PHY_TWD_HS 0x40 +#define MIPI_PHY_AN_CTRL0 0x44 +#define MIPI_PHY_AN_CTRL1 0x48 +#define MIPI_PHY_AN_CTRL2 0x4C +#define MIPI_PHY_CLK_LANE_STS 0x50 +#define MIPI_PHY_DATA_LANE0_STS 0x54 +#define MIPI_PHY_DATA_LANE1_STS 0x58 +#define MIPI_PHY_DATA_LANE2_STS 0x5C +#define MIPI_PHY_DATA_LANE3_STS 0x60 +#define MIPI_PHY_INT_STS 0x6C +#define MIPI_PHY_MUX_CTRL0 (0x61 << 2) +#define MIPI_PHY_MUX_CTRL1 (0x62 << 2) + +/*mipi-csi2 host registers*/ +#define CSI2_HOST_CSI2_RESETN 0x010 +#define CSI2_HOST_N_LANES 0x004 +#define CSI2_HOST_MASK1 0x028 +#define CSI2_HOST_MASK2 0x02c + +/*adapt frontend registers*/ +#define CSI2_CLK_RESET (0x00 << 2) +#define CSI2_GEN_CTRL0 (0x01 << 2) +#define CSI2_GEN_CTRL1 (0x02 << 2) +#define CSI2_X_START_END_ISP (0x03 << 2) +#define CSI2_Y_START_END_ISP (0x04 << 2) +#define CSI2_INTERRUPT_CTRL_STAT (0x14 << 2) +#define CSI2_GEN_STAT0 (0x20 << 2) +#define CSI2_ERR_STAT0 (0x21 << 2) +#define CSI2_PIC_SIZE_STAT (0x22 << 2) + +enum amcsi_status_e { + TVIN_AMCSI_STOP, + TVIN_AMCSI_RUNNING, + TVIN_AMCSI_START, +}; + +struct amcsi_dev_s { + int index; + dev_t devt; + struct cdev cdev; + struct device *dev; + struct platform_device *pdev; + unsigned int overflow_cnt; + enum amcsi_status_e dec_status; + struct vdin_parm_s para; + struct csi_parm_s csi_parm; + unsigned char reset; + unsigned int reset_count; + unsigned int irq_num; + struct tvin_frontend_s frontend; + unsigned int period; + unsigned int min_frmrate; + struct timer_list t; + void __iomem *csi_adapt_addr; +}; + +struct csi_adapt { + struct platform_device *p_dev; + struct resource csi_phy_reg; + struct resource csi_host_reg; + struct resource csi_adapt_reg; + void __iomem *csi_phy; + void __iomem *csi_host; + void __iomem *csi_adapt; + struct clk *csi_clk; + struct clk *adapt_clk; +}; + +void deinit_am_mipi_csi2_clock(void); +void am_mipi_csi2_para_init(struct platform_device *pdev); +void WRITE_CSI_ADPT_REG(int addr, uint32_t val); +uint32_t READ_CSI_PHY_REG(int addr); +uint32_t READ_CSI_HST_REG(int addr); +uint32_t READ_CSI_ADPT_REG(int addr); +uint32_t READ_CSI_ADPT_REG_BIT(int addr, + const uint32_t _start, const uint32_t _len); + +#endif diff --git a/drivers/amlogic/media/vin/tvin/csi/mipi_hw.c b/drivers/amlogic/media/vin/tvin/csi/mipi_hw.c new file mode 100644 index 0000000..90260a4 --- /dev/null +++ b/drivers/amlogic/media/vin/tvin/csi/mipi_hw.c @@ -0,0 +1,385 @@ +/* + * drivers/amlogic/media/vin/tvin/csi/mipi_hw.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "csi.h" + +#define HHI_CSI_PHY 0xff63c000 +#define HHI_CSI_PHY_CNTL0 (0x0d3 << 2) +#define HHI_CSI_PHY_CNTL1 (0x0d4 << 2) +#define HHI_CSI_PHY_CNTL2 (0x0d5 << 2) + +static struct csi_adapt g_csi; + +static inline uint32_t WRITE_CBUS_REG(void __iomem *base, uint32_t addr, + unsigned long val) +{ + void __iomem *io_addr = base + addr; + + __raw_writel(val, io_addr); + + return 0; +} + +inline void phy_update_wr_reg_bits(unsigned int reg, + unsigned int mask, unsigned int val) +{ + unsigned int tmp, orig; + void __iomem *base = g_csi.csi_phy; + + if (base != NULL) { + orig = __raw_readl(base + reg); + tmp = orig & ~mask; + tmp |= val & mask; + __raw_writel(tmp, base + reg); + } +} + +inline void WRITE_CSI_PHY_REG_BITS(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len) +{ + phy_update_wr_reg_bits(adr, + ((1 << len) - 1) << start, val << start); +} + +inline void WRITE_CSI_PHY_REG(int addr, uint32_t val) +{ + void __iomem *reg_addr = g_csi.csi_phy + addr; + + __raw_writel(val, reg_addr); +} + +inline uint32_t READ_CSI_PHY_REG(int addr) +{ + uint32_t val; + void __iomem *reg_addr = g_csi.csi_phy + addr; + + val = __raw_readl(reg_addr); + return val; +} + +inline void WRITE_CSI_HST_REG(int addr, uint32_t val) +{ + void __iomem *reg_addr = g_csi.csi_host + addr; + + __raw_writel(val, reg_addr); +} + +inline uint32_t READ_CSI_HST_REG(int addr) +{ + uint32_t val; + void __iomem *reg_addr = g_csi.csi_host + addr; + + val = __raw_readl(reg_addr); + return val; +} + +inline void WRITE_CSI_ADPT_REG(int addr, uint32_t val) +{ + void __iomem *reg_addr = g_csi.csi_adapt + addr; + + __raw_writel(val, reg_addr); +} + +inline uint32_t READ_CSI_ADPT_REG(int addr) +{ + uint32_t val; + void __iomem *reg_addr = g_csi.csi_adapt + addr; + + val = __raw_readl(reg_addr); + return val; +} + +inline uint32_t READ_CSI_ADPT_REG_BIT(int addr, + const uint32_t _start, const uint32_t _len) +{ + void __iomem *reg_addr = g_csi.csi_adapt + addr; + + return ((__raw_readl(reg_addr) >> (_start)) & ((1L << (_len)) - 1)); +} + +void mipi_phy_reg_wr_and_check(int32_t addr, int32_t data) +{ + +#ifdef MIPI_WR_AND_CHECK + uint32_t tmp; +#endif + WRITE_CSI_PHY_REG(addr, data); +#ifdef MIPI_WR_AND_CHECK + tmp = READ_CSI_PHY_REG(addr); + if (tmp != data) { + pr_info("%s, addr = %x, data = %x, read write unmatch\n", + __func__, addr, tmp); + } +#endif + +} + +void init_am_mipi_csi2_clock(void) +{ + int32_t rc = 0; + uint32_t csi_rate = 200000000; + uint32_t adapt_rate = 666666667; + + g_csi.csi_clk = devm_clk_get(&(g_csi.p_dev->dev), + "cts_csi_phy_clk_composite"); + if (IS_ERR(g_csi.csi_clk)) { + pr_err("%s: cannot get clk_gate_csi !!!\n", + __func__); + g_csi.csi_clk = NULL; + return; + } + clk_set_rate(g_csi.csi_clk, csi_rate); + rc = clk_prepare_enable(g_csi.csi_clk); + if (rc != 0) { + pr_err("Failed to enable csi clk\n"); + return; + } + + g_csi.adapt_clk = devm_clk_get(&(g_csi.p_dev->dev), + "cts_csi_adapt_clk_composite"); + if (IS_ERR(g_csi.adapt_clk)) { + pr_err("%s: cannot get clk_gate_adapt !!!\n", + __func__); + g_csi.adapt_clk = NULL; + return; + } + clk_set_rate(g_csi.adapt_clk, adapt_rate); + rc = clk_prepare_enable(g_csi.adapt_clk); + if (rc != 0) { + pr_err("Failed to enable adapt clk\n"); + return; + } +} + +void disable_am_mipi_csi2_clk(void) +{ + clk_disable_unprepare(g_csi.csi_clk); + clk_disable_unprepare(g_csi.adapt_clk); +} + +void deinit_am_mipi_csi2_clock(void) +{ + if (g_csi.csi_clk != NULL) { + devm_clk_put(&g_csi.p_dev->dev, g_csi.csi_clk); + g_csi.csi_clk = NULL; + } + + if (g_csi.adapt_clk != NULL) { + devm_clk_put(&g_csi.p_dev->dev, g_csi.adapt_clk); + g_csi.adapt_clk = NULL; + } +} + +static void init_am_mipi_csi2_host(struct csi_parm_s *info) +{ + pr_info("info->lanes = %d\n", info->lanes); + WRITE_CSI_HST_REG(CSI2_HOST_CSI2_RESETN, 1); + WRITE_CSI_HST_REG(CSI2_HOST_N_LANES, (info->lanes-1)&3); + WRITE_CSI_HST_REG(CSI2_HOST_MASK1, 0x0); + WRITE_CSI_HST_REG(CSI2_HOST_MASK2, 0x0); + udelay(1); +} + +static int init_am_mipi_csi2_adapter(struct csi_parm_s *info) +{ + unsigned int data32; + struct amcsi_dev_s *csi_devp; + + csi_devp = container_of(info, struct amcsi_dev_s, csi_parm); + WRITE_CSI_ADPT_REG(CSI2_CLK_RESET, 0); + data32 = 0; + data32 |= CSI2_CFG_422TO444_MODE << 21; + data32 |= 0x1f << 16; + data32 |= CSI2_CFG_COLOR_EXPAND << 15; + data32 |= CSI2_CFG_BUFFER_PIC_SIZE << 11; + data32 |= CSI2_CFG_USE_NULL_PACKET << 10; + data32 |= CSI2_CFG_INV_FIELD << 9; + data32 |= CSI2_CFG_INTERLACE_EN << 8; + data32 |= CSI2_CFG_ALL_TO_MEM << 4; + data32 |= 0xf; + WRITE_CSI_ADPT_REG(CSI2_GEN_CTRL0, data32); + + data32 = 0; + data32 |= (csi_devp->para.h_active - 1) << 16; + data32 |= 0 << 0; + WRITE_CSI_ADPT_REG(CSI2_X_START_END_ISP, data32); + + data32 = 0; + data32 |= (csi_devp->para.v_active - 1) << 16; + data32 |= 0 << 0; + WRITE_CSI_ADPT_REG(CSI2_Y_START_END_ISP, data32); + + WRITE_CSI_ADPT_REG(CSI2_INTERRUPT_CTRL_STAT, (1 << 1)); + + /*Enable clock*/ + data32 = 0; + data32 |= 0 << 2; + data32 |= 1 << 1; + data32 |= 0 << 0; + WRITE_CSI_ADPT_REG(CSI2_CLK_RESET, data32); + return 0; +} + +static void powerup_csi_analog(struct csi_parm_s *info) +{ + void __iomem *base_addr; + + base_addr = ioremap_nocache(HHI_CSI_PHY, 0x400); + if (base_addr == NULL) { + pr_err("%s: Failed to ioremap addr\n", __func__); + return; + } + + WRITE_CBUS_REG(base_addr, HHI_CSI_PHY_CNTL0, 0x0b440585); + WRITE_CBUS_REG(base_addr, HHI_CSI_PHY_CNTL1, 0x803f0000); + WRITE_CBUS_REG(base_addr, HHI_CSI_PHY_CNTL2, 0xf002); + + iounmap(base_addr); + + power_ctrl_mempd0(1, 3, 6); +} + +static void powerdown_csi_analog(void) +{ + power_ctrl_mempd0(0, 3, 6); +} + +static void init_am_mipi_phy(struct csi_parm_s *info) +{ + uint32_t settle = 0; + uint32_t ui_val = 0; + uint32_t cycle_time = 5; + + ui_val = 1000 / info->settle; + if ((1000 % info->settle) != 0) + ui_val += 1; + settle = (85 + 145 + (16 * ui_val)) / 2; + settle = settle / cycle_time; + pr_info("settle = 0x%04x\n", settle); + + mipi_phy_reg_wr_and_check(MIPI_PHY_CLK_LANE_CTRL, 0x3d8); + mipi_phy_reg_wr_and_check(MIPI_PHY_TCLK_MISS, 0x9); + mipi_phy_reg_wr_and_check(MIPI_PHY_TCLK_SETTLE, 0x1f); + mipi_phy_reg_wr_and_check(MIPI_PHY_THS_EXIT, 0x1f); + mipi_phy_reg_wr_and_check(MIPI_PHY_THS_SKIP, 0xa); + mipi_phy_reg_wr_and_check(MIPI_PHY_THS_SETTLE, settle); + mipi_phy_reg_wr_and_check(MIPI_PHY_TINIT, 0x4e20); + mipi_phy_reg_wr_and_check(MIPI_PHY_TMBIAS, 0x100); + mipi_phy_reg_wr_and_check(MIPI_PHY_TULPS_C, 0x1000); + mipi_phy_reg_wr_and_check(MIPI_PHY_TULPS_S, 0x100); + mipi_phy_reg_wr_and_check(MIPI_PHY_TLP_EN_W, 0x0c); + mipi_phy_reg_wr_and_check(MIPI_PHY_TLPOK, 0x100); + mipi_phy_reg_wr_and_check(MIPI_PHY_TWD_INIT, 0x400000); + mipi_phy_reg_wr_and_check(MIPI_PHY_TWD_HS, 0x400000); + mipi_phy_reg_wr_and_check(MIPI_PHY_DATA_LANE_CTRL, 0x0); + mipi_phy_reg_wr_and_check(MIPI_PHY_DATA_LANE_CTRL1, + 0x3 | (0x1f << 2) | (0x3 << 7)); + mipi_phy_reg_wr_and_check(MIPI_PHY_MUX_CTRL0, 0x00000123); + mipi_phy_reg_wr_and_check(MIPI_PHY_MUX_CTRL1, 0x00000123); + mipi_phy_reg_wr_and_check(MIPI_PHY_CTRL, 0); +} + +static void reset_am_mipi_csi2_host(void) +{ + WRITE_CSI_HST_REG(CSI2_HOST_CSI2_RESETN, 0); +} + +static void reset_am_mipi_csi2_adapter(void) +{ + WRITE_CSI_ADPT_REG(CSI2_CLK_RESET, 1); +} + +static void reset_am_mipi_phy(void) +{ + WRITE_CSI_PHY_REG_BITS(MIPI_PHY_CTRL, 0x1, 31, 1); +} + +void am_mipi_csi2_para_init(struct platform_device *pdev) +{ + struct resource rs; + int i = 0; + int rtn = -1; + + memset(&g_csi, 0, sizeof(struct csi_adapt)); + g_csi.p_dev = pdev; + + for (i = 0; i < 3; i++) { + rtn = of_address_to_resource(pdev->dev.of_node, i, &rs); + if (rtn != 0) { + pr_err("%s:Error idx %d get mipi csi reg resource\n", + __func__, i); + continue; + } else { + pr_info("%s: rs idx %d info: name: %s\n", __func__, + i, rs.name); + + if (strcmp(rs.name, "csi_phy") == 0) { + g_csi.csi_phy_reg = rs; + g_csi.csi_phy = + ioremap_nocache(g_csi.csi_phy_reg.start, + resource_size(&g_csi.csi_phy_reg)); + } else if (strcmp(rs.name, "csi_host") == 0) { + g_csi.csi_host_reg = rs; + g_csi.csi_host = + ioremap_nocache(g_csi.csi_host_reg.start, + resource_size(&g_csi.csi_host_reg)); + } else if (strcmp(rs.name, "csi_adapt") == 0) { + g_csi.csi_adapt_reg = rs; + g_csi.csi_adapt = + ioremap_nocache(g_csi.csi_adapt_reg.start, + resource_size(&g_csi.csi_adapt_reg)); + } else { + pr_err("%s:Error match address\n", __func__); + } + } + } +} + +void am_mipi_csi2_init(struct csi_parm_s *info) +{ + powerup_csi_analog(info); + init_am_mipi_phy(info); + init_am_mipi_csi2_host(info); + init_am_mipi_csi2_adapter(info); +} + +void am_mipi_csi2_uninit(void) +{ + reset_am_mipi_phy(); + reset_am_mipi_csi2_host(); + reset_am_mipi_csi2_adapter(); + disable_am_mipi_csi2_clk(); + powerdown_csi_analog(); +} + +void cal_csi_para(struct csi_parm_s *info) +{ +} diff --git a/include/dt-bindings/clock/amlogic,g12a-clkc.h b/include/dt-bindings/clock/amlogic,g12a-clkc.h index 7d748ee..34a66d6 100644 --- a/include/dt-bindings/clock/amlogic,g12a-clkc.h +++ b/include/dt-bindings/clock/amlogic,g12a-clkc.h @@ -315,8 +315,10 @@ #define CLKID_CSI_ADPAT_CLK (CLKID_SM1_ADD_BASE + 14) #define CLKID_TEMP_SENSOR_CLK (CLKID_SM1_ADD_BASE + 15) #define CLKID_CSI_PHY_CLK (CLKID_SM1_ADD_BASE + 16) +#define CLKID_MIPI_CSI_PHY_CLK_COMP (CLKID_SM1_ADD_BASE + 17) +#define CLKID_CSI_ADAPT_CLK_COMP (CLKID_SM1_ADD_BASE + 18) -#define CLKID_AO_BASE (CLKID_SM1_ADD_BASE + 17) +#define CLKID_AO_BASE (CLKID_SM1_ADD_BASE + 19) #define CLKID_AO_CLK81 (CLKID_AO_BASE + 0) #define CLKID_SARADC_MUX (CLKID_AO_BASE + 1) #define CLKID_SARADC_DIV (CLKID_AO_BASE + 2) diff --git a/include/linux/amlogic/media/camera/aml_cam_info.h b/include/linux/amlogic/media/camera/aml_cam_info.h index b669ef4..20c9689 100644 --- a/include/linux/amlogic/media/camera/aml_cam_info.h +++ b/include/linux/amlogic/media/camera/aml_cam_info.h @@ -108,6 +108,7 @@ struct aml_cam_info_s { /* gpio_t torch_ctrl_pin; */ unsigned int pwdn_pin; unsigned int rst_pin; + unsigned int cam_vdd; unsigned int flash_ctrl_pin; unsigned int torch_ctrl_pin; enum resolution_size max_cap_size; diff --git a/include/linux/amlogic/media/mipi/am_mipi_csi2.h b/include/linux/amlogic/media/mipi/am_mipi_csi2.h new file mode 100644 index 0000000..5943da3 --- /dev/null +++ b/include/linux/amlogic/media/mipi/am_mipi_csi2.h @@ -0,0 +1,183 @@ +/* + * include/linux/amlogic/media/mipi/am_mipi_csi2.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __AM_MIPI_CSI2_H__ +#define __AM_MIPI_CSI2_H__ + +#include + +#define CSI2_BUF_POOL_SIZE 6 +#define CSI2_OUTPUT_BUF_POOL_SIZE 1 + +#define AM_CSI2_FLAG_NULL 0x00000000 +#define AM_CSI2_FLAG_INITED 0x00000001 +#define AM_CSI2_FLAG_DEV_READY 0x00000002 +#define AM_CSI2_FLAG_STARTED 0x00000004 + +enum am_csi2_mode { + AM_CSI2_ALL_MEM, + AM_CSI2_VDIN, +}; + +struct am_csi2_pixel_fmt { + char *name; + u32 fourcc; + int depth; +}; + +struct am_csi2_camera_para { + const char *name; + unsigned int output_pixel; + unsigned int output_line; + unsigned int active_pixel; + unsigned int active_line; + unsigned int frame_rate; + unsigned int ui_val; + unsigned int hs_freq; + unsigned char clock_lane_mode; + unsigned char mirror; + unsigned int zoom; + unsigned int angle; + struct am_csi2_pixel_fmt *in_fmt; + struct am_csi2_pixel_fmt *out_fmt; +}; + +struct am_csi2_client_config { + enum am_csi2_mode mode; + unsigned char lanes; + unsigned char channel; + int vdin_num; + char name[32]; + void *pdev; +}; + +struct am_csi2_pdata { + struct am_csi2_client_config *clients; + int num_clients; +}; + +struct am_csi2_frame_s { + unsigned int ddr_address; + int index; + unsigned int status; + unsigned int w; + unsigned int h; + int read_cnt; + unsigned int err; +}; + +struct am_csi2_output_s { + void *vaddr; + unsigned int output_pixel; + unsigned int output_line; + u32 fourcc; + int depth; + unsigned int frame_size; + unsigned char frame_available; + unsigned int zoom; + unsigned int angle; + struct am_csi2_frame_s frame[CSI2_OUTPUT_BUF_POOL_SIZE]; +}; + +struct am_csi2_input_s { + unsigned int active_pixel; + unsigned int active_line; + u32 fourcc; + int depth; + unsigned int frame_size; + unsigned char frame_available; + struct am_csi2_frame_s frame[CSI2_BUF_POOL_SIZE]; +}; + +struct am_csi2_hw_s { + unsigned char lanes; + unsigned char channel; + unsigned char mode; + unsigned char clock_lane_mode; + struct am_csi2_frame_s *frame; + unsigned int active_pixel; + unsigned int active_line; + unsigned int frame_size; + unsigned int ui_val; + unsigned int hs_freq; + unsigned int urgent; +}; + +struct am_csi2_s { + char *name; + enum am_csi2_mode mode; + unsigned char lanes; + unsigned char channel; + int vdin_num; + int id; + struct platform_device *pdev; + struct am_csi2_client_config *client; + struct mutex lock; +#ifdef CONFIG_MEM_MIPI + int irq; +#endif + unsigned int pbufAddr; + unsigned int decbuf_size; + unsigned int frame_rate; + unsigned int ui_val; + unsigned int hs_freq; + unsigned char clock_lane_mode; + unsigned char mirror; + unsigned int status; + struct am_csi2_input_s input; + struct am_csi2_output_s output; + struct am_csi2_ops_s *ops; +}; + +struct am_csi2_ops_s { + enum am_csi2_mode mode; + struct am_csi2_pixel_fmt* (*getPixelFormat)(u32 fourcc, bool input); + int (*init)(struct am_csi2_s *dev); + int (*streamon)(struct am_csi2_s *dev); + int (*streamoff)(struct am_csi2_s *dev); + int (*fill)(struct am_csi2_s *dev); + int (*uninit)(struct am_csi2_s *dev); + void *privdata; + int data_num; +}; + +extern int start_mipi_csi2_service(struct am_csi2_camera_para *para); +extern int stop_mipi_csi2_service(struct am_csi2_camera_para *para); +extern void am_mipi_csi2_init(struct csi_parm_s *info); +extern void am_mipi_csi2_uninit(void); +extern void init_am_mipi_csi2_clock(void); +extern void cal_csi_para(struct csi_parm_s *info); + +#define MIPI_DEBUG +#ifdef MIPI_DEBUG +#define mipi_dbg(fmt, args...) printk(fmt, ## args) +#else +#define mipi_dbg(fmt, args...) +#endif +#define mipi_error(fmt, args...) printk(fmt, ## args) + + +#define CSI_ADPT_START_REG CSI2_CLK_RESET +#define CSI_ADPT_END_REG CSI2_PIC_SIZE_STAT + +#define CSI_PHY_START_REG MIPI_PHY_CTRL +#define CSI_PHY_END_REG MIPI_PHY_MUX_CTRL1 + +#define CSI_HST_START_REG CSI2_HOST_CSI2_RESETN +#define CSI_HST_END_REG CSI2_HOST_MASK2 + +#endif