2022-01-11 16:08:27 +01:00
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022 Intel Corporation.
# include <asm/unaligned.h>
# include <linux/acpi.h>
# include <linux/delay.h>
# include <linux/i2c.h>
# include <linux/module.h>
# include <linux/pm_runtime.h>
# include <media/v4l2-ctrls.h>
# include <media/v4l2-device.h>
# include <media/v4l2-fwnode.h>
# define HI847_REG_VALUE_08BIT 1
# define HI847_REG_VALUE_16BIT 2
# define HI847_REG_VALUE_24BIT 3
# define HI847_LINK_FREQ_400MHZ 400000000ULL
# define HI847_LINK_FREQ_200MHZ 200000000ULL
# define HI847_SCLK 72000000ULL
# define HI847_MCLK 19200000
# define HI847_DATA_LANES 4
# define HI847_RGB_DEPTH 10
# define HI847_REG_CHIP_ID 0x0716
# define HI847_CHIP_ID 0x0847
# define HI847_REG_MODE_SELECT 0x0B00
# define HI847_MODE_STANDBY 0x0000
# define HI847_MODE_STREAMING 0x0100
# define HI847_REG_MODE_TG 0x027E
# define HI847_REG_MODE_TG_ENABLE 0x0100
# define HI847_REG_MODE_TG_DISABLE 0x0000
/* vertical-timings from sensor */
# define HI847_REG_FLL 0x020E
# define HI847_FLL_30FPS 0x0B51
# define HI847_FLL_30FPS_MIN 0x0B51
# define HI847_FLL_60FPS 0x05A9
# define HI847_FLL_60FPS_MIN 0x05A9
# define HI847_FLL_MAX 0x7fff
/* horizontal-timings from sensor */
# define HI847_REG_LLP 0x0206
/* Exposure controls from sensor */
# define HI847_REG_EXPOSURE 0x020A
# define HI847_EXPOSURE_MIN 4
# define HI847_EXPOSURE_MAX_MARGIN 4
# define HI847_EXPOSURE_STEP 1
/* Analog gain controls from sensor */
# define HI847_REG_ANALOG_GAIN 0x0212
# define HI847_ANAL_GAIN_MIN 0
# define HI847_ANAL_GAIN_MAX 240
# define HI847_ANAL_GAIN_STEP 1
/* Digital gain controls from sensor */
# define HI847_REG_MWB_GR_GAIN 0x0214
# define HI847_REG_MWB_GB_GAIN 0x0216
# define HI847_REG_MWB_R_GAIN 0x0218
# define HI847_REG_MWB_B_GAIN 0x021A
# define HI847_DGTL_GAIN_MIN 1
# define HI847_DGTL_GAIN_MAX 8191
# define HI847_DGTL_GAIN_STEP 1
# define HI847_DGTL_GAIN_DEFAULT 512
/* Test Pattern Control */
# define HI847_REG_ISP 0X0B04
# define HI847_REG_ISP_TPG_EN 0x0001
# define HI847_REG_TEST_PATTERN 0x0C0A
/* Flip Mirror Controls from sensor */
# define HI847_REG_MIRROR_FLIP 0x0202
# define HI847_REG_FORMAT_X 0x0F04
# define HI847_REG_FORMAT_Y 0x0F06
enum {
HI847_LINK_FREQ_400MHZ_INDEX ,
HI847_LINK_FREQ_200MHZ_INDEX ,
} ;
struct hi847_reg {
u16 address ;
u16 val ;
} ;
struct hi847_reg_list {
u32 num_of_regs ;
const struct hi847_reg * regs ;
} ;
struct hi847_link_freq_config {
const struct hi847_reg_list reg_list ;
} ;
struct hi847_mode {
/* Frame width in pixels */
u32 width ;
/* Frame height in pixels */
u32 height ;
/* Horizontal timining size */
u32 llp ;
/* Default vertical timining size */
u32 fll_def ;
/* Min vertical timining size */
u32 fll_min ;
/* Link frequency needed for this resolution */
u32 link_freq_index ;
/* Sensor register settings for this resolution */
const struct hi847_reg_list reg_list ;
} ;
# define to_hi847(_sd) container_of(_sd, struct hi847, sd)
//SENSOR_INITIALIZATION
static const struct hi847_reg mipi_data_rate_lane_4 [ ] = {
{ 0x0790 , 0x0100 } ,
{ 0x2000 , 0x0000 } ,
{ 0x2002 , 0x0058 } ,
{ 0x2006 , 0x40B2 } ,
{ 0x2008 , 0xB05C } ,
{ 0x200A , 0x8446 } ,
{ 0x200C , 0x40B2 } ,
{ 0x200E , 0xB082 } ,
{ 0x2010 , 0x8450 } ,
{ 0x2012 , 0x40B2 } ,
{ 0x2014 , 0xB0AE } ,
{ 0x2016 , 0x84C6 } ,
{ 0x2018 , 0x40B2 } ,
{ 0x201A , 0xB11A } ,
{ 0x201C , 0x84BC } ,
{ 0x201E , 0x40B2 } ,
{ 0x2020 , 0xB34A } ,
{ 0x2022 , 0x84B4 } ,
{ 0x2024 , 0x40B2 } ,
{ 0x2026 , 0xB386 } ,
{ 0x2028 , 0x84B0 } ,
{ 0x202A , 0x40B2 } ,
{ 0x202C , 0xB3B4 } ,
{ 0x202E , 0x84B8 } ,
{ 0x2030 , 0x40B2 } ,
{ 0x2032 , 0xB0F4 } ,
{ 0x2034 , 0x8470 } ,
{ 0x2036 , 0x40B2 } ,
{ 0x2038 , 0xB3EA } ,
{ 0x203A , 0x847C } ,
{ 0x203C , 0x40B2 } ,
{ 0x203E , 0xB658 } ,
{ 0x2040 , 0x8478 } ,
{ 0x2042 , 0x40B2 } ,
{ 0x2044 , 0xB67E } ,
{ 0x2046 , 0x847E } ,
{ 0x2048 , 0x40B2 } ,
{ 0x204A , 0xB78E } ,
{ 0x204C , 0x843A } ,
{ 0x204E , 0x40B2 } ,
{ 0x2050 , 0xB980 } ,
{ 0x2052 , 0x845C } ,
{ 0x2054 , 0x40B2 } ,
{ 0x2056 , 0xB9B0 } ,
{ 0x2058 , 0x845E } ,
{ 0x205A , 0x4130 } ,
{ 0x205C , 0x1292 } ,
{ 0x205E , 0xD016 } ,
{ 0x2060 , 0xB3D2 } ,
{ 0x2062 , 0x0B00 } ,
{ 0x2064 , 0x2002 } ,
{ 0x2066 , 0xD2E2 } ,
{ 0x2068 , 0x0381 } ,
{ 0x206A , 0x93C2 } ,
{ 0x206C , 0x0263 } ,
{ 0x206E , 0x2001 } ,
{ 0x2070 , 0x4130 } ,
{ 0x2072 , 0x422D } ,
{ 0x2074 , 0x403E } ,
{ 0x2076 , 0x888E } ,
{ 0x2078 , 0x403F } ,
{ 0x207A , 0x192A } ,
{ 0x207C , 0x1292 } ,
{ 0x207E , 0x843E } ,
{ 0x2080 , 0x3FF7 } ,
{ 0x2082 , 0x422D } ,
{ 0x2084 , 0x403E } ,
{ 0x2086 , 0x192A } ,
{ 0x2088 , 0x403F } ,
{ 0x208A , 0x888E } ,
{ 0x208C , 0x1292 } ,
{ 0x208E , 0x843E } ,
{ 0x2090 , 0xB3D2 } ,
{ 0x2092 , 0x0267 } ,
{ 0x2094 , 0x2403 } ,
{ 0x2096 , 0xD0F2 } ,
{ 0x2098 , 0x0040 } ,
{ 0x209A , 0x0381 } ,
{ 0x209C , 0x90F2 } ,
{ 0x209E , 0x0010 } ,
{ 0x20A0 , 0x0260 } ,
{ 0x20A2 , 0x2002 } ,
{ 0x20A4 , 0x1292 } ,
{ 0x20A6 , 0x84BC } ,
{ 0x20A8 , 0x1292 } ,
{ 0x20AA , 0xD020 } ,
{ 0x20AC , 0x4130 } ,
{ 0x20AE , 0x1292 } ,
{ 0x20B0 , 0x8470 } ,
{ 0x20B2 , 0x1292 } ,
{ 0x20B4 , 0x8452 } ,
{ 0x20B6 , 0x0900 } ,
{ 0x20B8 , 0x7118 } ,
{ 0x20BA , 0x1292 } ,
{ 0x20BC , 0x848E } ,
{ 0x20BE , 0x0900 } ,
{ 0x20C0 , 0x7112 } ,
{ 0x20C2 , 0x0800 } ,
{ 0x20C4 , 0x7A20 } ,
{ 0x20C6 , 0x4292 } ,
{ 0x20C8 , 0x87DE } ,
{ 0x20CA , 0x7334 } ,
{ 0x20CC , 0x0F00 } ,
{ 0x20CE , 0x7304 } ,
{ 0x20D0 , 0x421F } ,
{ 0x20D2 , 0x8718 } ,
{ 0x20D4 , 0x1292 } ,
{ 0x20D6 , 0x846E } ,
{ 0x20D8 , 0x1292 } ,
{ 0x20DA , 0x8488 } ,
{ 0x20DC , 0x0B00 } ,
{ 0x20DE , 0x7114 } ,
{ 0x20E0 , 0x0002 } ,
{ 0x20E2 , 0x1292 } ,
{ 0x20E4 , 0x848C } ,
{ 0x20E6 , 0x1292 } ,
{ 0x20E8 , 0x8454 } ,
{ 0x20EA , 0x43C2 } ,
{ 0x20EC , 0x86EE } ,
{ 0x20EE , 0x1292 } ,
{ 0x20F0 , 0x8444 } ,
{ 0x20F2 , 0x4130 } ,
{ 0x20F4 , 0x4392 } ,
{ 0x20F6 , 0x7360 } ,
{ 0x20F8 , 0xB3D2 } ,
{ 0x20FA , 0x0B00 } ,
{ 0x20FC , 0x2402 } ,
{ 0x20FE , 0xC2E2 } ,
{ 0x2100 , 0x0381 } ,
{ 0x2102 , 0x0900 } ,
{ 0x2104 , 0x732C } ,
{ 0x2106 , 0x4382 } ,
{ 0x2108 , 0x7360 } ,
{ 0x210A , 0x422D } ,
{ 0x210C , 0x403E } ,
{ 0x210E , 0x87F0 } ,
{ 0x2110 , 0x403F } ,
{ 0x2112 , 0x87E8 } ,
{ 0x2114 , 0x1292 } ,
{ 0x2116 , 0x843E } ,
{ 0x2118 , 0x4130 } ,
{ 0x211A , 0x120B } ,
{ 0x211C , 0x120A } ,
{ 0x211E , 0x4392 } ,
{ 0x2120 , 0x87FA } ,
{ 0x2122 , 0x4392 } ,
{ 0x2124 , 0x760E } ,
{ 0x2126 , 0x0900 } ,
{ 0x2128 , 0x760C } ,
{ 0x212A , 0x421B } ,
{ 0x212C , 0x760A } ,
{ 0x212E , 0x903B } ,
{ 0x2130 , 0x0201 } ,
{ 0x2132 , 0x2408 } ,
{ 0x2134 , 0x903B } ,
{ 0x2136 , 0x0102 } ,
{ 0x2138 , 0x2405 } ,
{ 0x213A , 0x4292 } ,
{ 0x213C , 0x030A } ,
{ 0x213E , 0x87F8 } ,
{ 0x2140 , 0x1292 } ,
{ 0x2142 , 0x849A } ,
{ 0x2144 , 0x903B } ,
{ 0x2146 , 0x0020 } ,
{ 0x2148 , 0x2010 } ,
{ 0x214A , 0x403B } ,
{ 0x214C , 0x8498 } ,
{ 0x214E , 0x422F } ,
{ 0x2150 , 0x12AB } ,
{ 0x2152 , 0x403F } ,
{ 0x2154 , 0x0028 } ,
{ 0x2156 , 0x12AB } ,
{ 0x2158 , 0x403B } ,
{ 0x215A , 0x84C4 } ,
{ 0x215C , 0x407F } ,
{ 0x215E , 0xFFAA } ,
{ 0x2160 , 0x12AB } ,
{ 0x2162 , 0x407F } ,
{ 0x2164 , 0x0055 } ,
{ 0x2166 , 0x12AB } ,
{ 0x2168 , 0x3FDC } ,
{ 0x216A , 0x903B } ,
{ 0x216C , 0x0021 } ,
{ 0x216E , 0x2890 } ,
{ 0x2170 , 0x903B } ,
{ 0x2172 , 0x0100 } ,
{ 0x2174 , 0x200D } ,
{ 0x2176 , 0x403F } ,
{ 0x2178 , 0x0028 } ,
{ 0x217A , 0x1292 } ,
{ 0x217C , 0x8498 } ,
{ 0x217E , 0x425F } ,
{ 0x2180 , 0x0306 } ,
{ 0x2182 , 0x1292 } ,
{ 0x2184 , 0x84C4 } ,
{ 0x2186 , 0x4FC2 } ,
{ 0x2188 , 0x0318 } ,
{ 0x218A , 0x0261 } ,
{ 0x218C , 0x0000 } ,
{ 0x218E , 0x3FC9 } ,
{ 0x2190 , 0x903B } ,
{ 0x2192 , 0x0101 } ,
{ 0x2194 , 0x2858 } ,
{ 0x2196 , 0x903B } ,
{ 0x2198 , 0x0200 } ,
{ 0x219A , 0x2450 } ,
{ 0x219C , 0x903B } ,
{ 0x219E , 0x0201 } ,
{ 0x21A0 , 0x2C47 } ,
{ 0x21A2 , 0x903B } ,
{ 0x21A4 , 0x0102 } ,
{ 0x21A6 , 0x2041 } ,
{ 0x21A8 , 0x93E2 } ,
{ 0x21AA , 0x0262 } ,
{ 0x21AC , 0x240A } ,
{ 0x21AE , 0x425F } ,
{ 0x21B0 , 0x0306 } ,
{ 0x21B2 , 0x1292 } ,
{ 0x21B4 , 0x84C4 } ,
{ 0x21B6 , 0x4F4E } ,
{ 0x21B8 , 0x4EC2 } ,
{ 0x21BA , 0x0318 } ,
{ 0x21BC , 0x0260 } ,
{ 0x21BE , 0x0000 } ,
{ 0x21C0 , 0x3FB0 } ,
{ 0x21C2 , 0x403A } ,
{ 0x21C4 , 0x8030 } ,
{ 0x21C6 , 0x4382 } ,
{ 0x21C8 , 0x0326 } ,
{ 0x21CA , 0x4382 } ,
{ 0x21CC , 0x0328 } ,
{ 0x21CE , 0x421B } ,
{ 0x21D0 , 0x030C } ,
{ 0x21D2 , 0x930B } ,
{ 0x21D4 , 0x2420 } ,
{ 0x21D6 , 0x4A5F } ,
{ 0x21D8 , 0x0001 } ,
{ 0x21DA , 0x1292 } ,
{ 0x21DC , 0x84C4 } ,
{ 0x21DE , 0x4F4E } ,
{ 0x21E0 , 0x4A5F } ,
{ 0x21E2 , 0x0001 } ,
{ 0x21E4 , 0x9F0E } ,
{ 0x21E6 , 0x2402 } ,
{ 0x21E8 , 0x5392 } ,
{ 0x21EA , 0x0326 } ,
{ 0x21EC , 0x4ECA } ,
{ 0x21EE , 0x0001 } ,
{ 0x21F0 , 0x533B } ,
{ 0x21F2 , 0x2411 } ,
{ 0x21F4 , 0x4A6F } ,
{ 0x21F6 , 0x1292 } ,
{ 0x21F8 , 0x84C4 } ,
{ 0x21FA , 0x4F4E } ,
{ 0x21FC , 0x4A6F } ,
{ 0x21FE , 0x9F0E } ,
{ 0x2200 , 0x2402 } ,
{ 0x2202 , 0x5392 } ,
{ 0x2204 , 0x0326 } ,
{ 0x2206 , 0x4ECA } ,
{ 0x2208 , 0x0000 } ,
{ 0x220A , 0x533B } ,
{ 0x220C , 0x532A } ,
{ 0x220E , 0x0260 } ,
{ 0x2210 , 0x0000 } ,
{ 0x2212 , 0x930B } ,
{ 0x2214 , 0x23E0 } ,
{ 0x2216 , 0x40B2 } ,
{ 0x2218 , 0xAA55 } ,
{ 0x221A , 0x0328 } ,
{ 0x221C , 0xB0F2 } ,
{ 0x221E , 0x0040 } ,
{ 0x2220 , 0x0381 } ,
{ 0x2222 , 0x277F } ,
{ 0x2224 , 0xD3D2 } ,
{ 0x2226 , 0x0267 } ,
{ 0x2228 , 0x3F7C } ,
{ 0x222A , 0x0261 } ,
{ 0x222C , 0x0000 } ,
{ 0x222E , 0x3F79 } ,
{ 0x2230 , 0x903B } ,
{ 0x2232 , 0x0201 } ,
{ 0x2234 , 0x23FA } ,
{ 0x2236 , 0x1292 } ,
{ 0x2238 , 0x84C0 } ,
{ 0x223A , 0x3F73 } ,
{ 0x223C , 0x1292 } ,
{ 0x223E , 0x84C0 } ,
{ 0x2240 , 0x0261 } ,
{ 0x2242 , 0x0000 } ,
{ 0x2244 , 0x3F6E } ,
{ 0x2246 , 0x903B } ,
{ 0x2248 , 0x0040 } ,
{ 0x224A , 0x2018 } ,
{ 0x224C , 0x422F } ,
{ 0x224E , 0x1292 } ,
{ 0x2250 , 0x8498 } ,
{ 0x2252 , 0x12B0 } ,
{ 0x2254 , 0xF0EA } ,
{ 0x2256 , 0x907F } ,
{ 0x2258 , 0xFFAA } ,
{ 0x225A , 0x240D } ,
{ 0x225C , 0x5392 } ,
{ 0x225E , 0x0312 } ,
{ 0x2260 , 0x12B0 } ,
{ 0x2262 , 0xF0EA } ,
{ 0x2264 , 0x907F } ,
{ 0x2266 , 0x0055 } ,
{ 0x2268 , 0x2403 } ,
{ 0x226A , 0x5392 } ,
{ 0x226C , 0x0312 } ,
{ 0x226E , 0x3F59 } ,
{ 0x2270 , 0x5392 } ,
{ 0x2272 , 0x0310 } ,
{ 0x2274 , 0x3F56 } ,
{ 0x2276 , 0x5392 } ,
{ 0x2278 , 0x0310 } ,
{ 0x227A , 0x3FF2 } ,
{ 0x227C , 0x903B } ,
{ 0x227E , 0x0080 } ,
{ 0x2280 , 0x23D4 } ,
{ 0x2282 , 0x4382 } ,
{ 0x2284 , 0x0312 } ,
{ 0x2286 , 0x4382 } ,
{ 0x2288 , 0x0310 } ,
{ 0x228A , 0x0261 } ,
{ 0x228C , 0x0000 } ,
{ 0x228E , 0x3F49 } ,
{ 0x2290 , 0x932B } ,
{ 0x2292 , 0x2005 } ,
{ 0x2294 , 0x403F } ,
{ 0x2296 , 0x0028 } ,
{ 0x2298 , 0x1292 } ,
{ 0x229A , 0x8498 } ,
{ 0x229C , 0x3F42 } ,
{ 0x229E , 0x903B } ,
{ 0x22A0 , 0x0003 } ,
{ 0x22A2 , 0x284B } ,
{ 0x22A4 , 0x923B } ,
{ 0x22A6 , 0x2015 } ,
{ 0x22A8 , 0x403F } ,
{ 0x22AA , 0x0023 } ,
{ 0x22AC , 0x1292 } ,
{ 0x22AE , 0x8498 } ,
{ 0x22B0 , 0x421B } ,
{ 0x22B2 , 0x87F8 } ,
{ 0x22B4 , 0x421F } ,
{ 0x22B6 , 0x030C } ,
{ 0x22B8 , 0x9F0B } ,
{ 0x22BA , 0x2F33 } ,
{ 0x22BC , 0x1292 } ,
{ 0x22BE , 0x84BA } ,
{ 0x22C0 , 0x930F } ,
{ 0x22C2 , 0x2004 } ,
{ 0x22C4 , 0x5392 } ,
{ 0x22C6 , 0x0312 } ,
{ 0x22C8 , 0x531B } ,
{ 0x22CA , 0x3FF4 } ,
{ 0x22CC , 0x5392 } ,
{ 0x22CE , 0x0310 } ,
{ 0x22D0 , 0x3FFB } ,
{ 0x22D2 , 0x903B } ,
{ 0x22D4 , 0x0009 } ,
{ 0x22D6 , 0x2818 } ,
{ 0x22D8 , 0x903B } ,
{ 0x22DA , 0x0010 } ,
{ 0x22DC , 0x23A6 } ,
{ 0x22DE , 0x403F } ,
{ 0x22E0 , 0x0027 } ,
{ 0x22E2 , 0x1292 } ,
{ 0x22E4 , 0x8498 } ,
{ 0x22E6 , 0x421B } ,
{ 0x22E8 , 0x87F8 } ,
{ 0x22EA , 0x421F } ,
{ 0x22EC , 0x030C } ,
{ 0x22EE , 0x9F0B } ,
{ 0x22F0 , 0x2F18 } ,
{ 0x22F2 , 0x1292 } ,
{ 0x22F4 , 0x84BA } ,
{ 0x22F6 , 0x930F } ,
{ 0x22F8 , 0x2004 } ,
{ 0x22FA , 0x5392 } ,
{ 0x22FC , 0x0312 } ,
{ 0x22FE , 0x531B } ,
{ 0x2300 , 0x3FF4 } ,
{ 0x2302 , 0x5392 } ,
{ 0x2304 , 0x0310 } ,
{ 0x2306 , 0x3FFB } ,
{ 0x2308 , 0x922B } ,
{ 0x230A , 0x238F } ,
{ 0x230C , 0x421B } ,
{ 0x230E , 0x87F8 } ,
{ 0x2310 , 0x421F } ,
{ 0x2312 , 0x030C } ,
{ 0x2314 , 0x9F0B } ,
{ 0x2316 , 0x2C0B } ,
{ 0x2318 , 0x1292 } ,
{ 0x231A , 0x84C2 } ,
{ 0x231C , 0x934F } ,
{ 0x231E , 0x240A } ,
{ 0x2320 , 0x5392 } ,
{ 0x2322 , 0x0312 } ,
{ 0x2324 , 0x531B } ,
{ 0x2326 , 0x421F } ,
{ 0x2328 , 0x030C } ,
{ 0x232A , 0x9F0B } ,
{ 0x232C , 0x2BF5 } ,
{ 0x232E , 0x0261 } ,
{ 0x2330 , 0x0000 } ,
{ 0x2332 , 0x3EF7 } ,
{ 0x2334 , 0x5392 } ,
{ 0x2336 , 0x0310 } ,
{ 0x2338 , 0x3FF5 } ,
{ 0x233A , 0x930B } ,
{ 0x233C , 0x277F } ,
{ 0x233E , 0x931B } ,
{ 0x2340 , 0x277A } ,
{ 0x2342 , 0x3F73 } ,
{ 0x2344 , 0x413A } ,
{ 0x2346 , 0x413B } ,
{ 0x2348 , 0x4130 } ,
{ 0x234A , 0x4F0C } ,
{ 0x234C , 0x403F } ,
{ 0x234E , 0x0267 } ,
{ 0x2350 , 0xF0FF } ,
{ 0x2352 , 0xFFDF } ,
{ 0x2354 , 0x0000 } ,
{ 0x2356 , 0xF0FF } ,
{ 0x2358 , 0xFFEF } ,
{ 0x235A , 0x0000 } ,
{ 0x235C , 0x421D } ,
{ 0x235E , 0x84B0 } ,
{ 0x2360 , 0x403E } ,
{ 0x2362 , 0x06F9 } ,
{ 0x2364 , 0x4C0F } ,
{ 0x2366 , 0x1292 } ,
{ 0x2368 , 0x84AC } ,
{ 0x236A , 0x4F4E } ,
{ 0x236C , 0xB31E } ,
{ 0x236E , 0x2403 } ,
{ 0x2370 , 0xD0F2 } ,
{ 0x2372 , 0x0020 } ,
{ 0x2374 , 0x0267 } ,
{ 0x2376 , 0xB32E } ,
{ 0x2378 , 0x2403 } ,
{ 0x237A , 0xD0F2 } ,
{ 0x237C , 0x0010 } ,
{ 0x237E , 0x0267 } ,
{ 0x2380 , 0xC3E2 } ,
{ 0x2382 , 0x0267 } ,
{ 0x2384 , 0x4130 } ,
{ 0x2386 , 0x120B } ,
{ 0x2388 , 0x120A } ,
{ 0x238A , 0x403A } ,
{ 0x238C , 0x1140 } ,
{ 0x238E , 0x1292 } ,
{ 0x2390 , 0xD080 } ,
{ 0x2392 , 0x430B } ,
{ 0x2394 , 0x4A0F } ,
{ 0x2396 , 0x532A } ,
{ 0x2398 , 0x1292 } ,
{ 0x239A , 0x84A4 } ,
{ 0x239C , 0x4F0E } ,
{ 0x239E , 0x430F } ,
{ 0x23A0 , 0x5E82 } ,
{ 0x23A2 , 0x87FC } ,
{ 0x23A4 , 0x6F82 } ,
{ 0x23A6 , 0x87FE } ,
{ 0x23A8 , 0x531B } ,
{ 0x23AA , 0x923B } ,
{ 0x23AC , 0x2BF3 } ,
{ 0x23AE , 0x413A } ,
{ 0x23B0 , 0x413B } ,
{ 0x23B2 , 0x4130 } ,
{ 0x23B4 , 0xF0F2 } ,
{ 0x23B6 , 0x007F } ,
{ 0x23B8 , 0x0267 } ,
{ 0x23BA , 0x421D } ,
{ 0x23BC , 0x84B6 } ,
{ 0x23BE , 0x403E } ,
{ 0x23C0 , 0x01F9 } ,
{ 0x23C2 , 0x1292 } ,
{ 0x23C4 , 0x84AC } ,
{ 0x23C6 , 0x4F4E } ,
{ 0x23C8 , 0xF35F } ,
{ 0x23CA , 0x2403 } ,
{ 0x23CC , 0xD0F2 } ,
{ 0x23CE , 0xFF80 } ,
{ 0x23D0 , 0x0267 } ,
{ 0x23D2 , 0xB36E } ,
{ 0x23D4 , 0x2404 } ,
{ 0x23D6 , 0xD0F2 } ,
{ 0x23D8 , 0x0040 } ,
{ 0x23DA , 0x0267 } ,
{ 0x23DC , 0x3C03 } ,
{ 0x23DE , 0xF0F2 } ,
{ 0x23E0 , 0xFFBF } ,
{ 0x23E2 , 0x0267 } ,
{ 0x23E4 , 0xC2E2 } ,
{ 0x23E6 , 0x0267 } ,
{ 0x23E8 , 0x4130 } ,
{ 0x23EA , 0x120B } ,
{ 0x23EC , 0x120A } ,
{ 0x23EE , 0x8231 } ,
{ 0x23F0 , 0x430B } ,
{ 0x23F2 , 0x93C2 } ,
{ 0x23F4 , 0x0C0A } ,
{ 0x23F6 , 0x2404 } ,
{ 0x23F8 , 0xB3D2 } ,
{ 0x23FA , 0x0B05 } ,
{ 0x23FC , 0x2401 } ,
{ 0x23FE , 0x431B } ,
{ 0x2400 , 0x422D } ,
{ 0x2402 , 0x403E } ,
{ 0x2404 , 0x192A } ,
{ 0x2406 , 0x403F } ,
{ 0x2408 , 0x888E } ,
{ 0x240A , 0x1292 } ,
{ 0x240C , 0x843E } ,
{ 0x240E , 0x930B } ,
{ 0x2410 , 0x20F4 } ,
{ 0x2412 , 0x93E2 } ,
{ 0x2414 , 0x0241 } ,
{ 0x2416 , 0x24EB } ,
{ 0x2418 , 0x403A } ,
{ 0x241A , 0x0292 } ,
{ 0x241C , 0x4AA2 } ,
{ 0x241E , 0x0A00 } ,
{ 0x2420 , 0xB2E2 } ,
{ 0x2422 , 0x0361 } ,
{ 0x2424 , 0x2405 } ,
{ 0x2426 , 0x4A2F } ,
{ 0x2428 , 0x1292 } ,
{ 0x242A , 0x8474 } ,
{ 0x242C , 0x4F82 } ,
{ 0x242E , 0x0A1C } ,
{ 0x2430 , 0x93C2 } ,
{ 0x2432 , 0x0360 } ,
{ 0x2434 , 0x34CD } ,
{ 0x2436 , 0x430C } ,
{ 0x2438 , 0x4C0F } ,
{ 0x243A , 0x5F0F } ,
{ 0x243C , 0x4F0D } ,
{ 0x243E , 0x510D } ,
{ 0x2440 , 0x4F0E } ,
{ 0x2442 , 0x5A0E } ,
{ 0x2444 , 0x4E1E } ,
{ 0x2446 , 0x0002 } ,
{ 0x2448 , 0x4F1F } ,
{ 0x244A , 0x192A } ,
{ 0x244C , 0x1202 } ,
{ 0x244E , 0xC232 } ,
{ 0x2450 , 0x4303 } ,
{ 0x2452 , 0x4E82 } ,
{ 0x2454 , 0x0130 } ,
{ 0x2456 , 0x4F82 } ,
{ 0x2458 , 0x0138 } ,
{ 0x245A , 0x421E } ,
{ 0x245C , 0x013A } ,
{ 0x245E , 0x421F } ,
{ 0x2460 , 0x013C } ,
{ 0x2462 , 0x4132 } ,
{ 0x2464 , 0x108E } ,
{ 0x2466 , 0x108F } ,
{ 0x2468 , 0xEF4E } ,
{ 0x246A , 0xEF0E } ,
{ 0x246C , 0xF37F } ,
{ 0x246E , 0xC312 } ,
{ 0x2470 , 0x100F } ,
{ 0x2472 , 0x100E } ,
{ 0x2474 , 0x4E8D } ,
{ 0x2476 , 0x0000 } ,
{ 0x2478 , 0x531C } ,
{ 0x247A , 0x922C } ,
{ 0x247C , 0x2BDD } ,
{ 0x247E , 0xB3D2 } ,
{ 0x2480 , 0x1921 } ,
{ 0x2482 , 0x2403 } ,
{ 0x2484 , 0x410F } ,
{ 0x2486 , 0x1292 } ,
{ 0x2488 , 0x847E } ,
{ 0x248A , 0x403B } ,
{ 0x248C , 0x843E } ,
{ 0x248E , 0x422D } ,
{ 0x2490 , 0x410E } ,
{ 0x2492 , 0x403F } ,
{ 0x2494 , 0x1908 } ,
{ 0x2496 , 0x12AB } ,
{ 0x2498 , 0x403D } ,
{ 0x249A , 0x0005 } ,
{ 0x249C , 0x403E } ,
{ 0x249E , 0x0292 } ,
{ 0x24A0 , 0x403F } ,
{ 0x24A2 , 0x86E4 } ,
{ 0x24A4 , 0x12AB } ,
{ 0x24A6 , 0x421F } ,
{ 0x24A8 , 0x060E } ,
{ 0x24AA , 0x9F82 } ,
{ 0x24AC , 0x8720 } ,
{ 0x24AE , 0x288D } ,
{ 0x24B0 , 0x9382 } ,
{ 0x24B2 , 0x060E } ,
{ 0x24B4 , 0x248A } ,
{ 0x24B6 , 0x90BA } ,
{ 0x24B8 , 0x0010 } ,
{ 0x24BA , 0x0000 } ,
{ 0x24BC , 0x2C0B } ,
{ 0x24BE , 0x93C2 } ,
{ 0x24C0 , 0x86EE } ,
{ 0x24C2 , 0x2008 } ,
{ 0x24C4 , 0x403F } ,
{ 0x24C6 , 0x06A7 } ,
{ 0x24C8 , 0xD0FF } ,
{ 0x24CA , 0x0007 } ,
{ 0x24CC , 0x0000 } ,
{ 0x24CE , 0xF0FF } ,
{ 0x24D0 , 0xFFF8 } ,
{ 0x24D2 , 0x0000 } ,
{ 0x24D4 , 0x4392 } ,
{ 0x24D6 , 0x8720 } ,
{ 0x24D8 , 0x403F } ,
{ 0x24DA , 0x06A7 } ,
{ 0x24DC , 0xD2EF } ,
{ 0x24DE , 0x0000 } ,
{ 0x24E0 , 0xC2EF } ,
{ 0x24E2 , 0x0000 } ,
{ 0x24E4 , 0x93C2 } ,
{ 0x24E6 , 0x87D3 } ,
{ 0x24E8 , 0x2068 } ,
{ 0x24EA , 0xB0F2 } ,
{ 0x24EC , 0x0040 } ,
{ 0x24EE , 0x0B05 } ,
{ 0x24F0 , 0x2461 } ,
{ 0x24F2 , 0xD3D2 } ,
{ 0x24F4 , 0x0410 } ,
{ 0x24F6 , 0xB3E2 } ,
{ 0x24F8 , 0x0381 } ,
{ 0x24FA , 0x2089 } ,
{ 0x24FC , 0x90B2 } ,
{ 0x24FE , 0x0030 } ,
{ 0x2500 , 0x0A00 } ,
{ 0x2502 , 0x2C52 } ,
{ 0x2504 , 0x93C2 } ,
{ 0x2506 , 0x86EE } ,
{ 0x2508 , 0x204F } ,
{ 0x250A , 0x430E } ,
{ 0x250C , 0x430C } ,
{ 0x250E , 0x4C0F } ,
{ 0x2510 , 0x5F0F } ,
{ 0x2512 , 0x5F0F } ,
{ 0x2514 , 0x5F0F } ,
{ 0x2516 , 0x4F1F } ,
{ 0x2518 , 0x8668 } ,
{ 0x251A , 0xF03F } ,
{ 0x251C , 0x07FF } ,
{ 0x251E , 0x903F } ,
{ 0x2520 , 0x0400 } ,
{ 0x2522 , 0x343E } ,
{ 0x2524 , 0x5F0E } ,
{ 0x2526 , 0x531C } ,
{ 0x2528 , 0x923C } ,
{ 0x252A , 0x2BF1 } ,
{ 0x252C , 0x4E0F } ,
{ 0x252E , 0x930E } ,
{ 0x2530 , 0x3834 } ,
{ 0x2532 , 0x110F } ,
{ 0x2534 , 0x110F } ,
{ 0x2536 , 0x110F } ,
{ 0x2538 , 0x9382 } ,
{ 0x253A , 0x86EE } ,
{ 0x253C , 0x2023 } ,
{ 0x253E , 0x5F82 } ,
{ 0x2540 , 0x87D6 } ,
{ 0x2542 , 0x403B } ,
{ 0x2544 , 0x87D6 } ,
{ 0x2546 , 0x4B2F } ,
{ 0x2548 , 0x12B0 } ,
{ 0x254A , 0xB624 } ,
{ 0x254C , 0x4F8B } ,
{ 0x254E , 0x0000 } ,
{ 0x2550 , 0x430C } ,
{ 0x2552 , 0x4C0D } ,
{ 0x2554 , 0x5D0D } ,
{ 0x2556 , 0x5D0D } ,
{ 0x2558 , 0x5D0D } ,
{ 0x255A , 0x403A } ,
{ 0x255C , 0x87D8 } ,
{ 0x255E , 0x421B } ,
{ 0x2560 , 0x87D6 } ,
{ 0x2562 , 0x4B0F } ,
{ 0x2564 , 0x8A2F } ,
{ 0x2566 , 0x4F0E } ,
{ 0x2568 , 0x4E0F } ,
{ 0x256A , 0x5F0F } ,
{ 0x256C , 0x7F0F } ,
{ 0x256E , 0xE33F } ,
{ 0x2570 , 0x8E8D } ,
{ 0x2572 , 0x8668 } ,
{ 0x2574 , 0x7F8D } ,
{ 0x2576 , 0x866A } ,
{ 0x2578 , 0x531C } ,
{ 0x257A , 0x923C } ,
{ 0x257C , 0x2BEA } ,
{ 0x257E , 0x4B8A } ,
{ 0x2580 , 0x0000 } ,
{ 0x2582 , 0x3C45 } ,
{ 0x2584 , 0x9382 } ,
{ 0x2586 , 0x86F0 } ,
{ 0x2588 , 0x2005 } ,
{ 0x258A , 0x4382 } ,
{ 0x258C , 0x87D6 } ,
{ 0x258E , 0x4382 } ,
{ 0x2590 , 0x87D8 } ,
{ 0x2592 , 0x3FD7 } ,
{ 0x2594 , 0x4F82 } ,
{ 0x2596 , 0x87D6 } ,
{ 0x2598 , 0x3FD4 } ,
{ 0x259A , 0x503F } ,
{ 0x259C , 0x0007 } ,
{ 0x259E , 0x3FC9 } ,
{ 0x25A0 , 0x5F0E } ,
{ 0x25A2 , 0x503E } ,
{ 0x25A4 , 0xF800 } ,
{ 0x25A6 , 0x3FBF } ,
{ 0x25A8 , 0x430F } ,
{ 0x25AA , 0x12B0 } ,
{ 0x25AC , 0xB624 } ,
{ 0x25AE , 0x4382 } ,
{ 0x25B0 , 0x87D6 } ,
{ 0x25B2 , 0x3C2D } ,
{ 0x25B4 , 0xC3D2 } ,
{ 0x25B6 , 0x0410 } ,
{ 0x25B8 , 0x3F9E } ,
{ 0x25BA , 0x430D } ,
{ 0x25BC , 0x403E } ,
{ 0x25BE , 0x0050 } ,
{ 0x25C0 , 0x403F } ,
{ 0x25C2 , 0x85C8 } ,
{ 0x25C4 , 0x1292 } ,
{ 0x25C6 , 0x844E } ,
{ 0x25C8 , 0x3F90 } ,
{ 0x25CA , 0x5392 } ,
{ 0x25CC , 0x8720 } ,
{ 0x25CE , 0x3F84 } ,
{ 0x25D0 , 0x403B } ,
{ 0x25D2 , 0x843E } ,
{ 0x25D4 , 0x4A0F } ,
{ 0x25D6 , 0x532F } ,
{ 0x25D8 , 0x422D } ,
{ 0x25DA , 0x4F0E } ,
{ 0x25DC , 0x403F } ,
{ 0x25DE , 0x0E08 } ,
{ 0x25E0 , 0x12AB } ,
{ 0x25E2 , 0x422D } ,
{ 0x25E4 , 0x403E } ,
{ 0x25E6 , 0x192A } ,
{ 0x25E8 , 0x410F } ,
{ 0x25EA , 0x12AB } ,
{ 0x25EC , 0x3F48 } ,
{ 0x25EE , 0x93C2 } ,
{ 0x25F0 , 0x86EE } ,
{ 0x25F2 , 0x2312 } ,
{ 0x25F4 , 0x403A } ,
{ 0x25F6 , 0x86E4 } ,
{ 0x25F8 , 0x3F11 } ,
{ 0x25FA , 0x403D } ,
{ 0x25FC , 0x0200 } ,
{ 0x25FE , 0x422E } ,
{ 0x2600 , 0x403F } ,
{ 0x2602 , 0x192A } ,
{ 0x2604 , 0x1292 } ,
{ 0x2606 , 0x844E } ,
{ 0x2608 , 0xC3D2 } ,
{ 0x260A , 0x1921 } ,
{ 0x260C , 0x3F02 } ,
{ 0x260E , 0x422D } ,
{ 0x2610 , 0x403E } ,
{ 0x2612 , 0x888E } ,
{ 0x2614 , 0x403F } ,
{ 0x2616 , 0x192A } ,
{ 0x2618 , 0x1292 } ,
{ 0x261A , 0x843E } ,
{ 0x261C , 0x5231 } ,
{ 0x261E , 0x413A } ,
{ 0x2620 , 0x413B } ,
{ 0x2622 , 0x4130 } ,
{ 0x2624 , 0x4382 } ,
{ 0x2626 , 0x052C } ,
{ 0x2628 , 0x4F0D } ,
{ 0x262A , 0x930D } ,
{ 0x262C , 0x3402 } ,
{ 0x262E , 0xE33D } ,
{ 0x2630 , 0x531D } ,
{ 0x2632 , 0xF03D } ,
{ 0x2634 , 0x07F0 } ,
{ 0x2636 , 0x4D0E } ,
{ 0x2638 , 0xC312 } ,
{ 0x263A , 0x100E } ,
{ 0x263C , 0x110E } ,
{ 0x263E , 0x110E } ,
{ 0x2640 , 0x110E } ,
{ 0x2642 , 0x930F } ,
{ 0x2644 , 0x3803 } ,
{ 0x2646 , 0x4EC2 } ,
{ 0x2648 , 0x052C } ,
{ 0x264A , 0x3C04 } ,
{ 0x264C , 0x4EC2 } ,
{ 0x264E , 0x052D } ,
{ 0x2650 , 0xE33D } ,
{ 0x2652 , 0x531D } ,
{ 0x2654 , 0x4D0F } ,
{ 0x2656 , 0x4130 } ,
{ 0x2658 , 0x1292 } ,
{ 0x265A , 0xD048 } ,
{ 0x265C , 0x93C2 } ,
{ 0x265E , 0x86EE } ,
{ 0x2660 , 0x200D } ,
{ 0x2662 , 0xB0F2 } ,
{ 0x2664 , 0x0020 } ,
{ 0x2666 , 0x0381 } ,
{ 0x2668 , 0x2407 } ,
{ 0x266A , 0x9292 } ,
{ 0x266C , 0x8722 } ,
{ 0x266E , 0x0384 } ,
{ 0x2670 , 0x2C03 } ,
{ 0x2672 , 0xD3D2 } ,
{ 0x2674 , 0x0649 } ,
{ 0x2676 , 0x4130 } ,
{ 0x2678 , 0xC3D2 } ,
{ 0x267A , 0x0649 } ,
{ 0x267C , 0x4130 } ,
{ 0x267E , 0x120B } ,
{ 0x2680 , 0x120A } ,
{ 0x2682 , 0x1209 } ,
{ 0x2684 , 0x1208 } ,
{ 0x2686 , 0x1207 } ,
{ 0x2688 , 0x1206 } ,
{ 0x268A , 0x1205 } ,
{ 0x268C , 0x1204 } ,
{ 0x268E , 0x8231 } ,
{ 0x2690 , 0x4F81 } ,
{ 0x2692 , 0x0000 } ,
{ 0x2694 , 0x4381 } ,
{ 0x2696 , 0x0002 } ,
{ 0x2698 , 0x4304 } ,
{ 0x269A , 0x411C } ,
{ 0x269C , 0x0002 } ,
{ 0x269E , 0x5C0C } ,
{ 0x26A0 , 0x4C0F } ,
{ 0x26A2 , 0x5F0F } ,
{ 0x26A4 , 0x5F0F } ,
{ 0x26A6 , 0x5F0F } ,
{ 0x26A8 , 0x5F0F } ,
{ 0x26AA , 0x5F0F } ,
{ 0x26AC , 0x503F } ,
{ 0x26AE , 0x1980 } ,
{ 0x26B0 , 0x440D } ,
{ 0x26B2 , 0x5D0D } ,
{ 0x26B4 , 0x4D0E } ,
{ 0x26B6 , 0x5F0E } ,
{ 0x26B8 , 0x4E2E } ,
{ 0x26BA , 0x4D05 } ,
{ 0x26BC , 0x5505 } ,
{ 0x26BE , 0x5F05 } ,
{ 0x26C0 , 0x4516 } ,
{ 0x26C2 , 0x0008 } ,
{ 0x26C4 , 0x4517 } ,
{ 0x26C6 , 0x000A } ,
{ 0x26C8 , 0x460A } ,
{ 0x26CA , 0x470B } ,
{ 0x26CC , 0xF30A } ,
{ 0x26CE , 0xF32B } ,
{ 0x26D0 , 0x4A81 } ,
{ 0x26D2 , 0x0004 } ,
{ 0x26D4 , 0x4B81 } ,
{ 0x26D6 , 0x0006 } ,
{ 0x26D8 , 0xB03E } ,
{ 0x26DA , 0x2000 } ,
{ 0x26DC , 0x2404 } ,
{ 0x26DE , 0xF03E } ,
{ 0x26E0 , 0x1FFF } ,
{ 0x26E2 , 0xE33E } ,
{ 0x26E4 , 0x531E } ,
{ 0x26E6 , 0xF317 } ,
{ 0x26E8 , 0x503E } ,
{ 0x26EA , 0x2000 } ,
{ 0x26EC , 0x4E0F } ,
{ 0x26EE , 0x5F0F } ,
{ 0x26F0 , 0x7F0F } ,
{ 0x26F2 , 0xE33F } ,
{ 0x26F4 , 0x512C } ,
{ 0x26F6 , 0x4C28 } ,
{ 0x26F8 , 0x4309 } ,
{ 0x26FA , 0x4E0A } ,
{ 0x26FC , 0x4F0B } ,
{ 0x26FE , 0x480C } ,
{ 0x2700 , 0x490D } ,
{ 0x2702 , 0x1202 } ,
{ 0x2704 , 0xC232 } ,
{ 0x2706 , 0x12B0 } ,
{ 0x2708 , 0xFFC0 } ,
{ 0x270A , 0x4132 } ,
{ 0x270C , 0x108E } ,
{ 0x270E , 0x108F } ,
{ 0x2710 , 0xEF4E } ,
{ 0x2712 , 0xEF0E } ,
{ 0x2714 , 0xF37F } ,
{ 0x2716 , 0xC312 } ,
{ 0x2718 , 0x100F } ,
{ 0x271A , 0x100E } ,
{ 0x271C , 0x4E85 } ,
{ 0x271E , 0x0018 } ,
{ 0x2720 , 0x4F85 } ,
{ 0x2722 , 0x001A } ,
{ 0x2724 , 0x480A } ,
{ 0x2726 , 0x490B } ,
{ 0x2728 , 0x460C } ,
{ 0x272A , 0x470D } ,
{ 0x272C , 0x1202 } ,
{ 0x272E , 0xC232 } ,
{ 0x2730 , 0x12B0 } ,
{ 0x2732 , 0xFFC0 } ,
{ 0x2734 , 0x4132 } ,
{ 0x2736 , 0x4E0C } ,
{ 0x2738 , 0x4F0D } ,
{ 0x273A , 0x108C } ,
{ 0x273C , 0x108D } ,
{ 0x273E , 0xED4C } ,
{ 0x2740 , 0xED0C } ,
{ 0x2742 , 0xF37D } ,
{ 0x2744 , 0xC312 } ,
{ 0x2746 , 0x100D } ,
{ 0x2748 , 0x100C } ,
{ 0x274A , 0x411E } ,
{ 0x274C , 0x0004 } ,
{ 0x274E , 0x411F } ,
{ 0x2750 , 0x0006 } ,
{ 0x2752 , 0x5E0E } ,
{ 0x2754 , 0x6F0F } ,
{ 0x2756 , 0x5E0E } ,
{ 0x2758 , 0x6F0F } ,
{ 0x275A , 0x5E0E } ,
{ 0x275C , 0x6F0F } ,
{ 0x275E , 0xDE0C } ,
{ 0x2760 , 0xDF0D } ,
{ 0x2762 , 0x4C85 } ,
{ 0x2764 , 0x002C } ,
{ 0x2766 , 0x4D85 } ,
{ 0x2768 , 0x002E } ,
{ 0x276A , 0x5314 } ,
{ 0x276C , 0x9224 } ,
{ 0x276E , 0x2B95 } ,
{ 0x2770 , 0x5391 } ,
{ 0x2772 , 0x0002 } ,
{ 0x2774 , 0x92A1 } ,
{ 0x2776 , 0x0002 } ,
{ 0x2778 , 0x2B8F } ,
{ 0x277A , 0x5231 } ,
{ 0x277C , 0x4134 } ,
{ 0x277E , 0x4135 } ,
{ 0x2780 , 0x4136 } ,
{ 0x2782 , 0x4137 } ,
{ 0x2784 , 0x4138 } ,
{ 0x2786 , 0x4139 } ,
{ 0x2788 , 0x413A } ,
{ 0x278A , 0x413B } ,
{ 0x278C , 0x4130 } ,
{ 0x278E , 0x120B } ,
{ 0x2790 , 0x120A } ,
{ 0x2792 , 0x1209 } ,
{ 0x2794 , 0x8031 } ,
{ 0x2796 , 0x000C } ,
{ 0x2798 , 0x425F } ,
{ 0x279A , 0x0205 } ,
{ 0x279C , 0xC312 } ,
{ 0x279E , 0x104F } ,
{ 0x27A0 , 0x114F } ,
{ 0x27A2 , 0x114F } ,
{ 0x27A4 , 0x114F } ,
{ 0x27A6 , 0x114F } ,
{ 0x27A8 , 0x114F } ,
{ 0x27AA , 0xF37F } ,
{ 0x27AC , 0x4F0B } ,
{ 0x27AE , 0xF31B } ,
{ 0x27B0 , 0x5B0B } ,
{ 0x27B2 , 0x5B0B } ,
{ 0x27B4 , 0x5B0B } ,
{ 0x27B6 , 0x503B } ,
{ 0x27B8 , 0xD194 } ,
{ 0x27BA , 0x4219 } ,
{ 0x27BC , 0x0508 } ,
{ 0x27BE , 0xF039 } ,
{ 0x27C0 , 0x2000 } ,
{ 0x27C2 , 0x4F0A } ,
{ 0x27C4 , 0xC312 } ,
{ 0x27C6 , 0x100A } ,
{ 0x27C8 , 0xE31A } ,
{ 0x27CA , 0x421F } ,
{ 0x27CC , 0x87DE } ,
{ 0x27CE , 0x503F } ,
{ 0x27D0 , 0xFF60 } ,
{ 0x27D2 , 0x903F } ,
{ 0x27D4 , 0x00C8 } ,
{ 0x27D6 , 0x2C02 } ,
{ 0x27D8 , 0x403F } ,
{ 0x27DA , 0x00C8 } ,
{ 0x27DC , 0x4F82 } ,
{ 0x27DE , 0x7322 } ,
{ 0x27E0 , 0xB3D2 } ,
{ 0x27E2 , 0x0381 } ,
{ 0x27E4 , 0x2009 } ,
{ 0x27E6 , 0x421F } ,
{ 0x27E8 , 0x86F0 } ,
{ 0x27EA , 0xD21F } ,
{ 0x27EC , 0x86EE } ,
{ 0x27EE , 0x930F } ,
{ 0x27F0 , 0x24B9 } ,
{ 0x27F2 , 0x40F2 } ,
{ 0x27F4 , 0xFF80 } ,
{ 0x27F6 , 0x0619 } ,
{ 0x27F8 , 0x1292 } ,
{ 0x27FA , 0xD00A } ,
{ 0x27FC , 0xB3D2 } ,
{ 0x27FE , 0x0385 } ,
{ 0x2800 , 0x2405 } ,
{ 0x2802 , 0x421F } ,
{ 0x2804 , 0x880A } ,
{ 0x2806 , 0x4F92 } ,
{ 0x2808 , 0x0002 } ,
{ 0x280A , 0x8714 } ,
{ 0x280C , 0x430D } ,
{ 0x280E , 0x93C2 } ,
{ 0x2810 , 0x87D0 } ,
{ 0x2812 , 0x2003 } ,
{ 0x2814 , 0xB2F2 } ,
{ 0x2816 , 0x0360 } ,
{ 0x2818 , 0x2001 } ,
{ 0x281A , 0x431D } ,
{ 0x281C , 0x425F } ,
{ 0x281E , 0x87D3 } ,
{ 0x2820 , 0xD25F } ,
{ 0x2822 , 0x87D2 } ,
{ 0x2824 , 0xF37F } ,
{ 0x2826 , 0x5F0F } ,
{ 0x2828 , 0x425E } ,
{ 0x282A , 0x87CD } ,
{ 0x282C , 0xDE0F } ,
{ 0x282E , 0x5F0F } ,
{ 0x2830 , 0x5B0F } ,
{ 0x2832 , 0x4FA2 } ,
{ 0x2834 , 0x0402 } ,
{ 0x2836 , 0x930D } ,
{ 0x2838 , 0x2007 } ,
{ 0x283A , 0x930A } ,
{ 0x283C , 0x248E } ,
{ 0x283E , 0x4F5F } ,
{ 0x2840 , 0x0001 } ,
{ 0x2842 , 0xF37F } ,
{ 0x2844 , 0x4FC2 } ,
{ 0x2846 , 0x0403 } ,
{ 0x2848 , 0x93C2 } ,
{ 0x284A , 0x87CD } ,
{ 0x284C , 0x2483 } ,
{ 0x284E , 0xC2F2 } ,
{ 0x2850 , 0x0400 } ,
{ 0x2852 , 0xB2E2 } ,
{ 0x2854 , 0x0265 } ,
{ 0x2856 , 0x2407 } ,
{ 0x2858 , 0x421F } ,
{ 0x285A , 0x0508 } ,
{ 0x285C , 0xF03F } ,
{ 0x285E , 0xFFDF } ,
{ 0x2860 , 0xD90F } ,
{ 0x2862 , 0x4F82 } ,
{ 0x2864 , 0x0508 } ,
{ 0x2866 , 0xB3D2 } ,
{ 0x2868 , 0x0383 } ,
{ 0x286A , 0x2484 } ,
{ 0x286C , 0x403F } ,
{ 0x286E , 0x0508 } ,
{ 0x2870 , 0x4FB1 } ,
{ 0x2872 , 0x0000 } ,
{ 0x2874 , 0x4FB1 } ,
{ 0x2876 , 0x0002 } ,
{ 0x2878 , 0x4FB1 } ,
{ 0x287A , 0x0004 } ,
{ 0x287C , 0x403F } ,
{ 0x287E , 0x0500 } ,
{ 0x2880 , 0x4FB1 } ,
{ 0x2882 , 0x0006 } ,
{ 0x2884 , 0x4FB1 } ,
{ 0x2886 , 0x0008 } ,
{ 0x2888 , 0x4FB1 } ,
{ 0x288A , 0x000A } ,
{ 0x288C , 0xB3E2 } ,
{ 0x288E , 0x0383 } ,
{ 0x2890 , 0x2412 } ,
{ 0x2892 , 0xC2E1 } ,
{ 0x2894 , 0x0002 } ,
{ 0x2896 , 0xB2E2 } ,
{ 0x2898 , 0x0383 } ,
{ 0x289A , 0x434F } ,
{ 0x289C , 0x634F } ,
{ 0x289E , 0xF37F } ,
{ 0x28A0 , 0x4F4E } ,
{ 0x28A2 , 0x114E } ,
{ 0x28A4 , 0x434E } ,
{ 0x28A6 , 0x104E } ,
{ 0x28A8 , 0x415F } ,
{ 0x28AA , 0x0007 } ,
{ 0x28AC , 0xF07F } ,
{ 0x28AE , 0x007F } ,
{ 0x28B0 , 0xDE4F } ,
{ 0x28B2 , 0x4FC1 } ,
{ 0x28B4 , 0x0007 } ,
{ 0x28B6 , 0xB2F2 } ,
{ 0x28B8 , 0x0383 } ,
{ 0x28BA , 0x2415 } ,
{ 0x28BC , 0xF0F1 } ,
{ 0x28BE , 0xFFBF } ,
{ 0x28C0 , 0x0000 } ,
{ 0x28C2 , 0xB0F2 } ,
{ 0x28C4 , 0x0010 } ,
{ 0x28C6 , 0x0383 } ,
{ 0x28C8 , 0x434E } ,
{ 0x28CA , 0x634E } ,
{ 0x28CC , 0x5E4E } ,
{ 0x28CE , 0x5E4E } ,
{ 0x28D0 , 0x5E4E } ,
{ 0x28D2 , 0x5E4E } ,
{ 0x28D4 , 0x5E4E } ,
{ 0x28D6 , 0x5E4E } ,
{ 0x28D8 , 0x415F } ,
{ 0x28DA , 0x0006 } ,
{ 0x28DC , 0xF07F } ,
{ 0x28DE , 0xFFBF } ,
{ 0x28E0 , 0xDE4F } ,
{ 0x28E2 , 0x4FC1 } ,
{ 0x28E4 , 0x0006 } ,
{ 0x28E6 , 0xB0F2 } ,
{ 0x28E8 , 0x0020 } ,
{ 0x28EA , 0x0383 } ,
{ 0x28EC , 0x2410 } ,
{ 0x28EE , 0xF0F1 } ,
{ 0x28F0 , 0xFFDF } ,
{ 0x28F2 , 0x0002 } ,
{ 0x28F4 , 0xB0F2 } ,
{ 0x28F6 , 0x0040 } ,
{ 0x28F8 , 0x0383 } ,
{ 0x28FA , 0x434E } ,
{ 0x28FC , 0x634E } ,
{ 0x28FE , 0x5E4E } ,
{ 0x2900 , 0x5E4E } ,
{ 0x2902 , 0x415F } ,
{ 0x2904 , 0x0008 } ,
{ 0x2906 , 0xC26F } ,
{ 0x2908 , 0xDE4F } ,
{ 0x290A , 0x4FC1 } ,
{ 0x290C , 0x0008 } ,
{ 0x290E , 0x93C2 } ,
{ 0x2910 , 0x0383 } ,
{ 0x2912 , 0x3412 } ,
{ 0x2914 , 0xF0F1 } ,
{ 0x2916 , 0xFFDF } ,
{ 0x2918 , 0x0000 } ,
{ 0x291A , 0x425E } ,
{ 0x291C , 0x0382 } ,
{ 0x291E , 0xF35E } ,
{ 0x2920 , 0x5E4E } ,
{ 0x2922 , 0x5E4E } ,
{ 0x2924 , 0x5E4E } ,
{ 0x2926 , 0x5E4E } ,
{ 0x2928 , 0x5E4E } ,
{ 0x292A , 0x415F } ,
{ 0x292C , 0x0006 } ,
{ 0x292E , 0xF07F } ,
{ 0x2930 , 0xFFDF } ,
{ 0x2932 , 0xDE4F } ,
{ 0x2934 , 0x4FC1 } ,
{ 0x2936 , 0x0006 } ,
{ 0x2938 , 0x410F } ,
{ 0x293A , 0x4FB2 } ,
{ 0x293C , 0x0508 } ,
{ 0x293E , 0x4FB2 } ,
{ 0x2940 , 0x050A } ,
{ 0x2942 , 0x4FB2 } ,
{ 0x2944 , 0x050C } ,
{ 0x2946 , 0x4FB2 } ,
{ 0x2948 , 0x0500 } ,
{ 0x294A , 0x4FB2 } ,
{ 0x294C , 0x0502 } ,
{ 0x294E , 0x4FB2 } ,
{ 0x2950 , 0x0504 } ,
{ 0x2952 , 0x3C10 } ,
{ 0x2954 , 0xD2F2 } ,
{ 0x2956 , 0x0400 } ,
{ 0x2958 , 0x3F7C } ,
{ 0x295A , 0x4F6F } ,
{ 0x295C , 0xF37F } ,
{ 0x295E , 0x4FC2 } ,
{ 0x2960 , 0x0402 } ,
{ 0x2962 , 0x3F72 } ,
{ 0x2964 , 0x90F2 } ,
{ 0x2966 , 0x0011 } ,
{ 0x2968 , 0x0619 } ,
{ 0x296A , 0x2B46 } ,
{ 0x296C , 0x50F2 } ,
{ 0x296E , 0xFFF0 } ,
{ 0x2970 , 0x0619 } ,
{ 0x2972 , 0x3F42 } ,
{ 0x2974 , 0x5031 } ,
{ 0x2976 , 0x000C } ,
{ 0x2978 , 0x4139 } ,
{ 0x297A , 0x413A } ,
{ 0x297C , 0x413B } ,
{ 0x297E , 0x4130 } ,
{ 0x2980 , 0x0900 } ,
{ 0x2982 , 0x7312 } ,
{ 0x2984 , 0x421F } ,
{ 0x2986 , 0x0A08 } ,
{ 0x2988 , 0xF03F } ,
{ 0x298A , 0xF7FF } ,
{ 0x298C , 0x4F82 } ,
{ 0x298E , 0x0A88 } ,
{ 0x2990 , 0x0900 } ,
{ 0x2992 , 0x7312 } ,
{ 0x2994 , 0x421F } ,
{ 0x2996 , 0x0A0E } ,
{ 0x2998 , 0xF03F } ,
{ 0x299A , 0x7FFF } ,
{ 0x299C , 0x4F82 } ,
{ 0x299E , 0x0A8E } ,
{ 0x29A0 , 0x0900 } ,
{ 0x29A2 , 0x7312 } ,
{ 0x29A4 , 0x421F } ,
{ 0x29A6 , 0x0A1E } ,
{ 0x29A8 , 0xC31F } ,
{ 0x29AA , 0x4F82 } ,
{ 0x29AC , 0x0A9E } ,
{ 0x29AE , 0x4130 } ,
{ 0x29B0 , 0x4292 } ,
{ 0x29B2 , 0x0A08 } ,
{ 0x29B4 , 0x0A88 } ,
{ 0x29B6 , 0x0900 } ,
{ 0x29B8 , 0x7312 } ,
{ 0x29BA , 0x4292 } ,
{ 0x29BC , 0x0A0E } ,
{ 0x29BE , 0x0A8E } ,
{ 0x29C0 , 0x0900 } ,
{ 0x29C2 , 0x7312 } ,
{ 0x29C4 , 0x4292 } ,
{ 0x29C6 , 0x0A1E } ,
{ 0x29C8 , 0x0A9E } ,
{ 0x29CA , 0x4130 } ,
{ 0x29CC , 0x7400 } ,
{ 0x29CE , 0x8058 } ,
{ 0x29D0 , 0x1807 } ,
{ 0x29D2 , 0x00E0 } ,
{ 0x29D4 , 0x7002 } ,
{ 0x29D6 , 0x17C7 } ,
{ 0x29D8 , 0x0045 } ,
{ 0x29DA , 0x0006 } ,
{ 0x29DC , 0x17CC } ,
{ 0x29DE , 0x0015 } ,
{ 0x29E0 , 0x1512 } ,
{ 0x29E2 , 0x216F } ,
{ 0x29E4 , 0x005B } ,
{ 0x29E6 , 0x005D } ,
{ 0x29E8 , 0x00DE } ,
{ 0x29EA , 0x00DD } ,
{ 0x29EC , 0x5023 } ,
{ 0x29EE , 0x00DE } ,
{ 0x29F0 , 0x005B } ,
{ 0x29F2 , 0x0410 } ,
{ 0x29F4 , 0x0091 } ,
{ 0x29F6 , 0x0015 } ,
{ 0x29F8 , 0x0040 } ,
{ 0x29FA , 0x7023 } ,
{ 0x29FC , 0x1653 } ,
{ 0x29FE , 0x0156 } ,
{ 0x2A00 , 0x0001 } ,
{ 0x2A02 , 0x2081 } ,
{ 0x2A04 , 0x7020 } ,
{ 0x2A06 , 0x2F99 } ,
{ 0x2A08 , 0x005C } ,
{ 0x2A0A , 0x0000 } ,
{ 0x2A0C , 0x5040 } ,
{ 0x2A0E , 0x0045 } ,
{ 0x2A10 , 0x213A } ,
{ 0x2A12 , 0x0303 } ,
{ 0x2A14 , 0x0148 } ,
{ 0x2A16 , 0x0049 } ,
{ 0x2A18 , 0x0045 } ,
{ 0x2A1A , 0x0046 } ,
{ 0x2A1C , 0x05DD } ,
{ 0x2A1E , 0x00DE } ,
{ 0x2A20 , 0x00DD } ,
{ 0x2A22 , 0x00DC } ,
{ 0x2A24 , 0x00DE } ,
{ 0x2A26 , 0x04D6 } ,
{ 0x2A28 , 0x2014 } ,
{ 0x2A2A , 0x2081 } ,
{ 0x2A2C , 0x7087 } ,
{ 0x2A2E , 0x2F99 } ,
{ 0x2A30 , 0x005C } ,
{ 0x2A32 , 0x0002 } ,
{ 0x2A34 , 0x5060 } ,
{ 0x2A36 , 0x31C0 } ,
{ 0x2A38 , 0x2122 } ,
{ 0x2A3A , 0x7800 } ,
{ 0x2A3C , 0xC08C } ,
{ 0x2A3E , 0x0001 } ,
{ 0x2A40 , 0x9038 } ,
{ 0x2A42 , 0x59F7 } ,
{ 0x2A44 , 0x907A } ,
{ 0x2A46 , 0x03D8 } ,
{ 0x2A48 , 0x8D90 } ,
{ 0x2A4A , 0x01C0 } ,
{ 0x2A4C , 0x7400 } ,
{ 0x2A4E , 0x8058 } ,
{ 0x2A50 , 0x1807 } ,
{ 0x2A52 , 0x00E0 } ,
{ 0x2A54 , 0x7002 } ,
{ 0x2A56 , 0x17C7 } ,
{ 0x2A58 , 0x0045 } ,
{ 0x2A5A , 0x0006 } ,
{ 0x2A5C , 0x17CC } ,
{ 0x2A5E , 0x0015 } ,
{ 0x2A60 , 0x1512 } ,
{ 0x2A62 , 0x216F } ,
{ 0x2A64 , 0x005B } ,
{ 0x2A66 , 0x005D } ,
{ 0x2A68 , 0x00DE } ,
{ 0x2A6A , 0x00DD } ,
{ 0x2A6C , 0x5023 } ,
{ 0x2A6E , 0x00DE } ,
{ 0x2A70 , 0x005B } ,
{ 0x2A72 , 0x0410 } ,
{ 0x2A74 , 0x0091 } ,
{ 0x2A76 , 0x0015 } ,
{ 0x2A78 , 0x0040 } ,
{ 0x2A7A , 0x7023 } ,
{ 0x2A7C , 0x1653 } ,
{ 0x2A7E , 0x0156 } ,
{ 0x2A80 , 0x0001 } ,
{ 0x2A82 , 0x2081 } ,
{ 0x2A84 , 0x7020 } ,
{ 0x2A86 , 0x2F99 } ,
{ 0x2A88 , 0x005C } ,
{ 0x2A8A , 0x0000 } ,
{ 0x2A8C , 0x5040 } ,
{ 0x2A8E , 0x0045 } ,
{ 0x2A90 , 0x213A } ,
{ 0x2A92 , 0x0303 } ,
{ 0x2A94 , 0x0148 } ,
{ 0x2A96 , 0x0049 } ,
{ 0x2A98 , 0x0045 } ,
{ 0x2A9A , 0x0046 } ,
{ 0x2A9C , 0x05DD } ,
{ 0x2A9E , 0x00DE } ,
{ 0x2AA0 , 0x00DD } ,
{ 0x2AA2 , 0x00DC } ,
{ 0x2AA4 , 0x00DE } ,
{ 0x2AA6 , 0x0296 } ,
{ 0x2AA8 , 0x2014 } ,
{ 0x2AAA , 0x2081 } ,
{ 0x2AAC , 0x7087 } ,
{ 0x2AAE , 0x2F99 } ,
{ 0x2AB0 , 0x005C } ,
{ 0x2AB2 , 0x0002 } ,
{ 0x2AB4 , 0x5060 } ,
{ 0x2AB6 , 0x31C0 } ,
{ 0x2AB8 , 0x2122 } ,
{ 0x2ABA , 0x7800 } ,
{ 0x2ABC , 0xC08C } ,
{ 0x2ABE , 0x0001 } ,
{ 0x2AC0 , 0x9038 } ,
{ 0x2AC2 , 0x59F7 } ,
{ 0x2AC4 , 0x907A } ,
{ 0x2AC6 , 0x03D8 } ,
{ 0x2AC8 , 0x8D90 } ,
{ 0x2ACA , 0x01C0 } ,
{ 0x2ACC , 0x7400 } ,
{ 0x2ACE , 0x2002 } ,
{ 0x2AD0 , 0x70DF } ,
{ 0x2AD2 , 0x2F21 } ,
{ 0x2AD4 , 0x04C1 } ,
{ 0x2AD6 , 0x0D80 } ,
{ 0x2AD8 , 0x7800 } ,
{ 0x2ADA , 0x0041 } ,
{ 0x2ADC , 0x7400 } ,
{ 0x2ADE , 0x2004 } ,
{ 0x2AE0 , 0x70DF } ,
{ 0x2AE2 , 0x2F21 } ,
{ 0x2AE4 , 0x04C2 } ,
{ 0x2AE6 , 0x0D80 } ,
{ 0x2AE8 , 0x7800 } ,
{ 0x2AEA , 0x7400 } ,
{ 0x2AEC , 0x2008 } ,
{ 0x2AEE , 0x70DF } ,
{ 0x2AF0 , 0x2F21 } ,
{ 0x2AF2 , 0x04C3 } ,
{ 0x2AF4 , 0x0D80 } ,
{ 0x2AF6 , 0x7800 } ,
{ 0x2AF8 , 0x7400 } ,
{ 0x2AFA , 0x0004 } ,
{ 0x2AFC , 0x70DF } ,
{ 0x2AFE , 0x2F22 } ,
{ 0x2B00 , 0x7008 } ,
{ 0x2B02 , 0x2F1F } ,
{ 0x2B04 , 0x7021 } ,
{ 0x2B06 , 0x2F01 } ,
{ 0x2B08 , 0x7800 } ,
{ 0x2B0A , 0x7400 } ,
{ 0x2B0C , 0x0002 } ,
{ 0x2B0E , 0x70DF } ,
{ 0x2B10 , 0x3F5F } ,
{ 0x2B12 , 0x703A } ,
{ 0x2B14 , 0x2F01 } ,
{ 0x2B16 , 0x7800 } ,
{ 0x2B18 , 0x7400 } ,
{ 0x2B1A , 0x2010 } ,
{ 0x2B1C , 0x70DF } ,
{ 0x2B1E , 0x3F40 } ,
{ 0x2B20 , 0x700A } ,
{ 0x2B22 , 0x0FC0 } ,
{ 0x2B24 , 0x7800 } ,
{ 0x2B26 , 0x7400 } ,
{ 0x2B28 , 0x2004 } ,
{ 0x2B2A , 0x70DF } ,
{ 0x2B2C , 0x2F21 } ,
{ 0x2B2E , 0x04C2 } ,
{ 0x2B30 , 0x0D80 } ,
{ 0x2B32 , 0x7800 } ,
{ 0x2B34 , 0x0041 } ,
{ 0x2B36 , 0x7400 } ,
{ 0x2B38 , 0x2002 } ,
{ 0x2B3A , 0x70DF } ,
{ 0x2B3C , 0x2F22 } ,
{ 0x2B3E , 0x04C1 } ,
{ 0x2B40 , 0x0D80 } ,
{ 0x2B42 , 0x7800 } ,
{ 0x2B44 , 0x7400 } ,
{ 0x2B46 , 0x0001 } ,
{ 0x2B48 , 0x70DF } ,
{ 0x2B4A , 0x3F5F } ,
{ 0x2B4C , 0x703A } ,
{ 0x2B4E , 0x2F01 } ,
{ 0x2B50 , 0x7800 } ,
{ 0x2B52 , 0x7400 } ,
{ 0x2B54 , 0x200A } ,
{ 0x2B56 , 0x70DF } ,
{ 0x2B58 , 0x3F40 } ,
{ 0x2B5A , 0x700A } ,
{ 0x2B5C , 0x0FC0 } ,
{ 0x2B5E , 0x7800 } ,
{ 0x2B60 , 0x7400 } ,
{ 0x2B62 , 0x2015 } ,
{ 0x2B64 , 0x70DF } ,
{ 0x2B66 , 0x3F5F } ,
{ 0x2B68 , 0x703A } ,
{ 0x2B6A , 0x2F01 } ,
{ 0x2B6C , 0x7800 } ,
{ 0x2B6E , 0x7400 } ,
{ 0x2B70 , 0x7800 } ,
{ 0x2B72 , 0x007F } ,
{ 0x2B74 , 0x0000 } ,
{ 0x2B76 , 0xB9CC } ,
{ 0x2B78 , 0x0000 } ,
{ 0x2B7A , 0xB9CC } ,
{ 0x2B7C , 0xBA3C } ,
{ 0x2B7E , 0x0002 } ,
{ 0x2B80 , 0x0000 } ,
{ 0x2B82 , 0xBA4C } ,
{ 0x2B84 , 0x0000 } ,
{ 0x2B86 , 0xBA4C } ,
{ 0x2B88 , 0xBABC } ,
{ 0x2B8A , 0x0002 } ,
{ 0x2B8C , 0x0063 } ,
{ 0x2B8E , 0xBB26 } ,
{ 0x2B90 , 0x0063 } ,
{ 0x2B92 , 0xBB36 } ,
{ 0x2B94 , 0x0063 } ,
{ 0x2B96 , 0xBAEA } ,
{ 0x2B98 , 0x0063 } ,
{ 0x2B9A , 0xBAF8 } ,
{ 0x2B9C , 0xBADA } ,
{ 0x2B9E , 0x0004 } ,
{ 0x2BA0 , 0x0063 } ,
{ 0x2BA2 , 0xBAEA } ,
{ 0x2BA4 , 0x0063 } ,
{ 0x2BA6 , 0xBB18 } ,
{ 0x2BA8 , 0x0063 } ,
{ 0x2BAA , 0xBB26 } ,
{ 0x2BAC , 0x0063 } ,
{ 0x2BAE , 0xBB44 } ,
{ 0x2BB0 , 0xBADA } ,
{ 0x2BB2 , 0x0004 } ,
{ 0x2BB4 , 0x0063 } ,
{ 0x2BB6 , 0xBACC } ,
{ 0x2BB8 , 0x0063 } ,
{ 0x2BBA , 0xBADC } ,
{ 0x2BBC , 0x0063 } ,
{ 0x2BBE , 0xBAEA } ,
{ 0x2BC0 , 0x0063 } ,
{ 0x2BC2 , 0xBAF8 } ,
{ 0x2BC4 , 0xBADA } ,
{ 0x2BC6 , 0x0004 } ,
{ 0x2BC8 , 0x0063 } ,
{ 0x2BCA , 0xBAEA } ,
{ 0x2BCC , 0x0063 } ,
{ 0x2BCE , 0xBB18 } ,
{ 0x2BD0 , 0x0063 } ,
{ 0x2BD2 , 0xBACC } ,
{ 0x2BD4 , 0x0063 } ,
{ 0x2BD6 , 0xBB0A } ,
{ 0x2BD8 , 0xBADA } ,
{ 0x2BDA , 0x0004 } ,
{ 0x2BDC , 0x0063 } ,
{ 0x2BDE , 0xBACC } ,
{ 0x2BE0 , 0x0063 } ,
{ 0x2BE2 , 0xBADC } ,
{ 0x2BE4 , 0x0063 } ,
{ 0x2BE6 , 0xBAEA } ,
{ 0x2BE8 , 0x0063 } ,
{ 0x2BEA , 0xBB18 } ,
{ 0x2BEC , 0xBADA } ,
{ 0x2BEE , 0x0004 } ,
{ 0x2BF0 , 0xFFFF } ,
{ 0x2BF2 , 0xBB6E } ,
{ 0x2BF4 , 0x0000 } ,
{ 0x2BF6 , 0x0000 } ,
{ 0x2BF8 , 0x0000 } ,
{ 0x2BFA , 0x0000 } ,
{ 0x2BFC , 0x0000 } ,
{ 0x2BFE , 0x0000 } ,
{ 0x2C00 , 0xBB72 } ,
{ 0x2C02 , 0x0001 } ,
{ 0x2C04 , 0x0063 } ,
{ 0x2C06 , 0xBB52 } ,
{ 0x2C08 , 0x0063 } ,
{ 0x2C0A , 0xBB60 } ,
{ 0x2C0C , 0x0000 } ,
{ 0x2C0E , 0x0000 } ,
{ 0x2C10 , 0x0000 } ,
{ 0x2C12 , 0x0000 } ,
{ 0x2C14 , 0xBADA } ,
{ 0x2C16 , 0x0002 } ,
{ 0x2C18 , 0x0066 } ,
{ 0x2C1A , 0x0067 } ,
{ 0x2C1C , 0x00AF } ,
{ 0x2C1E , 0x01CF } ,
{ 0x2C20 , 0x0087 } ,
{ 0x2C22 , 0x0083 } ,
{ 0x2C24 , 0x011B } ,
{ 0x2C26 , 0x035A } ,
{ 0x2C28 , 0x00FA } ,
{ 0x2C2A , 0x00F2 } ,
{ 0x2C2C , 0x00A6 } ,
{ 0x2C2E , 0x00A4 } ,
{ 0x2C30 , 0xFFFF } ,
{ 0x2C32 , 0x002C } ,
{ 0x2C34 , 0x0058 } ,
{ 0x2C36 , 0x0000 } ,
{ 0x2C38 , 0x0000 } ,
{ 0x2C3A , 0xBC18 } ,
{ 0x2C3C , 0xBB74 } ,
{ 0x2C3E , 0xBB80 } ,
{ 0x2C40 , 0xBC32 } ,
{ 0x2C42 , 0xBB8C } ,
{ 0x2C44 , 0xBBA0 } ,
{ 0x2C46 , 0xBB8C } ,
{ 0x2C48 , 0xBBA0 } ,
{ 0x2C4A , 0xBC04 } ,
{ 0x2C4C , 0xBC04 } ,
{ 0x2C4E , 0xBBF0 } ,
{ 0x2C50 , 0xBBF0 } ,
{ 0x2C52 , 0xBBB4 } ,
{ 0x2C54 , 0xBBC8 } ,
{ 0x2C56 , 0xBBB4 } ,
{ 0x2C58 , 0xBBC8 } ,
{ 0x2C5A , 0xBC04 } ,
{ 0x2C5C , 0xBC04 } ,
{ 0x2C5E , 0xBBF0 } ,
{ 0x2C60 , 0xBBF0 } ,
{ 0x2C62 , 0xBB8C } ,
{ 0x2C64 , 0xBBA0 } ,
{ 0x2C66 , 0xBB8C } ,
{ 0x2C68 , 0xBBA0 } ,
{ 0x2C6A , 0xBC04 } ,
{ 0x2C6C , 0xBC04 } ,
{ 0x2C6E , 0xBBF0 } ,
{ 0x2C70 , 0xBBF0 } ,
{ 0x2C72 , 0xBBB4 } ,
{ 0x2C74 , 0xBBC8 } ,
{ 0x2C76 , 0xBBB4 } ,
{ 0x2C78 , 0xBBC8 } ,
{ 0x2C7A , 0xBC04 } ,
{ 0x2C7C , 0xBC04 } ,
{ 0x2C7E , 0xBBF0 } ,
{ 0x2C80 , 0xBBF0 } ,
{ 0x3800 , 0x880E } ,
{ 0x3802 , 0xBC62 } ,
{ 0x3804 , 0xBC40 } ,
{ 0x3806 , 0xD13E } ,
{ 0x3808 , 0xBC42 } ,
{ 0x380A , 0xBC3C } ,
{ 0x380C , 0x0000 } ,
{ 0x380E , 0x0040 } ,
{ 0x3810 , 0x0040 } ,
{ 0x3812 , 0x0040 } ,
{ 0x3814 , 0x0043 } ,
{ 0x3816 , 0x0046 } ,
{ 0x3818 , 0x004B } ,
{ 0x381A , 0x004D } ,
{ 0x381C , 0x0051 } ,
{ 0x381E , 0x0055 } ,
{ 0x3820 , 0x005A } ,
{ 0x3822 , 0x005E } ,
{ 0x3824 , 0x0062 } ,
{ 0x3826 , 0x0067 } ,
{ 0x3828 , 0x006C } ,
{ 0x382A , 0x0070 } ,
{ 0x382C , 0x0078 } ,
{ 0x382E , 0x0086 } ,
{ 0x3830 , 0x0090 } ,
{ 0x3832 , 0x0096 } ,
{ 0x3834 , 0x009D } ,
{ 0x3836 , 0x00A5 } ,
{ 0x3838 , 0x00AD } ,
{ 0x383A , 0x00B4 } ,
{ 0x383C , 0x00B9 } ,
{ 0x383E , 0x00BE } ,
{ 0x3840 , 0x00C3 } ,
{ 0x3842 , 0x00C8 } ,
{ 0x3844 , 0x00CD } ,
{ 0x3846 , 0x00D2 } ,
{ 0x3848 , 0x00D7 } ,
{ 0x384A , 0x00DC } ,
{ 0x384C , 0x00DC } ,
{ 0x384E , 0x0000 } ,
{ 0x3850 , 0x0000 } ,
{ 0x3852 , 0x0000 } ,
{ 0x3854 , 0x0000 } ,
{ 0x3856 , 0x0000 } ,
{ 0x3858 , 0x0000 } ,
{ 0x385A , 0x0000 } ,
{ 0x385C , 0x0000 } ,
{ 0x385E , 0x0000 } ,
{ 0x3860 , 0x0000 } ,
{ 0x3862 , 0x0000 } ,
{ 0x3864 , 0x0000 } ,
{ 0x3866 , 0x0000 } ,
{ 0x3868 , 0x0000 } ,
{ 0x386A , 0x0000 } ,
{ 0x386C , 0x0000 } ,
{ 0x386E , 0x0000 } ,
{ 0x3870 , 0x0000 } ,
{ 0x3872 , 0x0000 } ,
{ 0x3874 , 0x0000 } ,
{ 0x3876 , 0x0000 } ,
{ 0x3878 , 0x0000 } ,
{ 0x387A , 0x0000 } ,
{ 0x387C , 0x0000 } ,
{ 0x387E , 0x0000 } ,
{ 0x3880 , 0x0000 } ,
{ 0x3882 , 0x0000 } ,
{ 0x3884 , 0x0000 } ,
{ 0x3886 , 0x0000 } ,
{ 0x3888 , 0x0000 } ,
{ 0x388A , 0x0000 } ,
{ 0x388C , 0x0000 } ,
{ 0x026A , 0xFFFF } ,
{ 0x026C , 0x00FF } ,
{ 0x026E , 0x0000 } ,
{ 0x0360 , 0x1E8E } ,
{ 0x040E , 0x01EB } ,
{ 0x0600 , 0x1130 } ,
{ 0x0602 , 0x3112 } ,
{ 0x0604 , 0x8048 } ,
{ 0x0606 , 0x00E9 } ,
{ 0x067A , 0x0404 } ,
{ 0x067C , 0x0404 } ,
{ 0x06A8 , 0x0240 } ,
{ 0x06AA , 0x00CA } ,
{ 0x06AC , 0x0041 } ,
{ 0x06B4 , 0x3FFF } ,
{ 0x06DE , 0x0404 } ,
{ 0x06E0 , 0x0404 } ,
{ 0x06E2 , 0xFF00 } ,
{ 0x06E4 , 0x8333 } ,
{ 0x06E6 , 0x8333 } ,
{ 0x06E8 , 0x8333 } ,
{ 0x06EA , 0x8333 } ,
{ 0x052A , 0x0000 } ,
{ 0x052C , 0x0000 } ,
{ 0x0F06 , 0x0002 } ,
{ 0x0A04 , 0xB4C5 } ,
{ 0x0A06 , 0xC400 } ,
{ 0x0A08 , 0x988A } ,
{ 0x0A0A , 0xA387 } ,
{ 0x0A0E , 0xEEC0 } ,
{ 0x0A12 , 0x0000 } ,
{ 0x0A18 , 0x0010 } ,
{ 0x0A1C , 0x0040 } ,
{ 0x0A20 , 0x0015 } ,
{ 0x0C00 , 0x0021 } ,
{ 0x0C16 , 0x0002 } ,
{ 0x0708 , 0x6FC0 } ,
{ 0x070C , 0x0000 } ,
{ 0x120C , 0x1428 } ,
{ 0x121A , 0x0000 } ,
{ 0x121C , 0x1896 } ,
{ 0x121E , 0x0032 } ,
{ 0x1220 , 0x0000 } ,
{ 0x1222 , 0x96FF } ,
{ 0x1244 , 0x0000 } ,
{ 0x105C , 0x0F0B } ,
{ 0x1958 , 0x0000 } ,
{ 0x195A , 0x004C } ,
{ 0x195C , 0x0097 } ,
{ 0x195E , 0x0221 } ,
{ 0x1960 , 0x03FE } ,
{ 0x1980 , 0x00E0 } ,
{ 0x1982 , 0x0010 } ,
{ 0x1984 , 0x2018 } ,
{ 0x1986 , 0x0008 } ,
{ 0x1988 , 0x0000 } ,
{ 0x198A , 0x0000 } ,
{ 0x198C , 0x0880 } ,
{ 0x198E , 0x0000 } ,
{ 0x1990 , 0x1A00 } ,
{ 0x1992 , 0x0000 } ,
{ 0x1994 , 0x2800 } ,
{ 0x1996 , 0x0002 } ,
{ 0x1962 , 0x0000 } ,
{ 0x1964 , 0x004C } ,
{ 0x1966 , 0x0097 } ,
{ 0x1968 , 0x0221 } ,
{ 0x196A , 0x03FE } ,
{ 0x19C0 , 0x00E0 } ,
{ 0x19C2 , 0x0010 } ,
{ 0x19C4 , 0x2018 } ,
{ 0x19C6 , 0x0008 } ,
{ 0x19C8 , 0x0000 } ,
{ 0x19CA , 0x0000 } ,
{ 0x19CC , 0x0880 } ,
{ 0x19CE , 0x0000 } ,
{ 0x19D0 , 0x1A00 } ,
{ 0x19D2 , 0x0000 } ,
{ 0x19D4 , 0x2800 } ,
{ 0x19D6 , 0x0002 } ,
{ 0x196C , 0x0000 } ,
{ 0x196E , 0x004C } ,
{ 0x1970 , 0x0097 } ,
{ 0x1972 , 0x0221 } ,
{ 0x1974 , 0x03FE } ,
{ 0x1A00 , 0x00E0 } ,
{ 0x1A02 , 0x0010 } ,
{ 0x1A04 , 0x2018 } ,
{ 0x1A06 , 0x0008 } ,
{ 0x1A08 , 0x0000 } ,
{ 0x1A0A , 0x0000 } ,
{ 0x1A0C , 0x0880 } ,
{ 0x1A0E , 0x0000 } ,
{ 0x1A10 , 0x1A00 } ,
{ 0x1A12 , 0x0000 } ,
{ 0x1A14 , 0x2800 } ,
{ 0x1A16 , 0x0002 } ,
{ 0x1976 , 0x0000 } ,
{ 0x1978 , 0x004C } ,
{ 0x197A , 0x0097 } ,
{ 0x197C , 0x0221 } ,
{ 0x197E , 0x03FE } ,
{ 0x1A40 , 0x00E0 } ,
{ 0x1A42 , 0x0010 } ,
{ 0x1A44 , 0x2018 } ,
{ 0x1A46 , 0x0008 } ,
{ 0x1A48 , 0x0000 } ,
{ 0x1A4A , 0x0000 } ,
{ 0x1A4C , 0x0880 } ,
{ 0x1A4E , 0x0000 } ,
{ 0x1A50 , 0x1A00 } ,
{ 0x1A52 , 0x0000 } ,
{ 0x1A54 , 0x2800 } ,
{ 0x1A56 , 0x0002 } ,
{ 0x192A , 0x0201 } ,
{ 0x0384 , 0x0001 } ,
{ 0x027E , 0x0100 } ,
} ;
static const struct hi847_reg mode_3264x2448_regs [ ] = {
{ 0x0B00 , 0x0000 } ,
{ 0x0204 , 0x0000 } ,
{ 0x0206 , 0x033C } ,
{ 0x020A , 0x0B4D } ,
{ 0x020E , 0x0B51 } ,
{ 0x0214 , 0x0200 } ,
{ 0x0216 , 0x0200 } ,
{ 0x0218 , 0x0200 } ,
{ 0x021A , 0x0200 } ,
{ 0x0224 , 0x002E } ,
{ 0x022A , 0x0017 } ,
{ 0x022C , 0x0E1F } ,
{ 0x022E , 0x09C1 } ,
{ 0x0234 , 0x1111 } ,
{ 0x0236 , 0x1111 } ,
{ 0x0238 , 0x1111 } ,
{ 0x023A , 0x1111 } ,
{ 0x0250 , 0x0000 } ,
{ 0x0252 , 0x0006 } ,
{ 0x0254 , 0x0000 } ,
{ 0x0256 , 0x0000 } ,
{ 0x0258 , 0x0000 } ,
{ 0x025A , 0x0000 } ,
{ 0x025C , 0x0000 } ,
{ 0x025E , 0x0202 } ,
{ 0x0268 , 0x00CD } ,
{ 0x0440 , 0x0002 } ,
{ 0x0F00 , 0x0000 } ,
{ 0x0F04 , 0x0008 } ,
{ 0x0F06 , 0x0002 } ,
{ 0x0B02 , 0x0100 } ,
{ 0x0B04 , 0x00DC } ,
{ 0x0B12 , 0x0CC0 } ,
{ 0x0B14 , 0x0990 } ,
{ 0x0B20 , 0x0100 } ,
{ 0x1100 , 0x1100 } ,
{ 0x1102 , 0x0008 } ,
{ 0x1108 , 0x0202 } ,
{ 0x1118 , 0x0000 } ,
{ 0x0A10 , 0xB040 } ,
{ 0x0C14 , 0x0008 } ,
{ 0x0C18 , 0x0CC0 } ,
{ 0x0C1A , 0x0990 } ,
{ 0x0730 , 0x0001 } ,
{ 0x0732 , 0x0000 } ,
{ 0x0734 , 0x0300 } ,
{ 0x0736 , 0x004B } ,
{ 0x0738 , 0x0001 } ,
{ 0x073C , 0x0900 } ,
{ 0x0740 , 0x0000 } ,
{ 0x0742 , 0x0000 } ,
{ 0x0744 , 0x0300 } ,
{ 0x0746 , 0x007D } ,
{ 0x0748 , 0x0002 } ,
{ 0x074A , 0x0900 } ,
{ 0x074C , 0x0000 } ,
{ 0x074E , 0x0100 } ,
{ 0x0750 , 0x0000 } ,
{ 0x1200 , 0x0946 } ,
{ 0x1202 , 0x1A00 } ,
{ 0x120E , 0x6027 } ,
{ 0x1210 , 0x8027 } ,
{ 0x1246 , 0x0105 } ,
{ 0x1000 , 0x0300 } ,
{ 0x1002 , 0xC311 } ,
{ 0x1004 , 0x2BB0 } ,
{ 0x1010 , 0x087B } ,
{ 0x1012 , 0x0040 } ,
{ 0x1014 , 0x0020 } ,
{ 0x1016 , 0x0020 } ,
{ 0x101A , 0x0020 } ,
{ 0x1020 , 0xC107 } ,
{ 0x1022 , 0x081E } ,
{ 0x1024 , 0x0509 } ,
{ 0x1026 , 0x0B0A } ,
{ 0x1028 , 0x1409 } ,
{ 0x102A , 0x0B05 } ,
{ 0x102C , 0x1400 } ,
{ 0x1038 , 0x0000 } ,
{ 0x103E , 0x0001 } ,
{ 0x1040 , 0x0000 } ,
{ 0x1042 , 0x0008 } ,
{ 0x1044 , 0x0120 } ,
{ 0x1046 , 0x01B0 } ,
{ 0x1048 , 0x0090 } ,
{ 0x1066 , 0x089C } ,
{ 0x1600 , 0x0000 } ,
{ 0x1608 , 0x0028 } ,
{ 0x160A , 0x0C80 } ,
{ 0x160C , 0x001A } ,
{ 0x160E , 0x0960 } ,
{ 0x0252 , 0x0009 } ,
{ 0x0202 , 0x0000 } ,
} ;
static const struct hi847_reg mode_1632x1224_regs [ ] = {
{ 0x0B00 , 0x0000 } ,
{ 0x0204 , 0x0200 } ,
{ 0x0206 , 0x033C } ,
{ 0x020A , 0x05A5 } ,
{ 0x020E , 0x05A9 } ,
{ 0x0214 , 0x0200 } ,
{ 0x0216 , 0x0200 } ,
{ 0x0218 , 0x0200 } ,
{ 0x021A , 0x0200 } ,
{ 0x0224 , 0x002C } ,
{ 0x022A , 0x0015 } ,
{ 0x022C , 0x0E2D } ,
{ 0x022E , 0x09C1 } ,
{ 0x0234 , 0x3311 } ,
{ 0x0236 , 0x3311 } ,
{ 0x0238 , 0x3311 } ,
{ 0x023A , 0x2222 } ,
{ 0x0250 , 0x0000 } ,
{ 0x0252 , 0x0006 } ,
{ 0x0254 , 0x0000 } ,
{ 0x0256 , 0x0000 } ,
{ 0x0258 , 0x0000 } ,
{ 0x025A , 0x0000 } ,
{ 0x025C , 0x0000 } ,
{ 0x025E , 0x0202 } ,
{ 0x0268 , 0x00CD } ,
{ 0x0440 , 0x0002 } ,
{ 0x0F00 , 0x0400 } ,
{ 0x0F04 , 0x0004 } ,
{ 0x0F06 , 0x0002 } ,
{ 0x0B02 , 0x0100 } ,
{ 0x0B04 , 0x00FC } ,
{ 0x0B12 , 0x0660 } ,
{ 0x0B14 , 0x04C8 } ,
{ 0x0B20 , 0x0200 } ,
{ 0x1100 , 0x1100 } ,
{ 0x1102 , 0x0008 } ,
{ 0x1108 , 0x0402 } ,
{ 0x1118 , 0x0000 } ,
{ 0x0A10 , 0xB060 } ,
{ 0x0C14 , 0x0008 } ,
{ 0x0C18 , 0x0CC0 } ,
{ 0x0C1A , 0x04C8 } ,
{ 0x0730 , 0x0001 } ,
{ 0x0732 , 0x0000 } ,
{ 0x0734 , 0x0300 } ,
{ 0x0736 , 0x004B } ,
{ 0x0738 , 0x0001 } ,
{ 0x073C , 0x0900 } ,
{ 0x0740 , 0x0000 } ,
{ 0x0742 , 0x0000 } ,
{ 0x0744 , 0x0300 } ,
{ 0x0746 , 0x007D } ,
{ 0x0748 , 0x0002 } ,
{ 0x074A , 0x0900 } ,
{ 0x074C , 0x0100 } ,
{ 0x074E , 0x0100 } ,
{ 0x0750 , 0x0000 } ,
{ 0x1200 , 0x0946 } ,
{ 0x1202 , 0x1A00 } ,
{ 0x120E , 0x6027 } ,
{ 0x1210 , 0x8027 } ,
{ 0x1246 , 0x0105 } ,
{ 0x1000 , 0x0300 } ,
{ 0x1002 , 0xC311 } ,
{ 0x1004 , 0x2BB0 } ,
{ 0x1010 , 0x042B } ,
{ 0x1012 , 0x0012 } ,
{ 0x1014 , 0x0020 } ,
{ 0x1016 , 0x0020 } ,
{ 0x101A , 0x0020 } ,
{ 0x1020 , 0xC103 } ,
{ 0x1022 , 0x040F } ,
{ 0x1024 , 0x0304 } ,
{ 0x1026 , 0x0607 } ,
{ 0x1028 , 0x0D06 } ,
{ 0x102A , 0x0605 } ,
{ 0x102C , 0x0C00 } ,
{ 0x1038 , 0x0000 } ,
{ 0x103E , 0x0101 } ,
{ 0x1040 , 0x0000 } ,
{ 0x1042 , 0x0008 } ,
{ 0x1044 , 0x0120 } ,
{ 0x1046 , 0x01B0 } ,
{ 0x1048 , 0x0090 } ,
{ 0x1066 , 0x043B } ,
{ 0x1600 , 0x0400 } ,
{ 0x1608 , 0x0028 } ,
{ 0x160A , 0x0C80 } ,
{ 0x160C , 0x001A } ,
{ 0x160E , 0x0960 } ,
{ 0x0252 , 0x0009 } ,
{ 0x0202 , 0x0000 } ,
} ;
static const char * const hi847_test_pattern_menu [ ] = {
" No Pattern " ,
" Solid Colour " ,
" 100% Colour Bars " ,
" Fade To Grey Colour Bars " ,
" PN9 " ,
" Horizontal Gradient Pattern " ,
" Vertical Gradient Pattern " ,
" Check Board " ,
" Slant Pattern " ,
} ;
static const s64 link_freq_menu_items [ ] = {
HI847_LINK_FREQ_400MHZ ,
HI847_LINK_FREQ_200MHZ ,
} ;
static const struct hi847_link_freq_config link_freq_configs [ ] = {
[ HI847_LINK_FREQ_400MHZ_INDEX ] = {
. reg_list = {
. num_of_regs = ARRAY_SIZE ( mipi_data_rate_lane_4 ) ,
. regs = mipi_data_rate_lane_4 ,
}
} ,
[ HI847_LINK_FREQ_200MHZ_INDEX ] = {
. reg_list = {
. num_of_regs = ARRAY_SIZE ( mipi_data_rate_lane_4 ) ,
. regs = mipi_data_rate_lane_4 ,
}
}
} ;
static const struct hi847_mode supported_modes [ ] = {
{
. width = 3264 ,
. height = 2448 ,
. fll_def = HI847_FLL_30FPS ,
. fll_min = HI847_FLL_30FPS_MIN ,
. llp = 0x033C ,
. reg_list = {
. num_of_regs = ARRAY_SIZE ( mode_3264x2448_regs ) ,
. regs = mode_3264x2448_regs ,
} ,
. link_freq_index = HI847_LINK_FREQ_400MHZ_INDEX ,
} ,
{
. width = 1632 ,
. height = 1224 ,
. fll_def = HI847_FLL_60FPS ,
. fll_min = HI847_FLL_60FPS_MIN ,
. llp = 0x033C ,
. reg_list = {
. num_of_regs = ARRAY_SIZE ( mode_1632x1224_regs ) ,
. regs = mode_1632x1224_regs ,
} ,
. link_freq_index = HI847_LINK_FREQ_200MHZ_INDEX ,
}
} ;
struct hi847 {
struct v4l2_subdev sd ;
struct media_pad pad ;
struct v4l2_ctrl_handler ctrl_handler ;
/* V4L2 Controls */
struct v4l2_ctrl * link_freq ;
struct v4l2_ctrl * pixel_rate ;
struct v4l2_ctrl * vblank ;
struct v4l2_ctrl * hblank ;
struct v4l2_ctrl * exposure ;
struct v4l2_ctrl * vflip ;
struct v4l2_ctrl * hflip ;
/* Current mode */
const struct hi847_mode * cur_mode ;
/* To serialize asynchronus callbacks */
struct mutex mutex ;
} ;
static u64 to_pixel_rate ( u32 f_index )
{
u64 pixel_rate = link_freq_menu_items [ f_index ] * 2 * HI847_DATA_LANES ;
do_div ( pixel_rate , HI847_RGB_DEPTH ) ;
return pixel_rate ;
}
static int hi847_read_reg ( struct hi847 * hi847 , u16 reg , u16 len , u32 * val )
{
struct i2c_client * client = v4l2_get_subdevdata ( & hi847 - > sd ) ;
struct i2c_msg msgs [ 2 ] ;
u8 addr_buf [ 2 ] ;
u8 data_buf [ 4 ] = { 0 } ;
int ret ;
if ( len > 4 )
return - EINVAL ;
put_unaligned_be16 ( reg , addr_buf ) ;
msgs [ 0 ] . addr = client - > addr ;
msgs [ 0 ] . flags = 0 ;
msgs [ 0 ] . len = sizeof ( addr_buf ) ;
msgs [ 0 ] . buf = addr_buf ;
msgs [ 1 ] . addr = client - > addr ;
msgs [ 1 ] . flags = I2C_M_RD ;
msgs [ 1 ] . len = len ;
msgs [ 1 ] . buf = & data_buf [ 4 - len ] ;
ret = i2c_transfer ( client - > adapter , msgs , ARRAY_SIZE ( msgs ) ) ;
if ( ret ! = ARRAY_SIZE ( msgs ) )
return - EIO ;
* val = get_unaligned_be32 ( data_buf ) ;
return 0 ;
}
static int hi847_write_reg ( struct hi847 * hi847 , u16 reg , u16 len , u32 val )
{
struct i2c_client * client = v4l2_get_subdevdata ( & hi847 - > sd ) ;
u8 buf [ 6 ] ;
if ( len > 4 )
return - EINVAL ;
put_unaligned_be16 ( reg , buf ) ;
put_unaligned_be32 ( val < < 8 * ( 4 - len ) , buf + 2 ) ;
if ( i2c_master_send ( client , buf , len + 2 ) ! = len + 2 )
return - EIO ;
return 0 ;
}
static int hi847_write_reg_list ( struct hi847 * hi847 ,
const struct hi847_reg_list * r_list )
{
struct i2c_client * client = v4l2_get_subdevdata ( & hi847 - > sd ) ;
unsigned int i ;
int ret ;
for ( i = 0 ; i < r_list - > num_of_regs ; i + + ) {
ret = hi847_write_reg ( hi847 , r_list - > regs [ i ] . address ,
HI847_REG_VALUE_16BIT ,
r_list - > regs [ i ] . val ) ;
if ( ret ) {
dev_err_ratelimited ( & client - > dev ,
" failed to write reg 0x%4.4x. error = %d " ,
r_list - > regs [ i ] . address , ret ) ;
return ret ;
}
}
return 0 ;
}
static int hi847_update_digital_gain ( struct hi847 * hi847 , u32 d_gain )
{
int ret ;
ret = hi847_write_reg ( hi847 , HI847_REG_MWB_GR_GAIN ,
HI847_REG_VALUE_16BIT , d_gain ) ;
if ( ret )
return ret ;
ret = hi847_write_reg ( hi847 , HI847_REG_MWB_GB_GAIN ,
HI847_REG_VALUE_16BIT , d_gain ) ;
if ( ret )
return ret ;
ret = hi847_write_reg ( hi847 , HI847_REG_MWB_R_GAIN ,
HI847_REG_VALUE_16BIT , d_gain ) ;
if ( ret )
return ret ;
return hi847_write_reg ( hi847 , HI847_REG_MWB_B_GAIN ,
HI847_REG_VALUE_16BIT , d_gain ) ;
}
static int hi847_test_pattern ( struct hi847 * hi847 , u32 pattern )
{
int ret ;
u32 val ;
if ( pattern ) {
ret = hi847_read_reg ( hi847 , HI847_REG_ISP ,
HI847_REG_VALUE_16BIT , & val ) ;
if ( ret )
return ret ;
ret = hi847_write_reg ( hi847 , HI847_REG_ISP ,
HI847_REG_VALUE_16BIT ,
val | HI847_REG_ISP_TPG_EN ) ;
if ( ret )
return ret ;
}
ret = hi847_read_reg ( hi847 , HI847_REG_TEST_PATTERN ,
HI847_REG_VALUE_16BIT , & val ) ;
if ( ret )
return ret ;
return hi847_write_reg ( hi847 , HI847_REG_TEST_PATTERN ,
HI847_REG_VALUE_16BIT , val | pattern < < 8 ) ;
}
static int hi847_grbg_shift ( struct hi847 * hi847 )
{
int ret ;
int hflip , vflip ;
/* regs shift for full size */
static const u32 FORMAT_X_SHIFT_1 [ 2 ] [ 2 ] = {
{ 0x0008 , 0x0007 , } ,
{ 0x0008 , 0x0007 , } ,
} ;
static const u32 FORMAT_Y_SHIFT_1 [ 2 ] [ 2 ] = {
{ 0x0002 , 0x0002 , } ,
{ 0x0001 , 0x0001 , } ,
} ;
/* regs shift for binning size */
static const u32 FORMAT_X_SHIFT_2 [ 2 ] [ 2 ] = {
{ 0x0004 , 0x0003 , } ,
{ 0x0004 , 0x0003 , } ,
} ;
static const u32 FORMAT_Y_SHIFT_2 [ 2 ] [ 2 ] = {
{ 0x0002 , 0x0002 , } ,
{ 0x0001 , 0x0001 , } ,
} ;
hflip = hi847 - > hflip - > val ;
vflip = hi847 - > vflip - > val ;
if ( hi847 - > cur_mode - > width = = 3264 ) {
ret = hi847_write_reg ( hi847 , HI847_REG_FORMAT_X ,
HI847_REG_VALUE_16BIT ,
FORMAT_X_SHIFT_1 [ vflip ] [ hflip ] ) ;
if ( ret )
return ret ;
return hi847_write_reg ( hi847 , HI847_REG_FORMAT_Y ,
HI847_REG_VALUE_16BIT ,
FORMAT_Y_SHIFT_1 [ vflip ] [ hflip ] ) ;
} else {
ret = hi847_write_reg ( hi847 , HI847_REG_FORMAT_X ,
HI847_REG_VALUE_16BIT ,
FORMAT_X_SHIFT_2 [ vflip ] [ hflip ] ) ;
if ( ret )
return ret ;
return hi847_write_reg ( hi847 , HI847_REG_FORMAT_Y ,
HI847_REG_VALUE_16BIT ,
FORMAT_Y_SHIFT_2 [ vflip ] [ hflip ] ) ;
}
}
static int hi847_set_ctrl_hflip ( struct hi847 * hi847 , u32 ctrl_val )
{
int ret ;
u32 val ;
ret = hi847_read_reg ( hi847 , HI847_REG_MIRROR_FLIP ,
HI847_REG_VALUE_16BIT , & val ) ;
if ( ret )
return ret ;
ret = hi847_grbg_shift ( hi847 ) ;
if ( ret )
return ret ;
return hi847_write_reg ( hi847 , HI847_REG_MIRROR_FLIP ,
HI847_REG_VALUE_16BIT ,
ctrl_val ? val | BIT ( 8 ) : val & ~ BIT ( 8 ) ) ;
}
static int hi847_set_ctrl_vflip ( struct hi847 * hi847 , u8 ctrl_val )
{
int ret ;
u32 val ;
ret = hi847_read_reg ( hi847 , HI847_REG_MIRROR_FLIP ,
HI847_REG_VALUE_16BIT , & val ) ;
if ( ret )
return ret ;
ret = hi847_grbg_shift ( hi847 ) ;
if ( ret )
return ret ;
return hi847_write_reg ( hi847 , HI847_REG_MIRROR_FLIP ,
HI847_REG_VALUE_16BIT ,
ctrl_val ? val | BIT ( 9 ) : val & ~ BIT ( 9 ) ) ;
}
static int hi847_set_ctrl ( struct v4l2_ctrl * ctrl )
{
struct hi847 * hi847 = container_of ( ctrl - > handler ,
struct hi847 , ctrl_handler ) ;
struct i2c_client * client = v4l2_get_subdevdata ( & hi847 - > sd ) ;
s64 exposure_max ;
int ret = 0 ;
/* Propagate change of current control to all related controls */
if ( ctrl - > id = = V4L2_CID_VBLANK ) {
/* Update max exposure while meeting expected vblanking */
exposure_max = hi847 - > cur_mode - > height + ctrl - > val -
HI847_EXPOSURE_MAX_MARGIN ;
__v4l2_ctrl_modify_range ( hi847 - > exposure ,
hi847 - > exposure - > minimum ,
exposure_max , hi847 - > exposure - > step ,
exposure_max ) ;
}
/* V4L2 controls values will be applied only when power is already up */
if ( ! pm_runtime_get_if_in_use ( & client - > dev ) )
return 0 ;
switch ( ctrl - > id ) {
case V4L2_CID_ANALOGUE_GAIN :
ret = hi847_write_reg ( hi847 , HI847_REG_ANALOG_GAIN ,
HI847_REG_VALUE_16BIT , ctrl - > val ) ;
break ;
case V4L2_CID_DIGITAL_GAIN :
ret = hi847_update_digital_gain ( hi847 , ctrl - > val ) ;
break ;
case V4L2_CID_EXPOSURE :
ret = hi847_write_reg ( hi847 , HI847_REG_EXPOSURE ,
HI847_REG_VALUE_16BIT , ctrl - > val ) ;
break ;
case V4L2_CID_VBLANK :
/* Update FLL that meets expected vertical blanking */
ret = hi847_write_reg ( hi847 , HI847_REG_FLL ,
HI847_REG_VALUE_16BIT ,
hi847 - > cur_mode - > height + ctrl - > val ) ;
break ;
case V4L2_CID_TEST_PATTERN :
ret = hi847_test_pattern ( hi847 , ctrl - > val ) ;
break ;
case V4L2_CID_HFLIP :
hi847_set_ctrl_hflip ( hi847 , ctrl - > val ) ;
break ;
case V4L2_CID_VFLIP :
hi847_set_ctrl_vflip ( hi847 , ctrl - > val ) ;
break ;
default :
ret = - EINVAL ;
break ;
}
pm_runtime_put ( & client - > dev ) ;
return ret ;
}
static const struct v4l2_ctrl_ops hi847_ctrl_ops = {
. s_ctrl = hi847_set_ctrl ,
} ;
static int hi847_init_controls ( struct hi847 * hi847 )
{
struct v4l2_ctrl_handler * ctrl_hdlr ;
s64 exposure_max , h_blank ;
int ret ;
ctrl_hdlr = & hi847 - > ctrl_handler ;
ret = v4l2_ctrl_handler_init ( ctrl_hdlr , 8 ) ;
if ( ret )
return ret ;
ctrl_hdlr - > lock = & hi847 - > mutex ;
hi847 - > link_freq = v4l2_ctrl_new_int_menu ( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_LINK_FREQ ,
ARRAY_SIZE ( link_freq_menu_items ) - 1 ,
0 , link_freq_menu_items ) ;
if ( hi847 - > link_freq )
hi847 - > link_freq - > flags | = V4L2_CTRL_FLAG_READ_ONLY ;
hi847 - > pixel_rate = v4l2_ctrl_new_std
( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_PIXEL_RATE , 0 ,
to_pixel_rate ( HI847_LINK_FREQ_400MHZ_INDEX ) ,
1 ,
to_pixel_rate ( HI847_LINK_FREQ_400MHZ_INDEX ) ) ;
hi847 - > vblank = v4l2_ctrl_new_std ( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_VBLANK ,
hi847 - > cur_mode - > fll_min -
hi847 - > cur_mode - > height ,
HI847_FLL_MAX -
hi847 - > cur_mode - > height , 1 ,
hi847 - > cur_mode - > fll_def -
hi847 - > cur_mode - > height ) ;
h_blank = hi847 - > cur_mode - > llp - hi847 - > cur_mode - > width ;
hi847 - > hblank = v4l2_ctrl_new_std ( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_HBLANK , h_blank , h_blank , 1 ,
h_blank ) ;
if ( hi847 - > hblank )
hi847 - > hblank - > flags | = V4L2_CTRL_FLAG_READ_ONLY ;
v4l2_ctrl_new_std ( ctrl_hdlr , & hi847_ctrl_ops , V4L2_CID_ANALOGUE_GAIN ,
HI847_ANAL_GAIN_MIN , HI847_ANAL_GAIN_MAX ,
HI847_ANAL_GAIN_STEP , HI847_ANAL_GAIN_MIN ) ;
v4l2_ctrl_new_std ( ctrl_hdlr , & hi847_ctrl_ops , V4L2_CID_DIGITAL_GAIN ,
HI847_DGTL_GAIN_MIN , HI847_DGTL_GAIN_MAX ,
HI847_DGTL_GAIN_STEP , HI847_DGTL_GAIN_DEFAULT ) ;
exposure_max = hi847 - > cur_mode - > fll_def - HI847_EXPOSURE_MAX_MARGIN ;
hi847 - > exposure = v4l2_ctrl_new_std ( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_EXPOSURE ,
HI847_EXPOSURE_MIN , exposure_max ,
HI847_EXPOSURE_STEP ,
exposure_max ) ;
v4l2_ctrl_new_std_menu_items ( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_TEST_PATTERN ,
ARRAY_SIZE ( hi847_test_pattern_menu ) - 1 ,
0 , 0 , hi847_test_pattern_menu ) ;
hi847 - > hflip = v4l2_ctrl_new_std ( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_HFLIP , 0 , 1 , 1 , 0 ) ;
hi847 - > vflip = v4l2_ctrl_new_std ( ctrl_hdlr , & hi847_ctrl_ops ,
V4L2_CID_VFLIP , 0 , 1 , 1 , 0 ) ;
if ( ctrl_hdlr - > error )
return ctrl_hdlr - > error ;
hi847 - > sd . ctrl_handler = ctrl_hdlr ;
return 0 ;
}
static void hi847_assign_pad_format ( const struct hi847_mode * mode ,
struct v4l2_mbus_framefmt * fmt )
{
fmt - > width = mode - > width ;
fmt - > height = mode - > height ;
fmt - > code = MEDIA_BUS_FMT_SGRBG10_1X10 ;
fmt - > field = V4L2_FIELD_NONE ;
}
static int hi847_start_streaming ( struct hi847 * hi847 )
{
struct i2c_client * client = v4l2_get_subdevdata ( & hi847 - > sd ) ;
const struct hi847_reg_list * reg_list ;
int link_freq_index , ret ;
link_freq_index = hi847 - > cur_mode - > link_freq_index ;
reg_list = & link_freq_configs [ link_freq_index ] . reg_list ;
ret = hi847_write_reg_list ( hi847 , reg_list ) ;
if ( ret ) {
dev_err ( & client - > dev , " failed to set plls " ) ;
return ret ;
}
reg_list = & hi847 - > cur_mode - > reg_list ;
ret = hi847_write_reg_list ( hi847 , reg_list ) ;
if ( ret ) {
dev_err ( & client - > dev , " failed to set mode " ) ;
return ret ;
}
ret = __v4l2_ctrl_handler_setup ( hi847 - > sd . ctrl_handler ) ;
if ( ret )
return ret ;
ret = hi847_write_reg ( hi847 , HI847_REG_MODE_TG ,
HI847_REG_VALUE_16BIT , HI847_REG_MODE_TG_ENABLE ) ;
ret = hi847_write_reg ( hi847 , HI847_REG_MODE_SELECT ,
HI847_REG_VALUE_16BIT , HI847_MODE_STREAMING ) ;
if ( ret ) {
dev_err ( & client - > dev , " failed to set stream " ) ;
return ret ;
}
return 0 ;
}
static void hi847_stop_streaming ( struct hi847 * hi847 )
{
struct i2c_client * client = v4l2_get_subdevdata ( & hi847 - > sd ) ;
if ( hi847_write_reg ( hi847 , HI847_REG_MODE_TG ,
HI847_REG_VALUE_16BIT , HI847_REG_MODE_TG_DISABLE ) )
dev_err ( & client - > dev , " failed to set stream 0x%x " ,
HI847_REG_MODE_TG ) ;
if ( hi847_write_reg ( hi847 , HI847_REG_MODE_SELECT ,
HI847_REG_VALUE_16BIT , HI847_MODE_STANDBY ) )
dev_err ( & client - > dev , " failed to set stream 0x%x " ,
HI847_REG_MODE_SELECT ) ;
}
static int hi847_set_stream ( struct v4l2_subdev * sd , int enable )
{
struct hi847 * hi847 = to_hi847 ( sd ) ;
struct i2c_client * client = v4l2_get_subdevdata ( sd ) ;
int ret = 0 ;
mutex_lock ( & hi847 - > mutex ) ;
if ( enable ) {
2023-09-14 20:20:54 +03:00
ret = pm_runtime_resume_and_get ( & client - > dev ) ;
if ( ret ) {
2022-01-11 16:08:27 +01:00
mutex_unlock ( & hi847 - > mutex ) ;
return ret ;
}
ret = hi847_start_streaming ( hi847 ) ;
if ( ret ) {
enable = 0 ;
hi847_stop_streaming ( hi847 ) ;
pm_runtime_put ( & client - > dev ) ;
}
} else {
hi847_stop_streaming ( hi847 ) ;
pm_runtime_put ( & client - > dev ) ;
}
mutex_unlock ( & hi847 - > mutex ) ;
return ret ;
}
static int hi847_set_format ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_format * fmt )
{
struct hi847 * hi847 = to_hi847 ( sd ) ;
const struct hi847_mode * mode ;
s32 vblank_def , h_blank ;
mode = v4l2_find_nearest_size ( supported_modes ,
ARRAY_SIZE ( supported_modes ) , width ,
height , fmt - > format . width ,
fmt - > format . height ) ;
mutex_lock ( & hi847 - > mutex ) ;
hi847_assign_pad_format ( mode , & fmt - > format ) ;
if ( fmt - > which = = V4L2_SUBDEV_FORMAT_TRY ) {
* v4l2_subdev_get_try_format ( sd , sd_state , fmt - > pad ) =
fmt - > format ;
} else {
hi847 - > cur_mode = mode ;
__v4l2_ctrl_s_ctrl ( hi847 - > link_freq , mode - > link_freq_index ) ;
__v4l2_ctrl_s_ctrl_int64 ( hi847 - > pixel_rate ,
to_pixel_rate ( mode - > link_freq_index ) ) ;
/* Update limits and set FPS to default */
vblank_def = mode - > fll_def - mode - > height ;
__v4l2_ctrl_modify_range ( hi847 - > vblank ,
mode - > fll_min - mode - > height ,
HI847_FLL_MAX - mode - > height , 1 ,
vblank_def ) ;
__v4l2_ctrl_s_ctrl ( hi847 - > vblank , vblank_def ) ;
h_blank = hi847 - > cur_mode - > llp - hi847 - > cur_mode - > width ;
__v4l2_ctrl_modify_range ( hi847 - > hblank , h_blank , h_blank , 1 ,
h_blank ) ;
}
mutex_unlock ( & hi847 - > mutex ) ;
return 0 ;
}
static int hi847_get_format ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_format * fmt )
{
struct hi847 * hi847 = to_hi847 ( sd ) ;
mutex_lock ( & hi847 - > mutex ) ;
if ( fmt - > which = = V4L2_SUBDEV_FORMAT_TRY )
fmt - > format = * v4l2_subdev_get_try_format ( & hi847 - > sd ,
sd_state ,
fmt - > pad ) ;
else
hi847_assign_pad_format ( hi847 - > cur_mode , & fmt - > format ) ;
mutex_unlock ( & hi847 - > mutex ) ;
return 0 ;
}
static int hi847_enum_mbus_code ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_mbus_code_enum * code )
{
if ( code - > index > 0 )
return - EINVAL ;
code - > code = MEDIA_BUS_FMT_SGRBG10_1X10 ;
return 0 ;
}
static int hi847_enum_frame_size ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_frame_size_enum * fse )
{
if ( fse - > index > = ARRAY_SIZE ( supported_modes ) )
return - EINVAL ;
if ( fse - > code ! = MEDIA_BUS_FMT_SGRBG10_1X10 )
return - EINVAL ;
fse - > min_width = supported_modes [ fse - > index ] . width ;
fse - > max_width = fse - > min_width ;
fse - > min_height = supported_modes [ fse - > index ] . height ;
fse - > max_height = fse - > min_height ;
return 0 ;
}
static int hi847_open ( struct v4l2_subdev * sd , struct v4l2_subdev_fh * fh )
{
struct hi847 * hi847 = to_hi847 ( sd ) ;
mutex_lock ( & hi847 - > mutex ) ;
hi847_assign_pad_format ( & supported_modes [ 0 ] ,
v4l2_subdev_get_try_format ( sd , fh - > state , 0 ) ) ;
mutex_unlock ( & hi847 - > mutex ) ;
return 0 ;
}
static const struct v4l2_subdev_video_ops hi847_video_ops = {
. s_stream = hi847_set_stream ,
} ;
static const struct v4l2_subdev_pad_ops hi847_pad_ops = {
. set_fmt = hi847_set_format ,
. get_fmt = hi847_get_format ,
. enum_mbus_code = hi847_enum_mbus_code ,
. enum_frame_size = hi847_enum_frame_size ,
} ;
static const struct v4l2_subdev_ops hi847_subdev_ops = {
. video = & hi847_video_ops ,
. pad = & hi847_pad_ops ,
} ;
static const struct media_entity_operations hi847_subdev_entity_ops = {
. link_validate = v4l2_subdev_link_validate ,
} ;
static const struct v4l2_subdev_internal_ops hi847_internal_ops = {
. open = hi847_open ,
} ;
static int hi847_identify_module ( struct hi847 * hi847 )
{
struct i2c_client * client = v4l2_get_subdevdata ( & hi847 - > sd ) ;
int ret ;
u32 val ;
ret = hi847_read_reg ( hi847 , HI847_REG_CHIP_ID ,
HI847_REG_VALUE_16BIT , & val ) ;
if ( ret )
return ret ;
if ( val ! = HI847_CHIP_ID ) {
dev_err ( & client - > dev , " chip id mismatch: %x!=%x " ,
HI847_CHIP_ID , val ) ;
return - ENXIO ;
}
return 0 ;
}
static int hi847_check_hwcfg ( struct device * dev )
{
struct fwnode_handle * ep ;
struct fwnode_handle * fwnode = dev_fwnode ( dev ) ;
struct v4l2_fwnode_endpoint bus_cfg = {
. bus_type = V4L2_MBUS_CSI2_DPHY
} ;
u32 mclk ;
int ret ;
unsigned int i , j ;
if ( ! fwnode )
return - ENXIO ;
ret = fwnode_property_read_u32 ( fwnode , " clock-frequency " , & mclk ) ;
if ( ret ) {
dev_err ( dev , " can't get clock frequency " ) ;
return ret ;
}
if ( mclk ! = HI847_MCLK ) {
dev_err ( dev , " external clock %d is not supported " , mclk ) ;
return - EINVAL ;
}
ep = fwnode_graph_get_next_endpoint ( fwnode , NULL ) ;
if ( ! ep )
return - ENXIO ;
ret = v4l2_fwnode_endpoint_alloc_parse ( ep , & bus_cfg ) ;
fwnode_handle_put ( ep ) ;
if ( ret )
return ret ;
if ( bus_cfg . bus . mipi_csi2 . num_data_lanes ! = HI847_DATA_LANES ) {
dev_err ( dev , " number of CSI2 data lanes %d is not supported " ,
bus_cfg . bus . mipi_csi2 . num_data_lanes ) ;
ret = - EINVAL ;
goto check_hwcfg_error ;
}
if ( ! bus_cfg . nr_of_link_frequencies ) {
dev_err ( dev , " no link frequencies defined " ) ;
ret = - EINVAL ;
goto check_hwcfg_error ;
}
for ( i = 0 ; i < ARRAY_SIZE ( link_freq_menu_items ) ; i + + ) {
for ( j = 0 ; j < bus_cfg . nr_of_link_frequencies ; j + + ) {
if ( link_freq_menu_items [ i ] = =
bus_cfg . link_frequencies [ j ] )
break ;
}
if ( j = = bus_cfg . nr_of_link_frequencies ) {
dev_err ( dev , " no link frequency %lld supported " ,
link_freq_menu_items [ i ] ) ;
ret = - EINVAL ;
goto check_hwcfg_error ;
}
}
check_hwcfg_error :
v4l2_fwnode_endpoint_free ( & bus_cfg ) ;
return ret ;
}
2022-08-15 10:02:30 +02:00
static void hi847_remove ( struct i2c_client * client )
2022-01-11 16:08:27 +01:00
{
struct v4l2_subdev * sd = i2c_get_clientdata ( client ) ;
struct hi847 * hi847 = to_hi847 ( sd ) ;
v4l2_async_unregister_subdev ( sd ) ;
media_entity_cleanup ( & sd - > entity ) ;
v4l2_ctrl_handler_free ( sd - > ctrl_handler ) ;
pm_runtime_disable ( & client - > dev ) ;
mutex_destroy ( & hi847 - > mutex ) ;
}
static int hi847_probe ( struct i2c_client * client )
{
struct hi847 * hi847 ;
int ret ;
hi847 = devm_kzalloc ( & client - > dev , sizeof ( * hi847 ) , GFP_KERNEL ) ;
if ( ! hi847 )
return - ENOMEM ;
ret = hi847_check_hwcfg ( & client - > dev ) ;
if ( ret ) {
dev_err ( & client - > dev , " failed to get HW configuration: %d " ,
ret ) ;
return ret ;
}
v4l2_i2c_subdev_init ( & hi847 - > sd , client , & hi847_subdev_ops ) ;
ret = hi847_identify_module ( hi847 ) ;
if ( ret ) {
dev_err ( & client - > dev , " failed to find sensor: %d " , ret ) ;
return ret ;
}
mutex_init ( & hi847 - > mutex ) ;
hi847 - > cur_mode = & supported_modes [ 0 ] ;
ret = hi847_init_controls ( hi847 ) ;
if ( ret ) {
dev_err ( & client - > dev , " failed to init controls: %d " , ret ) ;
goto probe_error_v4l2_ctrl_handler_free ;
}
hi847 - > sd . internal_ops = & hi847_internal_ops ;
hi847 - > sd . flags | = V4L2_SUBDEV_FL_HAS_DEVNODE ;
hi847 - > sd . entity . ops = & hi847_subdev_entity_ops ;
hi847 - > sd . entity . function = MEDIA_ENT_F_CAM_SENSOR ;
hi847 - > pad . flags = MEDIA_PAD_FL_SOURCE ;
ret = media_entity_pads_init ( & hi847 - > sd . entity , 1 , & hi847 - > pad ) ;
if ( ret ) {
dev_err ( & client - > dev , " failed to init entity pads: %d " , ret ) ;
goto probe_error_v4l2_ctrl_handler_free ;
}
ret = v4l2_async_register_subdev_sensor ( & hi847 - > sd ) ;
if ( ret < 0 ) {
dev_err ( & client - > dev , " failed to register V4L2 subdev: %d " ,
ret ) ;
goto probe_error_media_entity_cleanup ;
}
pm_runtime_set_active ( & client - > dev ) ;
pm_runtime_enable ( & client - > dev ) ;
pm_runtime_idle ( & client - > dev ) ;
return 0 ;
probe_error_media_entity_cleanup :
media_entity_cleanup ( & hi847 - > sd . entity ) ;
probe_error_v4l2_ctrl_handler_free :
v4l2_ctrl_handler_free ( hi847 - > sd . ctrl_handler ) ;
mutex_destroy ( & hi847 - > mutex ) ;
return ret ;
}
# ifdef CONFIG_ACPI
static const struct acpi_device_id hi847_acpi_ids [ ] = {
{ " HYV0847 " } ,
{ }
} ;
MODULE_DEVICE_TABLE ( acpi , hi847_acpi_ids ) ;
# endif
static struct i2c_driver hi847_i2c_driver = {
. driver = {
. name = " hi847 " ,
. acpi_match_table = ACPI_PTR ( hi847_acpi_ids ) ,
} ,
2023-05-14 14:04:07 +02:00
. probe = hi847_probe ,
2022-01-11 16:08:27 +01:00
. remove = hi847_remove ,
} ;
module_i2c_driver ( hi847_i2c_driver ) ;
2023-06-09 11:19:28 +02:00
MODULE_AUTHOR ( " Shawn Tu " ) ;
2022-01-11 16:08:27 +01:00
MODULE_DESCRIPTION ( " Hynix HI847 sensor driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;