From adc35280cb54e2decd98ff788bb544ddcac49e3b Mon Sep 17 00:00:00 2001 From: Ankur Pawar Date: Wed, 27 Mar 2024 10:22:57 +0000 Subject: [PATCH] media: i2c: enable IMX390 WDR mode Enable WDR(wide dynamic range) mode for IMX390. The following modification and addition are done: 1 Add WDR mode table 2 Restructure IMX390 driver for WDR gain and framerate 3 Use common driver to configure serializer(max9295) and deserializer(max9296) Bug 4505240 Change-Id: I52fc3f03a66fe4e2446d7b41f409ed4154c42f02 Signed-off-by: Ankur Pawar Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3105249 Reviewed-by: Narendra Kondapalli Reviewed-by: Shubham Chandra GVS: buildbot_gerritrpt Reviewed-by: Praveen AC --- drivers/media/i2c/Makefile | 1 + drivers/media/i2c/imx390_mode_tbls.h | 3983 +++++++++++++++++++++++- drivers/media/i2c/max929x.c | 182 ++ drivers/media/i2c/max929x.h | 152 + drivers/media/i2c/nv_imx390.c | 940 ++---- drivers/media/i2c/nv_imx390_archived.c | 911 ++++++ 6 files changed, 5507 insertions(+), 662 deletions(-) create mode 100644 drivers/media/i2c/max929x.c create mode 100644 drivers/media/i2c/max929x.h create mode 100644 drivers/media/i2c/nv_imx390_archived.c diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 7c5913c6..a85d6e88 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -20,6 +20,7 @@ obj-m += nv_imx477.o obj-m += nv_ov5693.o obj-m += nv_ar0234.o obj-m += nv_hawk_owl.o +obj-m += max929x.o endif obj-m += pca9570.o diff --git a/drivers/media/i2c/imx390_mode_tbls.h b/drivers/media/i2c/imx390_mode_tbls.h index 1c8885e3..a1d162c9 100644 --- a/drivers/media/i2c/imx390_mode_tbls.h +++ b/drivers/media/i2c/imx390_mode_tbls.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2018-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-FileCopyrightText: Copyright (c) 2018-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ /* * imx390_mode_tbls.h - imx390 sensor mode tables */ @@ -9,29 +9,18 @@ #include -#define IMX390_TABLE_WAIT_MS 0xff00 -#define IMX390_TABLE_END 0xff01 -#define IMX390_MAX_RETRIES 3 -#define IMX390_WAIT_MS_STOP 1 -#define IMX390_WAIT_MS_START 30 -#define IMX390_WAIT_MS_STREAM 210 -#define IMX390_GAIN_TABLE_SIZE 255 +/* + * define register table operation macro + */ +#define IMX390_TABLE_END (0xff00) +#define IMX390_TABLE_WAIT_MS (0xff01) +/* + * define the imx390 reg list structure + */ #define imx390_reg struct reg_8 -static imx390_reg imx390_start[] = { - {0x0000, 0x00}, - - { IMX390_TABLE_END, 0x00} -}; - -static imx390_reg imx390_stop[] = { - {0x0000, 0x01}, - - {IMX390_TABLE_END, 0x00} -}; - -static imx390_reg imx390_1920x1080_crop_30fps[] = { +static const imx390_reg imx390_mode1_linear_1920x1080_raw12[] = { {0x000C, 0x7F}, {0x000D, 0x01}, {0x000E, 0x00}, @@ -3230,40 +3219,3954 @@ static imx390_reg imx390_1920x1080_crop_30fps[] = { {0x45D6, 0xA7}, {0x45D7, 0xAC}, - {0x0000, 0x01}, - - {IMX390_TABLE_END, 0x00}, }; +/* + * imx390 mode1(refer to datasheet) register configuration with + * 4000x3000 resolution, raw10 data and mipi four lane output + */ +static const imx390_reg imx390_mode1_4000x3000_raw10[] = { + {0x2E18, 0x00}, + {0x000C, 0xF2}, + {0x000D, 0x02}, + {0x000E, 0x00}, + {0x0010, 0xF2}, + {0x0011, 0x02}, + {0x0012, 0x00}, + {0x0018, 0x1C}, + {0x0019, 0x00}, + {0x001A, 0x0A}, + {0x001B, 0x00}, + {0x0038, 0x00}, + {0x003C, 0x00}, + {0x003D, 0x00}, + {0x003E, 0x00}, + {0x0040, 0x00}, + {0x0041, 0x00}, + {0x0042, 0x00}, + {0x0044, 0x00}, + {0x0045, 0x00}, + {0x0046, 0x00}, + {0x0048, 0x00}, + {0x0049, 0x00}, + {0x004A, 0x00}, + {0x004C, 0x00}, + {0x004D, 0x00}, + {0x004E, 0x00}, + {0x0050, 0x00}, + {0x0051, 0x00}, + {0x0052, 0x00}, + {0x0054, 0x00}, + {0x0055, 0x00}, + {0x0056, 0x00}, + {0x0058, 0x00}, + {0x0059, 0x00}, + {0x005A, 0x00}, + {0x005C, 0x00}, + {0x005D, 0x00}, + {0x005E, 0x00}, + {0x0060, 0x00}, + {0x0061, 0x00}, + {0x0062, 0x00}, + {0x0064, 0x00}, + {0x0065, 0x00}, + {0x0066, 0x00}, + {0x0068, 0x00}, + {0x0069, 0x00}, + {0x006A, 0x00}, + {0x0078, 0x00}, + {0x007C, 0x00}, + {0x007D, 0x00}, + {0x0080, 0x00}, + {0x0081, 0x00}, + {0x0090, 0x00}, + {0x00F4, 0x1C}, + {0x00F5, 0xF8}, + {0x00F6, 0x01}, + {0x00F8, 0x03}, + {0x00F9, 0x01}, + {0x00FA, 0x00}, + {0x00FB, 0x02}, + {0x0114, 0x00}, + {0x0115, 0x01}, + {0x0118, 0x20}, + {0x0119, 0x03}, + {0x011A, 0x00}, + {0x011B, 0x41}, + {0x011C, 0x80}, + {0x011D, 0x00}, + {0x0120, 0x20}, + {0x0121, 0x00}, + {0x0122, 0x00}, + {0x0123, 0x44}, + {0x0124, 0x00}, + {0x0125, 0x01}, + {0x0128, 0x17}, + {0x0129, 0x06}, + {0x012A, 0x00}, + {0x012B, 0xA4}, + {0x012C, 0x00}, + {0x012D, 0x01}, + {0x0130, 0xD0}, + {0x0131, 0x07}, + {0x0132, 0x00}, + {0x0133, 0xDA}, + {0x0134, 0x00}, + {0x0136, 0xF0}, + {0x0137, 0x00}, + {0x013A, 0x00}, + {0x013B, 0x00}, + {0x013C, 0x00}, + {0x013D, 0x00}, + {0x013E, 0x00}, + {0x0140, 0x00}, + {0x0141, 0x00}, + {0x0142, 0x00}, + {0x0144, 0xDF}, + {0x0145, 0x01}, + {0x0146, 0x00}, + {0x0148, 0xDF}, + {0x0149, 0x01}, + {0x014A, 0x00}, + {0x014C, 0x9E}, + {0x014D, 0x05}, + {0x014E, 0x00}, + {0x0150, 0x45}, + {0x0151, 0x03}, + {0x0152, 0x00}, + {0x0154, 0xDB}, + {0x0155, 0x10}, + {0x0156, 0x00}, + {0x0158, 0xD6}, + {0x0159, 0x04}, + {0x015A, 0x00}, + {0x015C, 0x91}, + {0x015D, 0x32}, + {0x015E, 0x00}, + {0x0160, 0x98}, + {0x0161, 0x06}, + {0x0162, 0x00}, + {0x0164, 0xB4}, + {0x0165, 0x97}, + {0x0166, 0x00}, + {0x0168, 0x8F}, + {0x0169, 0x08}, + {0x016A, 0x00}, + {0x016C, 0x1C}, + {0x016D, 0xC7}, + {0x016E, 0x01}, + {0x0170, 0xC3}, + {0x0171, 0x0A}, + {0x0172, 0x00}, + {0x0174, 0x55}, + {0x0175, 0x55}, + {0x0176, 0x05}, + {0x0178, 0x3B}, + {0x0179, 0x0D}, + {0x017A, 0x00}, + {0x017C, 0xFF}, + {0x017D, 0xFF}, + {0x017E, 0x0F}, + {0x0180, 0xFF}, + {0x0181, 0x0F}, + {0x0182, 0x00}, + {0x0184, 0xFF}, + {0x0185, 0xFF}, + {0x0186, 0x0F}, + {0x0188, 0xFF}, + {0x0189, 0x0F}, + {0x018A, 0x00}, + {0x018C, 0xFF}, + {0x018D, 0xFF}, + {0x018E, 0xFF}, + {0x0190, 0xFF}, + {0x0191, 0x0F}, + {0x0192, 0x00}, + {0x0194, 0xFF}, + {0x0195, 0x0F}, + {0x0196, 0x00}, + {0x0198, 0x00}, + {0x0199, 0x00}, + {0x019A, 0x00}, + {0x019B, 0x01}, + {0x019C, 0xE8}, + {0x019D, 0x98}, + {0x019E, 0x5F}, + {0x019F, 0x00}, + {0x01A0, 0xD7}, + {0x01A1, 0xB2}, + {0x01A2, 0x23}, + {0x01A3, 0x00}, + {0x01A4, 0xB0}, + {0x01A5, 0x54}, + {0x01A6, 0x0D}, + {0x01A7, 0x00}, + {0x01A8, 0x63}, + {0x01A9, 0xFA}, + {0x01AA, 0x04}, + {0x01AB, 0x00}, + {0x01AC, 0xE4}, + {0x01AD, 0xDB}, + {0x01AE, 0x01}, + {0x01AF, 0x00}, + {0x01B0, 0xB5}, + {0x01B1, 0xB1}, + {0x01B2, 0x00}, + {0x01B3, 0x00}, + {0x01B4, 0x5C}, + {0x01B5, 0x42}, + {0x01B6, 0x00}, + {0x01B7, 0x00}, + {0x01B8, 0xC8}, + {0x01B9, 0x18}, + {0x01BA, 0x00}, + {0x01BB, 0x00}, + {0x01BC, 0x00}, + {0x01BD, 0x00}, + {0x01BE, 0x00}, + {0x01BF, 0x00}, + {0x01C0, 0x00}, + {0x01C1, 0x00}, + {0x01C2, 0x00}, + {0x01C3, 0x00}, + {0x01C4, 0x00}, + {0x01C5, 0x00}, + {0x01CC, 0x01}, + {0x01D0, 0x09}, + {0x01D4, 0x01}, + {0x0332, 0x76}, + {0x0333, 0x03}, + {0x0390, 0x00}, + {0x0391, 0x00}, + {0x0392, 0x00}, + {0x03C0, 0x00}, + {0x2000, 0x55}, + {0x2001, 0x55}, + {0x2002, 0x55}, + {0x2003, 0x05}, + {0x2004, 0x02}, + {0x2008, 0x65}, /* vmax = 0x465 == 1125 */ + {0x2009, 0x04}, + {0x200A, 0x00}, + {0x200C, 0x30}, /* hmax (line period) 0x1130 == 4400 */ + {0x200D, 0x11}, + {0x2010, 0x04}, + {0x2014, 0x01}, + {0x2018, 0x02}, + {0x2019, 0x04}, + {0x201A, 0x00}, + {0x201C, 0x21}, + {0x201D, 0x11}, + {0x201E, 0x00}, + {0x201F, 0x00}, + {0x2020, 0xBC}, + {0x2021, 0x00}, + {0x2022, 0x7F}, + {0x2023, 0x00}, + {0x2024, 0xBA}, + {0x2025, 0x00}, + {0x2026, 0x81}, + {0x2027, 0x00}, + {0x2028, 0x7D}, + {0x2029, 0x90}, + {0x202A, 0x05}, + {0x202C, 0xFC}, + {0x202D, 0x02}, + {0x202E, 0x25}, + {0x202F, 0x03}, + {0x2030, 0x05}, + {0x2031, 0x02}, + {0x2032, 0xCA}, + {0x2033, 0x02}, + {0x2034, 0xFC}, + {0x2035, 0x02}, + {0x2036, 0x25}, + {0x2037, 0x03}, + {0x2038, 0xF8}, + {0x2039, 0xE4}, + {0x203A, 0xE3}, + {0x203B, 0x01}, + {0x203C, 0xF5}, + {0x203D, 0x8E}, + {0x203E, 0x0C}, + {0x203F, 0x2D}, + {0x2040, 0x69}, + {0x2041, 0x01}, + {0x2042, 0x8E}, + {0x2043, 0x01}, + {0x2044, 0x0C}, + {0x2045, 0x02}, + {0x2046, 0x31}, + {0x2047, 0x02}, + {0x2048, 0x6A}, + {0x2049, 0x01}, + {0x204A, 0x8E}, + {0x204B, 0x01}, + {0x204C, 0x0D}, + {0x204D, 0x02}, + {0x204E, 0x31}, + {0x204F, 0x02}, + {0x2050, 0x7B}, + {0x2051, 0x00}, + {0x2052, 0x7D}, + {0x2053, 0x00}, + {0x2054, 0x95}, + {0x2055, 0x00}, + {0x2056, 0x97}, + {0x2057, 0x00}, + {0x2058, 0xAD}, + {0x2059, 0x00}, + {0x205A, 0xAF}, + {0x205B, 0x00}, + {0x205C, 0x92}, + {0x205D, 0x00}, + {0x205E, 0x94}, + {0x205F, 0x00}, + {0x2060, 0x8E}, + {0x2061, 0x00}, + {0x2062, 0x90}, + {0x2063, 0x00}, + {0x2064, 0xB1}, + {0x2065, 0x00}, + {0x2066, 0xB3}, + {0x2067, 0x00}, + {0x2068, 0x08}, + {0x2069, 0x00}, + {0x206A, 0x04}, + {0x206B, 0x00}, + {0x206C, 0x84}, + {0x206D, 0x00}, + {0x206E, 0x80}, + {0x206F, 0x00}, + {0x2070, 0x04}, + {0x2071, 0x00}, + {0x2072, 0x46}, + {0x2073, 0x00}, + {0x2074, 0xE9}, + {0x2075, 0x01}, + {0x2076, 0x74}, + {0x2077, 0x02}, + {0x2078, 0x80}, + {0x2079, 0x00}, + {0x207A, 0xC1}, + {0x207B, 0x00}, + {0x207C, 0xFF}, + {0x207D, 0x03}, + {0x207E, 0xFF}, + {0x207F, 0x03}, + {0x2080, 0x78}, + {0x2081, 0x00}, + {0x2082, 0x6A}, + {0x2083, 0x01}, + {0x2084, 0xE4}, + {0x2085, 0x01}, + {0x2086, 0x2B}, + {0x2087, 0x03}, + {0x2088, 0x00}, + {0x2089, 0x00}, + {0x208A, 0xFF}, + {0x208B, 0x03}, + {0x208C, 0xFF}, + {0x208D, 0x03}, + {0x208E, 0xFF}, + {0x208F, 0x03}, + {0x2090, 0x7D}, + {0x2091, 0x00}, + {0x2092, 0x62}, + {0x2093, 0x01}, + {0x2094, 0xE9}, + {0x2095, 0x01}, + {0x2096, 0x00}, + {0x2097, 0x00}, + {0x2098, 0x7C}, + {0x2099, 0x00}, + {0x209A, 0x21}, + {0x209B, 0x03}, + {0x209C, 0xE9}, + {0x209D, 0x01}, + {0x209E, 0x21}, + {0x209F, 0x03}, + {0x20A0, 0xFF}, + {0x20A1, 0x03}, + {0x20A2, 0xFF}, + {0x20A3, 0x03}, + {0x20A4, 0xFF}, + {0x20A5, 0x03}, + {0x20A6, 0xFF}, + {0x20A7, 0x03}, + {0x20A8, 0xFF}, + {0x20A9, 0x03}, + {0x20AA, 0xFF}, + {0x20AB, 0x03}, + {0x20AC, 0xFF}, + {0x20AD, 0x03}, + {0x20AE, 0xFF}, + {0x20AF, 0x03}, + {0x20B0, 0xFF}, + {0x20B1, 0x03}, + {0x20B2, 0xFF}, + {0x20B3, 0x03}, + {0x20B4, 0x87}, + {0x20B5, 0xCC}, + {0x20B6, 0x87}, + {0x20B7, 0x08}, + {0x20B8, 0xF4}, + {0x20B9, 0xA5}, + {0x20BA, 0x07}, + {0x20BC, 0x1F}, + {0x20BD, 0x01}, + {0x20BE, 0xF6}, + {0x20BF, 0x00}, + {0x20C0, 0x90}, + {0x20C1, 0x01}, + {0x20C2, 0x67}, + {0x20C3, 0x01}, + {0x20C4, 0xFF}, + {0x20C5, 0x03}, + {0x20C6, 0xFF}, + {0x20C7, 0x03}, + {0x20C8, 0x33}, + {0x20C9, 0x02}, + {0x20CA, 0x0A}, + {0x20CB, 0x02}, + {0x20CC, 0x7F}, + {0x20CD, 0x00}, + {0x20CE, 0xD2}, + {0x20CF, 0x00}, + {0x20D0, 0x81}, + {0x20D1, 0x00}, + {0x20D2, 0x87}, + {0x20D3, 0x00}, + {0x20D4, 0x09}, + {0x20D5, 0x00}, + {0x20D8, 0x7F}, + {0x20D9, 0x00}, + {0x20DA, 0x62}, + {0x20DB, 0x01}, + {0x20DC, 0x7F}, + {0x20DD, 0x00}, + {0x20DE, 0x62}, + {0x20DF, 0x01}, + {0x20E0, 0x65}, + {0x20E1, 0x00}, + {0x20E2, 0x75}, + {0x20E3, 0x00}, + {0x20E4, 0xE0}, + {0x20E5, 0x00}, + {0x20E6, 0xF0}, + {0x20E7, 0x00}, + {0x20E8, 0x4C}, + {0x20E9, 0x01}, + {0x20EA, 0x5C}, + {0x20EB, 0x01}, + {0x20EC, 0xD1}, + {0x20ED, 0x01}, + {0x20EE, 0xE1}, + {0x20EF, 0x01}, + {0x20F0, 0x93}, + {0x20F1, 0x02}, + {0x20F2, 0xA3}, + {0x20F3, 0x02}, + {0x20F4, 0x0D}, + {0x20F5, 0x03}, + {0x20F6, 0x1D}, + {0x20F7, 0x03}, + {0x20F8, 0x57}, + {0x20F9, 0x00}, + {0x20FA, 0x7B}, + {0x20FB, 0x00}, + {0x20FC, 0xD2}, + {0x20FD, 0x00}, + {0x20FE, 0xF6}, + {0x20FF, 0x00}, + {0x2100, 0x3E}, + {0x2101, 0x01}, + {0x2102, 0x60}, + {0x2103, 0x01}, + {0x2104, 0xC3}, + {0x2105, 0x01}, + {0x2106, 0xE5}, + {0x2107, 0x01}, + {0x2108, 0x85}, + {0x2109, 0x02}, + {0x210A, 0xA9}, + {0x210B, 0x02}, + {0x210C, 0xFF}, + {0x210D, 0x02}, + {0x210E, 0x21}, + {0x210F, 0x03}, + {0x2110, 0xFF}, + {0x2111, 0x03}, + {0x2112, 0x00}, + {0x2113, 0x00}, + {0x2114, 0xFF}, + {0x2115, 0x03}, + {0x2116, 0xFF}, + {0x2117, 0x03}, + {0x2118, 0xFF}, + {0x2119, 0x03}, + {0x211A, 0xFF}, + {0x211B, 0x03}, + {0x211C, 0xFF}, + {0x211D, 0x03}, + {0x211E, 0xFF}, + {0x211F, 0x03}, + {0x2120, 0xFF}, + {0x2121, 0x03}, + {0x2122, 0xFF}, + {0x2123, 0x03}, + {0x2124, 0xFF}, + {0x2125, 0x03}, + {0x2126, 0xFF}, + {0x2127, 0x03}, + {0x2128, 0x7D}, + {0x2129, 0x90}, + {0x212A, 0xD5}, + {0x212B, 0x07}, + {0x212C, 0x64}, + {0x212D, 0x01}, + {0x2130, 0x5F}, + {0x2131, 0x7D}, + {0x2132, 0x05}, + {0x2134, 0x78}, + {0x2135, 0x00}, + {0x2136, 0x76}, + {0x2137, 0x00}, + {0x2138, 0xF3}, + {0x2139, 0x00}, + {0x213A, 0xF1}, + {0x213B, 0x00}, + {0x213C, 0xA6}, + {0x213D, 0x02}, + {0x213E, 0xA4}, + {0x213F, 0x02}, + {0x2140, 0x7D}, + {0x2141, 0x00}, + {0x2142, 0x8D}, + {0x2143, 0x00}, + {0x2144, 0xA1}, + {0x2145, 0x01}, + {0x2146, 0xB1}, + {0x2147, 0x01}, + {0x2148, 0xAB}, + {0x2149, 0x02}, + {0x214A, 0xBB}, + {0x214B, 0x02}, + {0x214C, 0x17}, + {0x214D, 0x5C}, + {0x214E, 0x00}, + {0x2150, 0x00}, + {0x2151, 0x00}, + {0x2152, 0xF8}, + {0x2153, 0x00}, + {0x2154, 0x45}, + {0x2155, 0x00}, + {0x2156, 0x00}, + {0x2157, 0x00}, + {0x2158, 0x25}, + {0x2159, 0x00}, + {0x215A, 0x7D}, + {0x215B, 0x00}, + {0x215C, 0x62}, + {0x215D, 0x01}, + {0x215E, 0xFF}, + {0x215F, 0x03}, + {0x2160, 0x26}, + {0x2161, 0x00}, + {0x2162, 0x7D}, + {0x2163, 0x00}, + {0x2164, 0x63}, + {0x2165, 0x01}, + {0x2166, 0xFF}, + {0x2167, 0x03}, + {0x2168, 0xCB}, + {0x2169, 0x02}, + {0x216A, 0xCF}, + {0x216B, 0x02}, + {0x216C, 0xFF}, + {0x216D, 0x03}, + {0x216E, 0xFF}, + {0x216F, 0x03}, + {0x2170, 0xFF}, + {0x2171, 0x03}, + {0x2172, 0xFF}, + {0x2173, 0x03}, + {0x2174, 0xFF}, + {0x2175, 0x03}, + {0x2176, 0xFF}, + {0x2177, 0x03}, + {0x2178, 0x7E}, + {0x2179, 0x00}, + {0x217A, 0xBD}, + {0x217B, 0x00}, + {0x217C, 0xEC}, + {0x217D, 0x01}, + {0x217E, 0x7B}, + {0x217F, 0x02}, + {0x2180, 0xD1}, + {0x2181, 0x02}, + {0x2182, 0x25}, + {0x2183, 0x03}, + {0x2184, 0x7F}, + {0x2185, 0x00}, + {0x2186, 0xBD}, + {0x2187, 0x00}, + {0x2188, 0xED}, + {0x2189, 0x01}, + {0x218A, 0x7B}, + {0x218B, 0x02}, + {0x218C, 0xD2}, + {0x218D, 0x02}, + {0x218E, 0x25}, + {0x218F, 0x03}, + {0x2190, 0xFF}, + {0x2191, 0x03}, + {0x2192, 0xFF}, + {0x2193, 0x03}, + {0x2194, 0xE9}, + {0x2195, 0x01}, + {0x2196, 0x21}, + {0x2197, 0x03}, + {0x2198, 0x17}, + {0x2199, 0xFC}, + {0x219A, 0x7F}, + {0x219B, 0x01}, + {0x219C, 0xFF}, + {0x219D, 0x03}, + {0x21A0, 0x1B}, + {0x21A1, 0x1B}, + {0x21A2, 0x1B}, + {0x21A3, 0x01}, + {0x21A4, 0x2E}, + {0x21A5, 0x80}, + {0x21A6, 0x00}, + {0x21A8, 0x04}, + {0x21A9, 0x98}, + {0x21AA, 0x60}, + {0x21AB, 0x03}, + {0x21AC, 0x7F}, + {0x21AD, 0x80}, + {0x21AE, 0x09}, + {0x21B0, 0x1C}, + {0x21B1, 0x00}, + {0x21B2, 0xA0}, + {0x21B3, 0x00}, + {0x21B4, 0x0C}, + {0x21B5, 0x00}, + {0x21B6, 0x2D}, + {0x21B7, 0x00}, + {0x21B8, 0x20}, + {0x21B9, 0x00}, + {0x21BA, 0x02}, + {0x21BB, 0x00}, + {0x21BC, 0xCC}, + {0x21BD, 0x00}, + {0x21BE, 0x4A}, + {0x21BF, 0x00}, + {0x21C0, 0xD0}, + {0x21C1, 0x00}, + {0x21C2, 0x44}, + {0x21C3, 0x00}, + {0x21C4, 0x00}, + {0x21C5, 0xE0}, + {0x21C6, 0x00}, + {0x21C8, 0x11}, + {0x21C9, 0x00}, + {0x21CA, 0x02}, + {0x21CC, 0x08}, + {0x21CD, 0xC0}, + {0x21CE, 0x0C}, + {0x21D0, 0x44}, + {0x21D1, 0x00}, + {0x21D2, 0x02}, + {0x21D4, 0x02}, + {0x21D5, 0x20}, + {0x21D6, 0x2C}, + {0x21D8, 0xFE}, + {0x21D9, 0x9D}, + {0x21DA, 0xDF}, + {0x21DB, 0x03}, + {0x21DC, 0x62}, + {0x21DD, 0x01}, + {0x21DE, 0x7F}, + {0x21DF, 0x00}, + {0x21E0, 0xB7}, + {0x21E1, 0x01}, + {0x21E2, 0xB5}, + {0x21E3, 0x01}, + {0x21E4, 0xC1}, + {0x21E5, 0x02}, + {0x21E6, 0xBF}, + {0x21E7, 0x02}, + {0x21E8, 0xB3}, + {0x21E9, 0x4D}, + {0x21EA, 0x00}, + {0x21EB, 0x04}, + {0x21EC, 0x90}, + {0x21ED, 0x07}, + {0x21EE, 0x58}, + {0x21EF, 0x04}, + {0x21F0, 0x54}, + {0x21F1, 0x04}, + {0x21F4, 0x02}, + {0x21F5, 0x00}, + {0x21F6, 0x00}, + {0x21F8, 0x3C}, + {0x21F9, 0x00}, + {0x21FC, 0x28}, + {0x21FD, 0x00}, + {0x21FE, 0x3C}, + {0x21FF, 0x00}, + {0x2200, 0x00}, + {0x2204, 0x4C}, + {0x2205, 0x04}, + {0x2206, 0x65}, + {0x2207, 0x04}, + {0x2208, 0x0A}, + {0x2209, 0x00}, + {0x220C, 0x47}, + {0x220D, 0x00}, + {0x220E, 0x1F}, + {0x220F, 0x00}, + {0x2210, 0x17}, + {0x2211, 0x00}, + {0x2212, 0x0F}, + {0x2213, 0x00}, + {0x2214, 0x17}, + {0x2215, 0x00}, + {0x2216, 0x47}, + {0x2217, 0x00}, + {0x2218, 0x0F}, + {0x2219, 0x00}, + {0x221A, 0x0F}, + {0x221B, 0x00}, + {0x221C, 0x03}, + {0x2220, 0x20}, + {0x2221, 0x20}, + {0x2222, 0x22}, + {0x2223, 0x02}, + {0x2224, 0xA7}, + {0x2225, 0xAA}, + {0x2226, 0x80}, + {0x2227, 0x08}, + {0x2228, 0x01}, + {0x2260, 0xFF}, + {0x2261, 0x1F}, + {0x2262, 0x00}, + {0x2263, 0x00}, + {0x2264, 0x00}, + {0x2265, 0x00}, + {0x2266, 0xFF}, + {0x2267, 0x1F}, + {0x2268, 0x00}, + {0x2269, 0x00}, + {0x226A, 0xFF}, + {0x226B, 0x1F}, + {0x226C, 0x00}, + {0x226D, 0x00}, + {0x226E, 0xFF}, + {0x226F, 0x1F}, + {0x227C, 0xFF}, + {0x227D, 0x1F}, + {0x227E, 0x00}, + {0x227F, 0x10}, + {0x2280, 0xFF}, + {0x2281, 0x1F}, + {0x2282, 0x00}, + {0x2283, 0x10}, + {0x2284, 0xFF}, + {0x2285, 0x1F}, + {0x2286, 0x00}, + {0x2287, 0x10}, + {0x22B2, 0x92}, + {0x22B4, 0x20}, + {0x22B5, 0x00}, + {0x22B6, 0x20}, + {0x22B7, 0x00}, + {0x22B8, 0x20}, + {0x22B9, 0x00}, + {0x22BA, 0x20}, + {0x22BB, 0x00}, + {0x22BC, 0x20}, + {0x22BD, 0x00}, + {0x22BE, 0x20}, + {0x22BF, 0x00}, + {0x22C0, 0x20}, + {0x22C1, 0x00}, + {0x22C2, 0x20}, + {0x22C3, 0x00}, + {0x22C4, 0x20}, + {0x22C5, 0x00}, + {0x22C6, 0x20}, + {0x22C7, 0x00}, + {0x22C8, 0x20}, + {0x22C9, 0x00}, + {0x22CA, 0x20}, + {0x22CB, 0x00}, + {0x22CC, 0x20}, + {0x22CD, 0x00}, + {0x22CE, 0x20}, + {0x22CF, 0x00}, + {0x22DA, 0x00}, + {0x22EF, 0x82}, + {0x2308, 0x01}, + {0x2310, 0x73}, + {0x2311, 0x89}, + {0x2318, 0x40}, + {0x2319, 0xCD}, + {0x231A, 0x54}, + {0x2324, 0x20}, + {0x2325, 0x00}, + {0x2328, 0x00}, + {0x234A, 0x9F}, + {0x234B, 0x07}, + {0x2354, 0x0C}, + {0x23C0, 0x5D}, + {0x244C, 0x00}, + {0x244D, 0x02}, + {0x244E, 0x54}, + {0x244F, 0x02}, + {0x24A0, 0x00}, + {0x24A4, 0x16}, + {0x24A5, 0x01}, + {0x24A6, 0xA6}, + {0x24A7, 0x02}, + {0x24A8, 0xD5}, + {0x24A9, 0x02}, + {0x24BC, 0x17}, + {0x24BD, 0x01}, + {0x24BE, 0xA7}, + {0x24BF, 0x02}, + {0x24C0, 0xD5}, + {0x24C1, 0x02}, + {0x24DA, 0x6F}, + {0x24DB, 0x00}, + {0x24DC, 0x62}, + {0x24DD, 0x01}, + {0x24EA, 0x32}, + {0x24EB, 0x00}, + {0x24EC, 0xDC}, + {0x24ED, 0x00}, + {0x24FA, 0x32}, + {0x24FB, 0x00}, + {0x24FC, 0xDD}, + {0x24FD, 0x00}, + {0x254A, 0x15}, + {0x254B, 0x01}, + {0x255A, 0x15}, + {0x255B, 0x01}, + {0x2560, 0x01}, + {0x2561, 0x00}, + {0x2562, 0x2A}, + {0x2563, 0x00}, + {0x2564, 0xF8}, + {0x2565, 0x00}, + {0x2566, 0x15}, + {0x2567, 0x01}, + {0x2568, 0x0C}, + {0x2569, 0x02}, + {0x256A, 0x31}, + {0x256B, 0x02}, + {0x2578, 0x90}, + {0x2579, 0x01}, + {0x257A, 0x92}, + {0x257B, 0x01}, + {0x257C, 0xB8}, + {0x257D, 0x02}, + {0x257E, 0xBA}, + {0x257F, 0x02}, + {0x2584, 0x90}, + {0x2585, 0x01}, + {0x2586, 0x92}, + {0x2587, 0x01}, + {0x2588, 0xB8}, + {0x2589, 0x02}, + {0x258A, 0xBA}, + {0x258B, 0x02}, + {0x267A, 0xF8}, + {0x267B, 0x00}, + {0x267C, 0x16}, + {0x267D, 0x01}, + {0x267E, 0xA6}, + {0x267F, 0x02}, + {0x2680, 0xD5}, + {0x2681, 0x02}, + {0x2690, 0xF8}, + {0x2691, 0x00}, + {0x2694, 0xA6}, + {0x2695, 0x02}, + {0x2696, 0x16}, + {0x2697, 0x01}, + {0x269A, 0xD5}, + {0x269B, 0x02}, + {0x26B8, 0x10}, + {0x26B9, 0x00}, + {0x26BA, 0x33}, + {0x26BB, 0x00}, + {0x26BC, 0x89}, + {0x26BD, 0x00}, + {0x26BE, 0xB0}, + {0x26BF, 0x00}, + {0x26C4, 0x4E}, + {0x26C5, 0x00}, + {0x26C8, 0xC9}, + {0x26C9, 0x00}, + {0x26CC, 0x35}, + {0x26CD, 0x01}, + {0x26D0, 0xBA}, + {0x26D1, 0x01}, + {0x26D4, 0x7C}, + {0x26D5, 0x02}, + {0x26D8, 0xF6}, + {0x26D9, 0x02}, + {0x26DE, 0x51}, + {0x26DF, 0x00}, + {0x26E0, 0x7F}, + {0x26E1, 0x00}, + {0x26E2, 0xCC}, + {0x26E3, 0x00}, + {0x26E4, 0xF8}, + {0x26E5, 0x00}, + {0x26E6, 0x38}, + {0x26E7, 0x01}, + {0x26E8, 0x65}, + {0x26E9, 0x01}, + {0x26EA, 0xBD}, + {0x26EB, 0x01}, + {0x26EE, 0x7F}, + {0x26EF, 0x02}, + {0x26F0, 0xAB}, + {0x26F1, 0x02}, + {0x26F2, 0xF9}, + {0x26F3, 0x02}, + {0x2722, 0x59}, + {0x2723, 0x02}, + {0x2938, 0x55}, + {0x2939, 0x00}, + {0x293A, 0x17}, + {0x293B, 0x00}, + {0x293C, 0xD0}, + {0x293D, 0x00}, + {0x293E, 0x91}, + {0x293F, 0x00}, + {0x2940, 0x3C}, + {0x2941, 0x01}, + {0x2942, 0x0C}, + {0x2943, 0x01}, + {0x2944, 0xC1}, + {0x2945, 0x01}, + {0x2946, 0x76}, + {0x2947, 0x01}, + {0x2948, 0x83}, + {0x2949, 0x02}, + {0x294A, 0xFB}, + {0x294B, 0x01}, + {0x294C, 0xFD}, + {0x294D, 0x02}, + {0x294E, 0xBF}, + {0x294F, 0x02}, + {0x2A06, 0x25}, + {0x2A07, 0x03}, + {0x2A0C, 0xBE}, + {0x2A0D, 0x00}, + {0x2A0E, 0x7D}, + {0x2A0F, 0x00}, + {0x2A20, 0x00}, + {0x2A21, 0x00}, + {0x2A22, 0x7D}, + {0x2A23, 0x00}, + {0x2B11, 0x19}, + {0x2B13, 0x15}, + {0x2B14, 0x14}, + {0x2B15, 0x13}, + {0x2B16, 0x12}, + {0x2B17, 0x11}, + {0x2B18, 0x10}, + {0x2B19, 0x0F}, + {0x2B1A, 0x0E}, + {0x2B1B, 0x0D}, + {0x2B1C, 0x0C}, + {0x2B1D, 0x0B}, + {0x2B1E, 0x0A}, + {0x2B1F, 0x09}, + {0x2B20, 0x08}, + {0x2B21, 0x07}, + {0x2B22, 0x06}, + {0x2B23, 0x05}, + {0x2B24, 0x04}, + {0x2B25, 0x03}, + {0x2B26, 0x03}, + {0x2B38, 0x01}, + {0x2B45, 0xE3}, + {0x2B50, 0x01}, + {0x2B51, 0x00}, + {0x2B6D, 0x47}, + {0x2B70, 0x04}, + {0x2B71, 0x02}, + {0x2B72, 0x02}, + {0x2B7B, 0x42}, + {0x2B7F, 0x7F}, + {0x2B80, 0x94}, + {0x2B81, 0x06}, + {0x2B87, 0x1B}, + {0x2B88, 0x1A}, + {0x2B89, 0x17}, + {0x2B8A, 0x12}, + {0x2B8B, 0x01}, + {0x2B8D, 0x2B}, + {0x2B8E, 0x2B}, + {0x2B8F, 0x1B}, + {0x2B90, 0xBF}, + {0x2B91, 0x0F}, + {0x2B92, 0x73}, + {0x2B93, 0x0E}, + {0x2B94, 0xBF}, + {0x2B95, 0x07}, + {0x2B96, 0x73}, + {0x2B97, 0x0E}, + {0x2B98, 0xBF}, + {0x2B99, 0x57}, + {0x2B9B, 0x2A}, + {0x2BA8, 0xBC}, + {0x2BA9, 0x62}, + {0x2BC5, 0x80}, + {0x2BD5, 0x30}, + {0x2BD6, 0xF0}, + {0x2BD8, 0x5B}, + {0x2BD9, 0xF0}, + {0x2BDA, 0x21}, + {0x2BDB, 0x0E}, + {0x2BDC, 0x5E}, + {0x2BFE, 0x02}, + {0x2BFF, 0x00}, + {0x2C98, 0xE1}, + {0x2C99, 0x2E}, + {0x2C9B, 0x80}, + {0x2CA9, 0x80}, + {0x2CAA, 0x01}, + {0x2CBF, 0x08}, + {0x2D39, 0x0E}, + {0x2D50, 0x80}, + {0x2D54, 0x00}, + {0x2D5B, 0x58}, + {0x2DFD, 0x01}, + {0x2DFC, 0x00}, + {0x2E24, 0x01}, + {0x3000, 0x00}, + {0x3001, 0x00}, + {0x3002, 0x23}, + {0x3003, 0xA1}, + {0x3004, 0x00}, + {0x3005, 0x20}, + {0x3006, 0x84}, + {0x3007, 0x00}, + {0x3008, 0x06}, + {0x3009, 0xB4}, + {0x300A, 0x1F}, + {0x300B, 0x00}, + {0x300C, 0x00}, + {0x300D, 0x1B}, + {0x300E, 0x90}, + {0x300F, 0x97}, + {0x3010, 0x00}, + {0x3011, 0x00}, + {0x3012, 0x21}, + {0x3013, 0x21}, + {0x3014, 0x00}, + {0x3015, 0x20}, + {0x3016, 0x84}, + {0x3017, 0x00}, + {0x3018, 0x30}, + {0x3019, 0x09}, + {0x301A, 0x46}, + {0x301B, 0x00}, + {0x30A0, 0xCD}, + {0x30A1, 0x0C}, + {0x30A2, 0xBA}, + {0x30A3, 0x0C}, + {0x30A4, 0x5F}, + {0x30A5, 0x00}, + {0x30A6, 0x43}, + {0x30A7, 0x00}, + {0x30A8, 0xC8}, + {0x30A9, 0x0A}, + {0x30AA, 0x0B}, + {0x30AB, 0x08}, + {0x30AC, 0x4B}, + {0x30AD, 0x03}, + {0x30AE, 0x37}, + {0x30AF, 0x03}, + {0x30B0, 0x65}, + {0x30B1, 0x09}, + {0x30B2, 0x7A}, + {0x30B3, 0x09}, + {0x30B4, 0x20}, + {0x30B5, 0x00}, + {0x30B6, 0x28}, + {0x30B7, 0x00}, + {0x30B8, 0x91}, + {0x30B9, 0x04}, + {0x30BA, 0x75}, + {0x30BB, 0x05}, + {0x30BC, 0x7C}, + {0x30BD, 0x01}, + {0x30BE, 0x87}, + {0x30BF, 0x01}, + {0x3370, 0x01}, + {0x3374, 0x00}, + {0x3375, 0x00}, + {0x3376, 0x01}, + {0x3377, 0x00}, + {0x3410, 0x90}, + {0x3411, 0x07}, + {0x3450, 0x00}, + {0x3418, 0x48}, + {0x3419, 0x04}, + {0x34BE, 0x7A}, + {0x34BF, 0x02}, + {0x3584, 0x00}, + {0x3586, 0x00}, + {0x3587, 0x01}, + {0x3588, 0xE6}, + {0x3589, 0x00}, + {0x3590, 0x00}, + {0x3591, 0x00}, + {0x3594, 0x40}, + {0x3598, 0x03}, + {0x3599, 0x00}, + {0x359A, 0x80}, + {0x359B, 0x00}, + {0x359C, 0x00}, + {0x359D, 0x01}, + {0x359E, 0x00}, + {0x359F, 0x02}, + {0x35A0, 0x00}, + {0x35A1, 0x04}, + {0x35A2, 0x20}, + {0x35A3, 0x00}, + {0x35A4, 0x40}, + {0x35A5, 0x00}, + {0x35A6, 0x80}, + {0x35A7, 0x00}, + {0x35A8, 0x00}, + {0x35A9, 0x01}, + {0x35AC, 0x80}, + {0x35AD, 0x00}, + {0x35AE, 0x00}, + {0x35AF, 0x01}, + {0x35B0, 0x00}, + {0x35B1, 0x02}, + {0x35B2, 0x00}, + {0x35B3, 0x04}, + {0x35B4, 0x02}, + {0x35B5, 0x00}, + {0x35B6, 0x04}, + {0x35B7, 0x00}, + {0x35B8, 0x08}, + {0x35B9, 0x00}, + {0x35BA, 0x10}, + {0x35BB, 0x00}, + {0x35C8, 0x00}, + {0x35C9, 0x01}, + {0x35CA, 0x00}, + {0x35CB, 0x04}, + {0x35CC, 0x00}, + {0x35CD, 0x10}, + {0x35CE, 0x00}, + {0x35CF, 0x40}, + {0x35D0, 0x00}, + {0x35D1, 0x0C}, + {0x35D2, 0x00}, + {0x35D3, 0x0C}, + {0x35D4, 0x00}, + {0x35D5, 0x0C}, + {0x35D6, 0x00}, + {0x35D7, 0x0C}, + {0x35D8, 0x00}, + {0x35D9, 0x00}, + {0x35DA, 0x08}, + {0x35DB, 0x00}, + {0x35DC, 0xD8}, + {0x35DD, 0x0E}, + {0x35F0, 0x00}, + {0x35F1, 0x10}, + {0x35F2, 0x00}, + {0x35F3, 0x10}, + {0x35F4, 0x00}, + {0x35F5, 0x10}, + {0x35F6, 0x00}, + {0x35F7, 0x04}, + {0x35F8, 0x00}, + {0x35F9, 0x03}, + {0x35FA, 0x38}, + {0x35FB, 0x00}, + {0x35FC, 0xB3}, + {0x35FD, 0x01}, + {0x35FE, 0x00}, + {0x35FF, 0x00}, + {0x3600, 0x05}, + {0x3601, 0x06}, + {0x3604, 0x03}, + {0x3605, 0x00}, + {0x3608, 0x03}, + {0x3609, 0x00}, + {0x360C, 0x01}, + {0x360D, 0x00}, + {0x3610, 0x10}, + {0x3611, 0x01}, + {0x3612, 0x00}, + {0x3613, 0x00}, + {0x3614, 0x00}, + {0x3615, 0x00}, + {0x361C, 0x00}, + {0x361D, 0x01}, + {0x361E, 0x01}, + {0x361F, 0x00}, + {0x3620, 0x00}, + {0x3621, 0x01}, + {0x3622, 0xB0}, + {0x3623, 0x04}, + {0x3624, 0xDC}, + {0x3625, 0x05}, + {0x3626, 0x00}, + {0x3627, 0x01}, + {0x3628, 0xFF}, + {0x3629, 0x0F}, + {0x362A, 0x00}, + {0x362B, 0x10}, + {0x362C, 0x00}, + {0x362D, 0x01}, + {0x3630, 0x42}, + {0x3631, 0x00}, + {0x3632, 0x43}, + {0x3633, 0x00}, + {0x3634, 0x43}, + {0x3635, 0x00}, + {0x3636, 0x43}, + {0x3637, 0x00}, + {0x3638, 0x47}, + {0x3639, 0x00}, + {0x363A, 0x46}, + {0x363B, 0x00}, + {0x363C, 0x45}, + {0x363D, 0x00}, + {0x363E, 0x46}, + {0x363F, 0x00}, + {0x36C4, 0xFF}, + {0x36C5, 0x0F}, + {0x36C6, 0xFF}, + {0x36C7, 0x0F}, + {0x36C8, 0xFF}, + {0x36C9, 0x0F}, + {0x36CC, 0x00}, + {0x36CD, 0x00}, + {0x36CE, 0x00}, + {0x36CF, 0x00}, + {0x36D0, 0x00}, + {0x36D1, 0x00}, + {0x36D4, 0xFF}, + {0x36D5, 0x0F}, + {0x36D6, 0xFF}, + {0x36D7, 0x0F}, + {0x36D8, 0xFF}, + {0x36D9, 0x0F}, + {0x36DC, 0xFF}, + {0x36DD, 0x0F}, + {0x36DE, 0xFF}, + {0x36DF, 0x0F}, + {0x36E0, 0xFF}, + {0x36E1, 0x0F}, + {0x36E4, 0xFF}, + {0x36E5, 0x0F}, + {0x36E6, 0xFF}, + {0x36E7, 0x0F}, + {0x36E8, 0xFF}, + {0x36E9, 0x0F}, + {0x36EE, 0x00}, + {0x36EF, 0x00}, + {0x36F0, 0x00}, + {0x36F1, 0x80}, + {0x36F8, 0x00}, + {0x3700, 0x03}, + {0x3701, 0x05}, + {0x3702, 0x03}, + {0x3703, 0x04}, + {0x3704, 0x08}, + {0x3705, 0x03}, + {0x3706, 0x03}, + {0x3707, 0x03}, + {0x3708, 0x03}, + {0x3709, 0x03}, + {0x370A, 0x03}, + {0x370B, 0x03}, + {0x370C, 0x03}, + {0x370D, 0x03}, + {0x370E, 0x0E}, + {0x3718, 0x62}, + {0x3719, 0x4A}, + {0x371A, 0x38}, + {0x371B, 0x20}, + {0x371C, 0x64}, + {0x371D, 0x42}, + {0x371E, 0x32}, + {0x371F, 0x1B}, + {0x3720, 0x98}, + {0x3721, 0xA0}, + {0x3722, 0xA8}, + {0x3723, 0xB0}, + {0x3748, 0xA5}, + {0x3749, 0x9B}, + {0x374A, 0x91}, + {0x374B, 0x7D}, + {0x37C0, 0x00}, + {0x37C1, 0x00}, + {0x37C2, 0x00}, + {0x37C4, 0x00}, + {0x37C5, 0x00}, + {0x37C6, 0x00}, + {0x37C8, 0x00}, + {0x37C9, 0x00}, + {0x37CA, 0x00}, + {0x37CC, 0x00}, + {0x37CD, 0x00}, + {0x37CE, 0x00}, + {0x37D0, 0x00}, + {0x37D1, 0x00}, + {0x37D2, 0x00}, + {0x37D4, 0x00}, + {0x37D5, 0x00}, + {0x37D6, 0x00}, + {0x37D8, 0x00}, + {0x37D9, 0x00}, + {0x37DA, 0x00}, + {0x37DC, 0x00}, + {0x37DD, 0x00}, + {0x37DE, 0x00}, + {0x37E0, 0x00}, + {0x37E1, 0x00}, + {0x37E2, 0x00}, + {0x37E4, 0x00}, + {0x37E5, 0x00}, + {0x37E6, 0x00}, + {0x37E8, 0x00}, + {0x37E9, 0x00}, + {0x37EA, 0x00}, + {0x37EC, 0x00}, + {0x37ED, 0x00}, + {0x37EE, 0x00}, + {0x37F0, 0x00}, + {0x37F4, 0x00}, + {0x37F5, 0x1E}, + {0x37F6, 0x34}, + {0x37F7, 0x00}, + {0x37F8, 0xFF}, + {0x37F9, 0xFF}, + {0x37FA, 0x03}, + {0x37FC, 0x00}, + {0x37FD, 0x00}, + {0x37FE, 0x04}, + {0x3800, 0xFF}, + {0x3801, 0xFF}, + {0x3802, 0x03}, + {0x3804, 0x00}, + {0x3805, 0x00}, + {0x3806, 0x04}, + {0x3808, 0x00}, + {0x3809, 0x00}, + {0x380A, 0x00}, + {0x380C, 0x00}, + {0x380D, 0x00}, + {0x380E, 0x00}, + {0x3810, 0x00}, + {0x3811, 0x00}, + {0x3812, 0x00}, + {0x3814, 0x00}, + {0x3815, 0x00}, + {0x3816, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x381A, 0x00}, + {0x381C, 0x00}, + {0x381D, 0x00}, + {0x381E, 0x00}, + {0x3820, 0x00}, + {0x3821, 0x00}, + {0x3822, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3828, 0x00}, + {0x3829, 0x00}, + {0x382A, 0x00}, + {0x382C, 0x00}, + {0x382D, 0x00}, + {0x382E, 0x00}, + {0x3830, 0x00}, + {0x3831, 0x00}, + {0x3832, 0x00}, + {0x3834, 0x00}, + {0x3835, 0x00}, + {0x3836, 0x00}, + {0x3838, 0xE7}, + {0x3839, 0xFF}, + {0x383A, 0x0C}, + {0x383B, 0x00}, + {0x383C, 0xFD}, + {0x383D, 0xFF}, + {0x383E, 0xF7}, + {0x383F, 0xFF}, + {0x3840, 0x00}, + {0x3841, 0x00}, + {0x3842, 0x00}, + {0x3843, 0x00}, + {0x3844, 0x00}, + {0x3845, 0x00}, + {0x3846, 0x00}, + {0x3847, 0x00}, + {0x3848, 0xB6}, + {0x3849, 0xFF}, + {0x384A, 0xB6}, + {0x384B, 0xFF}, + {0x384C, 0xB3}, + {0x384D, 0xFF}, + {0x384E, 0xAF}, + {0x384F, 0xFF}, + {0x3850, 0xFF}, + {0x3851, 0x0F}, + {0x3852, 0x00}, + {0x3853, 0x10}, + {0x3854, 0xFF}, + {0x3855, 0x0F}, + {0x3856, 0x00}, + {0x3857, 0x10}, + {0x3858, 0xFF}, + {0x3859, 0x0F}, + {0x385A, 0x00}, + {0x385B, 0x10}, + {0x385C, 0x02}, + {0x385D, 0x00}, + {0x385E, 0x06}, + {0x385F, 0x00}, + {0x3860, 0x06}, + {0x3861, 0x00}, + {0x3862, 0x08}, + {0x3863, 0x00}, + {0x3864, 0x02}, + {0x3865, 0x00}, + {0x3870, 0x00}, + {0x3871, 0x01}, + {0x38A0, 0x01}, + {0x38A1, 0x01}, + {0x38A2, 0x00}, + {0x38A3, 0x01}, + {0x38A4, 0x03}, + {0x38A5, 0x00}, + {0x38A6, 0x04}, + {0x38A7, 0x04}, + {0x38A8, 0x00}, + {0x38A9, 0x00}, + {0x38AC, 0x00}, + {0x38AD, 0x00}, + {0x38AE, 0x01}, + {0x38B0, 0x02}, + {0x38B2, 0x06}, + {0x38B3, 0x00}, + {0x38B4, 0x02}, + {0x38B5, 0x00}, + {0x38B6, 0x01}, + {0x38B7, 0x00}, + {0x38B8, 0x01}, + {0x38B9, 0x00}, + {0x38BA, 0x20}, + {0x38BB, 0x00}, + {0x38BC, 0x14}, + {0x38BD, 0x00}, + {0x38BE, 0x0C}, + {0x38BF, 0x00}, + {0x38C0, 0x09}, + {0x38C1, 0x00}, + {0x38C2, 0x27}, + {0x38C3, 0x00}, + {0x38C4, 0x20}, + {0x38C5, 0x00}, + {0x38C6, 0x13}, + {0x38C7, 0x00}, + {0x38C8, 0x0C}, + {0x38C9, 0x00}, + {0x38CA, 0x35}, + {0x38CB, 0x00}, + {0x38CC, 0x25}, + {0x38CD, 0x00}, + {0x38CE, 0x1B}, + {0x38CF, 0x00}, + {0x38D0, 0x11}, + {0x38D1, 0x00}, + {0x38D2, 0x4E}, + {0x38D3, 0x00}, + {0x38D4, 0x31}, + {0x38D5, 0x00}, + {0x38D6, 0x25}, + {0x38D7, 0x00}, + {0x38D8, 0x18}, + {0x38D9, 0x00}, + {0x38DA, 0x6E}, + {0x38DB, 0x00}, + {0x38DC, 0x46}, + {0x38DD, 0x00}, + {0x38DE, 0x32}, + {0x38DF, 0x00}, + {0x38E0, 0x22}, + {0x38E1, 0x00}, + {0x38E2, 0x93}, + {0x38E3, 0x00}, + {0x38E4, 0x5F}, + {0x38E5, 0x00}, + {0x38E6, 0x44}, + {0x38E7, 0x00}, + {0x38E8, 0x31}, + {0x38E9, 0x00}, + {0x38EA, 0xD8}, + {0x38EB, 0x00}, + {0x38EC, 0x8D}, + {0x38ED, 0x00}, + {0x38EE, 0x6A}, + {0x38EF, 0x00}, + {0x38F0, 0x49}, + {0x38F1, 0x00}, + {0x38F2, 0x22}, + {0x38F3, 0x01}, + {0x38F4, 0xC8}, + {0x38F5, 0x00}, + {0x38F6, 0x8E}, + {0x38F7, 0x00}, + {0x38F8, 0x60}, + {0x38F9, 0x00}, + {0x38FA, 0x00}, + {0x38FB, 0x01}, + {0x38FC, 0x00}, + {0x38FD, 0x01}, + {0x38FE, 0x00}, + {0x38FF, 0x01}, + {0x3900, 0x00}, + {0x3901, 0x01}, + {0x3902, 0x60}, + {0x3903, 0x00}, + {0x3904, 0x25}, + {0x3905, 0x00}, + {0x3906, 0x18}, + {0x3907, 0x00}, + {0x3908, 0x10}, + {0x3909, 0x00}, + {0x390A, 0xFF}, + {0x390B, 0x00}, + {0x390C, 0xD5}, + {0x390D, 0x00}, + {0x390E, 0xAA}, + {0x390F, 0x00}, + {0x3910, 0x85}, + {0x3911, 0x00}, + {0x3912, 0xFF}, + {0x3913, 0x00}, + {0x3914, 0xD5}, + {0x3915, 0x00}, + {0x3916, 0xAA}, + {0x3917, 0x00}, + {0x3918, 0x85}, + {0x3919, 0x00}, + {0x391A, 0xFF}, + {0x391B, 0x00}, + {0x391C, 0xD5}, + {0x391D, 0x00}, + {0x391E, 0xAA}, + {0x391F, 0x00}, + {0x3920, 0x85}, + {0x3921, 0x00}, + {0x3922, 0x40}, + {0x3923, 0x00}, + {0x3924, 0x40}, + {0x3925, 0x00}, + {0x3926, 0x40}, + {0x3927, 0x00}, + {0x3928, 0x40}, + {0x3929, 0x00}, + {0x392A, 0x80}, + {0x392B, 0x00}, + {0x392C, 0x80}, + {0x392D, 0x00}, + {0x392E, 0x80}, + {0x392F, 0x00}, + {0x3930, 0x80}, + {0x3931, 0x00}, + {0x3932, 0x4C}, + {0x3933, 0x4C}, + {0x3934, 0x4C}, + {0x3940, 0x01}, + {0x3941, 0x01}, + {0x3942, 0x00}, + {0x3943, 0x01}, + {0x3944, 0x03}, + {0x3945, 0x00}, + {0x3946, 0x04}, + {0x3947, 0x04}, + {0x3948, 0x00}, + {0x3949, 0x00}, + {0x394C, 0x00}, + {0x394D, 0x00}, + {0x394E, 0x01}, + {0x3950, 0x03}, + {0x3952, 0x05}, + {0x3953, 0x00}, + {0x3954, 0x02}, + {0x3955, 0x00}, + {0x3956, 0x02}, + {0x3957, 0x00}, + {0x3958, 0x01}, + {0x3959, 0x00}, + {0x395A, 0x12}, + {0x395B, 0x00}, + {0x395C, 0x09}, + {0x395D, 0x00}, + {0x395E, 0x07}, + {0x395F, 0x00}, + {0x3960, 0x04}, + {0x3961, 0x00}, + {0x3962, 0x1A}, + {0x3963, 0x00}, + {0x3964, 0x0E}, + {0x3965, 0x00}, + {0x3966, 0x09}, + {0x3967, 0x00}, + {0x3968, 0x06}, + {0x3969, 0x00}, + {0x396A, 0x21}, + {0x396B, 0x00}, + {0x396C, 0x11}, + {0x396D, 0x00}, + {0x396E, 0x0C}, + {0x396F, 0x00}, + {0x3970, 0x08}, + {0x3971, 0x00}, + {0x3972, 0x29}, + {0x3973, 0x00}, + {0x3974, 0x18}, + {0x3975, 0x00}, + {0x3976, 0x11}, + {0x3977, 0x00}, + {0x3978, 0x0D}, + {0x3979, 0x00}, + {0x397A, 0x3A}, + {0x397B, 0x00}, + {0x397C, 0x21}, + {0x397D, 0x00}, + {0x397E, 0x19}, + {0x397F, 0x00}, + {0x3980, 0x12}, + {0x3981, 0x00}, + {0x3982, 0x52}, + {0x3983, 0x00}, + {0x3984, 0x2F}, + {0x3985, 0x00}, + {0x3986, 0x24}, + {0x3987, 0x00}, + {0x3988, 0x18}, + {0x3989, 0x00}, + {0x398A, 0x78}, + {0x398B, 0x00}, + {0x398C, 0x44}, + {0x398D, 0x00}, + {0x398E, 0x34}, + {0x398F, 0x00}, + {0x3990, 0x27}, + {0x3991, 0x00}, + {0x3992, 0xA1}, + {0x3993, 0x00}, + {0x3994, 0x61}, + {0x3995, 0x00}, + {0x3996, 0x4E}, + {0x3997, 0x00}, + {0x3998, 0x37}, + {0x3999, 0x00}, + {0x399A, 0x00}, + {0x399B, 0x01}, + {0x399C, 0x00}, + {0x399D, 0x01}, + {0x399E, 0x00}, + {0x399F, 0x01}, + {0x39A0, 0x00}, + {0x39A1, 0x01}, + {0x39A2, 0x60}, + {0x39A3, 0x00}, + {0x39A4, 0x20}, + {0x39A5, 0x00}, + {0x39A6, 0x15}, + {0x39A7, 0x00}, + {0x39A8, 0x10}, + {0x39A9, 0x00}, + {0x39AA, 0xFF}, + {0x39AB, 0x00}, + {0x39AC, 0xD5}, + {0x39AD, 0x00}, + {0x39AE, 0xAA}, + {0x39AF, 0x00}, + {0x39B0, 0x85}, + {0x39B1, 0x00}, + {0x39B2, 0xFF}, + {0x39B3, 0x00}, + {0x39B4, 0xD5}, + {0x39B5, 0x00}, + {0x39B6, 0xAA}, + {0x39B7, 0x00}, + {0x39B8, 0x85}, + {0x39B9, 0x00}, + {0x39BA, 0xFF}, + {0x39BB, 0x00}, + {0x39BC, 0xD5}, + {0x39BD, 0x00}, + {0x39BE, 0xAA}, + {0x39BF, 0x00}, + {0x39C0, 0x85}, + {0x39C1, 0x00}, + {0x39C2, 0x40}, + {0x39C3, 0x00}, + {0x39C4, 0x40}, + {0x39C5, 0x00}, + {0x39C6, 0x40}, + {0x39C7, 0x00}, + {0x39C8, 0x40}, + {0x39C9, 0x00}, + {0x39CA, 0x80}, + {0x39CB, 0x00}, + {0x39CC, 0x80}, + {0x39CD, 0x00}, + {0x39CE, 0x80}, + {0x39CF, 0x00}, + {0x39D0, 0x80}, + {0x39D1, 0x00}, + {0x39D2, 0x4C}, + {0x39D3, 0x4C}, + {0x39D4, 0x4C}, + {0x39E0, 0x01}, + {0x39E1, 0x01}, + {0x39E4, 0x40}, + {0x39E5, 0x01}, + {0x39E6, 0x01}, + {0x39E8, 0x00}, + {0x39E9, 0x01}, + {0x39EA, 0x00}, + {0x39EB, 0x00}, + {0x39EC, 0x01}, + {0x39ED, 0x00}, + {0x39EE, 0x01}, + {0x39F0, 0x03}, + {0x39F1, 0x04}, + {0x39F2, 0x0E}, + {0x39F4, 0x0B}, + {0x39F5, 0x00}, + {0x39F6, 0x07}, + {0x39F7, 0x00}, + {0x39F8, 0x05}, + {0x39F9, 0x00}, + {0x39FA, 0x02}, + {0x39FB, 0x00}, + {0x39FC, 0x34}, + {0x39FD, 0x00}, + {0x39FE, 0x1B}, + {0x39FF, 0x00}, + {0x3A00, 0x13}, + {0x3A01, 0x00}, + {0x3A02, 0x09}, + {0x3A03, 0x00}, + {0x3A04, 0x4D}, + {0x3A05, 0x00}, + {0x3A06, 0x22}, + {0x3A07, 0x00}, + {0x3A08, 0x14}, + {0x3A09, 0x00}, + {0x3A0A, 0x09}, + {0x3A0B, 0x00}, + {0x3A0C, 0x61}, + {0x3A0D, 0x00}, + {0x3A0E, 0x22}, + {0x3A0F, 0x00}, + {0x3A10, 0x15}, + {0x3A11, 0x00}, + {0x3A12, 0x0A}, + {0x3A13, 0x00}, + {0x3A14, 0x6D}, + {0x3A15, 0x00}, + {0x3A16, 0x24}, + {0x3A17, 0x00}, + {0x3A18, 0x16}, + {0x3A19, 0x00}, + {0x3A1A, 0x0B}, + {0x3A1B, 0x00}, + {0x3A1C, 0x6F}, + {0x3A1D, 0x00}, + {0x3A1E, 0x26}, + {0x3A1F, 0x00}, + {0x3A20, 0x18}, + {0x3A21, 0x00}, + {0x3A22, 0x0E}, + {0x3A23, 0x00}, + {0x3A24, 0x72}, + {0x3A25, 0x00}, + {0x3A26, 0x2B}, + {0x3A27, 0x00}, + {0x3A28, 0x1E}, + {0x3A29, 0x00}, + {0x3A2A, 0x13}, + {0x3A2B, 0x00}, + {0x3A2C, 0x7B}, + {0x3A2D, 0x00}, + {0x3A2E, 0x37}, + {0x3A2F, 0x00}, + {0x3A30, 0x29}, + {0x3A31, 0x00}, + {0x3A32, 0x1F}, + {0x3A33, 0x00}, + {0x3A34, 0x94}, + {0x3A35, 0x00}, + {0x3A36, 0x4E}, + {0x3A37, 0x00}, + {0x3A38, 0x42}, + {0x3A39, 0x00}, + {0x3A3A, 0x36}, + {0x3A3B, 0x00}, + {0x3A3C, 0x00}, + {0x3A3D, 0x01}, + {0x3A3E, 0x00}, + {0x3A3F, 0x01}, + {0x3A40, 0x00}, + {0x3A41, 0x01}, + {0x3A42, 0x00}, + {0x3A43, 0x01}, + {0x3A44, 0x70}, + {0x3A45, 0x00}, + {0x3A46, 0x25}, + {0x3A47, 0x00}, + {0x3A48, 0x18}, + {0x3A49, 0x00}, + {0x3A4A, 0x10}, + {0x3A4B, 0x00}, + {0x3A4C, 0xFF}, + {0x3A4D, 0x00}, + {0x3A4E, 0xD5}, + {0x3A4F, 0x00}, + {0x3A50, 0xAA}, + {0x3A51, 0x00}, + {0x3A52, 0x85}, + {0x3A53, 0x00}, + {0x3A54, 0xFF}, + {0x3A55, 0x00}, + {0x3A56, 0xD5}, + {0x3A57, 0x00}, + {0x3A58, 0xAA}, + {0x3A59, 0x00}, + {0x3A5A, 0x85}, + {0x3A5B, 0x00}, + {0x3A5C, 0xFF}, + {0x3A5D, 0x00}, + {0x3A5E, 0xD5}, + {0x3A5F, 0x00}, + {0x3A60, 0xAA}, + {0x3A61, 0x00}, + {0x3A62, 0x85}, + {0x3A63, 0x00}, + {0x3A64, 0x1C}, + {0x3A65, 0x00}, + {0x3A66, 0x13}, + {0x3A67, 0x00}, + {0x3A68, 0x0D}, + {0x3A69, 0x00}, + {0x3A6A, 0x07}, + {0x3A6B, 0x00}, + {0x3A6C, 0x0D}, + {0x3A6D, 0x00}, + {0x3A6E, 0x0B}, + {0x3A6F, 0x00}, + {0x3A70, 0x06}, + {0x3A71, 0x00}, + {0x3A72, 0x05}, + {0x3A73, 0x00}, + {0x3A74, 0x19}, + {0x3A75, 0x00}, + {0x3A76, 0x14}, + {0x3A77, 0x00}, + {0x3A78, 0x0F}, + {0x3A79, 0x00}, + {0x3A7A, 0x0A}, + {0x3A7B, 0x00}, + {0x3A7C, 0x80}, + {0x3A7D, 0x00}, + {0x3A7E, 0x80}, + {0x3A7F, 0x00}, + {0x3A80, 0x80}, + {0x3A81, 0x00}, + {0x3A82, 0x80}, + {0x3A83, 0x00}, + {0x3A84, 0x08}, + {0x3A85, 0x00}, + {0x3A86, 0x05}, + {0x3A87, 0x00}, + {0x3A88, 0x04}, + {0x3A89, 0x00}, + {0x3A8A, 0x03}, + {0x3A8B, 0x00}, + {0x3A8C, 0xCD}, + {0x3A8D, 0x00}, + {0x3A8E, 0xAA}, + {0x3A8F, 0x00}, + {0x3A90, 0x8C}, + {0x3A91, 0x00}, + {0x3A92, 0x64}, + {0x3A93, 0x00}, + {0x3A94, 0xCD}, + {0x3A95, 0x00}, + {0x3A96, 0xAA}, + {0x3A97, 0x00}, + {0x3A98, 0x8C}, + {0x3A99, 0x00}, + {0x3A9A, 0x64}, + {0x3A9B, 0x00}, + {0x3A9C, 0x08}, + {0x3A9D, 0x10}, + {0x3A9E, 0x4C}, + {0x3A9F, 0x4C}, + {0x3AA0, 0x4C}, + {0x3AA1, 0x04}, + {0x3AA2, 0x04}, + {0x3AC0, 0x01}, + {0x3AC4, 0x81}, + {0x3AC5, 0x00}, + {0x3AC6, 0x00}, + {0x3AC7, 0x00}, + {0x3AC8, 0x00}, + {0x3AC9, 0x00}, + {0x3ACA, 0x00}, + {0x3ACB, 0x00}, + {0x3ACC, 0x02}, + {0x3ACD, 0x00}, + {0x3ACE, 0x81}, + {0x3ACF, 0x00}, + {0x3AD0, 0x00}, + {0x3AD1, 0x00}, + {0x3AD2, 0xFD}, + {0x3AD3, 0x03}, + {0x3AD4, 0x02}, + {0x3AD5, 0x00}, + {0x3AD6, 0x00}, + {0x3AD7, 0x00}, + {0x3AD8, 0x81}, + {0x3AD9, 0x00}, + {0x3ADA, 0xFD}, + {0x3ADB, 0x03}, + {0x3ADC, 0xFF}, + {0x3ADD, 0x03}, + {0x3ADE, 0x01}, + {0x3ADF, 0x00}, + {0x3AE0, 0x01}, + {0x3AE1, 0x00}, + {0x3AE2, 0x7E}, + {0x3AE3, 0x00}, + {0x3AF4, 0x00}, + {0x3AF6, 0x40}, + {0x3AF7, 0x1E}, + {0x3AF8, 0x00}, + {0x3AFA, 0x00}, + {0x3AFB, 0x00}, + {0x3AFC, 0x00}, + {0x3AFD, 0x00}, + {0x3AFE, 0x00}, + {0x3AFF, 0x00}, + {0x3B00, 0x00}, + {0x3B01, 0x00}, + {0x3B02, 0x00}, + {0x3B03, 0x00}, + {0x3B04, 0x00}, + {0x3B05, 0x00}, + {0x3B06, 0x00}, + {0x3B07, 0x00}, + {0x3B08, 0x00}, + {0x3B09, 0x00}, + {0x3B0A, 0x00}, + {0x3B0B, 0x00}, + {0x3B0C, 0x00}, + {0x3B0D, 0x00}, + {0x3B0E, 0x00}, + {0x3B0F, 0x00}, + {0x3B10, 0x00}, + {0x3B11, 0x00}, + {0x3B12, 0x00}, + {0x3B13, 0x00}, + {0x3B14, 0x00}, + {0x3B15, 0x00}, + {0x3B16, 0x00}, + {0x3B17, 0x00}, + {0x3B18, 0x00}, + {0x3B19, 0x00}, + {0x3B1A, 0x00}, + {0x3B1B, 0x00}, + {0x3B1C, 0x00}, + {0x3B1D, 0x00}, + {0x3B1E, 0x00}, + {0x3B1F, 0x00}, + {0x3B20, 0x00}, + {0x3B21, 0x00}, + {0x3B22, 0x00}, + {0x3B23, 0x00}, + {0x3B24, 0x00}, + {0x3B25, 0x00}, + {0x3B26, 0x00}, + {0x3B27, 0x00}, + {0x3B28, 0x00}, + {0x3B29, 0x00}, + {0x3B2A, 0x00}, + {0x3B2C, 0x00}, + {0x3B2E, 0x00}, + {0x3B30, 0x00}, + {0x3B32, 0x0C}, + {0x4000, 0xD0}, + {0x4001, 0xC8}, + {0x4002, 0xC8}, + {0x4003, 0xC6}, + {0x4004, 0xBA}, + {0x4005, 0xB5}, + {0x4006, 0xB5}, + {0x4007, 0xB4}, + {0x4008, 0xAA}, + {0x4009, 0xA7}, + {0x400A, 0xA7}, + {0x400B, 0xA7}, + {0x400C, 0xA1}, + {0x400D, 0x9F}, + {0x400E, 0x9F}, + {0x400F, 0x9F}, + {0x4010, 0x9C}, + {0x4011, 0x9B}, + {0x4012, 0x9B}, + {0x4013, 0x9B}, + {0x4014, 0x9F}, + {0x4015, 0x9E}, + {0x4016, 0x9D}, + {0x4017, 0x9E}, + {0x4018, 0xA7}, + {0x4019, 0xA4}, + {0x401A, 0xA4}, + {0x401B, 0xA4}, + {0x401C, 0xB5}, + {0x401D, 0xB0}, + {0x401E, 0xB0}, + {0x401F, 0xB0}, + {0x4020, 0xC9}, + {0x4021, 0xC1}, + {0x4022, 0xC1}, + {0x4023, 0xC0}, + {0x4024, 0xC3}, + {0x4025, 0xBB}, + {0x4026, 0xBC}, + {0x4027, 0xBA}, + {0x4028, 0xA5}, + {0x4029, 0xA1}, + {0x402A, 0xA1}, + {0x402B, 0xA0}, + {0x402C, 0x99}, + {0x402D, 0x97}, + {0x402E, 0x97}, + {0x402F, 0x96}, + {0x4030, 0x8F}, + {0x4031, 0x8E}, + {0x4032, 0x8E}, + {0x4033, 0x8E}, + {0x4034, 0x8A}, + {0x4035, 0x8A}, + {0x4036, 0x8A}, + {0x4037, 0x8A}, + {0x4038, 0x8D}, + {0x4039, 0x8D}, + {0x403A, 0x8D}, + {0x403B, 0x8D}, + {0x403C, 0x96}, + {0x403D, 0x94}, + {0x403E, 0x94}, + {0x403F, 0x94}, + {0x4040, 0xA2}, + {0x4041, 0x9E}, + {0x4042, 0x9E}, + {0x4043, 0x9D}, + {0x4044, 0xBC}, + {0x4045, 0xB5}, + {0x4046, 0xB5}, + {0x4047, 0xB4}, + {0x4048, 0xBC}, + {0x4049, 0xB5}, + {0x404A, 0xB5}, + {0x404B, 0xB3}, + {0x404C, 0xA3}, + {0x404D, 0x9F}, + {0x404E, 0x9F}, + {0x404F, 0x9E}, + {0x4050, 0x95}, + {0x4051, 0x93}, + {0x4052, 0x93}, + {0x4053, 0x93}, + {0x4054, 0x89}, + {0x4055, 0x88}, + {0x4056, 0x88}, + {0x4057, 0x88}, + {0x4058, 0x81}, + {0x4059, 0x81}, + {0x405A, 0x81}, + {0x405B, 0x81}, + {0x405C, 0x86}, + {0x405D, 0x86}, + {0x405E, 0x86}, + {0x405F, 0x86}, + {0x4060, 0x92}, + {0x4061, 0x90}, + {0x4062, 0x90}, + {0x4063, 0x90}, + {0x4064, 0x9E}, + {0x4065, 0x9B}, + {0x4066, 0x9B}, + {0x4067, 0x9A}, + {0x4068, 0xB5}, + {0x4069, 0xAE}, + {0x406A, 0xAE}, + {0x406B, 0xAE}, + {0x406C, 0xBE}, + {0x406D, 0xB6}, + {0x406E, 0xB7}, + {0x406F, 0xB5}, + {0x4070, 0xA4}, + {0x4071, 0xA0}, + {0x4072, 0xA0}, + {0x4073, 0x9F}, + {0x4074, 0x96}, + {0x4075, 0x94}, + {0x4076, 0x94}, + {0x4077, 0x94}, + {0x4078, 0x8A}, + {0x4079, 0x8A}, + {0x407A, 0x8A}, + {0x407B, 0x8A}, + {0x407C, 0x83}, + {0x407D, 0x83}, + {0x407E, 0x83}, + {0x407F, 0x83}, + {0x4080, 0x88}, + {0x4081, 0x87}, + {0x4082, 0x87}, + {0x4083, 0x88}, + {0x4084, 0x93}, + {0x4085, 0x91}, + {0x4086, 0x91}, + {0x4087, 0x91}, + {0x4088, 0xA0}, + {0x4089, 0x9C}, + {0x408A, 0x9C}, + {0x408B, 0x9C}, + {0x408C, 0xB6}, + {0x408D, 0xAF}, + {0x408E, 0xAF}, + {0x408F, 0xAF}, + {0x4090, 0xCA}, + {0x4091, 0xC1}, + {0x4092, 0xC1}, + {0x4093, 0xBF}, + {0x4094, 0xAB}, + {0x4095, 0xA5}, + {0x4096, 0xA5}, + {0x4097, 0xA4}, + {0x4098, 0x9E}, + {0x4099, 0x9A}, + {0x409A, 0x9A}, + {0x409B, 0x9A}, + {0x409C, 0x94}, + {0x409D, 0x92}, + {0x409E, 0x92}, + {0x409F, 0x92}, + {0x40A0, 0x8F}, + {0x40A1, 0x8E}, + {0x40A2, 0x8E}, + {0x40A3, 0x8E}, + {0x40A4, 0x92}, + {0x40A5, 0x90}, + {0x40A6, 0x90}, + {0x40A7, 0x90}, + {0x40A8, 0x9A}, + {0x40A9, 0x97}, + {0x40AA, 0x97}, + {0x40AB, 0x97}, + {0x40AC, 0xA6}, + {0x40AD, 0xA0}, + {0x40AE, 0xA0}, + {0x40AF, 0xA0}, + {0x40B0, 0xC1}, + {0x40B1, 0xB9}, + {0x40B2, 0xB9}, + {0x40B3, 0xB8}, + {0x40B4, 0xDD}, + {0x40B5, 0xD2}, + {0x40B6, 0xD2}, + {0x40B7, 0xCF}, + {0x40B8, 0xC6}, + {0x40B9, 0xBF}, + {0x40BA, 0xBF}, + {0x40BB, 0xBD}, + {0x40BC, 0xB5}, + {0x40BD, 0xB0}, + {0x40BE, 0xB0}, + {0x40BF, 0xAF}, + {0x40C0, 0xAB}, + {0x40C1, 0xA8}, + {0x40C2, 0xA8}, + {0x40C3, 0xA7}, + {0x40C4, 0xA7}, + {0x40C5, 0xA3}, + {0x40C6, 0xA3}, + {0x40C7, 0xA3}, + {0x40C8, 0xA9}, + {0x40C9, 0xA6}, + {0x40CA, 0xA6}, + {0x40CB, 0xA6}, + {0x40CC, 0xB0}, + {0x40CD, 0xAB}, + {0x40CE, 0xAB}, + {0x40CF, 0xAB}, + {0x40D0, 0xBF}, + {0x40D1, 0xB7}, + {0x40D2, 0xB7}, + {0x40D3, 0xB7}, + {0x40D4, 0xD2}, + {0x40D5, 0xC8}, + {0x40D6, 0xC7}, + {0x40D7, 0xC7}, + {0x4100, 0x80}, + {0x4101, 0x80}, + {0x4102, 0x80}, + {0x4103, 0x80}, + {0x4104, 0x80}, + {0x4105, 0x80}, + {0x4106, 0x80}, + {0x4107, 0x80}, + {0x4108, 0x80}, + {0x4109, 0x80}, + {0x410A, 0x80}, + {0x410B, 0x80}, + {0x410C, 0x80}, + {0x410D, 0x80}, + {0x410E, 0x80}, + {0x410F, 0x80}, + {0x4110, 0x80}, + {0x4111, 0x80}, + {0x4112, 0x80}, + {0x4113, 0x80}, + {0x4114, 0x80}, + {0x4115, 0x80}, + {0x4116, 0x80}, + {0x4117, 0x80}, + {0x4118, 0x80}, + {0x4119, 0x80}, + {0x411A, 0x80}, + {0x411B, 0x80}, + {0x411C, 0x80}, + {0x411D, 0x80}, + {0x411E, 0x80}, + {0x411F, 0x80}, + {0x4120, 0x80}, + {0x4121, 0x80}, + {0x4122, 0x80}, + {0x4123, 0x80}, + {0x4124, 0x80}, + {0x4125, 0x80}, + {0x4126, 0x80}, + {0x4127, 0x80}, + {0x4128, 0x80}, + {0x4129, 0x80}, + {0x412A, 0x80}, + {0x412B, 0x80}, + {0x412C, 0x80}, + {0x412D, 0x80}, + {0x412E, 0x80}, + {0x412F, 0x80}, + {0x4130, 0x80}, + {0x4131, 0x80}, + {0x4132, 0x80}, + {0x4133, 0x80}, + {0x4134, 0x80}, + {0x4135, 0x80}, + {0x4136, 0x80}, + {0x4137, 0x80}, + {0x4138, 0x80}, + {0x4139, 0x80}, + {0x413A, 0x80}, + {0x413B, 0x80}, + {0x413C, 0x80}, + {0x413D, 0x80}, + {0x413E, 0x80}, + {0x413F, 0x80}, + {0x4140, 0x80}, + {0x4141, 0x80}, + {0x4142, 0x80}, + {0x4143, 0x80}, + {0x4144, 0x80}, + {0x4145, 0x80}, + {0x4146, 0x80}, + {0x4147, 0x80}, + {0x4148, 0x80}, + {0x4149, 0x80}, + {0x414A, 0x80}, + {0x414B, 0x80}, + {0x414C, 0x80}, + {0x414D, 0x80}, + {0x414E, 0x80}, + {0x414F, 0x80}, + {0x4150, 0x80}, + {0x4151, 0x80}, + {0x4152, 0x80}, + {0x4153, 0x80}, + {0x4154, 0x80}, + {0x4155, 0x80}, + {0x4156, 0x80}, + {0x4157, 0x80}, + {0x4158, 0x80}, + {0x4159, 0x80}, + {0x415A, 0x80}, + {0x415B, 0x80}, + {0x415C, 0x80}, + {0x415D, 0x80}, + {0x415E, 0x80}, + {0x415F, 0x80}, + {0x4160, 0x80}, + {0x4161, 0x80}, + {0x4162, 0x80}, + {0x4163, 0x80}, + {0x4164, 0x80}, + {0x4165, 0x80}, + {0x4166, 0x80}, + {0x4167, 0x80}, + {0x4168, 0x80}, + {0x4169, 0x80}, + {0x416A, 0x80}, + {0x416B, 0x80}, + {0x416C, 0x80}, + {0x416D, 0x80}, + {0x416E, 0x80}, + {0x416F, 0x80}, + {0x4170, 0x80}, + {0x4171, 0x80}, + {0x4172, 0x80}, + {0x4173, 0x80}, + {0x4174, 0x80}, + {0x4175, 0x80}, + {0x4176, 0x80}, + {0x4177, 0x80}, + {0x4178, 0x80}, + {0x4179, 0x80}, + {0x417A, 0x80}, + {0x417B, 0x80}, + {0x417C, 0x80}, + {0x417D, 0x80}, + {0x417E, 0x80}, + {0x417F, 0x80}, + {0x4180, 0x80}, + {0x4181, 0x80}, + {0x4182, 0x80}, + {0x4183, 0x80}, + {0x4184, 0x80}, + {0x4185, 0x80}, + {0x4186, 0x80}, + {0x4187, 0x80}, + {0x4188, 0x80}, + {0x4189, 0x80}, + {0x418A, 0x80}, + {0x418B, 0x80}, + {0x418C, 0x80}, + {0x418D, 0x80}, + {0x418E, 0x80}, + {0x418F, 0x80}, + {0x4190, 0x80}, + {0x4191, 0x80}, + {0x4192, 0x80}, + {0x4193, 0x80}, + {0x4194, 0x80}, + {0x4195, 0x80}, + {0x4196, 0x80}, + {0x4197, 0x80}, + {0x4198, 0x80}, + {0x4199, 0x80}, + {0x419A, 0x80}, + {0x419B, 0x80}, + {0x419C, 0x80}, + {0x419D, 0x80}, + {0x419E, 0x80}, + {0x419F, 0x80}, + {0x41A0, 0x80}, + {0x41A1, 0x80}, + {0x41A2, 0x80}, + {0x41A3, 0x80}, + {0x41A4, 0x80}, + {0x41A5, 0x80}, + {0x41A6, 0x80}, + {0x41A7, 0x80}, + {0x41A8, 0x80}, + {0x41A9, 0x80}, + {0x41AA, 0x80}, + {0x41AB, 0x80}, + {0x41AC, 0x80}, + {0x41AD, 0x80}, + {0x41AE, 0x80}, + {0x41AF, 0x80}, + {0x41B0, 0x80}, + {0x41B1, 0x80}, + {0x41B2, 0x80}, + {0x41B3, 0x80}, + {0x41B4, 0x80}, + {0x41B5, 0x80}, + {0x41B6, 0x80}, + {0x41B7, 0x80}, + {0x41B8, 0x80}, + {0x41B9, 0x80}, + {0x41BA, 0x80}, + {0x41BB, 0x80}, + {0x41BC, 0x80}, + {0x41BD, 0x80}, + {0x41BE, 0x80}, + {0x41BF, 0x80}, + {0x41C0, 0x80}, + {0x41C1, 0x80}, + {0x41C2, 0x80}, + {0x41C3, 0x80}, + {0x41C4, 0x80}, + {0x41C5, 0x80}, + {0x41C6, 0x80}, + {0x41C7, 0x80}, + {0x41C8, 0x80}, + {0x41C9, 0x80}, + {0x41CA, 0x80}, + {0x41CB, 0x80}, + {0x41CC, 0x80}, + {0x41CD, 0x80}, + {0x41CE, 0x80}, + {0x41CF, 0x80}, + {0x41D0, 0x80}, + {0x41D1, 0x80}, + {0x41D2, 0x80}, + {0x41D3, 0x80}, + {0x41D4, 0x80}, + {0x41D5, 0x80}, + {0x41D6, 0x80}, + {0x41D7, 0x80}, + {0x4200, 0x80}, + {0x4201, 0x80}, + {0x4202, 0x80}, + {0x4203, 0x80}, + {0x4204, 0x80}, + {0x4205, 0x80}, + {0x4206, 0x80}, + {0x4207, 0x80}, + {0x4208, 0x80}, + {0x4209, 0x80}, + {0x420A, 0x80}, + {0x420B, 0x80}, + {0x420C, 0x80}, + {0x420D, 0x80}, + {0x420E, 0x80}, + {0x420F, 0x80}, + {0x4210, 0x80}, + {0x4211, 0x80}, + {0x4212, 0x80}, + {0x4213, 0x80}, + {0x4214, 0x80}, + {0x4215, 0x80}, + {0x4216, 0x80}, + {0x4217, 0x80}, + {0x4218, 0x80}, + {0x4219, 0x80}, + {0x421A, 0x80}, + {0x421B, 0x80}, + {0x421C, 0x80}, + {0x421D, 0x80}, + {0x421E, 0x80}, + {0x421F, 0x80}, + {0x4220, 0x80}, + {0x4221, 0x80}, + {0x4222, 0x80}, + {0x4223, 0x80}, + {0x4224, 0x80}, + {0x4225, 0x80}, + {0x4226, 0x80}, + {0x4227, 0x80}, + {0x4228, 0x80}, + {0x4229, 0x80}, + {0x422A, 0x80}, + {0x422B, 0x80}, + {0x422C, 0x80}, + {0x422D, 0x80}, + {0x422E, 0x80}, + {0x422F, 0x80}, + {0x4230, 0x80}, + {0x4231, 0x80}, + {0x4232, 0x80}, + {0x4233, 0x80}, + {0x4234, 0x80}, + {0x4235, 0x80}, + {0x4236, 0x80}, + {0x4237, 0x80}, + {0x4238, 0x80}, + {0x4239, 0x80}, + {0x423A, 0x80}, + {0x423B, 0x80}, + {0x423C, 0x80}, + {0x423D, 0x80}, + {0x423E, 0x80}, + {0x423F, 0x80}, + {0x4240, 0x80}, + {0x4241, 0x80}, + {0x4242, 0x80}, + {0x4243, 0x80}, + {0x4244, 0x80}, + {0x4245, 0x80}, + {0x4246, 0x80}, + {0x4247, 0x80}, + {0x4248, 0x80}, + {0x4249, 0x80}, + {0x424A, 0x80}, + {0x424B, 0x80}, + {0x424C, 0x80}, + {0x424D, 0x80}, + {0x424E, 0x80}, + {0x424F, 0x80}, + {0x4250, 0x80}, + {0x4251, 0x80}, + {0x4252, 0x80}, + {0x4253, 0x80}, + {0x4254, 0x80}, + {0x4255, 0x80}, + {0x4256, 0x80}, + {0x4257, 0x80}, + {0x4258, 0x80}, + {0x4259, 0x80}, + {0x425A, 0x80}, + {0x425B, 0x80}, + {0x425C, 0x80}, + {0x425D, 0x80}, + {0x425E, 0x80}, + {0x425F, 0x80}, + {0x4260, 0x80}, + {0x4261, 0x80}, + {0x4262, 0x80}, + {0x4263, 0x80}, + {0x4264, 0x80}, + {0x4265, 0x80}, + {0x4266, 0x80}, + {0x4267, 0x80}, + {0x4268, 0x80}, + {0x4269, 0x80}, + {0x426A, 0x80}, + {0x426B, 0x80}, + {0x426C, 0x80}, + {0x426D, 0x80}, + {0x426E, 0x80}, + {0x426F, 0x80}, + {0x4270, 0x80}, + {0x4271, 0x80}, + {0x4272, 0x80}, + {0x4273, 0x80}, + {0x4274, 0x80}, + {0x4275, 0x80}, + {0x4276, 0x80}, + {0x4277, 0x80}, + {0x4278, 0x80}, + {0x4279, 0x80}, + {0x427A, 0x80}, + {0x427B, 0x80}, + {0x427C, 0x80}, + {0x427D, 0x80}, + {0x427E, 0x80}, + {0x427F, 0x80}, + {0x4280, 0x80}, + {0x4281, 0x80}, + {0x4282, 0x80}, + {0x4283, 0x80}, + {0x4284, 0x80}, + {0x4285, 0x80}, + {0x4286, 0x80}, + {0x4287, 0x80}, + {0x4288, 0x80}, + {0x4289, 0x80}, + {0x428A, 0x80}, + {0x428B, 0x80}, + {0x428C, 0x80}, + {0x428D, 0x80}, + {0x428E, 0x80}, + {0x428F, 0x80}, + {0x4290, 0x80}, + {0x4291, 0x80}, + {0x4292, 0x80}, + {0x4293, 0x80}, + {0x4294, 0x80}, + {0x4295, 0x80}, + {0x4296, 0x80}, + {0x4297, 0x80}, + {0x4298, 0x80}, + {0x4299, 0x80}, + {0x429A, 0x80}, + {0x429B, 0x80}, + {0x429C, 0x80}, + {0x429D, 0x80}, + {0x429E, 0x80}, + {0x429F, 0x80}, + {0x42A0, 0x80}, + {0x42A1, 0x80}, + {0x42A2, 0x80}, + {0x42A3, 0x80}, + {0x42A4, 0x80}, + {0x42A5, 0x80}, + {0x42A6, 0x80}, + {0x42A7, 0x80}, + {0x42A8, 0x80}, + {0x42A9, 0x80}, + {0x42AA, 0x80}, + {0x42AB, 0x80}, + {0x42AC, 0x80}, + {0x42AD, 0x80}, + {0x42AE, 0x80}, + {0x42AF, 0x80}, + {0x42B0, 0x80}, + {0x42B1, 0x80}, + {0x42B2, 0x80}, + {0x42B3, 0x80}, + {0x42B4, 0x80}, + {0x42B5, 0x80}, + {0x42B6, 0x80}, + {0x42B7, 0x80}, + {0x42B8, 0x80}, + {0x42B9, 0x80}, + {0x42BA, 0x80}, + {0x42BB, 0x80}, + {0x42BC, 0x80}, + {0x42BD, 0x80}, + {0x42BE, 0x80}, + {0x42BF, 0x80}, + {0x42C0, 0x80}, + {0x42C1, 0x80}, + {0x42C2, 0x80}, + {0x42C3, 0x80}, + {0x42C4, 0x80}, + {0x42C5, 0x80}, + {0x42C6, 0x80}, + {0x42C7, 0x80}, + {0x42C8, 0x80}, + {0x42C9, 0x80}, + {0x42CA, 0x80}, + {0x42CB, 0x80}, + {0x42CC, 0x80}, + {0x42CD, 0x80}, + {0x42CE, 0x80}, + {0x42CF, 0x80}, + {0x42D0, 0x80}, + {0x42D1, 0x80}, + {0x42D2, 0x80}, + {0x42D3, 0x80}, + {0x42D4, 0x80}, + {0x42D5, 0x80}, + {0x42D6, 0x80}, + {0x42D7, 0x80}, + {0x42D8, 0x00}, + {0x42D9, 0x00}, + {0x4300, 0x8C}, + {0x4301, 0x88}, + {0x4302, 0x88}, + {0x4303, 0x8A}, + {0x4304, 0x88}, + {0x4305, 0x84}, + {0x4306, 0x84}, + {0x4307, 0x86}, + {0x4308, 0x84}, + {0x4309, 0x82}, + {0x430A, 0x82}, + {0x430B, 0x82}, + {0x430C, 0x81}, + {0x430D, 0x7F}, + {0x430E, 0x7F}, + {0x430F, 0x80}, + {0x4310, 0x7F}, + {0x4311, 0x7F}, + {0x4312, 0x7F}, + {0x4313, 0x80}, + {0x4314, 0x80}, + {0x4315, 0x80}, + {0x4316, 0x7F}, + {0x4317, 0x80}, + {0x4318, 0x83}, + {0x4319, 0x82}, + {0x431A, 0x82}, + {0x431B, 0x82}, + {0x431C, 0x83}, + {0x431D, 0x83}, + {0x431E, 0x83}, + {0x431F, 0x83}, + {0x4320, 0x88}, + {0x4321, 0x87}, + {0x4322, 0x86}, + {0x4323, 0x88}, + {0x4324, 0x8A}, + {0x4325, 0x86}, + {0x4326, 0x86}, + {0x4327, 0x88}, + {0x4328, 0x85}, + {0x4329, 0x82}, + {0x432A, 0x82}, + {0x432B, 0x84}, + {0x432C, 0x81}, + {0x432D, 0x80}, + {0x432E, 0x80}, + {0x432F, 0x81}, + {0x4330, 0x80}, + {0x4331, 0x7F}, + {0x4332, 0x7F}, + {0x4333, 0x80}, + {0x4334, 0x7F}, + {0x4335, 0x7F}, + {0x4336, 0x7F}, + {0x4337, 0x80}, + {0x4338, 0x80}, + {0x4339, 0x7F}, + {0x433A, 0x7F}, + {0x433B, 0x80}, + {0x433C, 0x81}, + {0x433D, 0x80}, + {0x433E, 0x80}, + {0x433F, 0x81}, + {0x4340, 0x82}, + {0x4341, 0x82}, + {0x4342, 0x82}, + {0x4343, 0x83}, + {0x4344, 0x85}, + {0x4345, 0x85}, + {0x4346, 0x85}, + {0x4347, 0x86}, + {0x4348, 0x88}, + {0x4349, 0x86}, + {0x434A, 0x86}, + {0x434B, 0x87}, + {0x434C, 0x84}, + {0x434D, 0x82}, + {0x434E, 0x82}, + {0x434F, 0x83}, + {0x4350, 0x81}, + {0x4351, 0x80}, + {0x4352, 0x80}, + {0x4353, 0x81}, + {0x4354, 0x80}, + {0x4355, 0x7F}, + {0x4356, 0x7F}, + {0x4357, 0x80}, + {0x4358, 0x80}, + {0x4359, 0x80}, + {0x435A, 0x80}, + {0x435B, 0x80}, + {0x435C, 0x80}, + {0x435D, 0x80}, + {0x435E, 0x80}, + {0x435F, 0x80}, + {0x4360, 0x80}, + {0x4361, 0x80}, + {0x4362, 0x80}, + {0x4363, 0x80}, + {0x4364, 0x82}, + {0x4365, 0x82}, + {0x4366, 0x82}, + {0x4367, 0x83}, + {0x4368, 0x87}, + {0x4369, 0x86}, + {0x436A, 0x86}, + {0x436B, 0x87}, + {0x436C, 0x89}, + {0x436D, 0x87}, + {0x436E, 0x87}, + {0x436F, 0x88}, + {0x4370, 0x85}, + {0x4371, 0x83}, + {0x4372, 0x83}, + {0x4373, 0x84}, + {0x4374, 0x82}, + {0x4375, 0x81}, + {0x4376, 0x81}, + {0x4377, 0x81}, + {0x4378, 0x80}, + {0x4379, 0x80}, + {0x437A, 0x80}, + {0x437B, 0x80}, + {0x437C, 0x80}, + {0x437D, 0x80}, + {0x437E, 0x80}, + {0x437F, 0x80}, + {0x4380, 0x80}, + {0x4381, 0x80}, + {0x4382, 0x80}, + {0x4383, 0x80}, + {0x4384, 0x81}, + {0x4385, 0x81}, + {0x4386, 0x81}, + {0x4387, 0x80}, + {0x4388, 0x83}, + {0x4389, 0x83}, + {0x438A, 0x83}, + {0x438B, 0x83}, + {0x438C, 0x87}, + {0x438D, 0x87}, + {0x438E, 0x86}, + {0x438F, 0x86}, + {0x4390, 0x8C}, + {0x4391, 0x88}, + {0x4392, 0x89}, + {0x4393, 0x8C}, + {0x4394, 0x87}, + {0x4395, 0x85}, + {0x4396, 0x85}, + {0x4397, 0x86}, + {0x4398, 0x83}, + {0x4399, 0x82}, + {0x439A, 0x82}, + {0x439B, 0x83}, + {0x439C, 0x81}, + {0x439D, 0x81}, + {0x439E, 0x81}, + {0x439F, 0x81}, + {0x43A0, 0x81}, + {0x43A1, 0x81}, + {0x43A2, 0x81}, + {0x43A3, 0x81}, + {0x43A4, 0x80}, + {0x43A5, 0x81}, + {0x43A6, 0x81}, + {0x43A7, 0x80}, + {0x43A8, 0x81}, + {0x43A9, 0x82}, + {0x43AA, 0x82}, + {0x43AB, 0x81}, + {0x43AC, 0x84}, + {0x43AD, 0x84}, + {0x43AE, 0x84}, + {0x43AF, 0x84}, + {0x43B0, 0x88}, + {0x43B1, 0x88}, + {0x43B2, 0x88}, + {0x43B3, 0x88}, + {0x43B4, 0x8F}, + {0x43B5, 0x8B}, + {0x43B6, 0x8C}, + {0x43B7, 0x90}, + {0x43B8, 0x8A}, + {0x43B9, 0x87}, + {0x43BA, 0x88}, + {0x43BB, 0x8B}, + {0x43BC, 0x85}, + {0x43BD, 0x84}, + {0x43BE, 0x84}, + {0x43BF, 0x85}, + {0x43C0, 0x83}, + {0x43C1, 0x82}, + {0x43C2, 0x83}, + {0x43C3, 0x83}, + {0x43C4, 0x82}, + {0x43C5, 0x81}, + {0x43C6, 0x81}, + {0x43C7, 0x82}, + {0x43C8, 0x81}, + {0x43C9, 0x81}, + {0x43CA, 0x81}, + {0x43CB, 0x80}, + {0x43CC, 0x83}, + {0x43CD, 0x83}, + {0x43CE, 0x82}, + {0x43CF, 0x82}, + {0x43D0, 0x86}, + {0x43D1, 0x85}, + {0x43D2, 0x85}, + {0x43D3, 0x86}, + {0x43D4, 0x8A}, + {0x43D5, 0x89}, + {0x43D6, 0x89}, + {0x43D7, 0x89}, + {0x4400, 0x80}, + {0x4401, 0x80}, + {0x4402, 0x80}, + {0x4403, 0x80}, + {0x4404, 0x80}, + {0x4405, 0x80}, + {0x4406, 0x80}, + {0x4407, 0x80}, + {0x4408, 0x80}, + {0x4409, 0x80}, + {0x440A, 0x80}, + {0x440B, 0x80}, + {0x440C, 0x80}, + {0x440D, 0x80}, + {0x440E, 0x80}, + {0x440F, 0x80}, + {0x4410, 0x80}, + {0x4411, 0x80}, + {0x4412, 0x80}, + {0x4413, 0x80}, + {0x4414, 0x80}, + {0x4415, 0x80}, + {0x4416, 0x80}, + {0x4417, 0x80}, + {0x4418, 0x80}, + {0x4419, 0x80}, + {0x441A, 0x80}, + {0x441B, 0x80}, + {0x441C, 0x80}, + {0x441D, 0x80}, + {0x441E, 0x80}, + {0x441F, 0x80}, + {0x4420, 0x80}, + {0x4421, 0x80}, + {0x4422, 0x80}, + {0x4423, 0x80}, + {0x4424, 0x80}, + {0x4425, 0x80}, + {0x4426, 0x80}, + {0x4427, 0x80}, + {0x4428, 0x80}, + {0x4429, 0x80}, + {0x442A, 0x80}, + {0x442B, 0x80}, + {0x442C, 0x80}, + {0x442D, 0x80}, + {0x442E, 0x80}, + {0x442F, 0x80}, + {0x4430, 0x80}, + {0x4431, 0x80}, + {0x4432, 0x80}, + {0x4433, 0x80}, + {0x4434, 0x80}, + {0x4435, 0x80}, + {0x4436, 0x80}, + {0x4437, 0x80}, + {0x4438, 0x80}, + {0x4439, 0x80}, + {0x443A, 0x80}, + {0x443B, 0x80}, + {0x443C, 0x80}, + {0x443D, 0x80}, + {0x443E, 0x80}, + {0x443F, 0x80}, + {0x4440, 0x80}, + {0x4441, 0x80}, + {0x4442, 0x80}, + {0x4443, 0x80}, + {0x4444, 0x80}, + {0x4445, 0x80}, + {0x4446, 0x80}, + {0x4447, 0x80}, + {0x4448, 0x80}, + {0x4449, 0x80}, + {0x444A, 0x80}, + {0x444B, 0x80}, + {0x444C, 0x80}, + {0x444D, 0x80}, + {0x444E, 0x80}, + {0x444F, 0x80}, + {0x4450, 0x80}, + {0x4451, 0x80}, + {0x4452, 0x80}, + {0x4453, 0x80}, + {0x4454, 0x80}, + {0x4455, 0x80}, + {0x4456, 0x80}, + {0x4457, 0x80}, + {0x4458, 0x80}, + {0x4459, 0x80}, + {0x445A, 0x80}, + {0x445B, 0x80}, + {0x445C, 0x80}, + {0x445D, 0x80}, + {0x445E, 0x80}, + {0x445F, 0x80}, + {0x4460, 0x80}, + {0x4461, 0x80}, + {0x4462, 0x80}, + {0x4463, 0x80}, + {0x4464, 0x80}, + {0x4465, 0x80}, + {0x4466, 0x80}, + {0x4467, 0x80}, + {0x4468, 0x80}, + {0x4469, 0x80}, + {0x446A, 0x80}, + {0x446B, 0x80}, + {0x446C, 0x80}, + {0x446D, 0x80}, + {0x446E, 0x80}, + {0x446F, 0x80}, + {0x4470, 0x80}, + {0x4471, 0x80}, + {0x4472, 0x80}, + {0x4473, 0x80}, + {0x4474, 0x80}, + {0x4475, 0x80}, + {0x4476, 0x80}, + {0x4477, 0x80}, + {0x4478, 0x80}, + {0x4479, 0x80}, + {0x447A, 0x80}, + {0x447B, 0x80}, + {0x447C, 0x80}, + {0x447D, 0x80}, + {0x447E, 0x80}, + {0x447F, 0x80}, + {0x4480, 0x80}, + {0x4481, 0x80}, + {0x4482, 0x80}, + {0x4483, 0x80}, + {0x4484, 0x80}, + {0x4485, 0x80}, + {0x4486, 0x80}, + {0x4487, 0x80}, + {0x4488, 0x80}, + {0x4489, 0x80}, + {0x448A, 0x80}, + {0x448B, 0x80}, + {0x448C, 0x80}, + {0x448D, 0x80}, + {0x448E, 0x80}, + {0x448F, 0x80}, + {0x4490, 0x80}, + {0x4491, 0x80}, + {0x4492, 0x80}, + {0x4493, 0x80}, + {0x4494, 0x80}, + {0x4495, 0x80}, + {0x4496, 0x80}, + {0x4497, 0x80}, + {0x4498, 0x80}, + {0x4499, 0x80}, + {0x449A, 0x80}, + {0x449B, 0x80}, + {0x449C, 0x80}, + {0x449D, 0x80}, + {0x449E, 0x80}, + {0x449F, 0x80}, + {0x44A0, 0x80}, + {0x44A1, 0x80}, + {0x44A2, 0x80}, + {0x44A3, 0x80}, + {0x44A4, 0x80}, + {0x44A5, 0x80}, + {0x44A6, 0x80}, + {0x44A7, 0x80}, + {0x44A8, 0x80}, + {0x44A9, 0x80}, + {0x44AA, 0x80}, + {0x44AB, 0x80}, + {0x44AC, 0x80}, + {0x44AD, 0x80}, + {0x44AE, 0x80}, + {0x44AF, 0x80}, + {0x44B0, 0x80}, + {0x44B1, 0x80}, + {0x44B2, 0x80}, + {0x44B3, 0x80}, + {0x44B4, 0x80}, + {0x44B5, 0x80}, + {0x44B6, 0x80}, + {0x44B7, 0x80}, + {0x44B8, 0x80}, + {0x44B9, 0x80}, + {0x44BA, 0x80}, + {0x44BB, 0x80}, + {0x44BC, 0x80}, + {0x44BD, 0x80}, + {0x44BE, 0x80}, + {0x44BF, 0x80}, + {0x44C0, 0x80}, + {0x44C1, 0x80}, + {0x44C2, 0x80}, + {0x44C3, 0x80}, + {0x44C4, 0x80}, + {0x44C5, 0x80}, + {0x44C6, 0x80}, + {0x44C7, 0x80}, + {0x44C8, 0x80}, + {0x44C9, 0x80}, + {0x44CA, 0x80}, + {0x44CB, 0x80}, + {0x44CC, 0x80}, + {0x44CD, 0x80}, + {0x44CE, 0x80}, + {0x44CF, 0x80}, + {0x44D0, 0x80}, + {0x44D1, 0x80}, + {0x44D2, 0x80}, + {0x44D3, 0x80}, + {0x44D4, 0x80}, + {0x44D5, 0x80}, + {0x44D6, 0x80}, + {0x44D7, 0x80}, + {0x4500, 0x80}, + {0x4501, 0x80}, + {0x4502, 0x80}, + {0x4503, 0x80}, + {0x4504, 0x80}, + {0x4505, 0x80}, + {0x4506, 0x80}, + {0x4507, 0x80}, + {0x4508, 0x80}, + {0x4509, 0x80}, + {0x450A, 0x80}, + {0x450B, 0x80}, + {0x450C, 0x80}, + {0x450D, 0x80}, + {0x450E, 0x80}, + {0x450F, 0x80}, + {0x4510, 0x80}, + {0x4511, 0x80}, + {0x4512, 0x80}, + {0x4513, 0x80}, + {0x4514, 0x80}, + {0x4515, 0x80}, + {0x4516, 0x80}, + {0x4517, 0x80}, + {0x4518, 0x80}, + {0x4519, 0x80}, + {0x451A, 0x80}, + {0x451B, 0x80}, + {0x451C, 0x80}, + {0x451D, 0x80}, + {0x451E, 0x80}, + {0x451F, 0x80}, + {0x4520, 0x80}, + {0x4521, 0x80}, + {0x4522, 0x80}, + {0x4523, 0x80}, + {0x4524, 0x80}, + {0x4525, 0x80}, + {0x4526, 0x80}, + {0x4527, 0x80}, + {0x4528, 0x80}, + {0x4529, 0x80}, + {0x452A, 0x80}, + {0x452B, 0x80}, + {0x452C, 0x80}, + {0x452D, 0x80}, + {0x452E, 0x80}, + {0x452F, 0x80}, + {0x4530, 0x80}, + {0x4531, 0x80}, + {0x4532, 0x80}, + {0x4533, 0x80}, + {0x4534, 0x80}, + {0x4535, 0x80}, + {0x4536, 0x80}, + {0x4537, 0x80}, + {0x4538, 0x80}, + {0x4539, 0x80}, + {0x453A, 0x80}, + {0x453B, 0x80}, + {0x453C, 0x80}, + {0x453D, 0x80}, + {0x453E, 0x80}, + {0x453F, 0x80}, + {0x4540, 0x80}, + {0x4541, 0x80}, + {0x4542, 0x80}, + {0x4543, 0x80}, + {0x4544, 0x80}, + {0x4545, 0x80}, + {0x4546, 0x80}, + {0x4547, 0x80}, + {0x4548, 0x80}, + {0x4549, 0x80}, + {0x454A, 0x80}, + {0x454B, 0x80}, + {0x454C, 0x80}, + {0x454D, 0x80}, + {0x454E, 0x80}, + {0x454F, 0x80}, + {0x4550, 0x80}, + {0x4551, 0x80}, + {0x4552, 0x80}, + {0x4553, 0x80}, + {0x4554, 0x80}, + {0x4555, 0x80}, + {0x4556, 0x80}, + {0x4557, 0x80}, + {0x4558, 0x80}, + {0x4559, 0x80}, + {0x455A, 0x80}, + {0x455B, 0x80}, + {0x455C, 0x80}, + {0x455D, 0x80}, + {0x455E, 0x80}, + {0x455F, 0x80}, + {0x4560, 0x80}, + {0x4561, 0x80}, + {0x4562, 0x80}, + {0x4563, 0x80}, + {0x4564, 0x80}, + {0x4565, 0x80}, + {0x4566, 0x80}, + {0x4567, 0x80}, + {0x4568, 0x80}, + {0x4569, 0x80}, + {0x456A, 0x80}, + {0x456B, 0x80}, + {0x456C, 0x80}, + {0x456D, 0x80}, + {0x456E, 0x80}, + {0x456F, 0x80}, + {0x4570, 0x80}, + {0x4571, 0x80}, + {0x4572, 0x80}, + {0x4573, 0x80}, + {0x4574, 0x80}, + {0x4575, 0x80}, + {0x4576, 0x80}, + {0x4577, 0x80}, + {0x4578, 0x80}, + {0x4579, 0x80}, + {0x457A, 0x80}, + {0x457B, 0x80}, + {0x457C, 0x80}, + {0x457D, 0x80}, + {0x457E, 0x80}, + {0x457F, 0x80}, + {0x4580, 0x80}, + {0x4581, 0x80}, + {0x4582, 0x80}, + {0x4583, 0x80}, + {0x4584, 0x80}, + {0x4585, 0x80}, + {0x4586, 0x80}, + {0x4587, 0x80}, + {0x4588, 0x80}, + {0x4589, 0x80}, + {0x458A, 0x80}, + {0x458B, 0x80}, + {0x458C, 0x80}, + {0x458D, 0x80}, + {0x458E, 0x80}, + {0x458F, 0x80}, + {0x4590, 0x80}, + {0x4591, 0x80}, + {0x4592, 0x80}, + {0x4593, 0x80}, + {0x4594, 0x80}, + {0x4595, 0x80}, + {0x4596, 0x80}, + {0x4597, 0x80}, + {0x4598, 0x80}, + {0x4599, 0x80}, + {0x459A, 0x80}, + {0x459B, 0x80}, + {0x459C, 0x80}, + {0x459D, 0x80}, + {0x459E, 0x80}, + {0x459F, 0x80}, + {0x45A0, 0x80}, + {0x45A1, 0x80}, + {0x45A2, 0x80}, + {0x45A3, 0x80}, + {0x45A4, 0x80}, + {0x45A5, 0x80}, + {0x45A6, 0x80}, + {0x45A7, 0x80}, + {0x45A8, 0x80}, + {0x45A9, 0x80}, + {0x45AA, 0x80}, + {0x45AB, 0x80}, + {0x45AC, 0x80}, + {0x45AD, 0x80}, + {0x45AE, 0x80}, + {0x45AF, 0x80}, + {0x45B0, 0x80}, + {0x45B1, 0x80}, + {0x45B2, 0x80}, + {0x45B3, 0x80}, + {0x45B4, 0x80}, + {0x45B5, 0x80}, + {0x45B6, 0x80}, + {0x45B7, 0x80}, + {0x45B8, 0x80}, + {0x45B9, 0x80}, + {0x45BA, 0x80}, + {0x45BB, 0x80}, + {0x45BC, 0x80}, + {0x45BD, 0x80}, + {0x45BE, 0x80}, + {0x45BF, 0x80}, + {0x45C0, 0x80}, + {0x45C1, 0x80}, + {0x45C2, 0x80}, + {0x45C3, 0x80}, + {0x45C4, 0x80}, + {0x45C5, 0x80}, + {0x45C6, 0x80}, + {0x45C7, 0x80}, + {0x45C8, 0x80}, + {0x45C9, 0x80}, + {0x45CA, 0x80}, + {0x45CB, 0x80}, + {0x45CC, 0x80}, + {0x45CD, 0x80}, + {0x45CE, 0x80}, + {0x45CF, 0x80}, + {0x45D0, 0x80}, + {0x45D1, 0x80}, + {0x45D2, 0x80}, + {0x45D3, 0x80}, + {0x45D4, 0x80}, + {0x45D5, 0x80}, + {0x45D6, 0x80}, + {0x45D7, 0x80}, + {0x7000, 0xAB}, + {0x7001, 0xBA}, + {0x7002, 0x40}, + {0x7003, 0x02}, + {0x7004, 0x00}, + {0x7005, 0x00}, + {0x7006, 0x00}, + {0x7007, 0x00}, + {0x7008, 0x00}, + {0x7009, 0x00}, + {0x700A, 0x00}, + {0x700B, 0x00}, + {0x700C, 0x00}, + {0x700D, 0x00}, + {0x700E, 0x00}, + {0x700F, 0x00}, + {0x7010, 0x55}, + {0x7011, 0x88}, + {0x7012, 0x40}, + {0x7013, 0x01}, + {0x7014, 0x72}, + {0x7015, 0xF1}, + {0x7016, 0x02}, + {0x7017, 0xF8}, + {0x7018, 0x00}, + {0x7019, 0x00}, + {0x701A, 0x00}, + {0x701B, 0x00}, + {0x701C, 0x00}, + {0x701D, 0x00}, + {0x701E, 0x00}, + {0x701F, 0x00}, + {0x7020, 0x00}, + {0x7021, 0x00}, + {0x7022, 0x00}, + {0x7023, 0x00}, + {0x7024, 0x00}, + {0x7025, 0x00}, + {0x7026, 0x00}, + {0x7027, 0x00}, + {0x7028, 0x00}, + {0x7029, 0x00}, + {0x702A, 0x00}, + {0x702B, 0x00}, + {0x702C, 0x00}, + {0x702D, 0x00}, + {0x702E, 0x00}, + {0x702F, 0x00}, + {0x7030, 0x00}, + {0x7031, 0x00}, + {0x7032, 0x00}, + {0x7033, 0x00}, + {0x7034, 0x00}, + {0x7035, 0x00}, + {0x7036, 0x00}, + {0x7037, 0x00}, + {0x7038, 0x00}, + {0x7039, 0x00}, + {0x703A, 0x00}, + {0x703B, 0x00}, + {0x703C, 0x00}, + {0x703D, 0x00}, + {0x703E, 0x00}, + {0x703F, 0x00}, + {0x7040, 0x00}, + {0x7041, 0x00}, + {0x7042, 0x00}, + {0x7043, 0x00}, + {0x7044, 0x00}, + {0x7045, 0x00}, + {0x7046, 0x00}, + {0x7047, 0x00}, + {0x7048, 0x00}, + {0x7049, 0x00}, + {0x704A, 0x00}, + {0x704B, 0x00}, + {0x704C, 0x00}, + {0x704D, 0x00}, + {0x704E, 0x00}, + {0x704F, 0x00}, + {0x7050, 0x00}, + {0x7051, 0x00}, + {0x7052, 0x00}, + {0x7053, 0x00}, + {0x7054, 0x00}, + {0x7055, 0x00}, + {0x7056, 0x00}, + {0x7057, 0x00}, + {0x7058, 0x00}, + {0x7059, 0x00}, + {0x705A, 0x00}, + {0x705B, 0x00}, + {0x705C, 0x00}, + {0x705D, 0x00}, + {0x705E, 0x00}, + {0x705F, 0x00}, + {0x7060, 0x00}, + {0x7061, 0x00}, + {0x7062, 0x00}, + {0x7063, 0x00}, + {0x7064, 0x00}, + {0x7065, 0x00}, + {0x7066, 0x00}, + {0x7067, 0x00}, + {0x7068, 0x00}, + {0x7069, 0x00}, + {0x706A, 0x00}, + {0x706B, 0x00}, + {0x706C, 0x00}, + {0x706D, 0x00}, + {0x706E, 0x00}, + {0x706F, 0x00}, + {0x7070, 0x00}, + {0x7071, 0x00}, + {0x7072, 0x00}, + {0x7073, 0x00}, + {0x7074, 0x00}, + {0x7075, 0x00}, + {0x7076, 0x00}, + {0x7077, 0x00}, + {0x7078, 0x00}, + {0x7079, 0x00}, + {0x707A, 0x00}, + {0x707B, 0x00}, + {0x707C, 0x00}, + {0x707D, 0x00}, + {0x707E, 0x00}, + {0x707F, 0x00}, + {0x7080, 0x00}, + {0x7081, 0x00}, + {0x7082, 0x00}, + {0x7083, 0x00}, + {0x7084, 0x00}, + {0x7085, 0x00}, + {0x7086, 0x00}, + {0x7087, 0x00}, + {0x7088, 0x00}, + {0x7089, 0x00}, + {0x708A, 0x00}, + {0x708B, 0x00}, + {0x708C, 0x00}, + {0x708D, 0x00}, + {0x708E, 0x00}, + {0x708F, 0x00}, + {0x7090, 0x00}, + {0x7091, 0xF0}, + {0x7092, 0x02}, + {0x7093, 0xF8}, + {0x7094, 0x8D}, + {0x7095, 0xF6}, + {0x7096, 0xFA}, + {0x7097, 0xFF}, + {0x7098, 0xF0}, + {0x7099, 0xB5}, + {0x709A, 0x04}, + {0x709B, 0x46}, + {0x709C, 0x8F}, + {0x709D, 0xB0}, + {0x709E, 0x5F}, + {0x709F, 0x48}, + {0x70A0, 0x0C}, + {0x70A1, 0x90}, + {0x70A2, 0x5F}, + {0x70A3, 0x48}, + {0x70A4, 0x06}, + {0x70A5, 0x90}, + {0x70A6, 0x20}, + {0x70A7, 0x46}, + {0x70A8, 0x34}, + {0x70A9, 0x30}, + {0x70AA, 0x0B}, + {0x70AB, 0x90}, + {0x70AC, 0x5B}, + {0x70AD, 0x48}, + {0x70AE, 0x5A}, + {0x70AF, 0x49}, + {0x70B0, 0x26}, + {0x70B1, 0x46}, + {0x70B2, 0x66}, + {0x70B3, 0x30}, + {0x70B4, 0x3A}, + {0x70B5, 0x31}, + {0x70B6, 0x3C}, + {0x70B7, 0x36}, + {0x70B8, 0x05}, + {0x70B9, 0x90}, + {0x70BA, 0x0A}, + {0x70BB, 0x30}, + {0x70BC, 0x04}, + {0x70BD, 0x90}, + {0x70BE, 0x59}, + {0x70BF, 0x48}, + {0x70C0, 0x55}, + {0x70C1, 0x4A}, + {0x70C2, 0x40}, + {0x70C3, 0x6E}, + {0x70C4, 0xC0}, + {0x70C5, 0x07}, + {0x70C6, 0x7D}, + {0x70C7, 0xD1}, + {0x70C8, 0x17}, + {0x70C9, 0x88}, + {0x70CA, 0x0A}, + {0x70CB, 0x5E}, + {0x70CC, 0x0D}, + {0x70CD, 0x92}, + {0x70CE, 0x53}, + {0x70CF, 0x49}, + {0x70D0, 0x55}, + {0x70D1, 0x48}, + {0x70D2, 0x94}, + {0x70D3, 0x31}, + {0x70D4, 0x89}, + {0x70D5, 0x6B}, + {0x70D6, 0x80}, + {0x70D7, 0x68}, + {0x70D8, 0x09}, + {0x70D9, 0x02}, + {0x70DA, 0x00}, + {0x70DB, 0x03}, + {0x70DC, 0x09}, + {0x70DD, 0x0E}, + {0x70DE, 0x00}, + {0x70DF, 0x0B}, + {0x70E0, 0x49}, + {0x70E1, 0x1C}, + {0x70E2, 0x48}, + {0x70E3, 0x43}, + {0x70E4, 0x4D}, + {0x70E5, 0x49}, + {0x70E6, 0x6C}, + {0x70E7, 0x39}, + {0x70E8, 0x8A}, + {0x70E9, 0x6A}, + {0x70EA, 0x07}, + {0x70EB, 0x92}, + {0x70EC, 0xCA}, + {0x70ED, 0x6A}, + {0x70EE, 0x00}, + {0x70EF, 0x21}, + {0x70F0, 0xC9}, + {0x70F1, 0x43}, + {0x70F2, 0x03}, + {0x70F3, 0x92}, + {0x70F4, 0x00}, + {0x70F5, 0x22}, + {0x70F6, 0x00}, + {0x70F7, 0x91}, + {0x70F8, 0x01}, + {0x70F9, 0x92}, + {0x70FA, 0x39}, + {0x70FB, 0x46}, + {0x70FC, 0x8F}, + {0x70FD, 0xF6}, + {0x70FE, 0xCE}, + {0x70FF, 0xFB}, + {0x7100, 0x01}, + {0x7101, 0x22}, + {0x7102, 0x00}, + {0x7103, 0x23}, + {0x7104, 0x8C}, + {0x7105, 0xF6}, + {0x7106, 0x02}, + {0x7107, 0xFA}, + {0x7108, 0x00}, + {0x7109, 0x21}, + {0x710A, 0x05}, + {0x710B, 0x46}, + {0x710C, 0x01}, + {0x710D, 0x91}, + {0x710E, 0x00}, + {0x710F, 0x90}, + {0x7110, 0x39}, + {0x7111, 0x46}, + {0x7112, 0x07}, + {0x7113, 0x98}, + {0x7114, 0x8F}, + {0x7115, 0xF6}, + {0x7116, 0xC2}, + {0x7117, 0xFB}, + {0x7118, 0x0D}, + {0x7119, 0x9A}, + {0x711A, 0xD3}, + {0x711B, 0x17}, + {0x711C, 0x80}, + {0x711D, 0x18}, + {0x711E, 0x59}, + {0x711F, 0x41}, + {0x7120, 0x01}, + {0x7121, 0x22}, + {0x7122, 0x00}, + {0x7123, 0x23}, + {0x7124, 0x8C}, + {0x7125, 0xF6}, + {0x7126, 0xCD}, + {0x7127, 0xF9}, + {0x7128, 0x07}, + {0x7129, 0x90}, + {0x712A, 0x00}, + {0x712B, 0x20}, + {0x712C, 0x01}, + {0x712D, 0x90}, + {0x712E, 0x00}, + {0x712F, 0x95}, + {0x7130, 0x39}, + {0x7131, 0x46}, + {0x7132, 0x03}, + {0x7133, 0x98}, + {0x7134, 0x8F}, + {0x7135, 0xF6}, + {0x7136, 0xB2}, + {0x7137, 0xFB}, + {0x7138, 0x01}, + {0x7139, 0x22}, + {0x713A, 0x00}, + {0x713B, 0x23}, + {0x713C, 0x8C}, + {0x713D, 0xF6}, + {0x713E, 0xE6}, + {0x713F, 0xF9}, + {0x7140, 0x02}, + {0x7141, 0x46}, + {0x7142, 0x07}, + {0x7143, 0x98}, + {0x7144, 0x00}, + {0x7145, 0x23}, + {0x7146, 0x81}, + {0x7147, 0x0B}, + {0x7148, 0x80}, + {0x7149, 0x04}, + {0x714A, 0x7A}, + {0x714B, 0xF6}, + {0x714C, 0x54}, + {0x714D, 0xF8}, + {0x714E, 0x37}, + {0x714F, 0x4A}, + {0x7150, 0x00}, + {0x7151, 0x23}, + {0x7152, 0x00}, + {0x7153, 0x92}, + {0x7154, 0x01}, + {0x7155, 0x93}, + {0x7156, 0x01}, + {0x7157, 0x22}, + {0x7158, 0x8C}, + {0x7159, 0xF6}, + {0x715A, 0xD8}, + {0x715B, 0xF9}, + {0x715C, 0x05}, + {0x715D, 0x46}, + {0x715E, 0x60}, + {0x715F, 0x68}, + {0x7160, 0x00}, + {0x7161, 0x23}, + {0x7162, 0x01}, + {0x7163, 0x0C}, + {0x7164, 0x00}, + {0x7165, 0x04}, + {0x7166, 0xE2}, + {0x7167, 0x68}, + {0x7168, 0x7A}, + {0x7169, 0xF6}, + {0x716A, 0x45}, + {0x716B, 0xF8}, + {0x716C, 0x00}, + {0x716D, 0x22}, + {0x716E, 0xD2}, + {0x716F, 0x43}, + {0x7170, 0x00}, + {0x7171, 0x23}, + {0x7172, 0x00}, + {0x7173, 0x92}, + {0x7174, 0x01}, + {0x7175, 0x93}, + {0x7176, 0x1A}, + {0x7177, 0x46}, + {0x7178, 0x8C}, + {0x7179, 0xF6}, + {0x717A, 0xC8}, + {0x717B, 0xF9}, + {0x717C, 0x29}, + {0x717D, 0x46}, + {0x717E, 0x8F}, + {0x717F, 0xF6}, + {0x7180, 0x8D}, + {0x7181, 0xFB}, + {0x7182, 0x8A}, + {0x7183, 0x03}, + {0x7184, 0x80}, + {0x7185, 0x0C}, + {0x7186, 0x10}, + {0x7187, 0x43}, + {0x7188, 0x00}, + {0x7189, 0x22}, + {0x718A, 0xD2}, + {0x718B, 0x43}, + {0x718C, 0x00}, + {0x718D, 0x23}, + {0x718E, 0x00}, + {0x718F, 0x92}, + {0x7190, 0x89}, + {0x7191, 0x0C}, + {0x7192, 0x01}, + {0x7193, 0x93}, + {0x7194, 0x1A}, + {0x7195, 0x46}, + {0x7196, 0x8C}, + {0x7197, 0xF6}, + {0x7198, 0xB9}, + {0x7199, 0xF9}, + {0x719A, 0x00}, + {0x719B, 0x24}, + {0x719C, 0x03}, + {0x719D, 0x90}, + {0x719E, 0x0C}, + {0x719F, 0x98}, + {0x71A0, 0x61}, + {0x71A1, 0x00}, + {0x71A2, 0x45}, + {0x71A3, 0x5A}, + {0x71A4, 0x06}, + {0x71A5, 0x98}, + {0x71A6, 0x22}, + {0x71A7, 0x4A}, + {0x71A8, 0x40}, + {0x71A9, 0x5A}, + {0x71AA, 0x00}, + {0x71AB, 0x21}, + {0x71AC, 0x8C}, + {0x71AD, 0xF6}, + {0x71AE, 0xBE}, + {0x71AF, 0xF9}, + {0x71B0, 0x07}, + {0x71B1, 0x46}, + {0x71B2, 0x28}, + {0x71B3, 0x46}, + {0x71B4, 0x03}, + {0x71B5, 0x99}, + {0x71B6, 0x8F}, + {0x71B7, 0xF6}, + {0x71B8, 0x71}, + {0x71B9, 0xFB}, + {0x71BA, 0x3A}, + {0x71BB, 0x46}, + {0x71BC, 0x00}, + {0x71BD, 0x23}, + {0x71BE, 0x79}, + {0x71BF, 0xF6}, + {0x71C0, 0xCA}, + {0x71C1, 0xFF}, + {0x71C2, 0x00}, + {0x71C3, 0xE0}, + {0x71C4, 0x0F}, + {0x71C5, 0xE0}, + {0x71C6, 0x8A}, + {0x71C7, 0x02}, + {0x71C8, 0x80}, + {0x71C9, 0x0D}, + {0x71CA, 0x10}, + {0x71CB, 0x43}, + {0x71CC, 0x19}, + {0x71CD, 0x4A}, + {0x71CE, 0x00}, + {0x71CF, 0x23}, + {0x71D0, 0x00}, + {0x71D1, 0x92}, + {0x71D2, 0x89}, + {0x71D3, 0x0D}, + {0x71D4, 0x01}, + {0x71D5, 0x93}, + {0x71D6, 0x40}, + {0x71D7, 0x22}, + {0x71D8, 0x8C}, + {0x71D9, 0xF6}, + {0x71DA, 0x98}, + {0x71DB, 0xF9}, + {0x71DC, 0xA1}, + {0x71DD, 0x00}, + {0x71DE, 0x64}, + {0x71DF, 0x1C}, + {0x71E0, 0x70}, + {0x71E1, 0x50}, + {0x71E2, 0x04}, + {0x71E3, 0x2C}, + {0x71E4, 0xDB}, + {0x71E5, 0xD3}, + {0x71E6, 0x14}, + {0x71E7, 0x4D}, + {0x71E8, 0x00}, + {0x71E9, 0x24}, + {0x71EA, 0x0B}, + {0x71EB, 0x98}, + {0x71EC, 0x67}, + {0x71ED, 0x00}, + {0x71EE, 0xC0}, + {0x71EF, 0x5B}, + {0x71F0, 0x2A}, + {0x71F1, 0x46}, + {0x71F2, 0x40}, + {0x71F3, 0x21}, + {0x71F4, 0x8C}, + {0x71F5, 0xF6}, + {0x71F6, 0x9A}, + {0x71F7, 0xF9}, + {0x71F8, 0x05}, + {0x71F9, 0x99}, + {0x71FA, 0x0E}, + {0x71FB, 0x4A}, + {0x71FC, 0xC8}, + {0x71FD, 0x53}, + {0x71FE, 0xA7}, + {0x71FF, 0x00}, + {0x7200, 0xF0}, + {0x7201, 0x59}, + {0x7202, 0x40}, + {0x7203, 0x21}, + {0x7204, 0x8C}, + {0x7205, 0xF6}, + {0x7206, 0x7B}, + {0x7207, 0xF9}, + {0x7208, 0x04}, + {0x7209, 0x99}, + {0x720A, 0x64}, + {0x720B, 0x1C}, + {0x720C, 0xC8}, + {0x720D, 0x51}, + {0x720E, 0x04}, + {0x720F, 0x2C}, + {0x7210, 0xEB}, + {0x7211, 0xD3}, + {0x7212, 0x0F}, + {0x7213, 0xB0}, + {0x7214, 0xF0}, + {0x7215, 0xBD}, + {0x7216, 0x00}, + {0x7217, 0x00}, + {0x7218, 0x76}, + {0x7219, 0x69}, + {0x721A, 0x18}, + {0x721B, 0x00}, + {0x721C, 0xEC}, + {0x721D, 0x58}, + {0x721E, 0x18}, + {0x721F, 0x00}, + {0x7220, 0x38}, + {0x7221, 0x36}, + {0x7222, 0x18}, + {0x7223, 0x00}, + {0x7224, 0x00}, + {0x7225, 0x35}, + {0x7226, 0x18}, + {0x7227, 0x00}, + {0x7228, 0x00}, + {0x7229, 0x20}, + {0x722A, 0x18}, + {0x722B, 0x00}, + {0x722C, 0xFF}, + {0x722D, 0xFF}, + {0x722E, 0xFF}, + {0x722F, 0x3F}, + {0x7230, 0xFF}, + {0x7231, 0x07}, + {0x7232, 0x00}, + {0x7233, 0x00}, + {0x7234, 0xFF}, + {0x7235, 0xFF}, + {0x7236, 0x07}, + {0x7237, 0x00}, + {0x7238, 0xFF}, + {0x7239, 0x1F}, + {0x723A, 0x00}, + {0x723B, 0x00}, + {0x723C, 0x01}, + {0x723D, 0xF6}, + {0x723E, 0x45}, + {0x723F, 0x12}, + + {IMX390_TABLE_END, 0x00} +}; + +/* + * imx390 register configuration for stoping stream + */ +static const imx390_reg imx390_stop[] = { + {0x0000, 0x01}, + {IMX390_TABLE_END, 0x00} +}; + +/* + * imx390 register configuration for stoping stream + */ +static const imx390_reg imx390_start[] = { + {0x0000, 0x00}, /* STANDBY */ + {IMX390_TABLE_END, 0x00} +}; + +/* + * imx390 mode related structure + */ enum { - IMX390_MODE_1920X1080_CROP_30FPS, + IMX390_MODE_4000X3000, + IMX390_MODE_linear_1920X1080, IMX390_MODE_START_STREAM, - IMX390_MODE_STOP_STREAM, + IMX390_MODE_STOP_STREAM }; -static imx390_reg *mode_table[] = { - [IMX390_MODE_1920X1080_CROP_30FPS] - = imx390_1920x1080_crop_30fps, - [IMX390_MODE_START_STREAM] - = imx390_start, - [IMX390_MODE_STOP_STREAM] - = imx390_stop, +static const imx390_reg *mode_table[] = { + [IMX390_MODE_4000X3000] = imx390_mode1_4000x3000_raw10, + [IMX390_MODE_linear_1920X1080] = imx390_mode1_linear_1920x1080_raw12, + [IMX390_MODE_START_STREAM] = imx390_start, + [IMX390_MODE_STOP_STREAM] = imx390_stop, }; -static const int imx390_30fps[] = { +static const int imx390_10_fr[] = { + 10, +}; + +static const int imx390_30_fr[] = { 30, }; -static const int imx390_60fps[] = { +static const int imx390_60_fr[] = { 60, }; -static const int imx390_120fps[] = { +static const int imx390_120_fr[] = { 120, }; -static const struct camera_common_frmfmt imx390_frmfmt[] = { - {{1920, 1080}, imx390_30fps, 1, 0, IMX390_MODE_1920X1080_CROP_30FPS}, +static const int imx390_164_fr[] = { + 164, }; -#endif /* __IMX390_I2C_TABLES__ */ + +static const int imx390_180_fr[] = { + 180, +}; + +static const int imx390_240_fr[] = { + 240, +}; + +static const struct camera_common_frmfmt imx390_frmfmt[] = { + {{1936, 1096}, imx390_30_fr, 1, 0, IMX390_MODE_4000X3000}, + {{1920, 1080}, imx390_30_fr, 1, 0, IMX390_MODE_linear_1920X1080}, +}; +#endif /* __IMX390_I2C_TABLES__ */ diff --git a/drivers/media/i2c/max929x.c b/drivers/media/i2c/max929x.c new file mode 100644 index 00000000..f5668370 --- /dev/null +++ b/drivers/media/i2c/max929x.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +/* + * max929x.c - max929x IO Expander driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "max929x.h" + +struct max929x { + struct i2c_client *i2c_client; + struct regmap *regmap; + unsigned int pwdn_gpio; + unsigned short ser_addr; +}; +struct max929x *priv; + +static int max929x_write_reg(u8 slave_addr, u16 reg, u8 val) +{ + struct i2c_client *i2c_client = priv->i2c_client; + int err; + + i2c_client->addr = slave_addr; + err = regmap_write(priv->regmap, reg, val); + if (err) + dev_err(&i2c_client->dev, "%s:i2c write failed, slave_addr 0x%x, 0x%x = 0x%x\n", + __func__, slave_addr, reg, val); + + return err; +} + +static int max929x_write_reg_list(struct max929x_reg *table, int size) +{ + struct device dev = priv->i2c_client->dev; + int err = 0; + int i; + u8 slave_addr; + u16 reg; + u8 val; + + for (i = 0; i < size; i++) { + if (table[i].slave_addr == SER_SLAVE2) + slave_addr = priv->ser_addr; + else + slave_addr = table[i].slave_addr; + + reg = table[i].reg; + val = table[i].val; + + if (slave_addr == 0xf1) { + msleep(val); + msleep(2000); + continue; + } + + dev_dbg(&dev, "%s: size %d, slave_addr 0x%x, reg 0x%x, val 0x%x\n", + __func__, size, slave_addr, reg, val); + + err = max929x_write_reg(slave_addr, reg, val); + if (err != 0) + break; + mdelay(5); + } + + return err; +} + +static struct regmap_config max929x_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, +}; + +static int max929x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device dev = client->dev; + struct device_node *np = (&dev)->of_node; + unsigned short ser_addr = SER_SLAVE2; + int err; + + dev_dbg(&dev, "%s: enter\n", __func__); + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + priv->i2c_client = client; + priv->regmap = devm_regmap_init_i2c(priv->i2c_client, &max929x_regmap_config); + if (IS_ERR(priv->regmap)) { + dev_err(&client->dev, + "regmap init failed: %ld\n", PTR_ERR(priv->regmap)); + return -ENODEV; + } + + priv->pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); + if (priv->pwdn_gpio < 0) { + dev_err(&dev, "pwdn-gpios not found\n"); + return -EINVAL; + } + + if (priv->pwdn_gpio) { + gpio_direction_output(priv->pwdn_gpio, 1); + gpio_set_value(priv->pwdn_gpio, 1); + msleep(100); + } + + /* + * Try to find the I2C address of serializer by writting to register + * 0x00 at i2c slave address 0x62 and 0x40. When write is successful + * the slave address is saved and used when configuring serializer. + */ + if (max929x_write_reg(SER_SLAVE2, MAX9295_DEV_ADDR, SER_SLAVE2 << 1)) { + if (max929x_write_reg(SER_SLAVE1, MAX9295_DEV_ADDR, SER_SLAVE1 << 1)) { + dev_err(&dev, "%s: failed to find serializer at 0x%x or 0x%x\n", + __func__, SER_SLAVE2, SER_SLAVE1); + return -ENODEV; + } + ser_addr = SER_SLAVE1; + } + + msleep(100); + priv->ser_addr = ser_addr; + + err = max929x_write_reg_list(max929x_Double_Dser_Ser_init, + sizeof(max929x_Double_Dser_Ser_init)/sizeof(struct max929x_reg)); + if (err == 0) + dev_dbg(&dev, "%s: success\n", __func__); + else + dev_err(&dev, "%s: fail\n", __func__); + + dev_set_drvdata(&client->dev, priv); + + return 0; +} + +static int max929x_remove(struct i2c_client *client) +{ + struct device dev = client->dev; + + gpio_set_value(priv->pwdn_gpio, 0); + dev_dbg(&dev, "%s: \n", __func__); + + return 0; +} + +static const struct i2c_device_id max929x_id[] = { + { "max929x", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, max929x_id); + +const struct of_device_id max929x_of_match[] = { + { .compatible = "Maxim,max929x", }, + { }, +}; +MODULE_DEVICE_TABLE(of, max929x_of_match); + +static struct i2c_driver max929x_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "max929x", + .of_match_table = of_match_ptr(max929x_of_match), + }, + .probe = max929x_probe, + .remove = max929x_remove, + .id_table = max929x_id, +}; + +module_i2c_driver(max929x_i2c_driver); + +MODULE_DESCRIPTION("IO Expander driver max929x"); +MODULE_AUTHOR("NVIDIA Corporation"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/max929x.h b/drivers/media/i2c/max929x.h new file mode 100644 index 00000000..c253a5ec --- /dev/null +++ b/drivers/media/i2c/max929x.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#ifndef __MAX929X_H__ +#define __MAX929X_H__ + +/* TI FPD Link III 954 deser I2C address */ +#define TI954_ADDR (0x30) +/* TI FPD Link III 953 ser I2C address */ +#define TI953_ADDR (0x18) +/* TI 953 alias address */ +#define TI953_CAM1_ADDR (0x29) +#define TI953_CAM2_ADDR (0X2A) + +#define MAX9295_DEV_ADDR 0x00 + +#define SENSOR_ADDR (0x1a) +/* CAM alias address */ +#define CAM1_SENSOR_ADDR (0x1b) +#define CAM2_SENSOR_ADDR (0x1c) + +#define TI954_RESET_ADDR (0x01) +#define TI954_RESET_VAL (0x02) + +#define AFDRV_I2C_ADDR (0x3E) +/*AF ctrl*/ +#define AFDRV1_I2C_ADDR (0x21) +#define AFDRV2_I2C_ADDR (0x20) + +#define EEPROM_I2C_ADDR (0x50) +/*eeprom ctrl*/ +#define EEPROM1_I2C_ADDR (0x51) +#define EEPROM2_I2C_ADDR (0x52) + +struct max929x_reg { + u8 slave_addr; + u16 reg; + u8 val; +}; + +/* Serializer slave addresses */ +#define SER_SLAVE1 0x40 +#define SER_SLAVE2 0x62 + +/* Deserializer slave addresses */ +#define DESER_SLAVE 0x48 + +/* + * MAX9296 i2c addr 0x90(8bits) 0x48(7bits) + * (MAX9296 link A) MAX9295 i2c addr 0xc4(8bits) 0x62(7bits) + */ +static struct max929x_reg max929x_Double_Dser_Ser_init[] = { + /* set MFP0 low to reset sensor */ + {0x62, 0x02be, 0x80}, + /* Set SER to 1x4 mode (phy_config = 0) */ + {0x62, 0x0330, 0x00}, + {0x62, 0x0332, 0xe4}, + /* Additional lane map */ + {0x62, 0x0333, 0xe4}, + /* Set 4 lanes for serializer (ctrl1_num_lanes = 3) */ + {0x62, 0x0331, 0x31}, + /* Start video from both port A and port B. */ + {0x62, 0x0311, 0x20}, + /* + * Enable info lines. Additional start bits for Port A and B. + * Use data from port B for all pipelines + */ + {0x62, 0x0308, 0x62}, + /* Route 16bit DCG (DT = 0x30) to VIDEO_X (Bit 6 enable) */ + {0x62, 0x0314, 0x22}, + /* Route 12bit RAW (DT = 0x2C) to VIDEO_Y (Bit 6 enable) */ + {0x62, 0x0316, 0x6c}, + /* Route EMBEDDED8 to VIDEO_Z (Bit 6 enable) */ + {0x62, 0x0318, 0x22}, + /* Unused VIDEO_U */ + {0x62, 0x031A, 0x22}, + /* + * Make sure all pipelines start transmission + * (VID_TX_EN_X/Y/Z/U = 1) + */ + {0x62, 0x0002, 0x22}, + /* Set MIPI Phy Mode: 2x(1x4) mode */ + {0x48, 0x0330, 0x04}, + /* lane maps - all 4 ports mapped straight */ + {0x48, 0x0333, 0x4E}, + /* Additional lane map */ + {0x48, 0x0334, 0xE4}, + /* + * lane count - 0 lanes striping on controller 0 + * (Port A slave in 2x1x4 mode). + */ + {0x48, 0x040A, 0x00}, + /* + * lane count - 4 lanes striping on controller 1 + * (Port A master in 2x1x4 mode). + */ + {0x48, 0x044A, 0xd0}, + /* + * lane count - 4 lanes striping on controller 2 + * (Port B master in 2x1x4 mode). + */ + {0x48, 0x048A, 0xd0}, + /* + * lane count - 0 lanes striping on controller 3 + * (Port B slave in 2x1x4 mode). + */ + {0x48, 0x04CA, 0x00}, + /* + * MIPI clock rate - 1.5Gbps from controller 0 clock + * (Port A slave in 2x1x4 mode). + */ + {0x48, 0x031D, 0x2f}, + /* + * MIPI clock rate - 1.5Gbps from controller 1 clock + * (Port A master in 2x1x4 mode). + */ + {0x48, 0x0320, 0x2f}, + /* + * MIPI clock rate - 1.5Gbps from controller 2 clock + * (Port B master in 2x1x4 mode). + */ + {0x48, 0x0323, 0x2f}, + /* + * MIPI clock rate - 1.5Gbps from controller 2 clock + * (Port B slave in 2x1x4 mode). + */ + {0x48, 0x0326, 0x2f}, + /* Route data from stream 0 to pipe X */ + {0x48, 0x0050, 0x00}, + /* Route data from stream 0 to pipe Y */ + {0x48, 0x0051, 0x01}, + /* Route data from stream 0 to pipe Z */ + {0x48, 0x0052, 0x02}, + /* Route data from stream 0 to pipe U */ + {0x48, 0x0053, 0x03}, + /* Enable all PHYS. */ + {0x48, 0x0332, 0xF0}, + /* Enable sensor power down pin. Put imager in,Active mode */ + {0x62, 0x02be, 0x90}, + /* Output RCLK to sensor. */ + {0x62, 0x03F1, 0x89}, + /* MFP8 for FSIN */ + {0x62, 0x02D8, 0x10}, + {0x62, 0x02D6, 0x04}, + /* need disable pixel clk out inb order to use MFP1 */ + {0x48, 0x0005, 0x00}, + /* GPIO TX compensation */ + {0x48, 0x02B3, 0x83}, + {0x48, 0x02B4, 0x10}, +}; + +#endif diff --git a/drivers/media/i2c/nv_imx390.c b/drivers/media/i2c/nv_imx390.c index 9ed2cdd3..04fbd401 100644 --- a/drivers/media/i2c/nv_imx390.c +++ b/drivers/media/i2c/nv_imx390.c @@ -1,226 +1,202 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2018-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - -#include +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +/* + * imx390.c - imx390 sensor driver + * Copyright (c) 2020, RidgeRun. All rights reserved. + * + */ #include #include #include #include - #include #include #include #include -#include -#include - +#include #include + +#include "../platform/tegra/camera/camera_gpio.h" #include "imx390_mode_tbls.h" +/* imx390 - sensor parameters */ #define IMX390_MIN_GAIN (0) -#define IMX390_MAX_GAIN (30) -#define IMX390_MAX_GAIN_REG ((IMX390_MAX_GAIN - IMX390_MIN_GAIN) * 10 / 3) -#define IMX390_DEFAULT_FRAME_LENGTH (1125) -#define IMX390_FRAME_LENGTH_ADDR_MSB 0x200A -#define IMX390_FRAME_LENGTH_ADDR_MID 0x2009 -#define IMX390_FRAME_LENGTH_ADDR_LSB 0x2008 -#define IMX390_COARSE_TIME_SHS1_ADDR_MSB 0x000E -#define IMX390_COARSE_TIME_SHS1_ADDR_MID 0x000D -#define IMX390_COARSE_TIME_SHS1_ADDR_LSB 0x000C -#define IMX390_COARSE_TIME_SHS2_ADDR_MSB 0x0012 -#define IMX390_COARSE_TIME_SHS2_ADDR_MID 0x0011 -#define IMX390_COARSE_TIME_SHS2_ADDR_LSB 0x0010 -#define IMX390_GROUP_HOLD_ADDR 0x0008 -#define IMX390_ANALOG_GAIN_SP1H_ADDR 0x0018 -#define IMX390_ANALOG_GAIN_SP1L_ADDR 0x001A +#define IMX390_MAX_GAIN (978) +#define IMX390_ANALOG_GAIN_C0 (1024) +#define IMX390_SHIFT_8_BITS (8) +#define IMX390_MIN_COARSE_EXPOSURE (1) +#define IMX390_MAX_COARSE_DIFF (10) +#define IMX390_MASK_LSB_2_BITS 0x0003 +#define IMX390_MASK_LSB_8_BITS 0x00ff +#define IMX390_MIN_FRAME_LENGTH (3092) +#define IMX390_MAX_FRAME_LENGTH (0x1FFFF) + +/* imx390 sensor register address */ +#define IMX390_MODEL_ID_ADDR_MSB 0x0000 +#define IMX390_MODEL_ID_ADDR_LSB 0x0001 +#define IMX390_ANALOG_GAIN_ADDR_MSB 0x0204 +#define IMX390_ANALOG_GAIN_ADDR_LSB 0x0205 +#define IMX390_DIGITAL_GAIN_ADDR_MSB 0x020e +#define IMX390_DIGITAL_GAIN_ADDR_LSB 0x020f +#define IMX390_FRAME_LENGTH_ADDR_MSB 0x0340 +#define IMX390_FRAME_LENGTH_ADDR_LSB 0x0341 +#define IMX390_COARSE_INTEG_TIME_ADDR_MSB 0x0202 +#define IMX390_COARSE_INTEG_TIME_ADDR_LSB 0x0203 +#define IMX390_FINE_INTEG_TIME_ADDR_MSB 0x0200 +#define IMX390_FINE_INTEG_TIME_ADDR_LSB 0x0201 +#define IMX390_GROUP_HOLD_ADDR 0x0104 static const struct of_device_id imx390_of_match[] = { - { .compatible = "sony,imx390",}, - { }, + {.compatible = "sony,imx390",}, + {}, }; MODULE_DEVICE_TABLE(of, imx390_of_match); static const u32 ctrl_cid_list[] = { TEGRA_CAMERA_CID_GAIN, TEGRA_CAMERA_CID_EXPOSURE, - TEGRA_CAMERA_CID_EXPOSURE_SHORT, TEGRA_CAMERA_CID_FRAME_RATE, TEGRA_CAMERA_CID_HDR_EN, + TEGRA_CAMERA_CID_SENSOR_MODE_ID, }; struct imx390 { - struct i2c_client *i2c_client; - const struct i2c_device_id *id; - struct v4l2_subdev *subdev; - struct device *ser_dev; - struct device *dser_dev; - struct gmsl_link_ctx g_ctx; - u32 frame_length; - struct camera_common_data *s_data; - struct tegracam_device *tc_dev; + struct i2c_client *i2c_client; + struct v4l2_subdev *subdev; + u16 fine_integ_time; + u32 frame_length; + struct camera_common_data *s_data; + struct tegracam_device *tc_dev; }; static const struct regmap_config sensor_regmap_config = { .reg_bits = 16, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_NONE, }; static inline void imx390_get_frame_length_regs(imx390_reg *regs, - u32 frame_length) + u32 frame_length) { regs->addr = IMX390_FRAME_LENGTH_ADDR_MSB; - regs->val = (frame_length >> 16) & 0x01; - - (regs + 1)->addr = IMX390_FRAME_LENGTH_ADDR_MID; - (regs + 1)->val = (frame_length >> 8) & 0xff; - - (regs + 2)->addr = IMX390_FRAME_LENGTH_ADDR_LSB; - (regs + 2)->val = (frame_length) & 0xff; + regs->val = (frame_length >> 8) & 0xff; + (regs + 1)->addr = IMX390_FRAME_LENGTH_ADDR_LSB; + (regs + 1)->val = (frame_length) & 0xff; } -static inline void imx390_get_coarse_time_regs_shs1(imx390_reg *regs, - u32 coarse_time) +static inline void imx390_get_coarse_integ_time_regs(imx390_reg *regs, + u32 coarse_time) { - regs->addr = IMX390_COARSE_TIME_SHS1_ADDR_MSB; - regs->val = (coarse_time >> 16) & 0x0f; - - (regs + 1)->addr = IMX390_COARSE_TIME_SHS1_ADDR_MID; - (regs + 1)->val = (coarse_time >> 8) & 0xff; - - (regs + 2)->addr = IMX390_COARSE_TIME_SHS1_ADDR_LSB; - (regs + 2)->val = (coarse_time) & 0xff; + regs->addr = IMX390_COARSE_INTEG_TIME_ADDR_MSB; + regs->val = (coarse_time >> 8) & 0xff; + (regs + 1)->addr = IMX390_COARSE_INTEG_TIME_ADDR_LSB; + (regs + 1)->val = (coarse_time) & 0xff; } -static inline void imx390_get_coarse_time_regs_shs2(imx390_reg *regs, - u32 coarse_time) +static inline void imx390_get_gain_reg(imx390_reg *reg, u16 gain) { - regs->addr = IMX390_COARSE_TIME_SHS2_ADDR_MSB; - regs->val = (coarse_time >> 16) & 0x0f; + reg->addr = IMX390_ANALOG_GAIN_ADDR_MSB; + reg->val = (gain >> IMX390_SHIFT_8_BITS) & IMX390_MASK_LSB_2_BITS; - (regs + 1)->addr = IMX390_COARSE_TIME_SHS2_ADDR_MID; - (regs + 1)->val = (coarse_time >> 8) & 0xff; - - (regs + 2)->addr = IMX390_COARSE_TIME_SHS2_ADDR_LSB; - (regs + 2)->val = (coarse_time) & 0xff; + (reg + 1)->addr = IMX390_ANALOG_GAIN_ADDR_LSB; + (reg + 1)->val = (gain) & IMX390_MASK_LSB_8_BITS; } -static inline void imx390_get_gain_reg(imx390_reg *regs, - u16 gain) -{ - regs->addr = IMX390_ANALOG_GAIN_SP1H_ADDR; - regs->val = (gain) & 0xff; - - (regs + 1)->addr = IMX390_ANALOG_GAIN_SP1H_ADDR + 1; - (regs + 1)->val = (gain >> 8) & 0xff; - - (regs + 2)->addr = IMX390_ANALOG_GAIN_SP1L_ADDR; - (regs + 2)->val = (gain) & 0xff; - - (regs + 3)->addr = IMX390_ANALOG_GAIN_SP1L_ADDR + 1; - (regs + 3)->val = (gain >> 8) & 0xff; -} - - -static int test_mode; -module_param(test_mode, int, 0644); - static inline int imx390_read_reg(struct camera_common_data *s_data, - u16 addr, u8 *val) + u16 addr, u8 *val) { int err = 0; u32 reg_val = 0; err = regmap_read(s_data->regmap, addr, ®_val); - *val = reg_val & 0xFF; + *val = reg_val & 0xff; return err; } -static int imx390_write_reg(struct camera_common_data *s_data, - u16 addr, u8 val) +static inline int imx390_write_reg(struct camera_common_data *s_data, + u16 addr, u8 val) { - int err; - struct device *dev = s_data->dev; + int err = 0; err = regmap_write(s_data->regmap, addr, val); if (err) - dev_err(dev, "%s:i2c write failed, 0x%x = %x\n", - __func__, addr, val); + dev_err(s_data->dev, "%s: i2c write failed, 0x%x = %x", + __func__, addr, val); return err; } -static int imx390_write_table(struct imx390 *priv, - const imx390_reg table[]) +static int imx390_write_table(struct imx390 *priv, const imx390_reg table[]) { - struct camera_common_data *s_data = priv->s_data; + struct tegracam_device *tc_dev = priv->tc_dev; + struct device *dev = tc_dev->dev; + int i = 0; + int ret = 0; + int retry; - return regmap_util_write_table_8(s_data->regmap, - table, - NULL, 0, - IMX390_TABLE_WAIT_MS, - IMX390_TABLE_END); -} + while (table[i].addr != IMX390_TABLE_END) { + retry = 5; -static struct mutex serdes_lock__; + if (table[i].addr == IMX390_TABLE_WAIT_MS) { + dev_dbg(dev, "%s: sleep %d\n", __func__, table[i].val); + msleep(table[i].val); + i++; + continue; + } -static int imx390_gmsl_serdes_setup(struct imx390 *priv) -{ - int err = 0; - int des_err = 0; - struct device *dev; + do { + ret = imx390_write_reg(priv->s_data, table[i].addr, table[i].val); + if (!ret) + break; + dev_warn(dev, "imx390_write_reg: try %d\n", retry); + msleep(4); + retry--; + } while (retry > 0); - if (!priv || !priv->ser_dev || !priv->dser_dev || !priv->i2c_client) - return -EINVAL; + if (retry == 0 && ret) + return -EINVAL; - dev = &priv->i2c_client->dev; - - mutex_lock(&serdes_lock__); - - /* For now no separate power on required for serializer device */ - max9296_power_on(priv->dser_dev); - - /* setup serdes addressing and control pipeline */ - err = max9296_setup_link(priv->dser_dev, &priv->i2c_client->dev); - if (err) { - dev_err(dev, "gmsl deserializer link config failed\n"); - goto error; + i++; } - err = max9295_setup_control(priv->ser_dev); - - /* proceed even if ser setup failed, to setup deser correctly */ - if (err) - dev_err(dev, "gmsl serializer setup failed\n"); - - des_err = max9296_setup_control(priv->dser_dev, &priv->i2c_client->dev); - if (des_err) { - dev_err(dev, "gmsl deserializer setup failed\n"); - /* overwrite err only if deser setup also failed */ - err = des_err; - } - -error: - mutex_unlock(&serdes_lock__); - return err; + return 0; } -static void imx390_gmsl_serdes_reset(struct imx390 *priv) +static int imx390_set_group_hold(struct tegracam_device *tc_dev, bool val) { - mutex_lock(&serdes_lock__); - - /* reset serdes addressing and control pipeline */ - max9295_reset_control(priv->ser_dev); - max9296_reset_control(priv->dser_dev, &priv->i2c_client->dev); - - max9296_power_off(priv->dser_dev); - - mutex_unlock(&serdes_lock__); + return 0; } +static int imx390_set_gain(struct tegracam_device *tc_dev, s64 val) +{ + return 0; +} + +static int imx390_set_frame_rate(struct tegracam_device *tc_dev, s64 val) +{ + struct imx390 *priv = (struct imx390 *)tc_dev->priv; + + priv->frame_length = IMX390_MIN_FRAME_LENGTH; + return 0; +} + +static int imx390_set_exposure(struct tegracam_device *tc_dev, s64 val) +{ + return 0; +} + +static struct tegracam_ctrl_ops imx390_ctrl_ops = { + .numctrls = ARRAY_SIZE(ctrl_cid_list), + .ctrl_cid_list = ctrl_cid_list, + .set_gain = imx390_set_gain, + .set_exposure = imx390_set_exposure, + .set_frame_rate = imx390_set_frame_rate, + .set_group_hold = imx390_set_group_hold, +}; + static int imx390_power_on(struct camera_common_data *s_data) { int err = 0; @@ -228,7 +204,7 @@ static int imx390_power_on(struct camera_common_data *s_data) struct camera_common_pdata *pdata = s_data->pdata; struct device *dev = s_data->dev; - dev_dbg(dev, "%s: power on\n", __func__); + dev_err(dev, "%s: power on\n", __func__); if (pdata && pdata->power_on) { err = pdata->power_on(pw); if (err) @@ -238,9 +214,64 @@ static int imx390_power_on(struct camera_common_data *s_data) return err; } + if (gpio_is_valid(pw->reset_gpio)) { + if (gpio_cansleep(pw->reset_gpio)) + gpio_set_value_cansleep(pw->reset_gpio, 0); + else + gpio_set_value(pw->reset_gpio, 0); + } + + if (unlikely(!(pw->avdd || pw->iovdd || pw->dvdd))) + goto skip_power_seqn; + + usleep_range(10, 20); + + if (pw->avdd) { + err = regulator_enable(pw->avdd); + if (err) + goto imx390_avdd_fail; + } + + if (pw->iovdd) { + err = regulator_enable(pw->iovdd); + if (err) + goto imx390_iovdd_fail; + } + + if (pw->dvdd) { + err = regulator_enable(pw->dvdd); + if (err) + goto imx390_dvdd_fail; + } + + usleep_range(10, 20); + +skip_power_seqn: + if (gpio_is_valid(pw->reset_gpio)) { + if (gpio_cansleep(pw->reset_gpio)) + gpio_set_value_cansleep(pw->reset_gpio, 1); + else + gpio_set_value(pw->reset_gpio, 1); + } + + /* Need to wait for t4 + t5 + t9 + t10 time as per the data sheet */ + /* t4 - 200us, t5 - 21.2ms, t9 - 1.2ms t10 - 270 ms */ + usleep_range(300000, 300100); + pw->state = SWITCH_ON; return 0; + +imx390_dvdd_fail: + regulator_disable(pw->iovdd); + +imx390_iovdd_fail: + regulator_disable(pw->avdd); + +imx390_avdd_fail: + dev_err(dev, "%s failed.\n", __func__); + + return -ENODEV; } static int imx390_power_off(struct camera_common_data *s_data) @@ -250,62 +281,37 @@ static int imx390_power_off(struct camera_common_data *s_data) struct camera_common_pdata *pdata = s_data->pdata; struct device *dev = s_data->dev; - dev_dbg(dev, "%s:\n", __func__); + dev_dbg(dev, "%s: power off\n", __func__); if (pdata && pdata->power_off) { err = pdata->power_off(pw); - if (!err) - goto power_off_done; - else + if (err) { dev_err(dev, "%s failed.\n", __func__); - return err; + return err; + } + } else { + if (pw->reset_gpio) { + if (gpio_cansleep(pw->reset_gpio)) + gpio_set_value_cansleep(pw->reset_gpio, 0); + else + gpio_set_value(pw->reset_gpio, 0); + } + + usleep_range(10, 10); + + if (pw->dvdd) + regulator_disable(pw->dvdd); + if (pw->iovdd) + regulator_disable(pw->iovdd); + if (pw->avdd) + regulator_disable(pw->avdd); } -power_off_done: pw->state = SWITCH_OFF; return 0; } -static int imx390_power_get(struct tegracam_device *tc_dev) -{ - struct device *dev = tc_dev->dev; - struct camera_common_data *s_data = tc_dev->s_data; - struct camera_common_power_rail *pw = s_data->power; - struct camera_common_pdata *pdata = s_data->pdata; - const char *mclk_name; - const char *parentclk_name; - struct clk *parent; - int err = 0; - - mclk_name = pdata->mclk_name ? - pdata->mclk_name : "cam_mclk1"; - pw->mclk = devm_clk_get(dev, mclk_name); - if (IS_ERR(pw->mclk)) { - dev_err(dev, "unable to get clock %s\n", mclk_name); - return PTR_ERR(pw->mclk); - } - - parentclk_name = pdata->parentclk_name; - if (parentclk_name) { - parent = devm_clk_get(dev, parentclk_name); - if (IS_ERR(parent)) { - dev_err(dev, "unable to get parent clcok %s", - parentclk_name); - } else { - err = clk_set_parent(pw->mclk, parent); - if (err < 0) - dev_dbg(dev, - "%s failed to set parent clock %d\n", - __func__, err); - } - } - - pw->state = SWITCH_OFF; - - return err; -} - static int imx390_power_put(struct tegracam_device *tc_dev) { struct camera_common_data *s_data = tc_dev->s_data; @@ -314,135 +320,89 @@ static int imx390_power_put(struct tegracam_device *tc_dev) if (unlikely(!pw)) return -EFAULT; - return 0; -} + if (likely(pw->dvdd)) + devm_regulator_put(pw->dvdd); -static int imx390_set_group_hold(struct tegracam_device *tc_dev, bool val) -{ - struct camera_common_data *s_data = tc_dev->s_data; - struct device *dev = tc_dev->dev; - int err; + if (likely(pw->avdd)) + devm_regulator_put(pw->avdd); - err = imx390_write_reg(s_data, - IMX390_GROUP_HOLD_ADDR, val); - if (err) { - dev_dbg(dev, - "%s: Group hold control error\n", __func__); - return err; - } + if (likely(pw->iovdd)) + devm_regulator_put(pw->iovdd); + + pw->dvdd = NULL; + pw->avdd = NULL; + pw->iovdd = NULL; + + if (likely(pw->reset_gpio)) + gpio_free(pw->reset_gpio); return 0; } -static int imx390_set_gain(struct tegracam_device *tc_dev, s64 val) +static int imx390_power_get(struct tegracam_device *tc_dev) { - struct camera_common_data *s_data = tc_dev->s_data; struct device *dev = tc_dev->dev; - const struct sensor_mode_properties *mode = - &s_data->sensor_props.sensor_modes[s_data->mode_prop_idx]; - imx390_reg reg_list[4]; - int err, i; - u16 gain; + struct camera_common_data *s_data = tc_dev->s_data; + struct camera_common_power_rail *pw = s_data->power; + struct camera_common_pdata *pdata = s_data->pdata; + struct clk *parent; + int err = 0; - gain = (u16)(val / mode->control_properties.step_gain_val); - - dev_dbg(dev, "%s: db: %d\n", __func__, gain); - - if (gain > IMX390_MAX_GAIN_REG) - gain = IMX390_MAX_GAIN_REG; - - imx390_get_gain_reg(reg_list, gain); - for (i = 0; i < 4; i++) { - err = imx390_write_reg(s_data, reg_list[i].addr, - reg_list[i].val); - if (err) - goto fail; + if (!pdata) { + dev_err(dev, "pdata missing\n"); + return -EFAULT; } - return 0; + /* Sensor MCLK (aka. INCK) */ + if (pdata->mclk_name) { + pw->mclk = devm_clk_get(dev, pdata->mclk_name); + if (IS_ERR(pw->mclk)) { + dev_err(dev, "unable to get clock %s\n", + pdata->mclk_name); + return PTR_ERR(pw->mclk); + } + + if (pdata->parentclk_name) { + parent = devm_clk_get(dev, pdata->parentclk_name); + if (IS_ERR(parent)) { + dev_err(dev, "unable to get parent clock %s", + pdata->parentclk_name); + } else + clk_set_parent(pw->mclk, parent); + } + } + + /* analog 2.8v */ + if (pdata->regulators.avdd) + err |= camera_common_regulator_get(dev, + &pw->avdd, + pdata->regulators.avdd); + /* IO 1.8v */ + if (pdata->regulators.iovdd) + err |= camera_common_regulator_get(dev, + &pw->iovdd, + pdata->regulators.iovdd); + /* dig 1.2v */ + if (pdata->regulators.dvdd) + err |= camera_common_regulator_get(dev, + &pw->dvdd, + pdata->regulators.dvdd); + if (err) + dev_err(dev, "%s: unable to get regulator(s)\n", __func__); -fail: - dev_info(dev, "%s: GAIN control error\n", __func__); return err; } -static int imx390_set_frame_rate(struct tegracam_device *tc_dev, s64 val) -{ - struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); - - /* fixed 30fps */ - priv->frame_length = IMX390_DEFAULT_FRAME_LENGTH; - return 0; -} - -static int imx390_set_exposure(struct tegracam_device *tc_dev, s64 val) -{ - struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); - struct camera_common_data *s_data = tc_dev->s_data; - const struct sensor_mode_properties *mode = - &s_data->sensor_props.sensor_modes[s_data->mode]; - imx390_reg reg_list[3]; - int err; - u32 coarse_time; - u32 shs1; - int i = 0; - - if (priv->frame_length == 0) - priv->frame_length = IMX390_DEFAULT_FRAME_LENGTH; - - /* coarse time in lines */ - coarse_time = (u32) (val * s_data->frmfmt[s_data->mode].framerates[0] * - priv->frame_length / mode->control_properties.exposure_factor); - - shs1 = priv->frame_length - coarse_time; - /* 0 and 1 are prohibited */ - if (shs1 < 2) - shs1 = 2; - - imx390_get_coarse_time_regs_shs1(reg_list, shs1); - for (i = 0; i < 3; i++) { - err = imx390_write_reg(priv->s_data, reg_list[i].addr, - reg_list[i].val); - if (err) - goto fail; - } - - imx390_get_coarse_time_regs_shs2(reg_list, shs1); - for (i = 0; i < 3; i++) { - err = imx390_write_reg(priv->s_data, reg_list[i].addr, - reg_list[i].val); - if (err) - goto fail; - } - - return 0; - -fail: - dev_dbg(&priv->i2c_client->dev, - "%s: set coarse time error\n", __func__); - return err; -} - -static struct tegracam_ctrl_ops imx390_ctrl_ops = { - .numctrls = ARRAY_SIZE(ctrl_cid_list), - .ctrl_cid_list = ctrl_cid_list, - .set_gain = imx390_set_gain, - .set_exposure = imx390_set_exposure, - .set_exposure_short = imx390_set_exposure, - .set_frame_rate = imx390_set_frame_rate, - .set_group_hold = imx390_set_group_hold, -}; - -static struct camera_common_pdata -*imx390_parse_dt(struct tegracam_device *tc_dev) +static struct camera_common_pdata *imx390_parse_dt(struct tegracam_device + *tc_dev) { struct device *dev = tc_dev->dev; - struct device_node *node = dev->of_node; + struct device_node *np = dev->of_node; struct camera_common_pdata *board_priv_pdata; const struct of_device_id *match; - int err; + int err = 0; - if (!node) + if (!np) return NULL; match = of_match_device(imx390_of_match, dev); @@ -452,12 +412,26 @@ static struct camera_common_pdata } board_priv_pdata = devm_kzalloc(dev, - sizeof(*board_priv_pdata), GFP_KERNEL); + sizeof(*board_priv_pdata), GFP_KERNEL); + if (!board_priv_pdata) + return NULL; - err = of_property_read_string(node, "mclk", - &board_priv_pdata->mclk_name); + err = of_property_read_string(np, "mclk", &board_priv_pdata->mclk_name); if (err) - dev_err(dev, "mclk not in DT\n"); + dev_dbg(dev, "mclk name not present, " + "assume sensor driven externally\n"); + + err = of_property_read_string(np, "avdd-reg", + &board_priv_pdata->regulators.avdd); + err |= of_property_read_string(np, "iovdd-reg", + &board_priv_pdata->regulators.iovdd); + err |= of_property_read_string(np, "dvdd-reg", + &board_priv_pdata->regulators.dvdd); + if (err) + dev_dbg(dev, "avdd, iovdd and/or dvdd reglrs. not present, " + "assume sensor powered independently\n"); + + board_priv_pdata->has_eeprom = of_property_read_bool(np, "has-eeprom"); return board_priv_pdata; } @@ -466,62 +440,37 @@ static int imx390_set_mode(struct tegracam_device *tc_dev) { struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); struct camera_common_data *s_data = tc_dev->s_data; - struct device *dev = tc_dev->dev; - const struct of_device_id *match; + int err = 0; - match = of_match_device(imx390_of_match, dev); - if (!match) { - dev_err(dev, "Failed to find matching dt id\n"); - return -EINVAL; + dev_dbg(tc_dev->dev, "%s:\n", __func__); + + err = imx390_write_table(priv, mode_table[s_data->mode]); + if (err) { + dev_err(tc_dev->dev, "%s: sensor write table failed with error %d\n", + __func__, err); + return err; } - if (s_data->mode_prop_idx < 0) - return -EINVAL; - - return imx390_write_table(priv, mode_table[s_data->mode_prop_idx]); + return 0; } static int imx390_start_streaming(struct tegracam_device *tc_dev) { struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); - struct device *dev = tc_dev->dev; - int err; - /* enable serdes streaming */ - err = max9295_setup_streaming(priv->ser_dev); - if (err) - goto exit; - err = max9296_setup_streaming(priv->dser_dev, dev); - if (err) - goto exit; - err = max9296_start_streaming(priv->dser_dev, dev); - if (err) - goto exit; - - err = imx390_write_table(priv, - mode_table[IMX390_MODE_START_STREAM]); - if (err) - return err; - - msleep(20); - - return 0; - -exit: - dev_err(dev, "%s: error setting stream\n", __func__); - - return err; + dev_dbg(tc_dev->dev, "%s:\n", __func__); + return imx390_write_table(priv, mode_table[IMX390_MODE_START_STREAM]); } static int imx390_stop_streaming(struct tegracam_device *tc_dev) { - struct device *dev = tc_dev->dev; + int err; struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); - /* disable serdes streaming */ - max9296_stop_streaming(priv->dser_dev, dev); + dev_dbg(tc_dev->dev, "%s:\n", __func__); + err = imx390_write_table(priv, mode_table[IMX390_MODE_STOP_STREAM]); - return imx390_write_table(priv, mode_table[IMX390_MODE_STOP_STREAM]); + return err; } static struct camera_common_sensor_ops imx390_common_ops = { @@ -539,6 +488,21 @@ static struct camera_common_sensor_ops imx390_common_ops = { .stop_streaming = imx390_stop_streaming, }; +static int imx390_board_setup(struct imx390 *priv) +{ + struct camera_common_data *s_data = priv->s_data; + struct device *dev = s_data->dev; + int err = 0; + + /* Skip mclk enable as this camera has an internal oscillator */ + + err = imx390_power_on(s_data); + if (err) + dev_err(dev, "error during power on sensor (%d)\n", err); + + return err; +} + static int imx390_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -552,238 +516,30 @@ static const struct v4l2_subdev_internal_ops imx390_subdev_internal_ops = { .open = imx390_open, }; -static int imx390_board_setup(struct imx390 *priv) -{ - struct tegracam_device *tc_dev = priv->tc_dev; - struct device *dev = tc_dev->dev; - struct device_node *node = dev->of_node; - struct device_node *ser_node; - struct i2c_client *ser_i2c = NULL; - struct device_node *dser_node; - struct i2c_client *dser_i2c = NULL; - struct device_node *gmsl; - int value = 0xFFFF; - const char *str_value; - const char *str_value1[2]; - int i; - int err; - - err = of_property_read_u32(node, "reg", &priv->g_ctx.sdev_reg); - if (err < 0) { - dev_err(dev, "reg not found\n"); - goto error; - } - - err = of_property_read_u32(node, "def-addr", - &priv->g_ctx.sdev_def); - if (err < 0) { - dev_err(dev, "def-addr not found\n"); - goto error; - } - - ser_node = of_parse_phandle(node, "nvidia,gmsl-ser-device", 0); - if (ser_node == NULL) { - dev_err(dev, - "missing %s handle\n", - "nvidia,gmsl-ser-device"); - err = -EINVAL; - goto error; - } - - err = of_property_read_u32(ser_node, "reg", &priv->g_ctx.ser_reg); - if (err < 0) { - dev_err(dev, "serializer reg not found\n"); - goto error; - } - - ser_i2c = of_find_i2c_device_by_node(ser_node); - of_node_put(ser_node); - - if (ser_i2c == NULL) { - err = -EPROBE_DEFER; - goto error; - } - if (ser_i2c->dev.driver == NULL) { - dev_err(dev, "missing serializer driver\n"); - err = -EINVAL; - goto error; - } - - priv->ser_dev = &ser_i2c->dev; - - dser_node = of_parse_phandle(node, "nvidia,gmsl-dser-device", 0); - if (dser_node == NULL) { - dev_err(dev, - "missing %s handle\n", - "nvidia,gmsl-dser-device"); - err = -EINVAL; - goto error; - } - - dser_i2c = of_find_i2c_device_by_node(dser_node); - of_node_put(dser_node); - - if (dser_i2c == NULL) { - err = -EPROBE_DEFER; - goto error; - } - if (dser_i2c->dev.driver == NULL) { - dev_err(dev, "missing deserializer driver\n"); - err = -EINVAL; - goto error; - } - - priv->dser_dev = &dser_i2c->dev; - - /* populate g_ctx from DT */ - gmsl = of_get_child_by_name(node, "gmsl-link"); - if (gmsl == NULL) { - dev_err(dev, "missing gmsl-link device node\n"); - err = -EINVAL; - goto error; - } - - err = of_property_read_string(gmsl, "dst-csi-port", &str_value); - if (err < 0) { - dev_err(dev, "No dst-csi-port found\n"); - goto error; - } - priv->g_ctx.dst_csi_port = - (!strcmp(str_value, "a")) ? GMSL_CSI_PORT_A : GMSL_CSI_PORT_B; - - err = of_property_read_string(gmsl, "src-csi-port", &str_value); - if (err < 0) { - dev_err(dev, "No src-csi-port found\n"); - goto error; - } - priv->g_ctx.src_csi_port = - (!strcmp(str_value, "a")) ? GMSL_CSI_PORT_A : GMSL_CSI_PORT_B; - - err = of_property_read_string(gmsl, "csi-mode", &str_value); - if (err < 0) { - dev_err(dev, "No csi-mode found\n"); - goto error; - } - - if (!strcmp(str_value, "1x4")) { - priv->g_ctx.csi_mode = GMSL_CSI_1X4_MODE; - } else if (!strcmp(str_value, "2x4")) { - priv->g_ctx.csi_mode = GMSL_CSI_2X4_MODE; - } else if (!strcmp(str_value, "4x2")) { - priv->g_ctx.csi_mode = GMSL_CSI_4X2_MODE; - } else if (!strcmp(str_value, "2x2")) { - priv->g_ctx.csi_mode = GMSL_CSI_2X2_MODE; - } else { - dev_err(dev, "invalid csi mode\n"); - err = -EINVAL; - goto error; - } - - err = of_property_read_string(gmsl, "serdes-csi-link", &str_value); - if (err < 0) { - dev_err(dev, "No serdes-csi-link found\n"); - goto error; - } - priv->g_ctx.serdes_csi_link = - (!strcmp(str_value, "a")) ? - GMSL_SERDES_CSI_LINK_A : GMSL_SERDES_CSI_LINK_B; - - err = of_property_read_u32(gmsl, "st-vc", &value); - if (err < 0) { - dev_err(dev, "No st-vc info\n"); - goto error; - } - priv->g_ctx.st_vc = value; - - err = of_property_read_u32(gmsl, "vc-id", &value); - if (err < 0) { - dev_err(dev, "No vc-id info\n"); - goto error; - } - priv->g_ctx.dst_vc = value; - - err = of_property_read_u32(gmsl, "num-lanes", &value); - if (err < 0) { - dev_err(dev, "No num-lanes info\n"); - goto error; - } - priv->g_ctx.num_csi_lanes = value; - - priv->g_ctx.num_streams = - of_property_count_strings(gmsl, "streams"); - if (priv->g_ctx.num_streams <= 0) { - dev_err(dev, "No streams found\n"); - err = -EINVAL; - goto error; - } - - for (i = 0; i < priv->g_ctx.num_streams; i++) { - err = of_property_read_string_index(gmsl, "streams", i, - &str_value1[i]); - if (err < 0) { - dev_err(dev, "Failed to get streams index\n"); - goto error; - } - - if (!str_value1[i]) { - dev_err(dev, "invalid stream info\n"); - err = -EINVAL; - goto error; - } - if (!strcmp(str_value1[i], "raw12")) { - priv->g_ctx.streams[i].st_data_type = - GMSL_CSI_DT_RAW_12; - } else if (!strcmp(str_value1[i], "embed")) { - priv->g_ctx.streams[i].st_data_type = - GMSL_CSI_DT_EMBED; - } else if (!strcmp(str_value1[i], "ued-u1")) { - priv->g_ctx.streams[i].st_data_type = - GMSL_CSI_DT_UED_U1; - } else { - dev_err(dev, "invalid stream data type\n"); - err = -EINVAL; - goto error; - } - } - - priv->g_ctx.s_dev = dev; - - return 0; - -error: - return err; -} - -#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */ -static int imx390_probe(struct i2c_client *client) -#else static int imx390_probe(struct i2c_client *client, - const struct i2c_device_id *id) -#endif + const struct i2c_device_id *id) { struct device *dev = &client->dev; - struct device_node *node = dev->of_node; struct tegracam_device *tc_dev; struct imx390 *priv; int err; - dev_info(dev, "probing v4l2 sensor.\n"); + dev_dbg(dev, "probing v4l2 sensor at addr 0x%0x\n", client->addr); - if (!IS_ENABLED(CONFIG_OF) || !node) + if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) return -EINVAL; priv = devm_kzalloc(dev, sizeof(struct imx390), GFP_KERNEL); if (!priv) return -ENOMEM; - tc_dev = devm_kzalloc(dev, - sizeof(struct tegracam_device), GFP_KERNEL); + tc_dev = devm_kzalloc(dev, sizeof(struct tegracam_device), GFP_KERNEL); if (!tc_dev) return -ENOMEM; priv->i2c_client = tc_dev->client = client; tc_dev->dev = dev; - strscpy(tc_dev->name, "imx390", sizeof(tc_dev->name)); + strncpy(tc_dev->name, "imx390", sizeof(tc_dev->name)); tc_dev->dev_regmap_config = &sensor_regmap_config; tc_dev->sensor_ops = &imx390_common_ops; tc_dev->v4l2sd_internal_ops = &imx390_subdev_internal_ops; @@ -794,102 +550,43 @@ static int imx390_probe(struct i2c_client *client, dev_err(dev, "tegra camera driver registration failed\n"); return err; } - priv->tc_dev = tc_dev; priv->s_data = tc_dev->s_data; priv->subdev = &tc_dev->s_data->subdev; - tegracam_set_privdata(tc_dev, (void *)priv); err = imx390_board_setup(priv); if (err) { - tegracam_device_unregister(tc_dev); dev_err(dev, "board setup failed\n"); return err; } - mutex_init(&serdes_lock__); - - /* Pair sensor to serializer dev */ - err = max9295_sdev_pair(priv->ser_dev, &priv->g_ctx); - if (err) { - dev_err(&client->dev, "gmsl ser pairing failed\n"); - return err; - } - - /* Register sensor to deserializer dev */ - err = max9296_sdev_register(priv->dser_dev, &priv->g_ctx); - if (err) { - dev_err(&client->dev, "gmsl deserializer register failed\n"); - return err; - } - - /* - * gmsl serdes setup - * - * Sensor power on/off should be the right place for serdes - * setup/reset. But the problem is, the total required delay - * in serdes setup/reset exceeds the frame wait timeout, looks to - * be related to multiple channel open and close sequence - * issue (#BUG 200477330). - * Once this bug is fixed, these may be moved to power on/off. - * The delays in serdes is as per guidelines and can't be reduced, - * so it is placed in probe/remove, though for that, deserializer - * would be powered on always post boot, until 1.2v is supplied - * to deserializer from CVB. - */ - err = imx390_gmsl_serdes_setup(priv); - if (err) { - dev_err(&client->dev, - "%s gmsl serdes setup failed\n", __func__); - return err; - } - err = tegracam_v4l2subdev_register(tc_dev, true); if (err) { dev_err(dev, "tegra camera subdev registration failed\n"); return err; } - dev_info(&client->dev, "Detected IMX390 sensor\n"); + dev_dbg(dev, "detected imx390 sensor\n"); return 0; } -#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */ static int imx390_remove(struct i2c_client *client) -#else -static void imx390_remove(struct i2c_client *client) -#endif { struct camera_common_data *s_data = to_camera_common_data(&client->dev); - struct imx390 *priv; + struct imx390 *priv = (struct imx390 *)s_data->priv; - if (!s_data) -#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */ - return -EINVAL; -#else - return; -#endif - - priv = (struct imx390 *)s_data->priv; - - imx390_gmsl_serdes_reset(priv); - - mutex_destroy(&serdes_lock__); tegracam_v4l2subdev_unregister(priv->tc_dev); tegracam_device_unregister(priv->tc_dev); -#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */ return 0; -#endif } static const struct i2c_device_id imx390_id[] = { - { "imx390", 0 }, - { } + {"imx390", 0}, + {} }; - MODULE_DEVICE_TABLE(i2c, imx390_id); static struct i2c_driver imx390_i2c_driver = { @@ -907,5 +604,4 @@ module_i2c_driver(imx390_i2c_driver); MODULE_DESCRIPTION("Media Controller driver for Sony IMX390"); MODULE_AUTHOR("NVIDIA Corporation"); -MODULE_AUTHOR("Sudhir Vyas + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include "imx390_mode_tbls.h" + +#define IMX390_MIN_GAIN (0) +#define IMX390_MAX_GAIN (30) +#define IMX390_MAX_GAIN_REG ((IMX390_MAX_GAIN - IMX390_MIN_GAIN) * 10 / 3) +#define IMX390_DEFAULT_FRAME_LENGTH (1125) +#define IMX390_FRAME_LENGTH_ADDR_MSB 0x200A +#define IMX390_FRAME_LENGTH_ADDR_MID 0x2009 +#define IMX390_FRAME_LENGTH_ADDR_LSB 0x2008 +#define IMX390_COARSE_TIME_SHS1_ADDR_MSB 0x000E +#define IMX390_COARSE_TIME_SHS1_ADDR_MID 0x000D +#define IMX390_COARSE_TIME_SHS1_ADDR_LSB 0x000C +#define IMX390_COARSE_TIME_SHS2_ADDR_MSB 0x0012 +#define IMX390_COARSE_TIME_SHS2_ADDR_MID 0x0011 +#define IMX390_COARSE_TIME_SHS2_ADDR_LSB 0x0010 +#define IMX390_GROUP_HOLD_ADDR 0x0008 +#define IMX390_ANALOG_GAIN_SP1H_ADDR 0x0018 +#define IMX390_ANALOG_GAIN_SP1L_ADDR 0x001A + +static const struct of_device_id imx390_of_match[] = { + { .compatible = "sony,imx390",}, + { }, +}; +MODULE_DEVICE_TABLE(of, imx390_of_match); + +static const u32 ctrl_cid_list[] = { + TEGRA_CAMERA_CID_GAIN, + TEGRA_CAMERA_CID_EXPOSURE, + TEGRA_CAMERA_CID_EXPOSURE_SHORT, + TEGRA_CAMERA_CID_FRAME_RATE, + TEGRA_CAMERA_CID_HDR_EN, +}; + +struct imx390 { + struct i2c_client *i2c_client; + const struct i2c_device_id *id; + struct v4l2_subdev *subdev; + struct device *ser_dev; + struct device *dser_dev; + struct gmsl_link_ctx g_ctx; + u32 frame_length; + struct camera_common_data *s_data; + struct tegracam_device *tc_dev; +}; + +static const struct regmap_config sensor_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, +}; + +static inline void imx390_get_frame_length_regs(imx390_reg *regs, + u32 frame_length) +{ + regs->addr = IMX390_FRAME_LENGTH_ADDR_MSB; + regs->val = (frame_length >> 16) & 0x01; + + (regs + 1)->addr = IMX390_FRAME_LENGTH_ADDR_MID; + (regs + 1)->val = (frame_length >> 8) & 0xff; + + (regs + 2)->addr = IMX390_FRAME_LENGTH_ADDR_LSB; + (regs + 2)->val = (frame_length) & 0xff; +} + +static inline void imx390_get_coarse_time_regs_shs1(imx390_reg *regs, + u32 coarse_time) +{ + regs->addr = IMX390_COARSE_TIME_SHS1_ADDR_MSB; + regs->val = (coarse_time >> 16) & 0x0f; + + (regs + 1)->addr = IMX390_COARSE_TIME_SHS1_ADDR_MID; + (regs + 1)->val = (coarse_time >> 8) & 0xff; + + (regs + 2)->addr = IMX390_COARSE_TIME_SHS1_ADDR_LSB; + (regs + 2)->val = (coarse_time) & 0xff; +} + +static inline void imx390_get_coarse_time_regs_shs2(imx390_reg *regs, + u32 coarse_time) +{ + regs->addr = IMX390_COARSE_TIME_SHS2_ADDR_MSB; + regs->val = (coarse_time >> 16) & 0x0f; + + (regs + 1)->addr = IMX390_COARSE_TIME_SHS2_ADDR_MID; + (regs + 1)->val = (coarse_time >> 8) & 0xff; + + (regs + 2)->addr = IMX390_COARSE_TIME_SHS2_ADDR_LSB; + (regs + 2)->val = (coarse_time) & 0xff; +} + +static inline void imx390_get_gain_reg(imx390_reg *regs, + u16 gain) +{ + regs->addr = IMX390_ANALOG_GAIN_SP1H_ADDR; + regs->val = (gain) & 0xff; + + (regs + 1)->addr = IMX390_ANALOG_GAIN_SP1H_ADDR + 1; + (regs + 1)->val = (gain >> 8) & 0xff; + + (regs + 2)->addr = IMX390_ANALOG_GAIN_SP1L_ADDR; + (regs + 2)->val = (gain) & 0xff; + + (regs + 3)->addr = IMX390_ANALOG_GAIN_SP1L_ADDR + 1; + (regs + 3)->val = (gain >> 8) & 0xff; +} + + +static int test_mode; +module_param(test_mode, int, 0644); + +static inline int imx390_read_reg(struct camera_common_data *s_data, + u16 addr, u8 *val) +{ + int err = 0; + u32 reg_val = 0; + + err = regmap_read(s_data->regmap, addr, ®_val); + *val = reg_val & 0xFF; + + return err; +} + +static int imx390_write_reg(struct camera_common_data *s_data, + u16 addr, u8 val) +{ + int err; + struct device *dev = s_data->dev; + + err = regmap_write(s_data->regmap, addr, val); + if (err) + dev_err(dev, "%s:i2c write failed, 0x%x = %x\n", + __func__, addr, val); + + return err; +} + +static int imx390_write_table(struct imx390 *priv, + const imx390_reg table[]) +{ + struct camera_common_data *s_data = priv->s_data; + + return regmap_util_write_table_8(s_data->regmap, + table, + NULL, 0, + IMX390_TABLE_WAIT_MS, + IMX390_TABLE_END); +} + +static struct mutex serdes_lock__; + +static int imx390_gmsl_serdes_setup(struct imx390 *priv) +{ + int err = 0; + int des_err = 0; + struct device *dev; + + if (!priv || !priv->ser_dev || !priv->dser_dev || !priv->i2c_client) + return -EINVAL; + + dev = &priv->i2c_client->dev; + + mutex_lock(&serdes_lock__); + + /* For now no separate power on required for serializer device */ + max9296_power_on(priv->dser_dev); + + /* setup serdes addressing and control pipeline */ + err = max9296_setup_link(priv->dser_dev, &priv->i2c_client->dev); + if (err) { + dev_err(dev, "gmsl deserializer link config failed\n"); + goto error; + } + + err = max9295_setup_control(priv->ser_dev); + + /* proceed even if ser setup failed, to setup deser correctly */ + if (err) + dev_err(dev, "gmsl serializer setup failed\n"); + + des_err = max9296_setup_control(priv->dser_dev, &priv->i2c_client->dev); + if (des_err) { + dev_err(dev, "gmsl deserializer setup failed\n"); + /* overwrite err only if deser setup also failed */ + err = des_err; + } + +error: + mutex_unlock(&serdes_lock__); + return err; +} + +static void imx390_gmsl_serdes_reset(struct imx390 *priv) +{ + mutex_lock(&serdes_lock__); + + /* reset serdes addressing and control pipeline */ + max9295_reset_control(priv->ser_dev); + max9296_reset_control(priv->dser_dev, &priv->i2c_client->dev); + + max9296_power_off(priv->dser_dev); + + mutex_unlock(&serdes_lock__); +} + +static int imx390_power_on(struct camera_common_data *s_data) +{ + int err = 0; + struct camera_common_power_rail *pw = s_data->power; + struct camera_common_pdata *pdata = s_data->pdata; + struct device *dev = s_data->dev; + + dev_dbg(dev, "%s: power on\n", __func__); + if (pdata && pdata->power_on) { + err = pdata->power_on(pw); + if (err) + dev_err(dev, "%s failed.\n", __func__); + else + pw->state = SWITCH_ON; + return err; + } + + pw->state = SWITCH_ON; + + return 0; +} + +static int imx390_power_off(struct camera_common_data *s_data) +{ + int err = 0; + struct camera_common_power_rail *pw = s_data->power; + struct camera_common_pdata *pdata = s_data->pdata; + struct device *dev = s_data->dev; + + dev_dbg(dev, "%s:\n", __func__); + + if (pdata && pdata->power_off) { + err = pdata->power_off(pw); + if (!err) + goto power_off_done; + else + dev_err(dev, "%s failed.\n", __func__); + return err; + } + +power_off_done: + pw->state = SWITCH_OFF; + + return 0; +} + +static int imx390_power_get(struct tegracam_device *tc_dev) +{ + struct device *dev = tc_dev->dev; + struct camera_common_data *s_data = tc_dev->s_data; + struct camera_common_power_rail *pw = s_data->power; + struct camera_common_pdata *pdata = s_data->pdata; + const char *mclk_name; + const char *parentclk_name; + struct clk *parent; + int err = 0; + + mclk_name = pdata->mclk_name ? + pdata->mclk_name : "cam_mclk1"; + pw->mclk = devm_clk_get(dev, mclk_name); + if (IS_ERR(pw->mclk)) { + dev_err(dev, "unable to get clock %s\n", mclk_name); + return PTR_ERR(pw->mclk); + } + + parentclk_name = pdata->parentclk_name; + if (parentclk_name) { + parent = devm_clk_get(dev, parentclk_name); + if (IS_ERR(parent)) { + dev_err(dev, "unable to get parent clcok %s", + parentclk_name); + } else { + err = clk_set_parent(pw->mclk, parent); + if (err < 0) + dev_dbg(dev, + "%s failed to set parent clock %d\n", + __func__, err); + } + } + + pw->state = SWITCH_OFF; + + return err; +} + +static int imx390_power_put(struct tegracam_device *tc_dev) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct camera_common_power_rail *pw = s_data->power; + + if (unlikely(!pw)) + return -EFAULT; + + return 0; +} + +static int imx390_set_group_hold(struct tegracam_device *tc_dev, bool val) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct device *dev = tc_dev->dev; + int err; + + err = imx390_write_reg(s_data, + IMX390_GROUP_HOLD_ADDR, val); + if (err) { + dev_dbg(dev, + "%s: Group hold control error\n", __func__); + return err; + } + + return 0; +} + +static int imx390_set_gain(struct tegracam_device *tc_dev, s64 val) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct device *dev = tc_dev->dev; + const struct sensor_mode_properties *mode = + &s_data->sensor_props.sensor_modes[s_data->mode_prop_idx]; + imx390_reg reg_list[4]; + int err, i; + u16 gain; + + gain = (u16)(val / mode->control_properties.step_gain_val); + + dev_dbg(dev, "%s: db: %d\n", __func__, gain); + + if (gain > IMX390_MAX_GAIN_REG) + gain = IMX390_MAX_GAIN_REG; + + imx390_get_gain_reg(reg_list, gain); + for (i = 0; i < 4; i++) { + err = imx390_write_reg(s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_info(dev, "%s: GAIN control error\n", __func__); + return err; +} + +static int imx390_set_frame_rate(struct tegracam_device *tc_dev, s64 val) +{ + struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); + + /* fixed 30fps */ + priv->frame_length = IMX390_DEFAULT_FRAME_LENGTH; + return 0; +} + +static int imx390_set_exposure(struct tegracam_device *tc_dev, s64 val) +{ + struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); + struct camera_common_data *s_data = tc_dev->s_data; + const struct sensor_mode_properties *mode = + &s_data->sensor_props.sensor_modes[s_data->mode]; + imx390_reg reg_list[3]; + int err; + u32 coarse_time; + u32 shs1; + int i = 0; + + if (priv->frame_length == 0) + priv->frame_length = IMX390_DEFAULT_FRAME_LENGTH; + + /* coarse time in lines */ + coarse_time = (u32) (val * s_data->frmfmt[s_data->mode].framerates[0] * + priv->frame_length / mode->control_properties.exposure_factor); + + shs1 = priv->frame_length - coarse_time; + /* 0 and 1 are prohibited */ + if (shs1 < 2) + shs1 = 2; + + imx390_get_coarse_time_regs_shs1(reg_list, shs1); + for (i = 0; i < 3; i++) { + err = imx390_write_reg(priv->s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + imx390_get_coarse_time_regs_shs2(reg_list, shs1); + for (i = 0; i < 3; i++) { + err = imx390_write_reg(priv->s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(&priv->i2c_client->dev, + "%s: set coarse time error\n", __func__); + return err; +} + +static struct tegracam_ctrl_ops imx390_ctrl_ops = { + .numctrls = ARRAY_SIZE(ctrl_cid_list), + .ctrl_cid_list = ctrl_cid_list, + .set_gain = imx390_set_gain, + .set_exposure = imx390_set_exposure, + .set_exposure_short = imx390_set_exposure, + .set_frame_rate = imx390_set_frame_rate, + .set_group_hold = imx390_set_group_hold, +}; + +static struct camera_common_pdata +*imx390_parse_dt(struct tegracam_device *tc_dev) +{ + struct device *dev = tc_dev->dev; + struct device_node *node = dev->of_node; + struct camera_common_pdata *board_priv_pdata; + const struct of_device_id *match; + int err; + + if (!node) + return NULL; + + match = of_match_device(imx390_of_match, dev); + if (!match) { + dev_err(dev, "Failed to find matching dt id\n"); + return NULL; + } + + board_priv_pdata = devm_kzalloc(dev, + sizeof(*board_priv_pdata), GFP_KERNEL); + + err = of_property_read_string(node, "mclk", + &board_priv_pdata->mclk_name); + if (err) + dev_err(dev, "mclk not in DT\n"); + + return board_priv_pdata; +} + +static int imx390_set_mode(struct tegracam_device *tc_dev) +{ + struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); + struct camera_common_data *s_data = tc_dev->s_data; + struct device *dev = tc_dev->dev; + const struct of_device_id *match; + + match = of_match_device(imx390_of_match, dev); + if (!match) { + dev_err(dev, "Failed to find matching dt id\n"); + return -EINVAL; + } + + if (s_data->mode_prop_idx < 0) + return -EINVAL; + + return imx390_write_table(priv, mode_table[s_data->mode_prop_idx]); +} + +static int imx390_start_streaming(struct tegracam_device *tc_dev) +{ + struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); + struct device *dev = tc_dev->dev; + int err; + + /* enable serdes streaming */ + err = max9295_setup_streaming(priv->ser_dev); + if (err) + goto exit; + err = max9296_setup_streaming(priv->dser_dev, dev); + if (err) + goto exit; + err = max9296_start_streaming(priv->dser_dev, dev); + if (err) + goto exit; + + err = imx390_write_table(priv, + mode_table[IMX390_MODE_START_STREAM]); + if (err) + return err; + + msleep(20); + + return 0; + +exit: + dev_err(dev, "%s: error setting stream\n", __func__); + + return err; +} + +static int imx390_stop_streaming(struct tegracam_device *tc_dev) +{ + struct device *dev = tc_dev->dev; + struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev); + + /* disable serdes streaming */ + max9296_stop_streaming(priv->dser_dev, dev); + + return imx390_write_table(priv, mode_table[IMX390_MODE_STOP_STREAM]); +} + +static struct camera_common_sensor_ops imx390_common_ops = { + .numfrmfmts = ARRAY_SIZE(imx390_frmfmt), + .frmfmt_table = imx390_frmfmt, + .power_on = imx390_power_on, + .power_off = imx390_power_off, + .write_reg = imx390_write_reg, + .read_reg = imx390_read_reg, + .parse_dt = imx390_parse_dt, + .power_get = imx390_power_get, + .power_put = imx390_power_put, + .set_mode = imx390_set_mode, + .start_streaming = imx390_start_streaming, + .stop_streaming = imx390_stop_streaming, +}; + +static int imx390_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + dev_dbg(&client->dev, "%s:\n", __func__); + + return 0; +} + +static const struct v4l2_subdev_internal_ops imx390_subdev_internal_ops = { + .open = imx390_open, +}; + +static int imx390_board_setup(struct imx390 *priv) +{ + struct tegracam_device *tc_dev = priv->tc_dev; + struct device *dev = tc_dev->dev; + struct device_node *node = dev->of_node; + struct device_node *ser_node; + struct i2c_client *ser_i2c = NULL; + struct device_node *dser_node; + struct i2c_client *dser_i2c = NULL; + struct device_node *gmsl; + int value = 0xFFFF; + const char *str_value; + const char *str_value1[2]; + int i; + int err; + + err = of_property_read_u32(node, "reg", &priv->g_ctx.sdev_reg); + if (err < 0) { + dev_err(dev, "reg not found\n"); + goto error; + } + + err = of_property_read_u32(node, "def-addr", + &priv->g_ctx.sdev_def); + if (err < 0) { + dev_err(dev, "def-addr not found\n"); + goto error; + } + + ser_node = of_parse_phandle(node, "nvidia,gmsl-ser-device", 0); + if (ser_node == NULL) { + dev_err(dev, + "missing %s handle\n", + "nvidia,gmsl-ser-device"); + err = -EINVAL; + goto error; + } + + err = of_property_read_u32(ser_node, "reg", &priv->g_ctx.ser_reg); + if (err < 0) { + dev_err(dev, "serializer reg not found\n"); + goto error; + } + + ser_i2c = of_find_i2c_device_by_node(ser_node); + of_node_put(ser_node); + + if (ser_i2c == NULL) { + err = -EPROBE_DEFER; + goto error; + } + if (ser_i2c->dev.driver == NULL) { + dev_err(dev, "missing serializer driver\n"); + err = -EINVAL; + goto error; + } + + priv->ser_dev = &ser_i2c->dev; + + dser_node = of_parse_phandle(node, "nvidia,gmsl-dser-device", 0); + if (dser_node == NULL) { + dev_err(dev, + "missing %s handle\n", + "nvidia,gmsl-dser-device"); + err = -EINVAL; + goto error; + } + + dser_i2c = of_find_i2c_device_by_node(dser_node); + of_node_put(dser_node); + + if (dser_i2c == NULL) { + err = -EPROBE_DEFER; + goto error; + } + if (dser_i2c->dev.driver == NULL) { + dev_err(dev, "missing deserializer driver\n"); + err = -EINVAL; + goto error; + } + + priv->dser_dev = &dser_i2c->dev; + + /* populate g_ctx from DT */ + gmsl = of_get_child_by_name(node, "gmsl-link"); + if (gmsl == NULL) { + dev_err(dev, "missing gmsl-link device node\n"); + err = -EINVAL; + goto error; + } + + err = of_property_read_string(gmsl, "dst-csi-port", &str_value); + if (err < 0) { + dev_err(dev, "No dst-csi-port found\n"); + goto error; + } + priv->g_ctx.dst_csi_port = + (!strcmp(str_value, "a")) ? GMSL_CSI_PORT_A : GMSL_CSI_PORT_B; + + err = of_property_read_string(gmsl, "src-csi-port", &str_value); + if (err < 0) { + dev_err(dev, "No src-csi-port found\n"); + goto error; + } + priv->g_ctx.src_csi_port = + (!strcmp(str_value, "a")) ? GMSL_CSI_PORT_A : GMSL_CSI_PORT_B; + + err = of_property_read_string(gmsl, "csi-mode", &str_value); + if (err < 0) { + dev_err(dev, "No csi-mode found\n"); + goto error; + } + + if (!strcmp(str_value, "1x4")) { + priv->g_ctx.csi_mode = GMSL_CSI_1X4_MODE; + } else if (!strcmp(str_value, "2x4")) { + priv->g_ctx.csi_mode = GMSL_CSI_2X4_MODE; + } else if (!strcmp(str_value, "4x2")) { + priv->g_ctx.csi_mode = GMSL_CSI_4X2_MODE; + } else if (!strcmp(str_value, "2x2")) { + priv->g_ctx.csi_mode = GMSL_CSI_2X2_MODE; + } else { + dev_err(dev, "invalid csi mode\n"); + err = -EINVAL; + goto error; + } + + err = of_property_read_string(gmsl, "serdes-csi-link", &str_value); + if (err < 0) { + dev_err(dev, "No serdes-csi-link found\n"); + goto error; + } + priv->g_ctx.serdes_csi_link = + (!strcmp(str_value, "a")) ? + GMSL_SERDES_CSI_LINK_A : GMSL_SERDES_CSI_LINK_B; + + err = of_property_read_u32(gmsl, "st-vc", &value); + if (err < 0) { + dev_err(dev, "No st-vc info\n"); + goto error; + } + priv->g_ctx.st_vc = value; + + err = of_property_read_u32(gmsl, "vc-id", &value); + if (err < 0) { + dev_err(dev, "No vc-id info\n"); + goto error; + } + priv->g_ctx.dst_vc = value; + + err = of_property_read_u32(gmsl, "num-lanes", &value); + if (err < 0) { + dev_err(dev, "No num-lanes info\n"); + goto error; + } + priv->g_ctx.num_csi_lanes = value; + + priv->g_ctx.num_streams = + of_property_count_strings(gmsl, "streams"); + if (priv->g_ctx.num_streams <= 0) { + dev_err(dev, "No streams found\n"); + err = -EINVAL; + goto error; + } + + for (i = 0; i < priv->g_ctx.num_streams; i++) { + err = of_property_read_string_index(gmsl, "streams", i, + &str_value1[i]); + if (err < 0) { + dev_err(dev, "Failed to get streams index\n"); + goto error; + } + + if (!str_value1[i]) { + dev_err(dev, "invalid stream info\n"); + err = -EINVAL; + goto error; + } + if (!strcmp(str_value1[i], "raw12")) { + priv->g_ctx.streams[i].st_data_type = + GMSL_CSI_DT_RAW_12; + } else if (!strcmp(str_value1[i], "embed")) { + priv->g_ctx.streams[i].st_data_type = + GMSL_CSI_DT_EMBED; + } else if (!strcmp(str_value1[i], "ued-u1")) { + priv->g_ctx.streams[i].st_data_type = + GMSL_CSI_DT_UED_U1; + } else { + dev_err(dev, "invalid stream data type\n"); + err = -EINVAL; + goto error; + } + } + + priv->g_ctx.s_dev = dev; + + return 0; + +error: + return err; +} + +#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */ +static int imx390_probe(struct i2c_client *client) +#else +static int imx390_probe(struct i2c_client *client, + const struct i2c_device_id *id) +#endif +{ + struct device *dev = &client->dev; + struct device_node *node = dev->of_node; + struct tegracam_device *tc_dev; + struct imx390 *priv; + int err; + + dev_info(dev, "probing v4l2 sensor.\n"); + + if (!IS_ENABLED(CONFIG_OF) || !node) + return -EINVAL; + + priv = devm_kzalloc(dev, sizeof(struct imx390), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + tc_dev = devm_kzalloc(dev, + sizeof(struct tegracam_device), GFP_KERNEL); + if (!tc_dev) + return -ENOMEM; + + priv->i2c_client = tc_dev->client = client; + tc_dev->dev = dev; + strscpy(tc_dev->name, "imx390", sizeof(tc_dev->name)); + tc_dev->dev_regmap_config = &sensor_regmap_config; + tc_dev->sensor_ops = &imx390_common_ops; + tc_dev->v4l2sd_internal_ops = &imx390_subdev_internal_ops; + tc_dev->tcctrl_ops = &imx390_ctrl_ops; + + err = tegracam_device_register(tc_dev); + if (err) { + dev_err(dev, "tegra camera driver registration failed\n"); + return err; + } + + priv->tc_dev = tc_dev; + priv->s_data = tc_dev->s_data; + priv->subdev = &tc_dev->s_data->subdev; + + tegracam_set_privdata(tc_dev, (void *)priv); + + err = imx390_board_setup(priv); + if (err) { + tegracam_device_unregister(tc_dev); + dev_err(dev, "board setup failed\n"); + return err; + } + + mutex_init(&serdes_lock__); + + /* Pair sensor to serializer dev */ + err = max9295_sdev_pair(priv->ser_dev, &priv->g_ctx); + if (err) { + dev_err(&client->dev, "gmsl ser pairing failed\n"); + return err; + } + + /* Register sensor to deserializer dev */ + err = max9296_sdev_register(priv->dser_dev, &priv->g_ctx); + if (err) { + dev_err(&client->dev, "gmsl deserializer register failed\n"); + return err; + } + + /* + * gmsl serdes setup + * + * Sensor power on/off should be the right place for serdes + * setup/reset. But the problem is, the total required delay + * in serdes setup/reset exceeds the frame wait timeout, looks to + * be related to multiple channel open and close sequence + * issue (#BUG 200477330). + * Once this bug is fixed, these may be moved to power on/off. + * The delays in serdes is as per guidelines and can't be reduced, + * so it is placed in probe/remove, though for that, deserializer + * would be powered on always post boot, until 1.2v is supplied + * to deserializer from CVB. + */ + err = imx390_gmsl_serdes_setup(priv); + if (err) { + dev_err(&client->dev, + "%s gmsl serdes setup failed\n", __func__); + return err; + } + + err = tegracam_v4l2subdev_register(tc_dev, true); + if (err) { + dev_err(dev, "tegra camera subdev registration failed\n"); + return err; + } + + dev_info(&client->dev, "Detected IMX390 sensor\n"); + + return 0; +} + +#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */ +static int imx390_remove(struct i2c_client *client) +#else +static void imx390_remove(struct i2c_client *client) +#endif +{ + struct camera_common_data *s_data = to_camera_common_data(&client->dev); + struct imx390 *priv; + + if (!s_data) +#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */ + return -EINVAL; +#else + return; +#endif + + priv = (struct imx390 *)s_data->priv; + + imx390_gmsl_serdes_reset(priv); + + mutex_destroy(&serdes_lock__); + tegracam_v4l2subdev_unregister(priv->tc_dev); + tegracam_device_unregister(priv->tc_dev); + +#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */ + return 0; +#endif +} + +static const struct i2c_device_id imx390_id[] = { + { "imx390", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, imx390_id); + +static struct i2c_driver imx390_i2c_driver = { + .driver = { + .name = "imx390", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(imx390_of_match), + }, + .probe = imx390_probe, + .remove = imx390_remove, + .id_table = imx390_id, +}; + +module_i2c_driver(imx390_i2c_driver); + +MODULE_DESCRIPTION("Media Controller driver for Sony IMX390"); +MODULE_AUTHOR("NVIDIA Corporation"); +MODULE_AUTHOR("Sudhir Vyas