1*5fcf092eSHyungwoo Yang /* 2*5fcf092eSHyungwoo Yang * Copyright (c) 2017 Intel Corporation. 3*5fcf092eSHyungwoo Yang * 4*5fcf092eSHyungwoo Yang * This program is free software; you can redistribute it and/or 5*5fcf092eSHyungwoo Yang * modify it under the terms of the GNU General Public License version 6*5fcf092eSHyungwoo Yang * 2 as published by the Free Software Foundation. 7*5fcf092eSHyungwoo Yang * 8*5fcf092eSHyungwoo Yang * This program is distributed in the hope that it will be useful, 9*5fcf092eSHyungwoo Yang * but WITHOUT ANY WARRANTY; without even the implied warranty of 10*5fcf092eSHyungwoo Yang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11*5fcf092eSHyungwoo Yang * GNU General Public License for more details. 12*5fcf092eSHyungwoo Yang * 13*5fcf092eSHyungwoo Yang */ 14*5fcf092eSHyungwoo Yang 15*5fcf092eSHyungwoo Yang #include <linux/acpi.h> 16*5fcf092eSHyungwoo Yang #include <linux/i2c.h> 17*5fcf092eSHyungwoo Yang #include <linux/module.h> 18*5fcf092eSHyungwoo Yang #include <linux/pm_runtime.h> 19*5fcf092eSHyungwoo Yang #include <media/v4l2-ctrls.h> 20*5fcf092eSHyungwoo Yang #include <media/v4l2-device.h> 21*5fcf092eSHyungwoo Yang 22*5fcf092eSHyungwoo Yang #define OV13858_REG_VALUE_08BIT 1 23*5fcf092eSHyungwoo Yang #define OV13858_REG_VALUE_16BIT 2 24*5fcf092eSHyungwoo Yang #define OV13858_REG_VALUE_24BIT 3 25*5fcf092eSHyungwoo Yang 26*5fcf092eSHyungwoo Yang #define OV13858_REG_MODE_SELECT 0x0100 27*5fcf092eSHyungwoo Yang #define OV13858_MODE_STANDBY 0x00 28*5fcf092eSHyungwoo Yang #define OV13858_MODE_STREAMING 0x01 29*5fcf092eSHyungwoo Yang 30*5fcf092eSHyungwoo Yang #define OV13858_REG_SOFTWARE_RST 0x0103 31*5fcf092eSHyungwoo Yang #define OV13858_SOFTWARE_RST 0x01 32*5fcf092eSHyungwoo Yang 33*5fcf092eSHyungwoo Yang /* PLL1 generates PCLK and MIPI_PHY_CLK */ 34*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_0 0x0300 35*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_1 0x0301 36*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_2 0x0302 37*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_3 0x0303 38*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_4 0x0304 39*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_5 0x0305 40*5fcf092eSHyungwoo Yang 41*5fcf092eSHyungwoo Yang /* PLL2 generates DAC_CLK, SCLK and SRAM_CLK */ 42*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_B 0x030b 43*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_C 0x030c 44*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_D 0x030d 45*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_E 0x030e 46*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_F 0x030f 47*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_12 0x0312 48*5fcf092eSHyungwoo Yang #define OV13858_REG_MIPI_SC_CTRL0 0x3016 49*5fcf092eSHyungwoo Yang #define OV13858_REG_MIPI_SC_CTRL1 0x3022 50*5fcf092eSHyungwoo Yang 51*5fcf092eSHyungwoo Yang /* Chip ID */ 52*5fcf092eSHyungwoo Yang #define OV13858_REG_CHIP_ID 0x300a 53*5fcf092eSHyungwoo Yang #define OV13858_CHIP_ID 0x00d855 54*5fcf092eSHyungwoo Yang 55*5fcf092eSHyungwoo Yang /* V_TIMING internal */ 56*5fcf092eSHyungwoo Yang #define OV13858_REG_VTS 0x380e 57*5fcf092eSHyungwoo Yang #define OV13858_VTS_30FPS 0x0c8e /* 30 fps */ 58*5fcf092eSHyungwoo Yang #define OV13858_VTS_60FPS 0x0648 /* 60 fps */ 59*5fcf092eSHyungwoo Yang #define OV13858_VTS_MAX 0x7fff 60*5fcf092eSHyungwoo Yang #define OV13858_VBLANK_MIN 56 61*5fcf092eSHyungwoo Yang 62*5fcf092eSHyungwoo Yang /* HBLANK control - read only */ 63*5fcf092eSHyungwoo Yang #define OV13858_PPL_540MHZ 2244 64*5fcf092eSHyungwoo Yang #define OV13858_PPL_1080MHZ 4488 65*5fcf092eSHyungwoo Yang 66*5fcf092eSHyungwoo Yang /* Exposure control */ 67*5fcf092eSHyungwoo Yang #define OV13858_REG_EXPOSURE 0x3500 68*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_MIN 4 69*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_MAX (OV13858_VTS_MAX - 8) 70*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_STEP 1 71*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_DEFAULT 0x640 72*5fcf092eSHyungwoo Yang 73*5fcf092eSHyungwoo Yang /* Analog gain control */ 74*5fcf092eSHyungwoo Yang #define OV13858_REG_ANALOG_GAIN 0x3508 75*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_MIN 0 76*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_MAX 0x1fff 77*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_STEP 1 78*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_DEFAULT 0x80 79*5fcf092eSHyungwoo Yang 80*5fcf092eSHyungwoo Yang /* Digital gain control */ 81*5fcf092eSHyungwoo Yang #define OV13858_REG_DIGITAL_GAIN 0x350a 82*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_MASK 0xf3 83*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_SHIFT 2 84*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_MIN 1 85*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_MAX 4 86*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_STEP 1 87*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_DEFAULT 1 88*5fcf092eSHyungwoo Yang 89*5fcf092eSHyungwoo Yang /* Test Pattern Control */ 90*5fcf092eSHyungwoo Yang #define OV13858_REG_TEST_PATTERN 0x4503 91*5fcf092eSHyungwoo Yang #define OV13858_TEST_PATTERN_ENABLE BIT(7) 92*5fcf092eSHyungwoo Yang #define OV13858_TEST_PATTERN_MASK 0xfc 93*5fcf092eSHyungwoo Yang 94*5fcf092eSHyungwoo Yang /* Number of frames to skip */ 95*5fcf092eSHyungwoo Yang #define OV13858_NUM_OF_SKIP_FRAMES 2 96*5fcf092eSHyungwoo Yang 97*5fcf092eSHyungwoo Yang struct ov13858_reg { 98*5fcf092eSHyungwoo Yang u16 address; 99*5fcf092eSHyungwoo Yang u8 val; 100*5fcf092eSHyungwoo Yang }; 101*5fcf092eSHyungwoo Yang 102*5fcf092eSHyungwoo Yang struct ov13858_reg_list { 103*5fcf092eSHyungwoo Yang u32 num_of_regs; 104*5fcf092eSHyungwoo Yang const struct ov13858_reg *regs; 105*5fcf092eSHyungwoo Yang }; 106*5fcf092eSHyungwoo Yang 107*5fcf092eSHyungwoo Yang /* Link frequency config */ 108*5fcf092eSHyungwoo Yang struct ov13858_link_freq_config { 109*5fcf092eSHyungwoo Yang u32 pixel_rate; 110*5fcf092eSHyungwoo Yang u32 pixels_per_line; 111*5fcf092eSHyungwoo Yang 112*5fcf092eSHyungwoo Yang /* PLL registers for this link frequency */ 113*5fcf092eSHyungwoo Yang struct ov13858_reg_list reg_list; 114*5fcf092eSHyungwoo Yang }; 115*5fcf092eSHyungwoo Yang 116*5fcf092eSHyungwoo Yang /* Mode : resolution and related config&values */ 117*5fcf092eSHyungwoo Yang struct ov13858_mode { 118*5fcf092eSHyungwoo Yang /* Frame width */ 119*5fcf092eSHyungwoo Yang u32 width; 120*5fcf092eSHyungwoo Yang /* Frame height */ 121*5fcf092eSHyungwoo Yang u32 height; 122*5fcf092eSHyungwoo Yang 123*5fcf092eSHyungwoo Yang /* V-timing */ 124*5fcf092eSHyungwoo Yang u32 vts; 125*5fcf092eSHyungwoo Yang 126*5fcf092eSHyungwoo Yang /* Index of Link frequency config to be used */ 127*5fcf092eSHyungwoo Yang u32 link_freq_index; 128*5fcf092eSHyungwoo Yang /* Default register values */ 129*5fcf092eSHyungwoo Yang struct ov13858_reg_list reg_list; 130*5fcf092eSHyungwoo Yang }; 131*5fcf092eSHyungwoo Yang 132*5fcf092eSHyungwoo Yang /* 4224x3136 needs 1080Mbps/lane, 4 lanes */ 133*5fcf092eSHyungwoo Yang static const struct ov13858_reg mipi_data_rate_1080mbps[] = { 134*5fcf092eSHyungwoo Yang /* PLL1 registers */ 135*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_0, 0x07}, 136*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_1, 0x01}, 137*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_2, 0xc2}, 138*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_3, 0x00}, 139*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_4, 0x00}, 140*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_5, 0x01}, 141*5fcf092eSHyungwoo Yang 142*5fcf092eSHyungwoo Yang /* PLL2 registers */ 143*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_B, 0x05}, 144*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_C, 0x01}, 145*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_D, 0x0e}, 146*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_E, 0x05}, 147*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_F, 0x01}, 148*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_12, 0x01}, 149*5fcf092eSHyungwoo Yang {OV13858_REG_MIPI_SC_CTRL0, 0x72}, 150*5fcf092eSHyungwoo Yang {OV13858_REG_MIPI_SC_CTRL1, 0x01}, 151*5fcf092eSHyungwoo Yang }; 152*5fcf092eSHyungwoo Yang 153*5fcf092eSHyungwoo Yang /* 154*5fcf092eSHyungwoo Yang * 2112x1568, 2112x1188, 1056x784 need 540Mbps/lane, 155*5fcf092eSHyungwoo Yang * 4 lanes 156*5fcf092eSHyungwoo Yang */ 157*5fcf092eSHyungwoo Yang static const struct ov13858_reg mipi_data_rate_540mbps[] = { 158*5fcf092eSHyungwoo Yang /* PLL1 registers */ 159*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_0, 0x07}, 160*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_1, 0x01}, 161*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_2, 0xc2}, 162*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_3, 0x01}, 163*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_4, 0x00}, 164*5fcf092eSHyungwoo Yang {OV13858_REG_PLL1_CTRL_5, 0x01}, 165*5fcf092eSHyungwoo Yang 166*5fcf092eSHyungwoo Yang /* PLL2 registers */ 167*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_B, 0x05}, 168*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_C, 0x01}, 169*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_D, 0x0e}, 170*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_E, 0x05}, 171*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_F, 0x01}, 172*5fcf092eSHyungwoo Yang {OV13858_REG_PLL2_CTRL_12, 0x01}, 173*5fcf092eSHyungwoo Yang {OV13858_REG_MIPI_SC_CTRL0, 0x72}, 174*5fcf092eSHyungwoo Yang {OV13858_REG_MIPI_SC_CTRL1, 0x01}, 175*5fcf092eSHyungwoo Yang }; 176*5fcf092eSHyungwoo Yang 177*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_4224x3136_regs[] = { 178*5fcf092eSHyungwoo Yang {0x3013, 0x32}, 179*5fcf092eSHyungwoo Yang {0x301b, 0xf0}, 180*5fcf092eSHyungwoo Yang {0x301f, 0xd0}, 181*5fcf092eSHyungwoo Yang {0x3106, 0x15}, 182*5fcf092eSHyungwoo Yang {0x3107, 0x23}, 183*5fcf092eSHyungwoo Yang {0x350a, 0x00}, 184*5fcf092eSHyungwoo Yang {0x350e, 0x00}, 185*5fcf092eSHyungwoo Yang {0x3510, 0x00}, 186*5fcf092eSHyungwoo Yang {0x3511, 0x02}, 187*5fcf092eSHyungwoo Yang {0x3512, 0x00}, 188*5fcf092eSHyungwoo Yang {0x3600, 0x2b}, 189*5fcf092eSHyungwoo Yang {0x3601, 0x52}, 190*5fcf092eSHyungwoo Yang {0x3602, 0x60}, 191*5fcf092eSHyungwoo Yang {0x3612, 0x05}, 192*5fcf092eSHyungwoo Yang {0x3613, 0xa4}, 193*5fcf092eSHyungwoo Yang {0x3620, 0x80}, 194*5fcf092eSHyungwoo Yang {0x3621, 0x10}, 195*5fcf092eSHyungwoo Yang {0x3622, 0x30}, 196*5fcf092eSHyungwoo Yang {0x3624, 0x1c}, 197*5fcf092eSHyungwoo Yang {0x3640, 0x10}, 198*5fcf092eSHyungwoo Yang {0x3641, 0x70}, 199*5fcf092eSHyungwoo Yang {0x3661, 0x80}, 200*5fcf092eSHyungwoo Yang {0x3662, 0x12}, 201*5fcf092eSHyungwoo Yang {0x3664, 0x73}, 202*5fcf092eSHyungwoo Yang {0x3665, 0xa7}, 203*5fcf092eSHyungwoo Yang {0x366e, 0xff}, 204*5fcf092eSHyungwoo Yang {0x366f, 0xf4}, 205*5fcf092eSHyungwoo Yang {0x3674, 0x00}, 206*5fcf092eSHyungwoo Yang {0x3679, 0x0c}, 207*5fcf092eSHyungwoo Yang {0x367f, 0x01}, 208*5fcf092eSHyungwoo Yang {0x3680, 0x0c}, 209*5fcf092eSHyungwoo Yang {0x3681, 0x50}, 210*5fcf092eSHyungwoo Yang {0x3682, 0x50}, 211*5fcf092eSHyungwoo Yang {0x3683, 0xa9}, 212*5fcf092eSHyungwoo Yang {0x3684, 0xa9}, 213*5fcf092eSHyungwoo Yang {0x3709, 0x5f}, 214*5fcf092eSHyungwoo Yang {0x3714, 0x24}, 215*5fcf092eSHyungwoo Yang {0x371a, 0x3e}, 216*5fcf092eSHyungwoo Yang {0x3737, 0x04}, 217*5fcf092eSHyungwoo Yang {0x3738, 0xcc}, 218*5fcf092eSHyungwoo Yang {0x3739, 0x12}, 219*5fcf092eSHyungwoo Yang {0x373d, 0x26}, 220*5fcf092eSHyungwoo Yang {0x3764, 0x20}, 221*5fcf092eSHyungwoo Yang {0x3765, 0x20}, 222*5fcf092eSHyungwoo Yang {0x37a1, 0x36}, 223*5fcf092eSHyungwoo Yang {0x37a8, 0x3b}, 224*5fcf092eSHyungwoo Yang {0x37ab, 0x31}, 225*5fcf092eSHyungwoo Yang {0x37c2, 0x04}, 226*5fcf092eSHyungwoo Yang {0x37c3, 0xf1}, 227*5fcf092eSHyungwoo Yang {0x37c5, 0x00}, 228*5fcf092eSHyungwoo Yang {0x37d8, 0x03}, 229*5fcf092eSHyungwoo Yang {0x37d9, 0x0c}, 230*5fcf092eSHyungwoo Yang {0x37da, 0xc2}, 231*5fcf092eSHyungwoo Yang {0x37dc, 0x02}, 232*5fcf092eSHyungwoo Yang {0x37e0, 0x00}, 233*5fcf092eSHyungwoo Yang {0x37e1, 0x0a}, 234*5fcf092eSHyungwoo Yang {0x37e2, 0x14}, 235*5fcf092eSHyungwoo Yang {0x37e3, 0x04}, 236*5fcf092eSHyungwoo Yang {0x37e4, 0x2a}, 237*5fcf092eSHyungwoo Yang {0x37e5, 0x03}, 238*5fcf092eSHyungwoo Yang {0x37e6, 0x04}, 239*5fcf092eSHyungwoo Yang {0x3800, 0x00}, 240*5fcf092eSHyungwoo Yang {0x3801, 0x00}, 241*5fcf092eSHyungwoo Yang {0x3802, 0x00}, 242*5fcf092eSHyungwoo Yang {0x3803, 0x00}, 243*5fcf092eSHyungwoo Yang {0x3804, 0x10}, 244*5fcf092eSHyungwoo Yang {0x3805, 0x9f}, 245*5fcf092eSHyungwoo Yang {0x3806, 0x0c}, 246*5fcf092eSHyungwoo Yang {0x3807, 0x5f}, 247*5fcf092eSHyungwoo Yang {0x3808, 0x10}, 248*5fcf092eSHyungwoo Yang {0x3809, 0x80}, 249*5fcf092eSHyungwoo Yang {0x380a, 0x0c}, 250*5fcf092eSHyungwoo Yang {0x380b, 0x40}, 251*5fcf092eSHyungwoo Yang {0x380c, 0x04}, 252*5fcf092eSHyungwoo Yang {0x380d, 0x62}, 253*5fcf092eSHyungwoo Yang {0x380e, 0x0c}, 254*5fcf092eSHyungwoo Yang {0x380f, 0x8e}, 255*5fcf092eSHyungwoo Yang {0x3811, 0x04}, 256*5fcf092eSHyungwoo Yang {0x3813, 0x05}, 257*5fcf092eSHyungwoo Yang {0x3814, 0x01}, 258*5fcf092eSHyungwoo Yang {0x3815, 0x01}, 259*5fcf092eSHyungwoo Yang {0x3816, 0x01}, 260*5fcf092eSHyungwoo Yang {0x3817, 0x01}, 261*5fcf092eSHyungwoo Yang {0x3820, 0xa8}, 262*5fcf092eSHyungwoo Yang {0x3821, 0x00}, 263*5fcf092eSHyungwoo Yang {0x3822, 0xc2}, 264*5fcf092eSHyungwoo Yang {0x3823, 0x18}, 265*5fcf092eSHyungwoo Yang {0x3826, 0x11}, 266*5fcf092eSHyungwoo Yang {0x3827, 0x1c}, 267*5fcf092eSHyungwoo Yang {0x3829, 0x03}, 268*5fcf092eSHyungwoo Yang {0x3832, 0x00}, 269*5fcf092eSHyungwoo Yang {0x3c80, 0x00}, 270*5fcf092eSHyungwoo Yang {0x3c87, 0x01}, 271*5fcf092eSHyungwoo Yang {0x3c8c, 0x19}, 272*5fcf092eSHyungwoo Yang {0x3c8d, 0x1c}, 273*5fcf092eSHyungwoo Yang {0x3c90, 0x00}, 274*5fcf092eSHyungwoo Yang {0x3c91, 0x00}, 275*5fcf092eSHyungwoo Yang {0x3c92, 0x00}, 276*5fcf092eSHyungwoo Yang {0x3c93, 0x00}, 277*5fcf092eSHyungwoo Yang {0x3c94, 0x40}, 278*5fcf092eSHyungwoo Yang {0x3c95, 0x54}, 279*5fcf092eSHyungwoo Yang {0x3c96, 0x34}, 280*5fcf092eSHyungwoo Yang {0x3c97, 0x04}, 281*5fcf092eSHyungwoo Yang {0x3c98, 0x00}, 282*5fcf092eSHyungwoo Yang {0x3d8c, 0x73}, 283*5fcf092eSHyungwoo Yang {0x3d8d, 0xc0}, 284*5fcf092eSHyungwoo Yang {0x3f00, 0x0b}, 285*5fcf092eSHyungwoo Yang {0x3f03, 0x00}, 286*5fcf092eSHyungwoo Yang {0x4001, 0xe0}, 287*5fcf092eSHyungwoo Yang {0x4008, 0x00}, 288*5fcf092eSHyungwoo Yang {0x4009, 0x0f}, 289*5fcf092eSHyungwoo Yang {0x4011, 0xf0}, 290*5fcf092eSHyungwoo Yang {0x4017, 0x08}, 291*5fcf092eSHyungwoo Yang {0x4050, 0x04}, 292*5fcf092eSHyungwoo Yang {0x4051, 0x0b}, 293*5fcf092eSHyungwoo Yang {0x4052, 0x00}, 294*5fcf092eSHyungwoo Yang {0x4053, 0x80}, 295*5fcf092eSHyungwoo Yang {0x4054, 0x00}, 296*5fcf092eSHyungwoo Yang {0x4055, 0x80}, 297*5fcf092eSHyungwoo Yang {0x4056, 0x00}, 298*5fcf092eSHyungwoo Yang {0x4057, 0x80}, 299*5fcf092eSHyungwoo Yang {0x4058, 0x00}, 300*5fcf092eSHyungwoo Yang {0x4059, 0x80}, 301*5fcf092eSHyungwoo Yang {0x405e, 0x20}, 302*5fcf092eSHyungwoo Yang {0x4500, 0x07}, 303*5fcf092eSHyungwoo Yang {0x4503, 0x00}, 304*5fcf092eSHyungwoo Yang {0x450a, 0x04}, 305*5fcf092eSHyungwoo Yang {0x4809, 0x04}, 306*5fcf092eSHyungwoo Yang {0x480c, 0x12}, 307*5fcf092eSHyungwoo Yang {0x481f, 0x30}, 308*5fcf092eSHyungwoo Yang {0x4833, 0x10}, 309*5fcf092eSHyungwoo Yang {0x4837, 0x0e}, 310*5fcf092eSHyungwoo Yang {0x4902, 0x01}, 311*5fcf092eSHyungwoo Yang {0x4d00, 0x03}, 312*5fcf092eSHyungwoo Yang {0x4d01, 0xc9}, 313*5fcf092eSHyungwoo Yang {0x4d02, 0xbc}, 314*5fcf092eSHyungwoo Yang {0x4d03, 0xd7}, 315*5fcf092eSHyungwoo Yang {0x4d04, 0xf0}, 316*5fcf092eSHyungwoo Yang {0x4d05, 0xa2}, 317*5fcf092eSHyungwoo Yang {0x5000, 0xfd}, 318*5fcf092eSHyungwoo Yang {0x5001, 0x01}, 319*5fcf092eSHyungwoo Yang {0x5040, 0x39}, 320*5fcf092eSHyungwoo Yang {0x5041, 0x10}, 321*5fcf092eSHyungwoo Yang {0x5042, 0x10}, 322*5fcf092eSHyungwoo Yang {0x5043, 0x84}, 323*5fcf092eSHyungwoo Yang {0x5044, 0x62}, 324*5fcf092eSHyungwoo Yang {0x5180, 0x00}, 325*5fcf092eSHyungwoo Yang {0x5181, 0x10}, 326*5fcf092eSHyungwoo Yang {0x5182, 0x02}, 327*5fcf092eSHyungwoo Yang {0x5183, 0x0f}, 328*5fcf092eSHyungwoo Yang {0x5200, 0x1b}, 329*5fcf092eSHyungwoo Yang {0x520b, 0x07}, 330*5fcf092eSHyungwoo Yang {0x520c, 0x0f}, 331*5fcf092eSHyungwoo Yang {0x5300, 0x04}, 332*5fcf092eSHyungwoo Yang {0x5301, 0x0c}, 333*5fcf092eSHyungwoo Yang {0x5302, 0x0c}, 334*5fcf092eSHyungwoo Yang {0x5303, 0x0f}, 335*5fcf092eSHyungwoo Yang {0x5304, 0x00}, 336*5fcf092eSHyungwoo Yang {0x5305, 0x70}, 337*5fcf092eSHyungwoo Yang {0x5306, 0x00}, 338*5fcf092eSHyungwoo Yang {0x5307, 0x80}, 339*5fcf092eSHyungwoo Yang {0x5308, 0x00}, 340*5fcf092eSHyungwoo Yang {0x5309, 0xa5}, 341*5fcf092eSHyungwoo Yang {0x530a, 0x00}, 342*5fcf092eSHyungwoo Yang {0x530b, 0xd3}, 343*5fcf092eSHyungwoo Yang {0x530c, 0x00}, 344*5fcf092eSHyungwoo Yang {0x530d, 0xf0}, 345*5fcf092eSHyungwoo Yang {0x530e, 0x01}, 346*5fcf092eSHyungwoo Yang {0x530f, 0x10}, 347*5fcf092eSHyungwoo Yang {0x5310, 0x01}, 348*5fcf092eSHyungwoo Yang {0x5311, 0x20}, 349*5fcf092eSHyungwoo Yang {0x5312, 0x01}, 350*5fcf092eSHyungwoo Yang {0x5313, 0x20}, 351*5fcf092eSHyungwoo Yang {0x5314, 0x01}, 352*5fcf092eSHyungwoo Yang {0x5315, 0x20}, 353*5fcf092eSHyungwoo Yang {0x5316, 0x08}, 354*5fcf092eSHyungwoo Yang {0x5317, 0x08}, 355*5fcf092eSHyungwoo Yang {0x5318, 0x10}, 356*5fcf092eSHyungwoo Yang {0x5319, 0x88}, 357*5fcf092eSHyungwoo Yang {0x531a, 0x88}, 358*5fcf092eSHyungwoo Yang {0x531b, 0xa9}, 359*5fcf092eSHyungwoo Yang {0x531c, 0xaa}, 360*5fcf092eSHyungwoo Yang {0x531d, 0x0a}, 361*5fcf092eSHyungwoo Yang {0x5405, 0x02}, 362*5fcf092eSHyungwoo Yang {0x5406, 0x67}, 363*5fcf092eSHyungwoo Yang {0x5407, 0x01}, 364*5fcf092eSHyungwoo Yang {0x5408, 0x4a}, 365*5fcf092eSHyungwoo Yang }; 366*5fcf092eSHyungwoo Yang 367*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_2112x1568_regs[] = { 368*5fcf092eSHyungwoo Yang {0x3013, 0x32}, 369*5fcf092eSHyungwoo Yang {0x301b, 0xf0}, 370*5fcf092eSHyungwoo Yang {0x301f, 0xd0}, 371*5fcf092eSHyungwoo Yang {0x3106, 0x15}, 372*5fcf092eSHyungwoo Yang {0x3107, 0x23}, 373*5fcf092eSHyungwoo Yang {0x350a, 0x00}, 374*5fcf092eSHyungwoo Yang {0x350e, 0x00}, 375*5fcf092eSHyungwoo Yang {0x3510, 0x00}, 376*5fcf092eSHyungwoo Yang {0x3511, 0x02}, 377*5fcf092eSHyungwoo Yang {0x3512, 0x00}, 378*5fcf092eSHyungwoo Yang {0x3600, 0x2b}, 379*5fcf092eSHyungwoo Yang {0x3601, 0x52}, 380*5fcf092eSHyungwoo Yang {0x3602, 0x60}, 381*5fcf092eSHyungwoo Yang {0x3612, 0x05}, 382*5fcf092eSHyungwoo Yang {0x3613, 0xa4}, 383*5fcf092eSHyungwoo Yang {0x3620, 0x80}, 384*5fcf092eSHyungwoo Yang {0x3621, 0x10}, 385*5fcf092eSHyungwoo Yang {0x3622, 0x30}, 386*5fcf092eSHyungwoo Yang {0x3624, 0x1c}, 387*5fcf092eSHyungwoo Yang {0x3640, 0x10}, 388*5fcf092eSHyungwoo Yang {0x3641, 0x70}, 389*5fcf092eSHyungwoo Yang {0x3661, 0x80}, 390*5fcf092eSHyungwoo Yang {0x3662, 0x10}, 391*5fcf092eSHyungwoo Yang {0x3664, 0x73}, 392*5fcf092eSHyungwoo Yang {0x3665, 0xa7}, 393*5fcf092eSHyungwoo Yang {0x366e, 0xff}, 394*5fcf092eSHyungwoo Yang {0x366f, 0xf4}, 395*5fcf092eSHyungwoo Yang {0x3674, 0x00}, 396*5fcf092eSHyungwoo Yang {0x3679, 0x0c}, 397*5fcf092eSHyungwoo Yang {0x367f, 0x01}, 398*5fcf092eSHyungwoo Yang {0x3680, 0x0c}, 399*5fcf092eSHyungwoo Yang {0x3681, 0x50}, 400*5fcf092eSHyungwoo Yang {0x3682, 0x50}, 401*5fcf092eSHyungwoo Yang {0x3683, 0xa9}, 402*5fcf092eSHyungwoo Yang {0x3684, 0xa9}, 403*5fcf092eSHyungwoo Yang {0x3709, 0x5f}, 404*5fcf092eSHyungwoo Yang {0x3714, 0x28}, 405*5fcf092eSHyungwoo Yang {0x371a, 0x3e}, 406*5fcf092eSHyungwoo Yang {0x3737, 0x08}, 407*5fcf092eSHyungwoo Yang {0x3738, 0xcc}, 408*5fcf092eSHyungwoo Yang {0x3739, 0x20}, 409*5fcf092eSHyungwoo Yang {0x373d, 0x26}, 410*5fcf092eSHyungwoo Yang {0x3764, 0x20}, 411*5fcf092eSHyungwoo Yang {0x3765, 0x20}, 412*5fcf092eSHyungwoo Yang {0x37a1, 0x36}, 413*5fcf092eSHyungwoo Yang {0x37a8, 0x3b}, 414*5fcf092eSHyungwoo Yang {0x37ab, 0x31}, 415*5fcf092eSHyungwoo Yang {0x37c2, 0x14}, 416*5fcf092eSHyungwoo Yang {0x37c3, 0xf1}, 417*5fcf092eSHyungwoo Yang {0x37c5, 0x00}, 418*5fcf092eSHyungwoo Yang {0x37d8, 0x03}, 419*5fcf092eSHyungwoo Yang {0x37d9, 0x0c}, 420*5fcf092eSHyungwoo Yang {0x37da, 0xc2}, 421*5fcf092eSHyungwoo Yang {0x37dc, 0x02}, 422*5fcf092eSHyungwoo Yang {0x37e0, 0x00}, 423*5fcf092eSHyungwoo Yang {0x37e1, 0x0a}, 424*5fcf092eSHyungwoo Yang {0x37e2, 0x14}, 425*5fcf092eSHyungwoo Yang {0x37e3, 0x08}, 426*5fcf092eSHyungwoo Yang {0x37e4, 0x38}, 427*5fcf092eSHyungwoo Yang {0x37e5, 0x03}, 428*5fcf092eSHyungwoo Yang {0x37e6, 0x08}, 429*5fcf092eSHyungwoo Yang {0x3800, 0x00}, 430*5fcf092eSHyungwoo Yang {0x3801, 0x00}, 431*5fcf092eSHyungwoo Yang {0x3802, 0x00}, 432*5fcf092eSHyungwoo Yang {0x3803, 0x00}, 433*5fcf092eSHyungwoo Yang {0x3804, 0x10}, 434*5fcf092eSHyungwoo Yang {0x3805, 0x9f}, 435*5fcf092eSHyungwoo Yang {0x3806, 0x0c}, 436*5fcf092eSHyungwoo Yang {0x3807, 0x5f}, 437*5fcf092eSHyungwoo Yang {0x3808, 0x08}, 438*5fcf092eSHyungwoo Yang {0x3809, 0x40}, 439*5fcf092eSHyungwoo Yang {0x380a, 0x06}, 440*5fcf092eSHyungwoo Yang {0x380b, 0x20}, 441*5fcf092eSHyungwoo Yang {0x380c, 0x04}, 442*5fcf092eSHyungwoo Yang {0x380d, 0x62}, 443*5fcf092eSHyungwoo Yang {0x380e, 0x0c}, 444*5fcf092eSHyungwoo Yang {0x380f, 0x8e}, 445*5fcf092eSHyungwoo Yang {0x3811, 0x04}, 446*5fcf092eSHyungwoo Yang {0x3813, 0x05}, 447*5fcf092eSHyungwoo Yang {0x3814, 0x03}, 448*5fcf092eSHyungwoo Yang {0x3815, 0x01}, 449*5fcf092eSHyungwoo Yang {0x3816, 0x03}, 450*5fcf092eSHyungwoo Yang {0x3817, 0x01}, 451*5fcf092eSHyungwoo Yang {0x3820, 0xab}, 452*5fcf092eSHyungwoo Yang {0x3821, 0x00}, 453*5fcf092eSHyungwoo Yang {0x3822, 0xc2}, 454*5fcf092eSHyungwoo Yang {0x3823, 0x18}, 455*5fcf092eSHyungwoo Yang {0x3826, 0x04}, 456*5fcf092eSHyungwoo Yang {0x3827, 0x90}, 457*5fcf092eSHyungwoo Yang {0x3829, 0x07}, 458*5fcf092eSHyungwoo Yang {0x3832, 0x00}, 459*5fcf092eSHyungwoo Yang {0x3c80, 0x00}, 460*5fcf092eSHyungwoo Yang {0x3c87, 0x01}, 461*5fcf092eSHyungwoo Yang {0x3c8c, 0x19}, 462*5fcf092eSHyungwoo Yang {0x3c8d, 0x1c}, 463*5fcf092eSHyungwoo Yang {0x3c90, 0x00}, 464*5fcf092eSHyungwoo Yang {0x3c91, 0x00}, 465*5fcf092eSHyungwoo Yang {0x3c92, 0x00}, 466*5fcf092eSHyungwoo Yang {0x3c93, 0x00}, 467*5fcf092eSHyungwoo Yang {0x3c94, 0x40}, 468*5fcf092eSHyungwoo Yang {0x3c95, 0x54}, 469*5fcf092eSHyungwoo Yang {0x3c96, 0x34}, 470*5fcf092eSHyungwoo Yang {0x3c97, 0x04}, 471*5fcf092eSHyungwoo Yang {0x3c98, 0x00}, 472*5fcf092eSHyungwoo Yang {0x3d8c, 0x73}, 473*5fcf092eSHyungwoo Yang {0x3d8d, 0xc0}, 474*5fcf092eSHyungwoo Yang {0x3f00, 0x0b}, 475*5fcf092eSHyungwoo Yang {0x3f03, 0x00}, 476*5fcf092eSHyungwoo Yang {0x4001, 0xe0}, 477*5fcf092eSHyungwoo Yang {0x4008, 0x00}, 478*5fcf092eSHyungwoo Yang {0x4009, 0x0d}, 479*5fcf092eSHyungwoo Yang {0x4011, 0xf0}, 480*5fcf092eSHyungwoo Yang {0x4017, 0x08}, 481*5fcf092eSHyungwoo Yang {0x4050, 0x04}, 482*5fcf092eSHyungwoo Yang {0x4051, 0x0b}, 483*5fcf092eSHyungwoo Yang {0x4052, 0x00}, 484*5fcf092eSHyungwoo Yang {0x4053, 0x80}, 485*5fcf092eSHyungwoo Yang {0x4054, 0x00}, 486*5fcf092eSHyungwoo Yang {0x4055, 0x80}, 487*5fcf092eSHyungwoo Yang {0x4056, 0x00}, 488*5fcf092eSHyungwoo Yang {0x4057, 0x80}, 489*5fcf092eSHyungwoo Yang {0x4058, 0x00}, 490*5fcf092eSHyungwoo Yang {0x4059, 0x80}, 491*5fcf092eSHyungwoo Yang {0x405e, 0x20}, 492*5fcf092eSHyungwoo Yang {0x4500, 0x07}, 493*5fcf092eSHyungwoo Yang {0x4503, 0x00}, 494*5fcf092eSHyungwoo Yang {0x450a, 0x04}, 495*5fcf092eSHyungwoo Yang {0x4809, 0x04}, 496*5fcf092eSHyungwoo Yang {0x480c, 0x12}, 497*5fcf092eSHyungwoo Yang {0x481f, 0x30}, 498*5fcf092eSHyungwoo Yang {0x4833, 0x10}, 499*5fcf092eSHyungwoo Yang {0x4837, 0x1c}, 500*5fcf092eSHyungwoo Yang {0x4902, 0x01}, 501*5fcf092eSHyungwoo Yang {0x4d00, 0x03}, 502*5fcf092eSHyungwoo Yang {0x4d01, 0xc9}, 503*5fcf092eSHyungwoo Yang {0x4d02, 0xbc}, 504*5fcf092eSHyungwoo Yang {0x4d03, 0xd7}, 505*5fcf092eSHyungwoo Yang {0x4d04, 0xf0}, 506*5fcf092eSHyungwoo Yang {0x4d05, 0xa2}, 507*5fcf092eSHyungwoo Yang {0x5000, 0xfd}, 508*5fcf092eSHyungwoo Yang {0x5001, 0x01}, 509*5fcf092eSHyungwoo Yang {0x5040, 0x39}, 510*5fcf092eSHyungwoo Yang {0x5041, 0x10}, 511*5fcf092eSHyungwoo Yang {0x5042, 0x10}, 512*5fcf092eSHyungwoo Yang {0x5043, 0x84}, 513*5fcf092eSHyungwoo Yang {0x5044, 0x62}, 514*5fcf092eSHyungwoo Yang {0x5180, 0x00}, 515*5fcf092eSHyungwoo Yang {0x5181, 0x10}, 516*5fcf092eSHyungwoo Yang {0x5182, 0x02}, 517*5fcf092eSHyungwoo Yang {0x5183, 0x0f}, 518*5fcf092eSHyungwoo Yang {0x5200, 0x1b}, 519*5fcf092eSHyungwoo Yang {0x520b, 0x07}, 520*5fcf092eSHyungwoo Yang {0x520c, 0x0f}, 521*5fcf092eSHyungwoo Yang {0x5300, 0x04}, 522*5fcf092eSHyungwoo Yang {0x5301, 0x0c}, 523*5fcf092eSHyungwoo Yang {0x5302, 0x0c}, 524*5fcf092eSHyungwoo Yang {0x5303, 0x0f}, 525*5fcf092eSHyungwoo Yang {0x5304, 0x00}, 526*5fcf092eSHyungwoo Yang {0x5305, 0x70}, 527*5fcf092eSHyungwoo Yang {0x5306, 0x00}, 528*5fcf092eSHyungwoo Yang {0x5307, 0x80}, 529*5fcf092eSHyungwoo Yang {0x5308, 0x00}, 530*5fcf092eSHyungwoo Yang {0x5309, 0xa5}, 531*5fcf092eSHyungwoo Yang {0x530a, 0x00}, 532*5fcf092eSHyungwoo Yang {0x530b, 0xd3}, 533*5fcf092eSHyungwoo Yang {0x530c, 0x00}, 534*5fcf092eSHyungwoo Yang {0x530d, 0xf0}, 535*5fcf092eSHyungwoo Yang {0x530e, 0x01}, 536*5fcf092eSHyungwoo Yang {0x530f, 0x10}, 537*5fcf092eSHyungwoo Yang {0x5310, 0x01}, 538*5fcf092eSHyungwoo Yang {0x5311, 0x20}, 539*5fcf092eSHyungwoo Yang {0x5312, 0x01}, 540*5fcf092eSHyungwoo Yang {0x5313, 0x20}, 541*5fcf092eSHyungwoo Yang {0x5314, 0x01}, 542*5fcf092eSHyungwoo Yang {0x5315, 0x20}, 543*5fcf092eSHyungwoo Yang {0x5316, 0x08}, 544*5fcf092eSHyungwoo Yang {0x5317, 0x08}, 545*5fcf092eSHyungwoo Yang {0x5318, 0x10}, 546*5fcf092eSHyungwoo Yang {0x5319, 0x88}, 547*5fcf092eSHyungwoo Yang {0x531a, 0x88}, 548*5fcf092eSHyungwoo Yang {0x531b, 0xa9}, 549*5fcf092eSHyungwoo Yang {0x531c, 0xaa}, 550*5fcf092eSHyungwoo Yang {0x531d, 0x0a}, 551*5fcf092eSHyungwoo Yang {0x5405, 0x02}, 552*5fcf092eSHyungwoo Yang {0x5406, 0x67}, 553*5fcf092eSHyungwoo Yang {0x5407, 0x01}, 554*5fcf092eSHyungwoo Yang {0x5408, 0x4a}, 555*5fcf092eSHyungwoo Yang }; 556*5fcf092eSHyungwoo Yang 557*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_2112x1188_regs[] = { 558*5fcf092eSHyungwoo Yang {0x3013, 0x32}, 559*5fcf092eSHyungwoo Yang {0x301b, 0xf0}, 560*5fcf092eSHyungwoo Yang {0x301f, 0xd0}, 561*5fcf092eSHyungwoo Yang {0x3106, 0x15}, 562*5fcf092eSHyungwoo Yang {0x3107, 0x23}, 563*5fcf092eSHyungwoo Yang {0x350a, 0x00}, 564*5fcf092eSHyungwoo Yang {0x350e, 0x00}, 565*5fcf092eSHyungwoo Yang {0x3510, 0x00}, 566*5fcf092eSHyungwoo Yang {0x3511, 0x02}, 567*5fcf092eSHyungwoo Yang {0x3512, 0x00}, 568*5fcf092eSHyungwoo Yang {0x3600, 0x2b}, 569*5fcf092eSHyungwoo Yang {0x3601, 0x52}, 570*5fcf092eSHyungwoo Yang {0x3602, 0x60}, 571*5fcf092eSHyungwoo Yang {0x3612, 0x05}, 572*5fcf092eSHyungwoo Yang {0x3613, 0xa4}, 573*5fcf092eSHyungwoo Yang {0x3620, 0x80}, 574*5fcf092eSHyungwoo Yang {0x3621, 0x10}, 575*5fcf092eSHyungwoo Yang {0x3622, 0x30}, 576*5fcf092eSHyungwoo Yang {0x3624, 0x1c}, 577*5fcf092eSHyungwoo Yang {0x3640, 0x10}, 578*5fcf092eSHyungwoo Yang {0x3641, 0x70}, 579*5fcf092eSHyungwoo Yang {0x3661, 0x80}, 580*5fcf092eSHyungwoo Yang {0x3662, 0x10}, 581*5fcf092eSHyungwoo Yang {0x3664, 0x73}, 582*5fcf092eSHyungwoo Yang {0x3665, 0xa7}, 583*5fcf092eSHyungwoo Yang {0x366e, 0xff}, 584*5fcf092eSHyungwoo Yang {0x366f, 0xf4}, 585*5fcf092eSHyungwoo Yang {0x3674, 0x00}, 586*5fcf092eSHyungwoo Yang {0x3679, 0x0c}, 587*5fcf092eSHyungwoo Yang {0x367f, 0x01}, 588*5fcf092eSHyungwoo Yang {0x3680, 0x0c}, 589*5fcf092eSHyungwoo Yang {0x3681, 0x50}, 590*5fcf092eSHyungwoo Yang {0x3682, 0x50}, 591*5fcf092eSHyungwoo Yang {0x3683, 0xa9}, 592*5fcf092eSHyungwoo Yang {0x3684, 0xa9}, 593*5fcf092eSHyungwoo Yang {0x3709, 0x5f}, 594*5fcf092eSHyungwoo Yang {0x3714, 0x28}, 595*5fcf092eSHyungwoo Yang {0x371a, 0x3e}, 596*5fcf092eSHyungwoo Yang {0x3737, 0x08}, 597*5fcf092eSHyungwoo Yang {0x3738, 0xcc}, 598*5fcf092eSHyungwoo Yang {0x3739, 0x20}, 599*5fcf092eSHyungwoo Yang {0x373d, 0x26}, 600*5fcf092eSHyungwoo Yang {0x3764, 0x20}, 601*5fcf092eSHyungwoo Yang {0x3765, 0x20}, 602*5fcf092eSHyungwoo Yang {0x37a1, 0x36}, 603*5fcf092eSHyungwoo Yang {0x37a8, 0x3b}, 604*5fcf092eSHyungwoo Yang {0x37ab, 0x31}, 605*5fcf092eSHyungwoo Yang {0x37c2, 0x14}, 606*5fcf092eSHyungwoo Yang {0x37c3, 0xf1}, 607*5fcf092eSHyungwoo Yang {0x37c5, 0x00}, 608*5fcf092eSHyungwoo Yang {0x37d8, 0x03}, 609*5fcf092eSHyungwoo Yang {0x37d9, 0x0c}, 610*5fcf092eSHyungwoo Yang {0x37da, 0xc2}, 611*5fcf092eSHyungwoo Yang {0x37dc, 0x02}, 612*5fcf092eSHyungwoo Yang {0x37e0, 0x00}, 613*5fcf092eSHyungwoo Yang {0x37e1, 0x0a}, 614*5fcf092eSHyungwoo Yang {0x37e2, 0x14}, 615*5fcf092eSHyungwoo Yang {0x37e3, 0x08}, 616*5fcf092eSHyungwoo Yang {0x37e4, 0x38}, 617*5fcf092eSHyungwoo Yang {0x37e5, 0x03}, 618*5fcf092eSHyungwoo Yang {0x37e6, 0x08}, 619*5fcf092eSHyungwoo Yang {0x3800, 0x00}, 620*5fcf092eSHyungwoo Yang {0x3801, 0x00}, 621*5fcf092eSHyungwoo Yang {0x3802, 0x01}, 622*5fcf092eSHyungwoo Yang {0x3803, 0x84}, 623*5fcf092eSHyungwoo Yang {0x3804, 0x10}, 624*5fcf092eSHyungwoo Yang {0x3805, 0x9f}, 625*5fcf092eSHyungwoo Yang {0x3806, 0x0a}, 626*5fcf092eSHyungwoo Yang {0x3807, 0xd3}, 627*5fcf092eSHyungwoo Yang {0x3808, 0x08}, 628*5fcf092eSHyungwoo Yang {0x3809, 0x40}, 629*5fcf092eSHyungwoo Yang {0x380a, 0x04}, 630*5fcf092eSHyungwoo Yang {0x380b, 0xa4}, 631*5fcf092eSHyungwoo Yang {0x380c, 0x04}, 632*5fcf092eSHyungwoo Yang {0x380d, 0x62}, 633*5fcf092eSHyungwoo Yang {0x380e, 0x0c}, 634*5fcf092eSHyungwoo Yang {0x380f, 0x8e}, 635*5fcf092eSHyungwoo Yang {0x3811, 0x08}, 636*5fcf092eSHyungwoo Yang {0x3813, 0x03}, 637*5fcf092eSHyungwoo Yang {0x3814, 0x03}, 638*5fcf092eSHyungwoo Yang {0x3815, 0x01}, 639*5fcf092eSHyungwoo Yang {0x3816, 0x03}, 640*5fcf092eSHyungwoo Yang {0x3817, 0x01}, 641*5fcf092eSHyungwoo Yang {0x3820, 0xab}, 642*5fcf092eSHyungwoo Yang {0x3821, 0x00}, 643*5fcf092eSHyungwoo Yang {0x3822, 0xc2}, 644*5fcf092eSHyungwoo Yang {0x3823, 0x18}, 645*5fcf092eSHyungwoo Yang {0x3826, 0x04}, 646*5fcf092eSHyungwoo Yang {0x3827, 0x90}, 647*5fcf092eSHyungwoo Yang {0x3829, 0x07}, 648*5fcf092eSHyungwoo Yang {0x3832, 0x00}, 649*5fcf092eSHyungwoo Yang {0x3c80, 0x00}, 650*5fcf092eSHyungwoo Yang {0x3c87, 0x01}, 651*5fcf092eSHyungwoo Yang {0x3c8c, 0x19}, 652*5fcf092eSHyungwoo Yang {0x3c8d, 0x1c}, 653*5fcf092eSHyungwoo Yang {0x3c90, 0x00}, 654*5fcf092eSHyungwoo Yang {0x3c91, 0x00}, 655*5fcf092eSHyungwoo Yang {0x3c92, 0x00}, 656*5fcf092eSHyungwoo Yang {0x3c93, 0x00}, 657*5fcf092eSHyungwoo Yang {0x3c94, 0x40}, 658*5fcf092eSHyungwoo Yang {0x3c95, 0x54}, 659*5fcf092eSHyungwoo Yang {0x3c96, 0x34}, 660*5fcf092eSHyungwoo Yang {0x3c97, 0x04}, 661*5fcf092eSHyungwoo Yang {0x3c98, 0x00}, 662*5fcf092eSHyungwoo Yang {0x3d8c, 0x73}, 663*5fcf092eSHyungwoo Yang {0x3d8d, 0xc0}, 664*5fcf092eSHyungwoo Yang {0x3f00, 0x0b}, 665*5fcf092eSHyungwoo Yang {0x3f03, 0x00}, 666*5fcf092eSHyungwoo Yang {0x4001, 0xe0}, 667*5fcf092eSHyungwoo Yang {0x4008, 0x00}, 668*5fcf092eSHyungwoo Yang {0x4009, 0x0d}, 669*5fcf092eSHyungwoo Yang {0x4011, 0xf0}, 670*5fcf092eSHyungwoo Yang {0x4017, 0x08}, 671*5fcf092eSHyungwoo Yang {0x4050, 0x04}, 672*5fcf092eSHyungwoo Yang {0x4051, 0x0b}, 673*5fcf092eSHyungwoo Yang {0x4052, 0x00}, 674*5fcf092eSHyungwoo Yang {0x4053, 0x80}, 675*5fcf092eSHyungwoo Yang {0x4054, 0x00}, 676*5fcf092eSHyungwoo Yang {0x4055, 0x80}, 677*5fcf092eSHyungwoo Yang {0x4056, 0x00}, 678*5fcf092eSHyungwoo Yang {0x4057, 0x80}, 679*5fcf092eSHyungwoo Yang {0x4058, 0x00}, 680*5fcf092eSHyungwoo Yang {0x4059, 0x80}, 681*5fcf092eSHyungwoo Yang {0x405e, 0x20}, 682*5fcf092eSHyungwoo Yang {0x4500, 0x07}, 683*5fcf092eSHyungwoo Yang {0x4503, 0x00}, 684*5fcf092eSHyungwoo Yang {0x450a, 0x04}, 685*5fcf092eSHyungwoo Yang {0x4809, 0x04}, 686*5fcf092eSHyungwoo Yang {0x480c, 0x12}, 687*5fcf092eSHyungwoo Yang {0x481f, 0x30}, 688*5fcf092eSHyungwoo Yang {0x4833, 0x10}, 689*5fcf092eSHyungwoo Yang {0x4837, 0x1c}, 690*5fcf092eSHyungwoo Yang {0x4902, 0x01}, 691*5fcf092eSHyungwoo Yang {0x4d00, 0x03}, 692*5fcf092eSHyungwoo Yang {0x4d01, 0xc9}, 693*5fcf092eSHyungwoo Yang {0x4d02, 0xbc}, 694*5fcf092eSHyungwoo Yang {0x4d03, 0xd7}, 695*5fcf092eSHyungwoo Yang {0x4d04, 0xf0}, 696*5fcf092eSHyungwoo Yang {0x4d05, 0xa2}, 697*5fcf092eSHyungwoo Yang {0x5000, 0xfd}, 698*5fcf092eSHyungwoo Yang {0x5001, 0x01}, 699*5fcf092eSHyungwoo Yang {0x5040, 0x39}, 700*5fcf092eSHyungwoo Yang {0x5041, 0x10}, 701*5fcf092eSHyungwoo Yang {0x5042, 0x10}, 702*5fcf092eSHyungwoo Yang {0x5043, 0x84}, 703*5fcf092eSHyungwoo Yang {0x5044, 0x62}, 704*5fcf092eSHyungwoo Yang {0x5180, 0x00}, 705*5fcf092eSHyungwoo Yang {0x5181, 0x10}, 706*5fcf092eSHyungwoo Yang {0x5182, 0x02}, 707*5fcf092eSHyungwoo Yang {0x5183, 0x0f}, 708*5fcf092eSHyungwoo Yang {0x5200, 0x1b}, 709*5fcf092eSHyungwoo Yang {0x520b, 0x07}, 710*5fcf092eSHyungwoo Yang {0x520c, 0x0f}, 711*5fcf092eSHyungwoo Yang {0x5300, 0x04}, 712*5fcf092eSHyungwoo Yang {0x5301, 0x0c}, 713*5fcf092eSHyungwoo Yang {0x5302, 0x0c}, 714*5fcf092eSHyungwoo Yang {0x5303, 0x0f}, 715*5fcf092eSHyungwoo Yang {0x5304, 0x00}, 716*5fcf092eSHyungwoo Yang {0x5305, 0x70}, 717*5fcf092eSHyungwoo Yang {0x5306, 0x00}, 718*5fcf092eSHyungwoo Yang {0x5307, 0x80}, 719*5fcf092eSHyungwoo Yang {0x5308, 0x00}, 720*5fcf092eSHyungwoo Yang {0x5309, 0xa5}, 721*5fcf092eSHyungwoo Yang {0x530a, 0x00}, 722*5fcf092eSHyungwoo Yang {0x530b, 0xd3}, 723*5fcf092eSHyungwoo Yang {0x530c, 0x00}, 724*5fcf092eSHyungwoo Yang {0x530d, 0xf0}, 725*5fcf092eSHyungwoo Yang {0x530e, 0x01}, 726*5fcf092eSHyungwoo Yang {0x530f, 0x10}, 727*5fcf092eSHyungwoo Yang {0x5310, 0x01}, 728*5fcf092eSHyungwoo Yang {0x5311, 0x20}, 729*5fcf092eSHyungwoo Yang {0x5312, 0x01}, 730*5fcf092eSHyungwoo Yang {0x5313, 0x20}, 731*5fcf092eSHyungwoo Yang {0x5314, 0x01}, 732*5fcf092eSHyungwoo Yang {0x5315, 0x20}, 733*5fcf092eSHyungwoo Yang {0x5316, 0x08}, 734*5fcf092eSHyungwoo Yang {0x5317, 0x08}, 735*5fcf092eSHyungwoo Yang {0x5318, 0x10}, 736*5fcf092eSHyungwoo Yang {0x5319, 0x88}, 737*5fcf092eSHyungwoo Yang {0x531a, 0x88}, 738*5fcf092eSHyungwoo Yang {0x531b, 0xa9}, 739*5fcf092eSHyungwoo Yang {0x531c, 0xaa}, 740*5fcf092eSHyungwoo Yang {0x531d, 0x0a}, 741*5fcf092eSHyungwoo Yang {0x5405, 0x02}, 742*5fcf092eSHyungwoo Yang {0x5406, 0x67}, 743*5fcf092eSHyungwoo Yang {0x5407, 0x01}, 744*5fcf092eSHyungwoo Yang {0x5408, 0x4a}, 745*5fcf092eSHyungwoo Yang }; 746*5fcf092eSHyungwoo Yang 747*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_1056x784_regs[] = { 748*5fcf092eSHyungwoo Yang {0x3013, 0x32}, 749*5fcf092eSHyungwoo Yang {0x301b, 0xf0}, 750*5fcf092eSHyungwoo Yang {0x301f, 0xd0}, 751*5fcf092eSHyungwoo Yang {0x3106, 0x15}, 752*5fcf092eSHyungwoo Yang {0x3107, 0x23}, 753*5fcf092eSHyungwoo Yang {0x350a, 0x00}, 754*5fcf092eSHyungwoo Yang {0x350e, 0x00}, 755*5fcf092eSHyungwoo Yang {0x3510, 0x00}, 756*5fcf092eSHyungwoo Yang {0x3511, 0x02}, 757*5fcf092eSHyungwoo Yang {0x3512, 0x00}, 758*5fcf092eSHyungwoo Yang {0x3600, 0x2b}, 759*5fcf092eSHyungwoo Yang {0x3601, 0x52}, 760*5fcf092eSHyungwoo Yang {0x3602, 0x60}, 761*5fcf092eSHyungwoo Yang {0x3612, 0x05}, 762*5fcf092eSHyungwoo Yang {0x3613, 0xa4}, 763*5fcf092eSHyungwoo Yang {0x3620, 0x80}, 764*5fcf092eSHyungwoo Yang {0x3621, 0x10}, 765*5fcf092eSHyungwoo Yang {0x3622, 0x30}, 766*5fcf092eSHyungwoo Yang {0x3624, 0x1c}, 767*5fcf092eSHyungwoo Yang {0x3640, 0x10}, 768*5fcf092eSHyungwoo Yang {0x3641, 0x70}, 769*5fcf092eSHyungwoo Yang {0x3661, 0x80}, 770*5fcf092eSHyungwoo Yang {0x3662, 0x08}, 771*5fcf092eSHyungwoo Yang {0x3664, 0x73}, 772*5fcf092eSHyungwoo Yang {0x3665, 0xa7}, 773*5fcf092eSHyungwoo Yang {0x366e, 0xff}, 774*5fcf092eSHyungwoo Yang {0x366f, 0xf4}, 775*5fcf092eSHyungwoo Yang {0x3674, 0x00}, 776*5fcf092eSHyungwoo Yang {0x3679, 0x0c}, 777*5fcf092eSHyungwoo Yang {0x367f, 0x01}, 778*5fcf092eSHyungwoo Yang {0x3680, 0x0c}, 779*5fcf092eSHyungwoo Yang {0x3681, 0x50}, 780*5fcf092eSHyungwoo Yang {0x3682, 0x50}, 781*5fcf092eSHyungwoo Yang {0x3683, 0xa9}, 782*5fcf092eSHyungwoo Yang {0x3684, 0xa9}, 783*5fcf092eSHyungwoo Yang {0x3709, 0x5f}, 784*5fcf092eSHyungwoo Yang {0x3714, 0x30}, 785*5fcf092eSHyungwoo Yang {0x371a, 0x3e}, 786*5fcf092eSHyungwoo Yang {0x3737, 0x08}, 787*5fcf092eSHyungwoo Yang {0x3738, 0xcc}, 788*5fcf092eSHyungwoo Yang {0x3739, 0x20}, 789*5fcf092eSHyungwoo Yang {0x373d, 0x26}, 790*5fcf092eSHyungwoo Yang {0x3764, 0x20}, 791*5fcf092eSHyungwoo Yang {0x3765, 0x20}, 792*5fcf092eSHyungwoo Yang {0x37a1, 0x36}, 793*5fcf092eSHyungwoo Yang {0x37a8, 0x3b}, 794*5fcf092eSHyungwoo Yang {0x37ab, 0x31}, 795*5fcf092eSHyungwoo Yang {0x37c2, 0x2c}, 796*5fcf092eSHyungwoo Yang {0x37c3, 0xf1}, 797*5fcf092eSHyungwoo Yang {0x37c5, 0x00}, 798*5fcf092eSHyungwoo Yang {0x37d8, 0x03}, 799*5fcf092eSHyungwoo Yang {0x37d9, 0x06}, 800*5fcf092eSHyungwoo Yang {0x37da, 0xc2}, 801*5fcf092eSHyungwoo Yang {0x37dc, 0x02}, 802*5fcf092eSHyungwoo Yang {0x37e0, 0x00}, 803*5fcf092eSHyungwoo Yang {0x37e1, 0x0a}, 804*5fcf092eSHyungwoo Yang {0x37e2, 0x14}, 805*5fcf092eSHyungwoo Yang {0x37e3, 0x08}, 806*5fcf092eSHyungwoo Yang {0x37e4, 0x36}, 807*5fcf092eSHyungwoo Yang {0x37e5, 0x03}, 808*5fcf092eSHyungwoo Yang {0x37e6, 0x08}, 809*5fcf092eSHyungwoo Yang {0x3800, 0x00}, 810*5fcf092eSHyungwoo Yang {0x3801, 0x00}, 811*5fcf092eSHyungwoo Yang {0x3802, 0x00}, 812*5fcf092eSHyungwoo Yang {0x3803, 0x00}, 813*5fcf092eSHyungwoo Yang {0x3804, 0x10}, 814*5fcf092eSHyungwoo Yang {0x3805, 0x9f}, 815*5fcf092eSHyungwoo Yang {0x3806, 0x0c}, 816*5fcf092eSHyungwoo Yang {0x3807, 0x5f}, 817*5fcf092eSHyungwoo Yang {0x3808, 0x04}, 818*5fcf092eSHyungwoo Yang {0x3809, 0x20}, 819*5fcf092eSHyungwoo Yang {0x380a, 0x03}, 820*5fcf092eSHyungwoo Yang {0x380b, 0x10}, 821*5fcf092eSHyungwoo Yang {0x380c, 0x04}, 822*5fcf092eSHyungwoo Yang {0x380d, 0x62}, 823*5fcf092eSHyungwoo Yang {0x380e, 0x0c}, 824*5fcf092eSHyungwoo Yang {0x380f, 0x8e}, 825*5fcf092eSHyungwoo Yang {0x3811, 0x04}, 826*5fcf092eSHyungwoo Yang {0x3813, 0x05}, 827*5fcf092eSHyungwoo Yang {0x3814, 0x07}, 828*5fcf092eSHyungwoo Yang {0x3815, 0x01}, 829*5fcf092eSHyungwoo Yang {0x3816, 0x07}, 830*5fcf092eSHyungwoo Yang {0x3817, 0x01}, 831*5fcf092eSHyungwoo Yang {0x3820, 0xac}, 832*5fcf092eSHyungwoo Yang {0x3821, 0x00}, 833*5fcf092eSHyungwoo Yang {0x3822, 0xc2}, 834*5fcf092eSHyungwoo Yang {0x3823, 0x18}, 835*5fcf092eSHyungwoo Yang {0x3826, 0x04}, 836*5fcf092eSHyungwoo Yang {0x3827, 0x48}, 837*5fcf092eSHyungwoo Yang {0x3829, 0x03}, 838*5fcf092eSHyungwoo Yang {0x3832, 0x00}, 839*5fcf092eSHyungwoo Yang {0x3c80, 0x00}, 840*5fcf092eSHyungwoo Yang {0x3c87, 0x01}, 841*5fcf092eSHyungwoo Yang {0x3c8c, 0x19}, 842*5fcf092eSHyungwoo Yang {0x3c8d, 0x1c}, 843*5fcf092eSHyungwoo Yang {0x3c90, 0x00}, 844*5fcf092eSHyungwoo Yang {0x3c91, 0x00}, 845*5fcf092eSHyungwoo Yang {0x3c92, 0x00}, 846*5fcf092eSHyungwoo Yang {0x3c93, 0x00}, 847*5fcf092eSHyungwoo Yang {0x3c94, 0x40}, 848*5fcf092eSHyungwoo Yang {0x3c95, 0x54}, 849*5fcf092eSHyungwoo Yang {0x3c96, 0x34}, 850*5fcf092eSHyungwoo Yang {0x3c97, 0x04}, 851*5fcf092eSHyungwoo Yang {0x3c98, 0x00}, 852*5fcf092eSHyungwoo Yang {0x3d8c, 0x73}, 853*5fcf092eSHyungwoo Yang {0x3d8d, 0xc0}, 854*5fcf092eSHyungwoo Yang {0x3f00, 0x0b}, 855*5fcf092eSHyungwoo Yang {0x3f03, 0x00}, 856*5fcf092eSHyungwoo Yang {0x4001, 0xe0}, 857*5fcf092eSHyungwoo Yang {0x4008, 0x00}, 858*5fcf092eSHyungwoo Yang {0x4009, 0x05}, 859*5fcf092eSHyungwoo Yang {0x4011, 0xf0}, 860*5fcf092eSHyungwoo Yang {0x4017, 0x08}, 861*5fcf092eSHyungwoo Yang {0x4050, 0x02}, 862*5fcf092eSHyungwoo Yang {0x4051, 0x05}, 863*5fcf092eSHyungwoo Yang {0x4052, 0x00}, 864*5fcf092eSHyungwoo Yang {0x4053, 0x80}, 865*5fcf092eSHyungwoo Yang {0x4054, 0x00}, 866*5fcf092eSHyungwoo Yang {0x4055, 0x80}, 867*5fcf092eSHyungwoo Yang {0x4056, 0x00}, 868*5fcf092eSHyungwoo Yang {0x4057, 0x80}, 869*5fcf092eSHyungwoo Yang {0x4058, 0x00}, 870*5fcf092eSHyungwoo Yang {0x4059, 0x80}, 871*5fcf092eSHyungwoo Yang {0x405e, 0x20}, 872*5fcf092eSHyungwoo Yang {0x4500, 0x07}, 873*5fcf092eSHyungwoo Yang {0x4503, 0x00}, 874*5fcf092eSHyungwoo Yang {0x450a, 0x04}, 875*5fcf092eSHyungwoo Yang {0x4809, 0x04}, 876*5fcf092eSHyungwoo Yang {0x480c, 0x12}, 877*5fcf092eSHyungwoo Yang {0x481f, 0x30}, 878*5fcf092eSHyungwoo Yang {0x4833, 0x10}, 879*5fcf092eSHyungwoo Yang {0x4837, 0x1e}, 880*5fcf092eSHyungwoo Yang {0x4902, 0x02}, 881*5fcf092eSHyungwoo Yang {0x4d00, 0x03}, 882*5fcf092eSHyungwoo Yang {0x4d01, 0xc9}, 883*5fcf092eSHyungwoo Yang {0x4d02, 0xbc}, 884*5fcf092eSHyungwoo Yang {0x4d03, 0xd7}, 885*5fcf092eSHyungwoo Yang {0x4d04, 0xf0}, 886*5fcf092eSHyungwoo Yang {0x4d05, 0xa2}, 887*5fcf092eSHyungwoo Yang {0x5000, 0xfd}, 888*5fcf092eSHyungwoo Yang {0x5001, 0x01}, 889*5fcf092eSHyungwoo Yang {0x5040, 0x39}, 890*5fcf092eSHyungwoo Yang {0x5041, 0x10}, 891*5fcf092eSHyungwoo Yang {0x5042, 0x10}, 892*5fcf092eSHyungwoo Yang {0x5043, 0x84}, 893*5fcf092eSHyungwoo Yang {0x5044, 0x62}, 894*5fcf092eSHyungwoo Yang {0x5180, 0x00}, 895*5fcf092eSHyungwoo Yang {0x5181, 0x10}, 896*5fcf092eSHyungwoo Yang {0x5182, 0x02}, 897*5fcf092eSHyungwoo Yang {0x5183, 0x0f}, 898*5fcf092eSHyungwoo Yang {0x5200, 0x1b}, 899*5fcf092eSHyungwoo Yang {0x520b, 0x07}, 900*5fcf092eSHyungwoo Yang {0x520c, 0x0f}, 901*5fcf092eSHyungwoo Yang {0x5300, 0x04}, 902*5fcf092eSHyungwoo Yang {0x5301, 0x0c}, 903*5fcf092eSHyungwoo Yang {0x5302, 0x0c}, 904*5fcf092eSHyungwoo Yang {0x5303, 0x0f}, 905*5fcf092eSHyungwoo Yang {0x5304, 0x00}, 906*5fcf092eSHyungwoo Yang {0x5305, 0x70}, 907*5fcf092eSHyungwoo Yang {0x5306, 0x00}, 908*5fcf092eSHyungwoo Yang {0x5307, 0x80}, 909*5fcf092eSHyungwoo Yang {0x5308, 0x00}, 910*5fcf092eSHyungwoo Yang {0x5309, 0xa5}, 911*5fcf092eSHyungwoo Yang {0x530a, 0x00}, 912*5fcf092eSHyungwoo Yang {0x530b, 0xd3}, 913*5fcf092eSHyungwoo Yang {0x530c, 0x00}, 914*5fcf092eSHyungwoo Yang {0x530d, 0xf0}, 915*5fcf092eSHyungwoo Yang {0x530e, 0x01}, 916*5fcf092eSHyungwoo Yang {0x530f, 0x10}, 917*5fcf092eSHyungwoo Yang {0x5310, 0x01}, 918*5fcf092eSHyungwoo Yang {0x5311, 0x20}, 919*5fcf092eSHyungwoo Yang {0x5312, 0x01}, 920*5fcf092eSHyungwoo Yang {0x5313, 0x20}, 921*5fcf092eSHyungwoo Yang {0x5314, 0x01}, 922*5fcf092eSHyungwoo Yang {0x5315, 0x20}, 923*5fcf092eSHyungwoo Yang {0x5316, 0x08}, 924*5fcf092eSHyungwoo Yang {0x5317, 0x08}, 925*5fcf092eSHyungwoo Yang {0x5318, 0x10}, 926*5fcf092eSHyungwoo Yang {0x5319, 0x88}, 927*5fcf092eSHyungwoo Yang {0x531a, 0x88}, 928*5fcf092eSHyungwoo Yang {0x531b, 0xa9}, 929*5fcf092eSHyungwoo Yang {0x531c, 0xaa}, 930*5fcf092eSHyungwoo Yang {0x531d, 0x0a}, 931*5fcf092eSHyungwoo Yang {0x5405, 0x02}, 932*5fcf092eSHyungwoo Yang {0x5406, 0x67}, 933*5fcf092eSHyungwoo Yang {0x5407, 0x01}, 934*5fcf092eSHyungwoo Yang {0x5408, 0x4a}, 935*5fcf092eSHyungwoo Yang }; 936*5fcf092eSHyungwoo Yang 937*5fcf092eSHyungwoo Yang static const char * const ov13858_test_pattern_menu[] = { 938*5fcf092eSHyungwoo Yang "Disabled", 939*5fcf092eSHyungwoo Yang "Vertical Color Bar Type 1", 940*5fcf092eSHyungwoo Yang "Vertical Color Bar Type 2", 941*5fcf092eSHyungwoo Yang "Vertical Color Bar Type 3", 942*5fcf092eSHyungwoo Yang "Vertical Color Bar Type 4" 943*5fcf092eSHyungwoo Yang }; 944*5fcf092eSHyungwoo Yang 945*5fcf092eSHyungwoo Yang /* Configurations for supported link frequencies */ 946*5fcf092eSHyungwoo Yang #define OV13858_NUM_OF_LINK_FREQS 2 947*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_1080MBPS 1080000000 948*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_540MBPS 540000000 949*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_INDEX_0 0 950*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_INDEX_1 1 951*5fcf092eSHyungwoo Yang 952*5fcf092eSHyungwoo Yang /* Menu items for LINK_FREQ V4L2 control */ 953*5fcf092eSHyungwoo Yang static const const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = { 954*5fcf092eSHyungwoo Yang OV13858_LINK_FREQ_1080MBPS, 955*5fcf092eSHyungwoo Yang OV13858_LINK_FREQ_540MBPS 956*5fcf092eSHyungwoo Yang }; 957*5fcf092eSHyungwoo Yang 958*5fcf092eSHyungwoo Yang /* Link frequency configs */ 959*5fcf092eSHyungwoo Yang static const struct ov13858_link_freq_config 960*5fcf092eSHyungwoo Yang link_freq_configs[OV13858_NUM_OF_LINK_FREQS] = { 961*5fcf092eSHyungwoo Yang { 962*5fcf092eSHyungwoo Yang .pixel_rate = 864000000, 963*5fcf092eSHyungwoo Yang .pixels_per_line = OV13858_PPL_1080MHZ, 964*5fcf092eSHyungwoo Yang .reg_list = { 965*5fcf092eSHyungwoo Yang .num_of_regs = ARRAY_SIZE(mipi_data_rate_1080mbps), 966*5fcf092eSHyungwoo Yang .regs = mipi_data_rate_1080mbps, 967*5fcf092eSHyungwoo Yang } 968*5fcf092eSHyungwoo Yang }, 969*5fcf092eSHyungwoo Yang { 970*5fcf092eSHyungwoo Yang .pixel_rate = 432000000, 971*5fcf092eSHyungwoo Yang .pixels_per_line = OV13858_PPL_540MHZ, 972*5fcf092eSHyungwoo Yang .reg_list = { 973*5fcf092eSHyungwoo Yang .num_of_regs = ARRAY_SIZE(mipi_data_rate_540mbps), 974*5fcf092eSHyungwoo Yang .regs = mipi_data_rate_540mbps, 975*5fcf092eSHyungwoo Yang } 976*5fcf092eSHyungwoo Yang } 977*5fcf092eSHyungwoo Yang }; 978*5fcf092eSHyungwoo Yang 979*5fcf092eSHyungwoo Yang /* Mode configs */ 980*5fcf092eSHyungwoo Yang static const struct ov13858_mode supported_modes[] = { 981*5fcf092eSHyungwoo Yang { 982*5fcf092eSHyungwoo Yang .width = 4224, 983*5fcf092eSHyungwoo Yang .height = 3136, 984*5fcf092eSHyungwoo Yang .vts = OV13858_VTS_30FPS, 985*5fcf092eSHyungwoo Yang .reg_list = { 986*5fcf092eSHyungwoo Yang .num_of_regs = ARRAY_SIZE(mode_4224x3136_regs), 987*5fcf092eSHyungwoo Yang .regs = mode_4224x3136_regs, 988*5fcf092eSHyungwoo Yang }, 989*5fcf092eSHyungwoo Yang .link_freq_index = OV13858_LINK_FREQ_INDEX_0, 990*5fcf092eSHyungwoo Yang }, 991*5fcf092eSHyungwoo Yang { 992*5fcf092eSHyungwoo Yang .width = 2112, 993*5fcf092eSHyungwoo Yang .height = 1568, 994*5fcf092eSHyungwoo Yang .vts = OV13858_VTS_30FPS, 995*5fcf092eSHyungwoo Yang .reg_list = { 996*5fcf092eSHyungwoo Yang .num_of_regs = ARRAY_SIZE(mode_2112x1568_regs), 997*5fcf092eSHyungwoo Yang .regs = mode_2112x1568_regs, 998*5fcf092eSHyungwoo Yang }, 999*5fcf092eSHyungwoo Yang .link_freq_index = OV13858_LINK_FREQ_INDEX_1, 1000*5fcf092eSHyungwoo Yang }, 1001*5fcf092eSHyungwoo Yang { 1002*5fcf092eSHyungwoo Yang .width = 2112, 1003*5fcf092eSHyungwoo Yang .height = 1188, 1004*5fcf092eSHyungwoo Yang .vts = OV13858_VTS_30FPS, 1005*5fcf092eSHyungwoo Yang .reg_list = { 1006*5fcf092eSHyungwoo Yang .num_of_regs = ARRAY_SIZE(mode_2112x1188_regs), 1007*5fcf092eSHyungwoo Yang .regs = mode_2112x1188_regs, 1008*5fcf092eSHyungwoo Yang }, 1009*5fcf092eSHyungwoo Yang .link_freq_index = OV13858_LINK_FREQ_INDEX_1, 1010*5fcf092eSHyungwoo Yang }, 1011*5fcf092eSHyungwoo Yang { 1012*5fcf092eSHyungwoo Yang .width = 1056, 1013*5fcf092eSHyungwoo Yang .height = 784, 1014*5fcf092eSHyungwoo Yang .vts = OV13858_VTS_30FPS, 1015*5fcf092eSHyungwoo Yang .reg_list = { 1016*5fcf092eSHyungwoo Yang .num_of_regs = ARRAY_SIZE(mode_1056x784_regs), 1017*5fcf092eSHyungwoo Yang .regs = mode_1056x784_regs, 1018*5fcf092eSHyungwoo Yang }, 1019*5fcf092eSHyungwoo Yang .link_freq_index = OV13858_LINK_FREQ_INDEX_1, 1020*5fcf092eSHyungwoo Yang } 1021*5fcf092eSHyungwoo Yang }; 1022*5fcf092eSHyungwoo Yang 1023*5fcf092eSHyungwoo Yang struct ov13858 { 1024*5fcf092eSHyungwoo Yang struct v4l2_subdev sd; 1025*5fcf092eSHyungwoo Yang struct media_pad pad; 1026*5fcf092eSHyungwoo Yang 1027*5fcf092eSHyungwoo Yang struct v4l2_ctrl_handler ctrl_handler; 1028*5fcf092eSHyungwoo Yang /* V4L2 Controls */ 1029*5fcf092eSHyungwoo Yang struct v4l2_ctrl *link_freq; 1030*5fcf092eSHyungwoo Yang struct v4l2_ctrl *pixel_rate; 1031*5fcf092eSHyungwoo Yang struct v4l2_ctrl *vblank; 1032*5fcf092eSHyungwoo Yang struct v4l2_ctrl *hblank; 1033*5fcf092eSHyungwoo Yang struct v4l2_ctrl *exposure; 1034*5fcf092eSHyungwoo Yang 1035*5fcf092eSHyungwoo Yang /* Current mode */ 1036*5fcf092eSHyungwoo Yang const struct ov13858_mode *cur_mode; 1037*5fcf092eSHyungwoo Yang 1038*5fcf092eSHyungwoo Yang /* Mutex for serialized access */ 1039*5fcf092eSHyungwoo Yang struct mutex mutex; 1040*5fcf092eSHyungwoo Yang 1041*5fcf092eSHyungwoo Yang /* Streaming on/off */ 1042*5fcf092eSHyungwoo Yang bool streaming; 1043*5fcf092eSHyungwoo Yang }; 1044*5fcf092eSHyungwoo Yang 1045*5fcf092eSHyungwoo Yang #define to_ov13858(_sd) container_of(_sd, struct ov13858, sd) 1046*5fcf092eSHyungwoo Yang 1047*5fcf092eSHyungwoo Yang /* Read registers up to 4 at a time */ 1048*5fcf092eSHyungwoo Yang static int ov13858_read_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 *val) 1049*5fcf092eSHyungwoo Yang { 1050*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); 1051*5fcf092eSHyungwoo Yang struct i2c_msg msgs[2]; 1052*5fcf092eSHyungwoo Yang u8 *data_be_p; 1053*5fcf092eSHyungwoo Yang int ret; 1054*5fcf092eSHyungwoo Yang u32 data_be = 0; 1055*5fcf092eSHyungwoo Yang u16 reg_addr_be = cpu_to_be16(reg); 1056*5fcf092eSHyungwoo Yang 1057*5fcf092eSHyungwoo Yang if (len > 4) 1058*5fcf092eSHyungwoo Yang return -EINVAL; 1059*5fcf092eSHyungwoo Yang 1060*5fcf092eSHyungwoo Yang data_be_p = (u8 *)&data_be; 1061*5fcf092eSHyungwoo Yang /* Write register address */ 1062*5fcf092eSHyungwoo Yang msgs[0].addr = client->addr; 1063*5fcf092eSHyungwoo Yang msgs[0].flags = 0; 1064*5fcf092eSHyungwoo Yang msgs[0].len = 2; 1065*5fcf092eSHyungwoo Yang msgs[0].buf = (u8 *)®_addr_be; 1066*5fcf092eSHyungwoo Yang 1067*5fcf092eSHyungwoo Yang /* Read data from register */ 1068*5fcf092eSHyungwoo Yang msgs[1].addr = client->addr; 1069*5fcf092eSHyungwoo Yang msgs[1].flags = I2C_M_RD; 1070*5fcf092eSHyungwoo Yang msgs[1].len = len; 1071*5fcf092eSHyungwoo Yang msgs[1].buf = &data_be_p[4 - len]; 1072*5fcf092eSHyungwoo Yang 1073*5fcf092eSHyungwoo Yang ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 1074*5fcf092eSHyungwoo Yang if (ret != ARRAY_SIZE(msgs)) 1075*5fcf092eSHyungwoo Yang return -EIO; 1076*5fcf092eSHyungwoo Yang 1077*5fcf092eSHyungwoo Yang *val = be32_to_cpu(data_be); 1078*5fcf092eSHyungwoo Yang 1079*5fcf092eSHyungwoo Yang return 0; 1080*5fcf092eSHyungwoo Yang } 1081*5fcf092eSHyungwoo Yang 1082*5fcf092eSHyungwoo Yang /* Write registers up to 4 at a time */ 1083*5fcf092eSHyungwoo Yang static int ov13858_write_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 val) 1084*5fcf092eSHyungwoo Yang { 1085*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); 1086*5fcf092eSHyungwoo Yang int buf_i, val_i; 1087*5fcf092eSHyungwoo Yang u8 buf[6], *val_p; 1088*5fcf092eSHyungwoo Yang 1089*5fcf092eSHyungwoo Yang if (len > 4) 1090*5fcf092eSHyungwoo Yang return -EINVAL; 1091*5fcf092eSHyungwoo Yang 1092*5fcf092eSHyungwoo Yang buf[0] = reg >> 8; 1093*5fcf092eSHyungwoo Yang buf[1] = reg & 0xff; 1094*5fcf092eSHyungwoo Yang 1095*5fcf092eSHyungwoo Yang val = cpu_to_be32(val); 1096*5fcf092eSHyungwoo Yang val_p = (u8 *)&val; 1097*5fcf092eSHyungwoo Yang buf_i = 2; 1098*5fcf092eSHyungwoo Yang val_i = 4 - len; 1099*5fcf092eSHyungwoo Yang 1100*5fcf092eSHyungwoo Yang while (val_i < 4) 1101*5fcf092eSHyungwoo Yang buf[buf_i++] = val_p[val_i++]; 1102*5fcf092eSHyungwoo Yang 1103*5fcf092eSHyungwoo Yang if (i2c_master_send(client, buf, len + 2) != len + 2) 1104*5fcf092eSHyungwoo Yang return -EIO; 1105*5fcf092eSHyungwoo Yang 1106*5fcf092eSHyungwoo Yang return 0; 1107*5fcf092eSHyungwoo Yang } 1108*5fcf092eSHyungwoo Yang 1109*5fcf092eSHyungwoo Yang /* Write a list of registers */ 1110*5fcf092eSHyungwoo Yang static int ov13858_write_regs(struct ov13858 *ov13858, 1111*5fcf092eSHyungwoo Yang const struct ov13858_reg *regs, u32 len) 1112*5fcf092eSHyungwoo Yang { 1113*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); 1114*5fcf092eSHyungwoo Yang int ret; 1115*5fcf092eSHyungwoo Yang u32 i; 1116*5fcf092eSHyungwoo Yang 1117*5fcf092eSHyungwoo Yang for (i = 0; i < len; i++) { 1118*5fcf092eSHyungwoo Yang ret = ov13858_write_reg(ov13858, regs[i].address, 1, 1119*5fcf092eSHyungwoo Yang regs[i].val); 1120*5fcf092eSHyungwoo Yang if (ret) { 1121*5fcf092eSHyungwoo Yang dev_err_ratelimited( 1122*5fcf092eSHyungwoo Yang &client->dev, 1123*5fcf092eSHyungwoo Yang "Failed to write reg 0x%4.4x. error = %d\n", 1124*5fcf092eSHyungwoo Yang regs[i].address, ret); 1125*5fcf092eSHyungwoo Yang 1126*5fcf092eSHyungwoo Yang return ret; 1127*5fcf092eSHyungwoo Yang } 1128*5fcf092eSHyungwoo Yang } 1129*5fcf092eSHyungwoo Yang 1130*5fcf092eSHyungwoo Yang return 0; 1131*5fcf092eSHyungwoo Yang } 1132*5fcf092eSHyungwoo Yang 1133*5fcf092eSHyungwoo Yang static int ov13858_write_reg_list(struct ov13858 *ov13858, 1134*5fcf092eSHyungwoo Yang const struct ov13858_reg_list *r_list) 1135*5fcf092eSHyungwoo Yang { 1136*5fcf092eSHyungwoo Yang return ov13858_write_regs(ov13858, r_list->regs, r_list->num_of_regs); 1137*5fcf092eSHyungwoo Yang } 1138*5fcf092eSHyungwoo Yang 1139*5fcf092eSHyungwoo Yang /* Open sub-device */ 1140*5fcf092eSHyungwoo Yang static int ov13858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 1141*5fcf092eSHyungwoo Yang { 1142*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = to_ov13858(sd); 1143*5fcf092eSHyungwoo Yang struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd, 1144*5fcf092eSHyungwoo Yang fh->pad, 1145*5fcf092eSHyungwoo Yang 0); 1146*5fcf092eSHyungwoo Yang 1147*5fcf092eSHyungwoo Yang mutex_lock(&ov13858->mutex); 1148*5fcf092eSHyungwoo Yang 1149*5fcf092eSHyungwoo Yang /* Initialize try_fmt */ 1150*5fcf092eSHyungwoo Yang try_fmt->width = ov13858->cur_mode->width; 1151*5fcf092eSHyungwoo Yang try_fmt->height = ov13858->cur_mode->height; 1152*5fcf092eSHyungwoo Yang try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; 1153*5fcf092eSHyungwoo Yang try_fmt->field = V4L2_FIELD_NONE; 1154*5fcf092eSHyungwoo Yang 1155*5fcf092eSHyungwoo Yang /* No crop or compose */ 1156*5fcf092eSHyungwoo Yang mutex_unlock(&ov13858->mutex); 1157*5fcf092eSHyungwoo Yang 1158*5fcf092eSHyungwoo Yang return 0; 1159*5fcf092eSHyungwoo Yang } 1160*5fcf092eSHyungwoo Yang 1161*5fcf092eSHyungwoo Yang static int ov13858_update_digital_gain(struct ov13858 *ov13858, u32 d_gain) 1162*5fcf092eSHyungwoo Yang { 1163*5fcf092eSHyungwoo Yang int ret; 1164*5fcf092eSHyungwoo Yang u32 val; 1165*5fcf092eSHyungwoo Yang 1166*5fcf092eSHyungwoo Yang if (d_gain == 3) 1167*5fcf092eSHyungwoo Yang return -EINVAL; 1168*5fcf092eSHyungwoo Yang 1169*5fcf092eSHyungwoo Yang ret = ov13858_read_reg(ov13858, OV13858_REG_DIGITAL_GAIN, 1170*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_08BIT, &val); 1171*5fcf092eSHyungwoo Yang if (ret) 1172*5fcf092eSHyungwoo Yang return ret; 1173*5fcf092eSHyungwoo Yang 1174*5fcf092eSHyungwoo Yang val &= OV13858_DGTL_GAIN_MASK; 1175*5fcf092eSHyungwoo Yang val |= (d_gain - 1) << OV13858_DGTL_GAIN_SHIFT; 1176*5fcf092eSHyungwoo Yang 1177*5fcf092eSHyungwoo Yang return ov13858_write_reg(ov13858, OV13858_REG_DIGITAL_GAIN, 1178*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_08BIT, val); 1179*5fcf092eSHyungwoo Yang } 1180*5fcf092eSHyungwoo Yang 1181*5fcf092eSHyungwoo Yang static int ov13858_enable_test_pattern(struct ov13858 *ov13858, u32 pattern) 1182*5fcf092eSHyungwoo Yang { 1183*5fcf092eSHyungwoo Yang int ret; 1184*5fcf092eSHyungwoo Yang u32 val; 1185*5fcf092eSHyungwoo Yang 1186*5fcf092eSHyungwoo Yang ret = ov13858_read_reg(ov13858, OV13858_REG_TEST_PATTERN, 1187*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_08BIT, &val); 1188*5fcf092eSHyungwoo Yang if (ret) 1189*5fcf092eSHyungwoo Yang return ret; 1190*5fcf092eSHyungwoo Yang 1191*5fcf092eSHyungwoo Yang if (pattern) { 1192*5fcf092eSHyungwoo Yang val &= OV13858_TEST_PATTERN_MASK; 1193*5fcf092eSHyungwoo Yang val |= (pattern - 1) | OV13858_TEST_PATTERN_ENABLE; 1194*5fcf092eSHyungwoo Yang } else { 1195*5fcf092eSHyungwoo Yang val &= ~OV13858_TEST_PATTERN_ENABLE; 1196*5fcf092eSHyungwoo Yang } 1197*5fcf092eSHyungwoo Yang 1198*5fcf092eSHyungwoo Yang return ov13858_write_reg(ov13858, OV13858_REG_TEST_PATTERN, 1199*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_08BIT, val); 1200*5fcf092eSHyungwoo Yang } 1201*5fcf092eSHyungwoo Yang 1202*5fcf092eSHyungwoo Yang static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl) 1203*5fcf092eSHyungwoo Yang { 1204*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = container_of(ctrl->handler, 1205*5fcf092eSHyungwoo Yang struct ov13858, ctrl_handler); 1206*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); 1207*5fcf092eSHyungwoo Yang s64 max; 1208*5fcf092eSHyungwoo Yang int ret; 1209*5fcf092eSHyungwoo Yang 1210*5fcf092eSHyungwoo Yang /* Propagate change of current control to all related controls */ 1211*5fcf092eSHyungwoo Yang switch (ctrl->id) { 1212*5fcf092eSHyungwoo Yang case V4L2_CID_VBLANK: 1213*5fcf092eSHyungwoo Yang /* Update max exposure while meeting expected vblanking */ 1214*5fcf092eSHyungwoo Yang max = ov13858->cur_mode->height + ctrl->val - 8; 1215*5fcf092eSHyungwoo Yang __v4l2_ctrl_modify_range(ov13858->exposure, 1216*5fcf092eSHyungwoo Yang ov13858->exposure->minimum, 1217*5fcf092eSHyungwoo Yang max, ov13858->exposure->step, max); 1218*5fcf092eSHyungwoo Yang break; 1219*5fcf092eSHyungwoo Yang }; 1220*5fcf092eSHyungwoo Yang 1221*5fcf092eSHyungwoo Yang /* 1222*5fcf092eSHyungwoo Yang * Applying V4L2 control value only happens 1223*5fcf092eSHyungwoo Yang * when power is up for streaming 1224*5fcf092eSHyungwoo Yang */ 1225*5fcf092eSHyungwoo Yang if (pm_runtime_get_if_in_use(&client->dev) <= 0) 1226*5fcf092eSHyungwoo Yang return 0; 1227*5fcf092eSHyungwoo Yang 1228*5fcf092eSHyungwoo Yang ret = 0; 1229*5fcf092eSHyungwoo Yang switch (ctrl->id) { 1230*5fcf092eSHyungwoo Yang case V4L2_CID_ANALOGUE_GAIN: 1231*5fcf092eSHyungwoo Yang ret = ov13858_write_reg(ov13858, OV13858_REG_ANALOG_GAIN, 1232*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_16BIT, ctrl->val); 1233*5fcf092eSHyungwoo Yang break; 1234*5fcf092eSHyungwoo Yang case V4L2_CID_DIGITAL_GAIN: 1235*5fcf092eSHyungwoo Yang ret = ov13858_update_digital_gain(ov13858, ctrl->val); 1236*5fcf092eSHyungwoo Yang break; 1237*5fcf092eSHyungwoo Yang case V4L2_CID_EXPOSURE: 1238*5fcf092eSHyungwoo Yang ret = ov13858_write_reg(ov13858, OV13858_REG_EXPOSURE, 1239*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_24BIT, 1240*5fcf092eSHyungwoo Yang ctrl->val << 4); 1241*5fcf092eSHyungwoo Yang break; 1242*5fcf092eSHyungwoo Yang case V4L2_CID_VBLANK: 1243*5fcf092eSHyungwoo Yang /* Update VTS that meets expected vertical blanking */ 1244*5fcf092eSHyungwoo Yang ret = ov13858_write_reg(ov13858, OV13858_REG_VTS, 1245*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_16BIT, 1246*5fcf092eSHyungwoo Yang ov13858->cur_mode->height 1247*5fcf092eSHyungwoo Yang + ctrl->val); 1248*5fcf092eSHyungwoo Yang break; 1249*5fcf092eSHyungwoo Yang case V4L2_CID_TEST_PATTERN: 1250*5fcf092eSHyungwoo Yang ret = ov13858_enable_test_pattern(ov13858, ctrl->val); 1251*5fcf092eSHyungwoo Yang break; 1252*5fcf092eSHyungwoo Yang default: 1253*5fcf092eSHyungwoo Yang dev_info(&client->dev, 1254*5fcf092eSHyungwoo Yang "ctrl(id:0x%x,val:0x%x) is not handled\n", 1255*5fcf092eSHyungwoo Yang ctrl->id, ctrl->val); 1256*5fcf092eSHyungwoo Yang break; 1257*5fcf092eSHyungwoo Yang }; 1258*5fcf092eSHyungwoo Yang 1259*5fcf092eSHyungwoo Yang pm_runtime_put(&client->dev); 1260*5fcf092eSHyungwoo Yang 1261*5fcf092eSHyungwoo Yang return ret; 1262*5fcf092eSHyungwoo Yang } 1263*5fcf092eSHyungwoo Yang 1264*5fcf092eSHyungwoo Yang static const struct v4l2_ctrl_ops ov13858_ctrl_ops = { 1265*5fcf092eSHyungwoo Yang .s_ctrl = ov13858_set_ctrl, 1266*5fcf092eSHyungwoo Yang }; 1267*5fcf092eSHyungwoo Yang 1268*5fcf092eSHyungwoo Yang static int ov13858_enum_mbus_code(struct v4l2_subdev *sd, 1269*5fcf092eSHyungwoo Yang struct v4l2_subdev_pad_config *cfg, 1270*5fcf092eSHyungwoo Yang struct v4l2_subdev_mbus_code_enum *code) 1271*5fcf092eSHyungwoo Yang { 1272*5fcf092eSHyungwoo Yang /* Only one bayer order(GRBG) is supported */ 1273*5fcf092eSHyungwoo Yang if (code->index > 0) 1274*5fcf092eSHyungwoo Yang return -EINVAL; 1275*5fcf092eSHyungwoo Yang 1276*5fcf092eSHyungwoo Yang code->code = MEDIA_BUS_FMT_SGRBG10_1X10; 1277*5fcf092eSHyungwoo Yang 1278*5fcf092eSHyungwoo Yang return 0; 1279*5fcf092eSHyungwoo Yang } 1280*5fcf092eSHyungwoo Yang 1281*5fcf092eSHyungwoo Yang static int ov13858_enum_frame_size(struct v4l2_subdev *sd, 1282*5fcf092eSHyungwoo Yang struct v4l2_subdev_pad_config *cfg, 1283*5fcf092eSHyungwoo Yang struct v4l2_subdev_frame_size_enum *fse) 1284*5fcf092eSHyungwoo Yang { 1285*5fcf092eSHyungwoo Yang if (fse->index >= ARRAY_SIZE(supported_modes)) 1286*5fcf092eSHyungwoo Yang return -EINVAL; 1287*5fcf092eSHyungwoo Yang 1288*5fcf092eSHyungwoo Yang if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) 1289*5fcf092eSHyungwoo Yang return -EINVAL; 1290*5fcf092eSHyungwoo Yang 1291*5fcf092eSHyungwoo Yang fse->min_width = supported_modes[fse->index].width; 1292*5fcf092eSHyungwoo Yang fse->max_width = fse->min_width; 1293*5fcf092eSHyungwoo Yang fse->min_height = supported_modes[fse->index].height; 1294*5fcf092eSHyungwoo Yang fse->max_height = fse->min_height; 1295*5fcf092eSHyungwoo Yang 1296*5fcf092eSHyungwoo Yang return 0; 1297*5fcf092eSHyungwoo Yang } 1298*5fcf092eSHyungwoo Yang 1299*5fcf092eSHyungwoo Yang static void ov13858_update_pad_format(const struct ov13858_mode *mode, 1300*5fcf092eSHyungwoo Yang struct v4l2_subdev_format *fmt) 1301*5fcf092eSHyungwoo Yang { 1302*5fcf092eSHyungwoo Yang fmt->format.width = mode->width; 1303*5fcf092eSHyungwoo Yang fmt->format.height = mode->height; 1304*5fcf092eSHyungwoo Yang fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 1305*5fcf092eSHyungwoo Yang fmt->format.field = V4L2_FIELD_NONE; 1306*5fcf092eSHyungwoo Yang } 1307*5fcf092eSHyungwoo Yang 1308*5fcf092eSHyungwoo Yang static int ov13858_do_get_pad_format(struct ov13858 *ov13858, 1309*5fcf092eSHyungwoo Yang struct v4l2_subdev_pad_config *cfg, 1310*5fcf092eSHyungwoo Yang struct v4l2_subdev_format *fmt) 1311*5fcf092eSHyungwoo Yang { 1312*5fcf092eSHyungwoo Yang struct v4l2_mbus_framefmt *framefmt; 1313*5fcf092eSHyungwoo Yang struct v4l2_subdev *sd = &ov13858->sd; 1314*5fcf092eSHyungwoo Yang 1315*5fcf092eSHyungwoo Yang if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1316*5fcf092eSHyungwoo Yang framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); 1317*5fcf092eSHyungwoo Yang fmt->format = *framefmt; 1318*5fcf092eSHyungwoo Yang } else { 1319*5fcf092eSHyungwoo Yang ov13858_update_pad_format(ov13858->cur_mode, fmt); 1320*5fcf092eSHyungwoo Yang } 1321*5fcf092eSHyungwoo Yang 1322*5fcf092eSHyungwoo Yang return 0; 1323*5fcf092eSHyungwoo Yang } 1324*5fcf092eSHyungwoo Yang 1325*5fcf092eSHyungwoo Yang static int ov13858_get_pad_format(struct v4l2_subdev *sd, 1326*5fcf092eSHyungwoo Yang struct v4l2_subdev_pad_config *cfg, 1327*5fcf092eSHyungwoo Yang struct v4l2_subdev_format *fmt) 1328*5fcf092eSHyungwoo Yang { 1329*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = to_ov13858(sd); 1330*5fcf092eSHyungwoo Yang int ret; 1331*5fcf092eSHyungwoo Yang 1332*5fcf092eSHyungwoo Yang mutex_lock(&ov13858->mutex); 1333*5fcf092eSHyungwoo Yang ret = ov13858_do_get_pad_format(ov13858, cfg, fmt); 1334*5fcf092eSHyungwoo Yang mutex_unlock(&ov13858->mutex); 1335*5fcf092eSHyungwoo Yang 1336*5fcf092eSHyungwoo Yang return ret; 1337*5fcf092eSHyungwoo Yang } 1338*5fcf092eSHyungwoo Yang 1339*5fcf092eSHyungwoo Yang /* 1340*5fcf092eSHyungwoo Yang * Calculate resolution distance 1341*5fcf092eSHyungwoo Yang */ 1342*5fcf092eSHyungwoo Yang static int 1343*5fcf092eSHyungwoo Yang ov13858_get_resolution_dist(const struct ov13858_mode *mode, 1344*5fcf092eSHyungwoo Yang struct v4l2_mbus_framefmt *framefmt) 1345*5fcf092eSHyungwoo Yang { 1346*5fcf092eSHyungwoo Yang return abs(mode->width - framefmt->width) + 1347*5fcf092eSHyungwoo Yang abs(mode->height - framefmt->height); 1348*5fcf092eSHyungwoo Yang } 1349*5fcf092eSHyungwoo Yang 1350*5fcf092eSHyungwoo Yang /* 1351*5fcf092eSHyungwoo Yang * Find the closest supported resolution to the requested resolution 1352*5fcf092eSHyungwoo Yang */ 1353*5fcf092eSHyungwoo Yang static const struct ov13858_mode * 1354*5fcf092eSHyungwoo Yang ov13858_find_best_fit(struct ov13858 *ov13858, 1355*5fcf092eSHyungwoo Yang struct v4l2_subdev_format *fmt) 1356*5fcf092eSHyungwoo Yang { 1357*5fcf092eSHyungwoo Yang int i, dist, cur_best_fit = 0, cur_best_fit_dist = -1; 1358*5fcf092eSHyungwoo Yang struct v4l2_mbus_framefmt *framefmt = &fmt->format; 1359*5fcf092eSHyungwoo Yang 1360*5fcf092eSHyungwoo Yang for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { 1361*5fcf092eSHyungwoo Yang dist = ov13858_get_resolution_dist(&supported_modes[i], 1362*5fcf092eSHyungwoo Yang framefmt); 1363*5fcf092eSHyungwoo Yang if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { 1364*5fcf092eSHyungwoo Yang cur_best_fit_dist = dist; 1365*5fcf092eSHyungwoo Yang cur_best_fit = i; 1366*5fcf092eSHyungwoo Yang } 1367*5fcf092eSHyungwoo Yang } 1368*5fcf092eSHyungwoo Yang 1369*5fcf092eSHyungwoo Yang return &supported_modes[cur_best_fit]; 1370*5fcf092eSHyungwoo Yang } 1371*5fcf092eSHyungwoo Yang 1372*5fcf092eSHyungwoo Yang static int 1373*5fcf092eSHyungwoo Yang ov13858_set_pad_format(struct v4l2_subdev *sd, 1374*5fcf092eSHyungwoo Yang struct v4l2_subdev_pad_config *cfg, 1375*5fcf092eSHyungwoo Yang struct v4l2_subdev_format *fmt) 1376*5fcf092eSHyungwoo Yang { 1377*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = to_ov13858(sd); 1378*5fcf092eSHyungwoo Yang const struct ov13858_mode *mode; 1379*5fcf092eSHyungwoo Yang struct v4l2_mbus_framefmt *framefmt; 1380*5fcf092eSHyungwoo Yang s64 h_blank; 1381*5fcf092eSHyungwoo Yang 1382*5fcf092eSHyungwoo Yang mutex_lock(&ov13858->mutex); 1383*5fcf092eSHyungwoo Yang 1384*5fcf092eSHyungwoo Yang /* Only one raw bayer(GRBG) order is supported */ 1385*5fcf092eSHyungwoo Yang if (fmt->format.code != MEDIA_BUS_FMT_SGRBG10_1X10) 1386*5fcf092eSHyungwoo Yang fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 1387*5fcf092eSHyungwoo Yang 1388*5fcf092eSHyungwoo Yang mode = ov13858_find_best_fit(ov13858, fmt); 1389*5fcf092eSHyungwoo Yang ov13858_update_pad_format(mode, fmt); 1390*5fcf092eSHyungwoo Yang if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1391*5fcf092eSHyungwoo Yang framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); 1392*5fcf092eSHyungwoo Yang *framefmt = fmt->format; 1393*5fcf092eSHyungwoo Yang } else { 1394*5fcf092eSHyungwoo Yang ov13858->cur_mode = mode; 1395*5fcf092eSHyungwoo Yang __v4l2_ctrl_s_ctrl(ov13858->link_freq, mode->link_freq_index); 1396*5fcf092eSHyungwoo Yang __v4l2_ctrl_s_ctrl_int64( 1397*5fcf092eSHyungwoo Yang ov13858->pixel_rate, 1398*5fcf092eSHyungwoo Yang link_freq_configs[mode->link_freq_index].pixel_rate); 1399*5fcf092eSHyungwoo Yang /* Update limits and set FPS to default */ 1400*5fcf092eSHyungwoo Yang __v4l2_ctrl_modify_range( 1401*5fcf092eSHyungwoo Yang ov13858->vblank, OV13858_VBLANK_MIN, 1402*5fcf092eSHyungwoo Yang OV13858_VTS_MAX - ov13858->cur_mode->height, 1, 1403*5fcf092eSHyungwoo Yang ov13858->cur_mode->vts - ov13858->cur_mode->height); 1404*5fcf092eSHyungwoo Yang h_blank = 1405*5fcf092eSHyungwoo Yang link_freq_configs[mode->link_freq_index].pixels_per_line 1406*5fcf092eSHyungwoo Yang - ov13858->cur_mode->width; 1407*5fcf092eSHyungwoo Yang __v4l2_ctrl_modify_range(ov13858->hblank, h_blank, 1408*5fcf092eSHyungwoo Yang h_blank, 1, h_blank); 1409*5fcf092eSHyungwoo Yang } 1410*5fcf092eSHyungwoo Yang 1411*5fcf092eSHyungwoo Yang mutex_unlock(&ov13858->mutex); 1412*5fcf092eSHyungwoo Yang 1413*5fcf092eSHyungwoo Yang return 0; 1414*5fcf092eSHyungwoo Yang } 1415*5fcf092eSHyungwoo Yang 1416*5fcf092eSHyungwoo Yang static int ov13858_get_skip_frames(struct v4l2_subdev *sd, u32 *frames) 1417*5fcf092eSHyungwoo Yang { 1418*5fcf092eSHyungwoo Yang *frames = OV13858_NUM_OF_SKIP_FRAMES; 1419*5fcf092eSHyungwoo Yang 1420*5fcf092eSHyungwoo Yang return 0; 1421*5fcf092eSHyungwoo Yang } 1422*5fcf092eSHyungwoo Yang 1423*5fcf092eSHyungwoo Yang /* Start streaming */ 1424*5fcf092eSHyungwoo Yang static int ov13858_start_streaming(struct ov13858 *ov13858) 1425*5fcf092eSHyungwoo Yang { 1426*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); 1427*5fcf092eSHyungwoo Yang const struct ov13858_reg_list *reg_list; 1428*5fcf092eSHyungwoo Yang int ret, link_freq_index; 1429*5fcf092eSHyungwoo Yang 1430*5fcf092eSHyungwoo Yang /* Get out of from software reset */ 1431*5fcf092eSHyungwoo Yang ret = ov13858_write_reg(ov13858, OV13858_REG_SOFTWARE_RST, 1432*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_08BIT, OV13858_SOFTWARE_RST); 1433*5fcf092eSHyungwoo Yang if (ret) { 1434*5fcf092eSHyungwoo Yang dev_err(&client->dev, "%s failed to set powerup registers\n", 1435*5fcf092eSHyungwoo Yang __func__); 1436*5fcf092eSHyungwoo Yang return ret; 1437*5fcf092eSHyungwoo Yang } 1438*5fcf092eSHyungwoo Yang 1439*5fcf092eSHyungwoo Yang /* Setup PLL */ 1440*5fcf092eSHyungwoo Yang link_freq_index = ov13858->cur_mode->link_freq_index; 1441*5fcf092eSHyungwoo Yang reg_list = &link_freq_configs[link_freq_index].reg_list; 1442*5fcf092eSHyungwoo Yang ret = ov13858_write_reg_list(ov13858, reg_list); 1443*5fcf092eSHyungwoo Yang if (ret) { 1444*5fcf092eSHyungwoo Yang dev_err(&client->dev, "%s failed to set plls\n", __func__); 1445*5fcf092eSHyungwoo Yang return ret; 1446*5fcf092eSHyungwoo Yang } 1447*5fcf092eSHyungwoo Yang 1448*5fcf092eSHyungwoo Yang /* Apply default values of current mode */ 1449*5fcf092eSHyungwoo Yang reg_list = &ov13858->cur_mode->reg_list; 1450*5fcf092eSHyungwoo Yang ret = ov13858_write_reg_list(ov13858, reg_list); 1451*5fcf092eSHyungwoo Yang if (ret) { 1452*5fcf092eSHyungwoo Yang dev_err(&client->dev, "%s failed to set mode\n", __func__); 1453*5fcf092eSHyungwoo Yang return ret; 1454*5fcf092eSHyungwoo Yang } 1455*5fcf092eSHyungwoo Yang 1456*5fcf092eSHyungwoo Yang /* Apply customized values from user */ 1457*5fcf092eSHyungwoo Yang ret = __v4l2_ctrl_handler_setup(ov13858->sd.ctrl_handler); 1458*5fcf092eSHyungwoo Yang if (ret) 1459*5fcf092eSHyungwoo Yang return ret; 1460*5fcf092eSHyungwoo Yang 1461*5fcf092eSHyungwoo Yang return ov13858_write_reg(ov13858, OV13858_REG_MODE_SELECT, 1462*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_08BIT, 1463*5fcf092eSHyungwoo Yang OV13858_MODE_STREAMING); 1464*5fcf092eSHyungwoo Yang } 1465*5fcf092eSHyungwoo Yang 1466*5fcf092eSHyungwoo Yang /* Stop streaming */ 1467*5fcf092eSHyungwoo Yang static int ov13858_stop_streaming(struct ov13858 *ov13858) 1468*5fcf092eSHyungwoo Yang { 1469*5fcf092eSHyungwoo Yang return ov13858_write_reg(ov13858, OV13858_REG_MODE_SELECT, 1470*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_08BIT, OV13858_MODE_STANDBY); 1471*5fcf092eSHyungwoo Yang } 1472*5fcf092eSHyungwoo Yang 1473*5fcf092eSHyungwoo Yang static int ov13858_set_stream(struct v4l2_subdev *sd, int enable) 1474*5fcf092eSHyungwoo Yang { 1475*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = to_ov13858(sd); 1476*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(sd); 1477*5fcf092eSHyungwoo Yang int ret = 0; 1478*5fcf092eSHyungwoo Yang 1479*5fcf092eSHyungwoo Yang mutex_lock(&ov13858->mutex); 1480*5fcf092eSHyungwoo Yang if (ov13858->streaming == enable) { 1481*5fcf092eSHyungwoo Yang mutex_unlock(&ov13858->mutex); 1482*5fcf092eSHyungwoo Yang return 0; 1483*5fcf092eSHyungwoo Yang } 1484*5fcf092eSHyungwoo Yang 1485*5fcf092eSHyungwoo Yang if (enable) { 1486*5fcf092eSHyungwoo Yang ret = pm_runtime_get_sync(&client->dev); 1487*5fcf092eSHyungwoo Yang if (ret < 0) { 1488*5fcf092eSHyungwoo Yang pm_runtime_put_noidle(&client->dev); 1489*5fcf092eSHyungwoo Yang goto err_unlock; 1490*5fcf092eSHyungwoo Yang } 1491*5fcf092eSHyungwoo Yang 1492*5fcf092eSHyungwoo Yang /* 1493*5fcf092eSHyungwoo Yang * Apply default & customized values 1494*5fcf092eSHyungwoo Yang * and then start streaming. 1495*5fcf092eSHyungwoo Yang */ 1496*5fcf092eSHyungwoo Yang ret = ov13858_start_streaming(ov13858); 1497*5fcf092eSHyungwoo Yang if (ret) 1498*5fcf092eSHyungwoo Yang goto err_rpm_put; 1499*5fcf092eSHyungwoo Yang } else { 1500*5fcf092eSHyungwoo Yang ov13858_stop_streaming(ov13858); 1501*5fcf092eSHyungwoo Yang pm_runtime_put(&client->dev); 1502*5fcf092eSHyungwoo Yang } 1503*5fcf092eSHyungwoo Yang 1504*5fcf092eSHyungwoo Yang ov13858->streaming = enable; 1505*5fcf092eSHyungwoo Yang mutex_unlock(&ov13858->mutex); 1506*5fcf092eSHyungwoo Yang 1507*5fcf092eSHyungwoo Yang return ret; 1508*5fcf092eSHyungwoo Yang 1509*5fcf092eSHyungwoo Yang err_rpm_put: 1510*5fcf092eSHyungwoo Yang pm_runtime_put(&client->dev); 1511*5fcf092eSHyungwoo Yang err_unlock: 1512*5fcf092eSHyungwoo Yang mutex_unlock(&ov13858->mutex); 1513*5fcf092eSHyungwoo Yang 1514*5fcf092eSHyungwoo Yang return ret; 1515*5fcf092eSHyungwoo Yang } 1516*5fcf092eSHyungwoo Yang 1517*5fcf092eSHyungwoo Yang static int __maybe_unused ov13858_suspend(struct device *dev) 1518*5fcf092eSHyungwoo Yang { 1519*5fcf092eSHyungwoo Yang struct i2c_client *client = to_i2c_client(dev); 1520*5fcf092eSHyungwoo Yang struct v4l2_subdev *sd = i2c_get_clientdata(client); 1521*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = to_ov13858(sd); 1522*5fcf092eSHyungwoo Yang 1523*5fcf092eSHyungwoo Yang if (ov13858->streaming) 1524*5fcf092eSHyungwoo Yang ov13858_stop_streaming(ov13858); 1525*5fcf092eSHyungwoo Yang 1526*5fcf092eSHyungwoo Yang return 0; 1527*5fcf092eSHyungwoo Yang } 1528*5fcf092eSHyungwoo Yang 1529*5fcf092eSHyungwoo Yang static int __maybe_unused ov13858_resume(struct device *dev) 1530*5fcf092eSHyungwoo Yang { 1531*5fcf092eSHyungwoo Yang struct i2c_client *client = to_i2c_client(dev); 1532*5fcf092eSHyungwoo Yang struct v4l2_subdev *sd = i2c_get_clientdata(client); 1533*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = to_ov13858(sd); 1534*5fcf092eSHyungwoo Yang int ret; 1535*5fcf092eSHyungwoo Yang 1536*5fcf092eSHyungwoo Yang if (ov13858->streaming) { 1537*5fcf092eSHyungwoo Yang ret = ov13858_start_streaming(ov13858); 1538*5fcf092eSHyungwoo Yang if (ret) 1539*5fcf092eSHyungwoo Yang goto error; 1540*5fcf092eSHyungwoo Yang } 1541*5fcf092eSHyungwoo Yang 1542*5fcf092eSHyungwoo Yang return 0; 1543*5fcf092eSHyungwoo Yang 1544*5fcf092eSHyungwoo Yang error: 1545*5fcf092eSHyungwoo Yang ov13858_stop_streaming(ov13858); 1546*5fcf092eSHyungwoo Yang ov13858->streaming = 0; 1547*5fcf092eSHyungwoo Yang return ret; 1548*5fcf092eSHyungwoo Yang } 1549*5fcf092eSHyungwoo Yang 1550*5fcf092eSHyungwoo Yang /* Verify chip ID */ 1551*5fcf092eSHyungwoo Yang static int ov13858_identify_module(struct ov13858 *ov13858) 1552*5fcf092eSHyungwoo Yang { 1553*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); 1554*5fcf092eSHyungwoo Yang int ret; 1555*5fcf092eSHyungwoo Yang u32 val; 1556*5fcf092eSHyungwoo Yang 1557*5fcf092eSHyungwoo Yang ret = ov13858_read_reg(ov13858, OV13858_REG_CHIP_ID, 1558*5fcf092eSHyungwoo Yang OV13858_REG_VALUE_24BIT, &val); 1559*5fcf092eSHyungwoo Yang if (ret) 1560*5fcf092eSHyungwoo Yang return ret; 1561*5fcf092eSHyungwoo Yang 1562*5fcf092eSHyungwoo Yang if (val != OV13858_CHIP_ID) { 1563*5fcf092eSHyungwoo Yang dev_err(&client->dev, "chip id mismatch: %x!=%x\n", 1564*5fcf092eSHyungwoo Yang OV13858_CHIP_ID, val); 1565*5fcf092eSHyungwoo Yang return -EIO; 1566*5fcf092eSHyungwoo Yang } 1567*5fcf092eSHyungwoo Yang 1568*5fcf092eSHyungwoo Yang return 0; 1569*5fcf092eSHyungwoo Yang } 1570*5fcf092eSHyungwoo Yang 1571*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_video_ops ov13858_video_ops = { 1572*5fcf092eSHyungwoo Yang .s_stream = ov13858_set_stream, 1573*5fcf092eSHyungwoo Yang }; 1574*5fcf092eSHyungwoo Yang 1575*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_pad_ops ov13858_pad_ops = { 1576*5fcf092eSHyungwoo Yang .enum_mbus_code = ov13858_enum_mbus_code, 1577*5fcf092eSHyungwoo Yang .get_fmt = ov13858_get_pad_format, 1578*5fcf092eSHyungwoo Yang .set_fmt = ov13858_set_pad_format, 1579*5fcf092eSHyungwoo Yang .enum_frame_size = ov13858_enum_frame_size, 1580*5fcf092eSHyungwoo Yang }; 1581*5fcf092eSHyungwoo Yang 1582*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_sensor_ops ov13858_sensor_ops = { 1583*5fcf092eSHyungwoo Yang .g_skip_frames = ov13858_get_skip_frames, 1584*5fcf092eSHyungwoo Yang }; 1585*5fcf092eSHyungwoo Yang 1586*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_ops ov13858_subdev_ops = { 1587*5fcf092eSHyungwoo Yang .video = &ov13858_video_ops, 1588*5fcf092eSHyungwoo Yang .pad = &ov13858_pad_ops, 1589*5fcf092eSHyungwoo Yang .sensor = &ov13858_sensor_ops, 1590*5fcf092eSHyungwoo Yang }; 1591*5fcf092eSHyungwoo Yang 1592*5fcf092eSHyungwoo Yang static const struct media_entity_operations ov13858_subdev_entity_ops = { 1593*5fcf092eSHyungwoo Yang .link_validate = v4l2_subdev_link_validate, 1594*5fcf092eSHyungwoo Yang }; 1595*5fcf092eSHyungwoo Yang 1596*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_internal_ops ov13858_internal_ops = { 1597*5fcf092eSHyungwoo Yang .open = ov13858_open, 1598*5fcf092eSHyungwoo Yang }; 1599*5fcf092eSHyungwoo Yang 1600*5fcf092eSHyungwoo Yang /* Initialize control handlers */ 1601*5fcf092eSHyungwoo Yang static int ov13858_init_controls(struct ov13858 *ov13858) 1602*5fcf092eSHyungwoo Yang { 1603*5fcf092eSHyungwoo Yang struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); 1604*5fcf092eSHyungwoo Yang struct v4l2_ctrl_handler *ctrl_hdlr; 1605*5fcf092eSHyungwoo Yang int ret; 1606*5fcf092eSHyungwoo Yang 1607*5fcf092eSHyungwoo Yang ctrl_hdlr = &ov13858->ctrl_handler; 1608*5fcf092eSHyungwoo Yang ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8); 1609*5fcf092eSHyungwoo Yang if (ret) 1610*5fcf092eSHyungwoo Yang return ret; 1611*5fcf092eSHyungwoo Yang 1612*5fcf092eSHyungwoo Yang mutex_init(&ov13858->mutex); 1613*5fcf092eSHyungwoo Yang ctrl_hdlr->lock = &ov13858->mutex; 1614*5fcf092eSHyungwoo Yang ov13858->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, 1615*5fcf092eSHyungwoo Yang &ov13858_ctrl_ops, 1616*5fcf092eSHyungwoo Yang V4L2_CID_LINK_FREQ, 1617*5fcf092eSHyungwoo Yang OV13858_NUM_OF_LINK_FREQS - 1, 1618*5fcf092eSHyungwoo Yang 0, 1619*5fcf092eSHyungwoo Yang link_freq_menu_items); 1620*5fcf092eSHyungwoo Yang ov13858->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 1621*5fcf092eSHyungwoo Yang 1622*5fcf092eSHyungwoo Yang /* By default, PIXEL_RATE is read only */ 1623*5fcf092eSHyungwoo Yang ov13858->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, 1624*5fcf092eSHyungwoo Yang V4L2_CID_PIXEL_RATE, 0, 1625*5fcf092eSHyungwoo Yang link_freq_configs[0].pixel_rate, 1, 1626*5fcf092eSHyungwoo Yang link_freq_configs[0].pixel_rate); 1627*5fcf092eSHyungwoo Yang 1628*5fcf092eSHyungwoo Yang ov13858->vblank = v4l2_ctrl_new_std( 1629*5fcf092eSHyungwoo Yang ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_VBLANK, 1630*5fcf092eSHyungwoo Yang OV13858_VBLANK_MIN, 1631*5fcf092eSHyungwoo Yang OV13858_VTS_MAX - ov13858->cur_mode->height, 1, 1632*5fcf092eSHyungwoo Yang ov13858->cur_mode->vts 1633*5fcf092eSHyungwoo Yang - ov13858->cur_mode->height); 1634*5fcf092eSHyungwoo Yang 1635*5fcf092eSHyungwoo Yang ov13858->hblank = v4l2_ctrl_new_std( 1636*5fcf092eSHyungwoo Yang ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HBLANK, 1637*5fcf092eSHyungwoo Yang OV13858_PPL_1080MHZ - ov13858->cur_mode->width, 1638*5fcf092eSHyungwoo Yang OV13858_PPL_1080MHZ - ov13858->cur_mode->width, 1639*5fcf092eSHyungwoo Yang 1, 1640*5fcf092eSHyungwoo Yang OV13858_PPL_1080MHZ - ov13858->cur_mode->width); 1641*5fcf092eSHyungwoo Yang ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; 1642*5fcf092eSHyungwoo Yang 1643*5fcf092eSHyungwoo Yang ov13858->exposure = v4l2_ctrl_new_std( 1644*5fcf092eSHyungwoo Yang ctrl_hdlr, &ov13858_ctrl_ops, 1645*5fcf092eSHyungwoo Yang V4L2_CID_EXPOSURE, OV13858_EXPOSURE_MIN, 1646*5fcf092eSHyungwoo Yang OV13858_EXPOSURE_MAX, OV13858_EXPOSURE_STEP, 1647*5fcf092eSHyungwoo Yang OV13858_EXPOSURE_DEFAULT); 1648*5fcf092eSHyungwoo Yang 1649*5fcf092eSHyungwoo Yang v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 1650*5fcf092eSHyungwoo Yang OV13858_ANA_GAIN_MIN, OV13858_ANA_GAIN_MAX, 1651*5fcf092eSHyungwoo Yang OV13858_ANA_GAIN_STEP, OV13858_ANA_GAIN_DEFAULT); 1652*5fcf092eSHyungwoo Yang 1653*5fcf092eSHyungwoo Yang /* Digital gain */ 1654*5fcf092eSHyungwoo Yang v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_DIGITAL_GAIN, 1655*5fcf092eSHyungwoo Yang OV13858_DGTL_GAIN_MIN, OV13858_DGTL_GAIN_MAX, 1656*5fcf092eSHyungwoo Yang OV13858_DGTL_GAIN_STEP, OV13858_DGTL_GAIN_DEFAULT); 1657*5fcf092eSHyungwoo Yang 1658*5fcf092eSHyungwoo Yang v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov13858_ctrl_ops, 1659*5fcf092eSHyungwoo Yang V4L2_CID_TEST_PATTERN, 1660*5fcf092eSHyungwoo Yang ARRAY_SIZE(ov13858_test_pattern_menu) - 1, 1661*5fcf092eSHyungwoo Yang 0, 0, ov13858_test_pattern_menu); 1662*5fcf092eSHyungwoo Yang if (ctrl_hdlr->error) { 1663*5fcf092eSHyungwoo Yang ret = ctrl_hdlr->error; 1664*5fcf092eSHyungwoo Yang dev_err(&client->dev, "%s control init failed (%d)\n", 1665*5fcf092eSHyungwoo Yang __func__, ret); 1666*5fcf092eSHyungwoo Yang goto error; 1667*5fcf092eSHyungwoo Yang } 1668*5fcf092eSHyungwoo Yang 1669*5fcf092eSHyungwoo Yang ov13858->sd.ctrl_handler = ctrl_hdlr; 1670*5fcf092eSHyungwoo Yang 1671*5fcf092eSHyungwoo Yang return 0; 1672*5fcf092eSHyungwoo Yang 1673*5fcf092eSHyungwoo Yang error: 1674*5fcf092eSHyungwoo Yang v4l2_ctrl_handler_free(ctrl_hdlr); 1675*5fcf092eSHyungwoo Yang mutex_destroy(&ov13858->mutex); 1676*5fcf092eSHyungwoo Yang 1677*5fcf092eSHyungwoo Yang return ret; 1678*5fcf092eSHyungwoo Yang } 1679*5fcf092eSHyungwoo Yang 1680*5fcf092eSHyungwoo Yang static void ov13858_free_controls(struct ov13858 *ov13858) 1681*5fcf092eSHyungwoo Yang { 1682*5fcf092eSHyungwoo Yang v4l2_ctrl_handler_free(ov13858->sd.ctrl_handler); 1683*5fcf092eSHyungwoo Yang mutex_destroy(&ov13858->mutex); 1684*5fcf092eSHyungwoo Yang } 1685*5fcf092eSHyungwoo Yang 1686*5fcf092eSHyungwoo Yang static int ov13858_probe(struct i2c_client *client, 1687*5fcf092eSHyungwoo Yang const struct i2c_device_id *devid) 1688*5fcf092eSHyungwoo Yang { 1689*5fcf092eSHyungwoo Yang struct ov13858 *ov13858; 1690*5fcf092eSHyungwoo Yang int ret; 1691*5fcf092eSHyungwoo Yang u32 val = 0; 1692*5fcf092eSHyungwoo Yang 1693*5fcf092eSHyungwoo Yang device_property_read_u32(&client->dev, "clock-frequency", &val); 1694*5fcf092eSHyungwoo Yang if (val != 19200000) 1695*5fcf092eSHyungwoo Yang return -EINVAL; 1696*5fcf092eSHyungwoo Yang 1697*5fcf092eSHyungwoo Yang ov13858 = devm_kzalloc(&client->dev, sizeof(*ov13858), GFP_KERNEL); 1698*5fcf092eSHyungwoo Yang if (!ov13858) 1699*5fcf092eSHyungwoo Yang return -ENOMEM; 1700*5fcf092eSHyungwoo Yang 1701*5fcf092eSHyungwoo Yang /* Initialize subdev */ 1702*5fcf092eSHyungwoo Yang v4l2_i2c_subdev_init(&ov13858->sd, client, &ov13858_subdev_ops); 1703*5fcf092eSHyungwoo Yang 1704*5fcf092eSHyungwoo Yang /* Check module identity */ 1705*5fcf092eSHyungwoo Yang ret = ov13858_identify_module(ov13858); 1706*5fcf092eSHyungwoo Yang if (ret) { 1707*5fcf092eSHyungwoo Yang dev_err(&client->dev, "failed to find sensor: %d\n", ret); 1708*5fcf092eSHyungwoo Yang return ret; 1709*5fcf092eSHyungwoo Yang } 1710*5fcf092eSHyungwoo Yang 1711*5fcf092eSHyungwoo Yang /* Set default mode to max resolution */ 1712*5fcf092eSHyungwoo Yang ov13858->cur_mode = &supported_modes[0]; 1713*5fcf092eSHyungwoo Yang 1714*5fcf092eSHyungwoo Yang ret = ov13858_init_controls(ov13858); 1715*5fcf092eSHyungwoo Yang if (ret) 1716*5fcf092eSHyungwoo Yang return ret; 1717*5fcf092eSHyungwoo Yang 1718*5fcf092eSHyungwoo Yang /* Initialize subdev */ 1719*5fcf092eSHyungwoo Yang ov13858->sd.internal_ops = &ov13858_internal_ops; 1720*5fcf092eSHyungwoo Yang ov13858->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1721*5fcf092eSHyungwoo Yang ov13858->sd.entity.ops = &ov13858_subdev_entity_ops; 1722*5fcf092eSHyungwoo Yang ov13858->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; 1723*5fcf092eSHyungwoo Yang 1724*5fcf092eSHyungwoo Yang /* Initialize source pad */ 1725*5fcf092eSHyungwoo Yang ov13858->pad.flags = MEDIA_PAD_FL_SOURCE; 1726*5fcf092eSHyungwoo Yang ret = media_entity_pads_init(&ov13858->sd.entity, 1, &ov13858->pad); 1727*5fcf092eSHyungwoo Yang if (ret) { 1728*5fcf092eSHyungwoo Yang dev_err(&client->dev, "%s failed:%d\n", __func__, ret); 1729*5fcf092eSHyungwoo Yang goto error_handler_free; 1730*5fcf092eSHyungwoo Yang } 1731*5fcf092eSHyungwoo Yang 1732*5fcf092eSHyungwoo Yang ret = v4l2_async_register_subdev(&ov13858->sd); 1733*5fcf092eSHyungwoo Yang if (ret < 0) 1734*5fcf092eSHyungwoo Yang goto error_media_entity; 1735*5fcf092eSHyungwoo Yang 1736*5fcf092eSHyungwoo Yang /* 1737*5fcf092eSHyungwoo Yang * Device is already turned on by i2c-core with ACPI domain PM. 1738*5fcf092eSHyungwoo Yang * Enable runtime PM and turn off the device. 1739*5fcf092eSHyungwoo Yang */ 1740*5fcf092eSHyungwoo Yang pm_runtime_get_noresume(&client->dev); 1741*5fcf092eSHyungwoo Yang pm_runtime_set_active(&client->dev); 1742*5fcf092eSHyungwoo Yang pm_runtime_enable(&client->dev); 1743*5fcf092eSHyungwoo Yang pm_runtime_put(&client->dev); 1744*5fcf092eSHyungwoo Yang 1745*5fcf092eSHyungwoo Yang return 0; 1746*5fcf092eSHyungwoo Yang 1747*5fcf092eSHyungwoo Yang error_media_entity: 1748*5fcf092eSHyungwoo Yang media_entity_cleanup(&ov13858->sd.entity); 1749*5fcf092eSHyungwoo Yang 1750*5fcf092eSHyungwoo Yang error_handler_free: 1751*5fcf092eSHyungwoo Yang ov13858_free_controls(ov13858); 1752*5fcf092eSHyungwoo Yang dev_err(&client->dev, "%s failed:%d\n", __func__, ret); 1753*5fcf092eSHyungwoo Yang 1754*5fcf092eSHyungwoo Yang return ret; 1755*5fcf092eSHyungwoo Yang } 1756*5fcf092eSHyungwoo Yang 1757*5fcf092eSHyungwoo Yang static int ov13858_remove(struct i2c_client *client) 1758*5fcf092eSHyungwoo Yang { 1759*5fcf092eSHyungwoo Yang struct v4l2_subdev *sd = i2c_get_clientdata(client); 1760*5fcf092eSHyungwoo Yang struct ov13858 *ov13858 = to_ov13858(sd); 1761*5fcf092eSHyungwoo Yang 1762*5fcf092eSHyungwoo Yang v4l2_async_unregister_subdev(sd); 1763*5fcf092eSHyungwoo Yang media_entity_cleanup(&sd->entity); 1764*5fcf092eSHyungwoo Yang ov13858_free_controls(ov13858); 1765*5fcf092eSHyungwoo Yang 1766*5fcf092eSHyungwoo Yang /* 1767*5fcf092eSHyungwoo Yang * Disable runtime PM but keep the device turned on. 1768*5fcf092eSHyungwoo Yang * i2c-core with ACPI domain PM will turn off the device. 1769*5fcf092eSHyungwoo Yang */ 1770*5fcf092eSHyungwoo Yang pm_runtime_get_sync(&client->dev); 1771*5fcf092eSHyungwoo Yang pm_runtime_disable(&client->dev); 1772*5fcf092eSHyungwoo Yang pm_runtime_set_suspended(&client->dev); 1773*5fcf092eSHyungwoo Yang pm_runtime_put_noidle(&client->dev); 1774*5fcf092eSHyungwoo Yang 1775*5fcf092eSHyungwoo Yang return 0; 1776*5fcf092eSHyungwoo Yang } 1777*5fcf092eSHyungwoo Yang 1778*5fcf092eSHyungwoo Yang static const struct i2c_device_id ov13858_id_table[] = { 1779*5fcf092eSHyungwoo Yang {"ov13858", 0}, 1780*5fcf092eSHyungwoo Yang {}, 1781*5fcf092eSHyungwoo Yang }; 1782*5fcf092eSHyungwoo Yang 1783*5fcf092eSHyungwoo Yang MODULE_DEVICE_TABLE(i2c, ov13858_id_table); 1784*5fcf092eSHyungwoo Yang 1785*5fcf092eSHyungwoo Yang static const struct dev_pm_ops ov13858_pm_ops = { 1786*5fcf092eSHyungwoo Yang SET_SYSTEM_SLEEP_PM_OPS(ov13858_suspend, ov13858_resume) 1787*5fcf092eSHyungwoo Yang }; 1788*5fcf092eSHyungwoo Yang 1789*5fcf092eSHyungwoo Yang #ifdef CONFIG_ACPI 1790*5fcf092eSHyungwoo Yang static const struct acpi_device_id ov13858_acpi_ids[] = { 1791*5fcf092eSHyungwoo Yang {"OVTID858"}, 1792*5fcf092eSHyungwoo Yang { /* sentinel */ } 1793*5fcf092eSHyungwoo Yang }; 1794*5fcf092eSHyungwoo Yang 1795*5fcf092eSHyungwoo Yang MODULE_DEVICE_TABLE(acpi, ov13858_acpi_ids); 1796*5fcf092eSHyungwoo Yang #endif 1797*5fcf092eSHyungwoo Yang 1798*5fcf092eSHyungwoo Yang static struct i2c_driver ov13858_i2c_driver = { 1799*5fcf092eSHyungwoo Yang .driver = { 1800*5fcf092eSHyungwoo Yang .name = "ov13858", 1801*5fcf092eSHyungwoo Yang .owner = THIS_MODULE, 1802*5fcf092eSHyungwoo Yang .pm = &ov13858_pm_ops, 1803*5fcf092eSHyungwoo Yang .acpi_match_table = ACPI_PTR(ov13858_acpi_ids), 1804*5fcf092eSHyungwoo Yang }, 1805*5fcf092eSHyungwoo Yang .probe = ov13858_probe, 1806*5fcf092eSHyungwoo Yang .remove = ov13858_remove, 1807*5fcf092eSHyungwoo Yang .id_table = ov13858_id_table, 1808*5fcf092eSHyungwoo Yang }; 1809*5fcf092eSHyungwoo Yang 1810*5fcf092eSHyungwoo Yang module_i2c_driver(ov13858_i2c_driver); 1811*5fcf092eSHyungwoo Yang 1812*5fcf092eSHyungwoo Yang MODULE_AUTHOR("Kan, Chris <chris.kan@intel.com>"); 1813*5fcf092eSHyungwoo Yang MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>"); 1814*5fcf092eSHyungwoo Yang MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>"); 1815*5fcf092eSHyungwoo Yang MODULE_DESCRIPTION("Omnivision ov13858 sensor driver"); 1816*5fcf092eSHyungwoo Yang MODULE_LICENSE("GPL v2"); 1817