1*bf27502bSShawn Tu // SPDX-License-Identifier: GPL-2.0 2*bf27502bSShawn Tu // Copyright (c) 2019 Intel Corporation. 3*bf27502bSShawn Tu 4*bf27502bSShawn Tu #include <asm/unaligned.h> 5*bf27502bSShawn Tu #include <linux/acpi.h> 6*bf27502bSShawn Tu #include <linux/delay.h> 7*bf27502bSShawn Tu #include <linux/i2c.h> 8*bf27502bSShawn Tu #include <linux/module.h> 9*bf27502bSShawn Tu #include <linux/pm_runtime.h> 10*bf27502bSShawn Tu #include <media/v4l2-ctrls.h> 11*bf27502bSShawn Tu #include <media/v4l2-device.h> 12*bf27502bSShawn Tu #include <media/v4l2-fwnode.h> 13*bf27502bSShawn Tu 14*bf27502bSShawn Tu #define OV5675_REG_VALUE_08BIT 1 15*bf27502bSShawn Tu #define OV5675_REG_VALUE_16BIT 2 16*bf27502bSShawn Tu #define OV5675_REG_VALUE_24BIT 3 17*bf27502bSShawn Tu 18*bf27502bSShawn Tu #define OV5675_LINK_FREQ_450MHZ 450000000ULL 19*bf27502bSShawn Tu #define OV5675_SCLK 90000000LL 20*bf27502bSShawn Tu #define OV5675_MCLK 19200000 21*bf27502bSShawn Tu #define OV5675_DATA_LANES 2 22*bf27502bSShawn Tu #define OV5675_RGB_DEPTH 10 23*bf27502bSShawn Tu 24*bf27502bSShawn Tu #define OV5675_REG_CHIP_ID 0x300a 25*bf27502bSShawn Tu #define OV5675_CHIP_ID 0x5675 26*bf27502bSShawn Tu 27*bf27502bSShawn Tu #define OV5675_REG_MODE_SELECT 0x0100 28*bf27502bSShawn Tu #define OV5675_MODE_STANDBY 0x00 29*bf27502bSShawn Tu #define OV5675_MODE_STREAMING 0x01 30*bf27502bSShawn Tu 31*bf27502bSShawn Tu /* vertical-timings from sensor */ 32*bf27502bSShawn Tu #define OV5675_REG_VTS 0x380e 33*bf27502bSShawn Tu #define OV5675_VTS_30FPS 0x07e4 34*bf27502bSShawn Tu #define OV5675_VTS_30FPS_MIN 0x07e4 35*bf27502bSShawn Tu #define OV5675_VTS_MAX 0x7fff 36*bf27502bSShawn Tu 37*bf27502bSShawn Tu /* horizontal-timings from sensor */ 38*bf27502bSShawn Tu #define OV5675_REG_HTS 0x380c 39*bf27502bSShawn Tu 40*bf27502bSShawn Tu /* Exposure controls from sensor */ 41*bf27502bSShawn Tu #define OV5675_REG_EXPOSURE 0x3500 42*bf27502bSShawn Tu #define OV5675_EXPOSURE_MIN 4 43*bf27502bSShawn Tu #define OV5675_EXPOSURE_MAX_MARGIN 4 44*bf27502bSShawn Tu #define OV5675_EXPOSURE_STEP 1 45*bf27502bSShawn Tu 46*bf27502bSShawn Tu /* Analog gain controls from sensor */ 47*bf27502bSShawn Tu #define OV5675_REG_ANALOG_GAIN 0x3508 48*bf27502bSShawn Tu #define OV5675_ANAL_GAIN_MIN 128 49*bf27502bSShawn Tu #define OV5675_ANAL_GAIN_MAX 2047 50*bf27502bSShawn Tu #define OV5675_ANAL_GAIN_STEP 1 51*bf27502bSShawn Tu 52*bf27502bSShawn Tu /* Digital gain controls from sensor */ 53*bf27502bSShawn Tu #define OV5675_REG_MWB_R_GAIN 0x5019 54*bf27502bSShawn Tu #define OV5675_REG_MWB_G_GAIN 0x501b 55*bf27502bSShawn Tu #define OV5675_REG_MWB_B_GAIN 0x501d 56*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_MIN 0 57*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_MAX 4095 58*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_STEP 1 59*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_DEFAULT 1024 60*bf27502bSShawn Tu 61*bf27502bSShawn Tu /* Test Pattern Control */ 62*bf27502bSShawn Tu #define OV5675_REG_TEST_PATTERN 0x4503 63*bf27502bSShawn Tu #define OV5675_TEST_PATTERN_ENABLE BIT(7) 64*bf27502bSShawn Tu #define OV5675_TEST_PATTERN_BAR_SHIFT 2 65*bf27502bSShawn Tu 66*bf27502bSShawn Tu #define to_ov5675(_sd) container_of(_sd, struct ov5675, sd) 67*bf27502bSShawn Tu 68*bf27502bSShawn Tu enum { 69*bf27502bSShawn Tu OV5675_LINK_FREQ_900MBPS, 70*bf27502bSShawn Tu }; 71*bf27502bSShawn Tu 72*bf27502bSShawn Tu struct ov5675_reg { 73*bf27502bSShawn Tu u16 address; 74*bf27502bSShawn Tu u8 val; 75*bf27502bSShawn Tu }; 76*bf27502bSShawn Tu 77*bf27502bSShawn Tu struct ov5675_reg_list { 78*bf27502bSShawn Tu u32 num_of_regs; 79*bf27502bSShawn Tu const struct ov5675_reg *regs; 80*bf27502bSShawn Tu }; 81*bf27502bSShawn Tu 82*bf27502bSShawn Tu struct ov5675_link_freq_config { 83*bf27502bSShawn Tu const struct ov5675_reg_list reg_list; 84*bf27502bSShawn Tu }; 85*bf27502bSShawn Tu 86*bf27502bSShawn Tu struct ov5675_mode { 87*bf27502bSShawn Tu /* Frame width in pixels */ 88*bf27502bSShawn Tu u32 width; 89*bf27502bSShawn Tu 90*bf27502bSShawn Tu /* Frame height in pixels */ 91*bf27502bSShawn Tu u32 height; 92*bf27502bSShawn Tu 93*bf27502bSShawn Tu /* Horizontal timining size */ 94*bf27502bSShawn Tu u32 hts; 95*bf27502bSShawn Tu 96*bf27502bSShawn Tu /* Default vertical timining size */ 97*bf27502bSShawn Tu u32 vts_def; 98*bf27502bSShawn Tu 99*bf27502bSShawn Tu /* Min vertical timining size */ 100*bf27502bSShawn Tu u32 vts_min; 101*bf27502bSShawn Tu 102*bf27502bSShawn Tu /* Link frequency needed for this resolution */ 103*bf27502bSShawn Tu u32 link_freq_index; 104*bf27502bSShawn Tu 105*bf27502bSShawn Tu /* Sensor register settings for this resolution */ 106*bf27502bSShawn Tu const struct ov5675_reg_list reg_list; 107*bf27502bSShawn Tu }; 108*bf27502bSShawn Tu 109*bf27502bSShawn Tu static const struct ov5675_reg mipi_data_rate_900mbps[] = { 110*bf27502bSShawn Tu {0x0103, 0x01}, 111*bf27502bSShawn Tu {0x0100, 0x00}, 112*bf27502bSShawn Tu {0x0300, 0x04}, 113*bf27502bSShawn Tu {0x0302, 0x8d}, 114*bf27502bSShawn Tu {0x0303, 0x00}, 115*bf27502bSShawn Tu {0x030d, 0x26}, 116*bf27502bSShawn Tu }; 117*bf27502bSShawn Tu 118*bf27502bSShawn Tu static const struct ov5675_reg mode_2592x1944_regs[] = { 119*bf27502bSShawn Tu {0x3002, 0x21}, 120*bf27502bSShawn Tu {0x3107, 0x23}, 121*bf27502bSShawn Tu {0x3501, 0x20}, 122*bf27502bSShawn Tu {0x3503, 0x0c}, 123*bf27502bSShawn Tu {0x3508, 0x03}, 124*bf27502bSShawn Tu {0x3509, 0x00}, 125*bf27502bSShawn Tu {0x3600, 0x66}, 126*bf27502bSShawn Tu {0x3602, 0x30}, 127*bf27502bSShawn Tu {0x3610, 0xa5}, 128*bf27502bSShawn Tu {0x3612, 0x93}, 129*bf27502bSShawn Tu {0x3620, 0x80}, 130*bf27502bSShawn Tu {0x3642, 0x0e}, 131*bf27502bSShawn Tu {0x3661, 0x00}, 132*bf27502bSShawn Tu {0x3662, 0x10}, 133*bf27502bSShawn Tu {0x3664, 0xf3}, 134*bf27502bSShawn Tu {0x3665, 0x9e}, 135*bf27502bSShawn Tu {0x3667, 0xa5}, 136*bf27502bSShawn Tu {0x366e, 0x55}, 137*bf27502bSShawn Tu {0x366f, 0x55}, 138*bf27502bSShawn Tu {0x3670, 0x11}, 139*bf27502bSShawn Tu {0x3671, 0x11}, 140*bf27502bSShawn Tu {0x3672, 0x11}, 141*bf27502bSShawn Tu {0x3673, 0x11}, 142*bf27502bSShawn Tu {0x3714, 0x24}, 143*bf27502bSShawn Tu {0x371a, 0x3e}, 144*bf27502bSShawn Tu {0x3733, 0x10}, 145*bf27502bSShawn Tu {0x3734, 0x00}, 146*bf27502bSShawn Tu {0x373d, 0x24}, 147*bf27502bSShawn Tu {0x3764, 0x20}, 148*bf27502bSShawn Tu {0x3765, 0x20}, 149*bf27502bSShawn Tu {0x3766, 0x12}, 150*bf27502bSShawn Tu {0x37a1, 0x14}, 151*bf27502bSShawn Tu {0x37a8, 0x1c}, 152*bf27502bSShawn Tu {0x37ab, 0x0f}, 153*bf27502bSShawn Tu {0x37c2, 0x04}, 154*bf27502bSShawn Tu {0x37cb, 0x00}, 155*bf27502bSShawn Tu {0x37cc, 0x00}, 156*bf27502bSShawn Tu {0x37cd, 0x00}, 157*bf27502bSShawn Tu {0x37ce, 0x00}, 158*bf27502bSShawn Tu {0x37d8, 0x02}, 159*bf27502bSShawn Tu {0x37d9, 0x08}, 160*bf27502bSShawn Tu {0x37dc, 0x04}, 161*bf27502bSShawn Tu {0x3800, 0x00}, 162*bf27502bSShawn Tu {0x3801, 0x00}, 163*bf27502bSShawn Tu {0x3802, 0x00}, 164*bf27502bSShawn Tu {0x3803, 0x04}, 165*bf27502bSShawn Tu {0x3804, 0x0a}, 166*bf27502bSShawn Tu {0x3805, 0x3f}, 167*bf27502bSShawn Tu {0x3806, 0x07}, 168*bf27502bSShawn Tu {0x3807, 0xb3}, 169*bf27502bSShawn Tu {0x3808, 0x0a}, 170*bf27502bSShawn Tu {0x3809, 0x20}, 171*bf27502bSShawn Tu {0x380a, 0x07}, 172*bf27502bSShawn Tu {0x380b, 0x98}, 173*bf27502bSShawn Tu {0x380c, 0x02}, 174*bf27502bSShawn Tu {0x380d, 0xee}, 175*bf27502bSShawn Tu {0x380e, 0x07}, 176*bf27502bSShawn Tu {0x380f, 0xe4}, 177*bf27502bSShawn Tu {0x3811, 0x10}, 178*bf27502bSShawn Tu {0x3813, 0x0d}, 179*bf27502bSShawn Tu {0x3814, 0x01}, 180*bf27502bSShawn Tu {0x3815, 0x01}, 181*bf27502bSShawn Tu {0x3816, 0x01}, 182*bf27502bSShawn Tu {0x3817, 0x01}, 183*bf27502bSShawn Tu {0x381e, 0x02}, 184*bf27502bSShawn Tu {0x3820, 0x88}, 185*bf27502bSShawn Tu {0x3821, 0x01}, 186*bf27502bSShawn Tu {0x3832, 0x04}, 187*bf27502bSShawn Tu {0x3c80, 0x01}, 188*bf27502bSShawn Tu {0x3c82, 0x00}, 189*bf27502bSShawn Tu {0x3c83, 0xc8}, 190*bf27502bSShawn Tu {0x3c8c, 0x0f}, 191*bf27502bSShawn Tu {0x3c8d, 0xa0}, 192*bf27502bSShawn Tu {0x3c90, 0x07}, 193*bf27502bSShawn Tu {0x3c91, 0x00}, 194*bf27502bSShawn Tu {0x3c92, 0x00}, 195*bf27502bSShawn Tu {0x3c93, 0x00}, 196*bf27502bSShawn Tu {0x3c94, 0xd0}, 197*bf27502bSShawn Tu {0x3c95, 0x50}, 198*bf27502bSShawn Tu {0x3c96, 0x35}, 199*bf27502bSShawn Tu {0x3c97, 0x00}, 200*bf27502bSShawn Tu {0x4001, 0xe0}, 201*bf27502bSShawn Tu {0x4008, 0x02}, 202*bf27502bSShawn Tu {0x4009, 0x0d}, 203*bf27502bSShawn Tu {0x400f, 0x80}, 204*bf27502bSShawn Tu {0x4013, 0x02}, 205*bf27502bSShawn Tu {0x4040, 0x00}, 206*bf27502bSShawn Tu {0x4041, 0x07}, 207*bf27502bSShawn Tu {0x404c, 0x50}, 208*bf27502bSShawn Tu {0x404e, 0x20}, 209*bf27502bSShawn Tu {0x4500, 0x06}, 210*bf27502bSShawn Tu {0x4503, 0x00}, 211*bf27502bSShawn Tu {0x450a, 0x04}, 212*bf27502bSShawn Tu {0x4809, 0x04}, 213*bf27502bSShawn Tu {0x480c, 0x12}, 214*bf27502bSShawn Tu {0x4819, 0x70}, 215*bf27502bSShawn Tu {0x4825, 0x32}, 216*bf27502bSShawn Tu {0x4826, 0x32}, 217*bf27502bSShawn Tu {0x482a, 0x06}, 218*bf27502bSShawn Tu {0x4833, 0x08}, 219*bf27502bSShawn Tu {0x4837, 0x0d}, 220*bf27502bSShawn Tu {0x5000, 0x77}, 221*bf27502bSShawn Tu {0x5b00, 0x01}, 222*bf27502bSShawn Tu {0x5b01, 0x10}, 223*bf27502bSShawn Tu {0x5b02, 0x01}, 224*bf27502bSShawn Tu {0x5b03, 0xdb}, 225*bf27502bSShawn Tu {0x5b05, 0x6c}, 226*bf27502bSShawn Tu {0x5e10, 0xfc}, 227*bf27502bSShawn Tu {0x3500, 0x00}, 228*bf27502bSShawn Tu {0x3501, 0x3E}, 229*bf27502bSShawn Tu {0x3502, 0x60}, 230*bf27502bSShawn Tu {0x3503, 0x08}, 231*bf27502bSShawn Tu {0x3508, 0x04}, 232*bf27502bSShawn Tu {0x3509, 0x00}, 233*bf27502bSShawn Tu {0x3832, 0x48}, 234*bf27502bSShawn Tu {0x5780, 0x3e}, 235*bf27502bSShawn Tu {0x5781, 0x0f}, 236*bf27502bSShawn Tu {0x5782, 0x44}, 237*bf27502bSShawn Tu {0x5783, 0x02}, 238*bf27502bSShawn Tu {0x5784, 0x01}, 239*bf27502bSShawn Tu {0x5785, 0x01}, 240*bf27502bSShawn Tu {0x5786, 0x00}, 241*bf27502bSShawn Tu {0x5787, 0x04}, 242*bf27502bSShawn Tu {0x5788, 0x02}, 243*bf27502bSShawn Tu {0x5789, 0x0f}, 244*bf27502bSShawn Tu {0x578a, 0xfd}, 245*bf27502bSShawn Tu {0x578b, 0xf5}, 246*bf27502bSShawn Tu {0x578c, 0xf5}, 247*bf27502bSShawn Tu {0x578d, 0x03}, 248*bf27502bSShawn Tu {0x578e, 0x08}, 249*bf27502bSShawn Tu {0x578f, 0x0c}, 250*bf27502bSShawn Tu {0x5790, 0x08}, 251*bf27502bSShawn Tu {0x5791, 0x06}, 252*bf27502bSShawn Tu {0x5792, 0x00}, 253*bf27502bSShawn Tu {0x5793, 0x52}, 254*bf27502bSShawn Tu {0x5794, 0xa3}, 255*bf27502bSShawn Tu {0x4003, 0x40}, 256*bf27502bSShawn Tu {0x3107, 0x01}, 257*bf27502bSShawn Tu {0x3c80, 0x08}, 258*bf27502bSShawn Tu {0x3c83, 0xb1}, 259*bf27502bSShawn Tu {0x3c8c, 0x10}, 260*bf27502bSShawn Tu {0x3c8d, 0x00}, 261*bf27502bSShawn Tu {0x3c90, 0x00}, 262*bf27502bSShawn Tu {0x3c94, 0x00}, 263*bf27502bSShawn Tu {0x3c95, 0x00}, 264*bf27502bSShawn Tu {0x3c96, 0x00}, 265*bf27502bSShawn Tu {0x37cb, 0x09}, 266*bf27502bSShawn Tu {0x37cc, 0x15}, 267*bf27502bSShawn Tu {0x37cd, 0x1f}, 268*bf27502bSShawn Tu {0x37ce, 0x1f}, 269*bf27502bSShawn Tu }; 270*bf27502bSShawn Tu 271*bf27502bSShawn Tu static const struct ov5675_reg mode_1296x972_regs[] = { 272*bf27502bSShawn Tu {0x3002, 0x21}, 273*bf27502bSShawn Tu {0x3107, 0x23}, 274*bf27502bSShawn Tu {0x3501, 0x20}, 275*bf27502bSShawn Tu {0x3503, 0x0c}, 276*bf27502bSShawn Tu {0x3508, 0x03}, 277*bf27502bSShawn Tu {0x3509, 0x00}, 278*bf27502bSShawn Tu {0x3600, 0x66}, 279*bf27502bSShawn Tu {0x3602, 0x30}, 280*bf27502bSShawn Tu {0x3610, 0xa5}, 281*bf27502bSShawn Tu {0x3612, 0x93}, 282*bf27502bSShawn Tu {0x3620, 0x80}, 283*bf27502bSShawn Tu {0x3642, 0x0e}, 284*bf27502bSShawn Tu {0x3661, 0x00}, 285*bf27502bSShawn Tu {0x3662, 0x08}, 286*bf27502bSShawn Tu {0x3664, 0xf3}, 287*bf27502bSShawn Tu {0x3665, 0x9e}, 288*bf27502bSShawn Tu {0x3667, 0xa5}, 289*bf27502bSShawn Tu {0x366e, 0x55}, 290*bf27502bSShawn Tu {0x366f, 0x55}, 291*bf27502bSShawn Tu {0x3670, 0x11}, 292*bf27502bSShawn Tu {0x3671, 0x11}, 293*bf27502bSShawn Tu {0x3672, 0x11}, 294*bf27502bSShawn Tu {0x3673, 0x11}, 295*bf27502bSShawn Tu {0x3714, 0x28}, 296*bf27502bSShawn Tu {0x371a, 0x3e}, 297*bf27502bSShawn Tu {0x3733, 0x10}, 298*bf27502bSShawn Tu {0x3734, 0x00}, 299*bf27502bSShawn Tu {0x373d, 0x24}, 300*bf27502bSShawn Tu {0x3764, 0x20}, 301*bf27502bSShawn Tu {0x3765, 0x20}, 302*bf27502bSShawn Tu {0x3766, 0x12}, 303*bf27502bSShawn Tu {0x37a1, 0x14}, 304*bf27502bSShawn Tu {0x37a8, 0x1c}, 305*bf27502bSShawn Tu {0x37ab, 0x0f}, 306*bf27502bSShawn Tu {0x37c2, 0x14}, 307*bf27502bSShawn Tu {0x37cb, 0x00}, 308*bf27502bSShawn Tu {0x37cc, 0x00}, 309*bf27502bSShawn Tu {0x37cd, 0x00}, 310*bf27502bSShawn Tu {0x37ce, 0x00}, 311*bf27502bSShawn Tu {0x37d8, 0x02}, 312*bf27502bSShawn Tu {0x37d9, 0x04}, 313*bf27502bSShawn Tu {0x37dc, 0x04}, 314*bf27502bSShawn Tu {0x3800, 0x00}, 315*bf27502bSShawn Tu {0x3801, 0x00}, 316*bf27502bSShawn Tu {0x3802, 0x00}, 317*bf27502bSShawn Tu {0x3803, 0xf4}, 318*bf27502bSShawn Tu {0x3804, 0x0a}, 319*bf27502bSShawn Tu {0x3805, 0x3f}, 320*bf27502bSShawn Tu {0x3806, 0x06}, 321*bf27502bSShawn Tu {0x3807, 0xb3}, 322*bf27502bSShawn Tu {0x3808, 0x05}, 323*bf27502bSShawn Tu {0x3809, 0x00}, 324*bf27502bSShawn Tu {0x380a, 0x02}, 325*bf27502bSShawn Tu {0x380b, 0xd0}, 326*bf27502bSShawn Tu {0x380c, 0x02}, 327*bf27502bSShawn Tu {0x380d, 0xee}, 328*bf27502bSShawn Tu {0x380e, 0x07}, 329*bf27502bSShawn Tu {0x380f, 0xe4}, 330*bf27502bSShawn Tu {0x3811, 0x10}, 331*bf27502bSShawn Tu {0x3813, 0x09}, 332*bf27502bSShawn Tu {0x3814, 0x03}, 333*bf27502bSShawn Tu {0x3815, 0x01}, 334*bf27502bSShawn Tu {0x3816, 0x03}, 335*bf27502bSShawn Tu {0x3817, 0x01}, 336*bf27502bSShawn Tu {0x381e, 0x02}, 337*bf27502bSShawn Tu {0x3820, 0x8b}, 338*bf27502bSShawn Tu {0x3821, 0x01}, 339*bf27502bSShawn Tu {0x3832, 0x04}, 340*bf27502bSShawn Tu {0x3c80, 0x01}, 341*bf27502bSShawn Tu {0x3c82, 0x00}, 342*bf27502bSShawn Tu {0x3c83, 0xc8}, 343*bf27502bSShawn Tu {0x3c8c, 0x0f}, 344*bf27502bSShawn Tu {0x3c8d, 0xa0}, 345*bf27502bSShawn Tu {0x3c90, 0x07}, 346*bf27502bSShawn Tu {0x3c91, 0x00}, 347*bf27502bSShawn Tu {0x3c92, 0x00}, 348*bf27502bSShawn Tu {0x3c93, 0x00}, 349*bf27502bSShawn Tu {0x3c94, 0xd0}, 350*bf27502bSShawn Tu {0x3c95, 0x50}, 351*bf27502bSShawn Tu {0x3c96, 0x35}, 352*bf27502bSShawn Tu {0x3c97, 0x00}, 353*bf27502bSShawn Tu {0x4001, 0xe0}, 354*bf27502bSShawn Tu {0x4008, 0x00}, 355*bf27502bSShawn Tu {0x4009, 0x07}, 356*bf27502bSShawn Tu {0x400f, 0x80}, 357*bf27502bSShawn Tu {0x4013, 0x02}, 358*bf27502bSShawn Tu {0x4040, 0x00}, 359*bf27502bSShawn Tu {0x4041, 0x03}, 360*bf27502bSShawn Tu {0x404c, 0x50}, 361*bf27502bSShawn Tu {0x404e, 0x20}, 362*bf27502bSShawn Tu {0x4500, 0x06}, 363*bf27502bSShawn Tu {0x4503, 0x00}, 364*bf27502bSShawn Tu {0x450a, 0x04}, 365*bf27502bSShawn Tu {0x4809, 0x04}, 366*bf27502bSShawn Tu {0x480c, 0x12}, 367*bf27502bSShawn Tu {0x4819, 0x70}, 368*bf27502bSShawn Tu {0x4825, 0x32}, 369*bf27502bSShawn Tu {0x4826, 0x32}, 370*bf27502bSShawn Tu {0x482a, 0x06}, 371*bf27502bSShawn Tu {0x4833, 0x08}, 372*bf27502bSShawn Tu {0x4837, 0x0d}, 373*bf27502bSShawn Tu {0x5000, 0x77}, 374*bf27502bSShawn Tu {0x5b00, 0x01}, 375*bf27502bSShawn Tu {0x5b01, 0x10}, 376*bf27502bSShawn Tu {0x5b02, 0x01}, 377*bf27502bSShawn Tu {0x5b03, 0xdb}, 378*bf27502bSShawn Tu {0x5b05, 0x6c}, 379*bf27502bSShawn Tu {0x5e10, 0xfc}, 380*bf27502bSShawn Tu {0x3500, 0x00}, 381*bf27502bSShawn Tu {0x3501, 0x1F}, 382*bf27502bSShawn Tu {0x3502, 0x20}, 383*bf27502bSShawn Tu {0x3503, 0x08}, 384*bf27502bSShawn Tu {0x3508, 0x04}, 385*bf27502bSShawn Tu {0x3509, 0x00}, 386*bf27502bSShawn Tu {0x3832, 0x48}, 387*bf27502bSShawn Tu {0x5780, 0x3e}, 388*bf27502bSShawn Tu {0x5781, 0x0f}, 389*bf27502bSShawn Tu {0x5782, 0x44}, 390*bf27502bSShawn Tu {0x5783, 0x02}, 391*bf27502bSShawn Tu {0x5784, 0x01}, 392*bf27502bSShawn Tu {0x5785, 0x01}, 393*bf27502bSShawn Tu {0x5786, 0x00}, 394*bf27502bSShawn Tu {0x5787, 0x04}, 395*bf27502bSShawn Tu {0x5788, 0x02}, 396*bf27502bSShawn Tu {0x5789, 0x0f}, 397*bf27502bSShawn Tu {0x578a, 0xfd}, 398*bf27502bSShawn Tu {0x578b, 0xf5}, 399*bf27502bSShawn Tu {0x578c, 0xf5}, 400*bf27502bSShawn Tu {0x578d, 0x03}, 401*bf27502bSShawn Tu {0x578e, 0x08}, 402*bf27502bSShawn Tu {0x578f, 0x0c}, 403*bf27502bSShawn Tu {0x5790, 0x08}, 404*bf27502bSShawn Tu {0x5791, 0x06}, 405*bf27502bSShawn Tu {0x5792, 0x00}, 406*bf27502bSShawn Tu {0x5793, 0x52}, 407*bf27502bSShawn Tu {0x5794, 0xa3}, 408*bf27502bSShawn Tu {0x4003, 0x40}, 409*bf27502bSShawn Tu {0x3107, 0x01}, 410*bf27502bSShawn Tu {0x3c80, 0x08}, 411*bf27502bSShawn Tu {0x3c83, 0xb1}, 412*bf27502bSShawn Tu {0x3c8c, 0x10}, 413*bf27502bSShawn Tu {0x3c8d, 0x00}, 414*bf27502bSShawn Tu {0x3c90, 0x00}, 415*bf27502bSShawn Tu {0x3c94, 0x00}, 416*bf27502bSShawn Tu {0x3c95, 0x00}, 417*bf27502bSShawn Tu {0x3c96, 0x00}, 418*bf27502bSShawn Tu {0x37cb, 0x09}, 419*bf27502bSShawn Tu {0x37cc, 0x15}, 420*bf27502bSShawn Tu {0x37cd, 0x1f}, 421*bf27502bSShawn Tu {0x37ce, 0x1f}, 422*bf27502bSShawn Tu }; 423*bf27502bSShawn Tu 424*bf27502bSShawn Tu static const char * const ov5675_test_pattern_menu[] = { 425*bf27502bSShawn Tu "Disabled", 426*bf27502bSShawn Tu "Standard Color Bar", 427*bf27502bSShawn Tu "Top-Bottom Darker Color Bar", 428*bf27502bSShawn Tu "Right-Left Darker Color Bar", 429*bf27502bSShawn Tu "Bottom-Top Darker Color Bar" 430*bf27502bSShawn Tu }; 431*bf27502bSShawn Tu 432*bf27502bSShawn Tu static const s64 link_freq_menu_items[] = { 433*bf27502bSShawn Tu OV5675_LINK_FREQ_450MHZ, 434*bf27502bSShawn Tu }; 435*bf27502bSShawn Tu 436*bf27502bSShawn Tu static const struct ov5675_link_freq_config link_freq_configs[] = { 437*bf27502bSShawn Tu [OV5675_LINK_FREQ_900MBPS] = { 438*bf27502bSShawn Tu .reg_list = { 439*bf27502bSShawn Tu .num_of_regs = ARRAY_SIZE(mipi_data_rate_900mbps), 440*bf27502bSShawn Tu .regs = mipi_data_rate_900mbps, 441*bf27502bSShawn Tu } 442*bf27502bSShawn Tu } 443*bf27502bSShawn Tu }; 444*bf27502bSShawn Tu 445*bf27502bSShawn Tu static const struct ov5675_mode supported_modes[] = { 446*bf27502bSShawn Tu { 447*bf27502bSShawn Tu .width = 2592, 448*bf27502bSShawn Tu .height = 1944, 449*bf27502bSShawn Tu .hts = 1500, 450*bf27502bSShawn Tu .vts_def = OV5675_VTS_30FPS, 451*bf27502bSShawn Tu .vts_min = OV5675_VTS_30FPS_MIN, 452*bf27502bSShawn Tu .reg_list = { 453*bf27502bSShawn Tu .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs), 454*bf27502bSShawn Tu .regs = mode_2592x1944_regs, 455*bf27502bSShawn Tu }, 456*bf27502bSShawn Tu .link_freq_index = OV5675_LINK_FREQ_900MBPS, 457*bf27502bSShawn Tu }, 458*bf27502bSShawn Tu { 459*bf27502bSShawn Tu .width = 1296, 460*bf27502bSShawn Tu .height = 972, 461*bf27502bSShawn Tu .hts = 1500, 462*bf27502bSShawn Tu .vts_def = OV5675_VTS_30FPS, 463*bf27502bSShawn Tu .vts_min = OV5675_VTS_30FPS_MIN, 464*bf27502bSShawn Tu .reg_list = { 465*bf27502bSShawn Tu .num_of_regs = ARRAY_SIZE(mode_1296x972_regs), 466*bf27502bSShawn Tu .regs = mode_1296x972_regs, 467*bf27502bSShawn Tu }, 468*bf27502bSShawn Tu .link_freq_index = OV5675_LINK_FREQ_900MBPS, 469*bf27502bSShawn Tu } 470*bf27502bSShawn Tu }; 471*bf27502bSShawn Tu 472*bf27502bSShawn Tu struct ov5675 { 473*bf27502bSShawn Tu struct v4l2_subdev sd; 474*bf27502bSShawn Tu struct media_pad pad; 475*bf27502bSShawn Tu struct v4l2_ctrl_handler ctrl_handler; 476*bf27502bSShawn Tu 477*bf27502bSShawn Tu /* V4L2 Controls */ 478*bf27502bSShawn Tu struct v4l2_ctrl *link_freq; 479*bf27502bSShawn Tu struct v4l2_ctrl *pixel_rate; 480*bf27502bSShawn Tu struct v4l2_ctrl *vblank; 481*bf27502bSShawn Tu struct v4l2_ctrl *hblank; 482*bf27502bSShawn Tu struct v4l2_ctrl *exposure; 483*bf27502bSShawn Tu 484*bf27502bSShawn Tu /* Current mode */ 485*bf27502bSShawn Tu const struct ov5675_mode *cur_mode; 486*bf27502bSShawn Tu 487*bf27502bSShawn Tu /* To serialize asynchronus callbacks */ 488*bf27502bSShawn Tu struct mutex mutex; 489*bf27502bSShawn Tu 490*bf27502bSShawn Tu /* Streaming on/off */ 491*bf27502bSShawn Tu bool streaming; 492*bf27502bSShawn Tu }; 493*bf27502bSShawn Tu 494*bf27502bSShawn Tu static u64 to_pixel_rate(u32 f_index) 495*bf27502bSShawn Tu { 496*bf27502bSShawn Tu u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV5675_DATA_LANES; 497*bf27502bSShawn Tu 498*bf27502bSShawn Tu do_div(pixel_rate, OV5675_RGB_DEPTH); 499*bf27502bSShawn Tu 500*bf27502bSShawn Tu return pixel_rate; 501*bf27502bSShawn Tu } 502*bf27502bSShawn Tu 503*bf27502bSShawn Tu static u64 to_pixels_per_line(u32 hts, u32 f_index) 504*bf27502bSShawn Tu { 505*bf27502bSShawn Tu u64 ppl = hts * to_pixel_rate(f_index); 506*bf27502bSShawn Tu 507*bf27502bSShawn Tu do_div(ppl, OV5675_SCLK); 508*bf27502bSShawn Tu 509*bf27502bSShawn Tu return ppl; 510*bf27502bSShawn Tu } 511*bf27502bSShawn Tu 512*bf27502bSShawn Tu static int ov5675_read_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 *val) 513*bf27502bSShawn Tu { 514*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); 515*bf27502bSShawn Tu struct i2c_msg msgs[2]; 516*bf27502bSShawn Tu u8 addr_buf[2]; 517*bf27502bSShawn Tu u8 data_buf[4] = {0}; 518*bf27502bSShawn Tu int ret; 519*bf27502bSShawn Tu 520*bf27502bSShawn Tu if (len > 4) 521*bf27502bSShawn Tu return -EINVAL; 522*bf27502bSShawn Tu 523*bf27502bSShawn Tu put_unaligned_be16(reg, addr_buf); 524*bf27502bSShawn Tu msgs[0].addr = client->addr; 525*bf27502bSShawn Tu msgs[0].flags = 0; 526*bf27502bSShawn Tu msgs[0].len = sizeof(addr_buf); 527*bf27502bSShawn Tu msgs[0].buf = addr_buf; 528*bf27502bSShawn Tu msgs[1].addr = client->addr; 529*bf27502bSShawn Tu msgs[1].flags = I2C_M_RD; 530*bf27502bSShawn Tu msgs[1].len = len; 531*bf27502bSShawn Tu msgs[1].buf = &data_buf[4 - len]; 532*bf27502bSShawn Tu 533*bf27502bSShawn Tu ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 534*bf27502bSShawn Tu if (ret != ARRAY_SIZE(msgs)) 535*bf27502bSShawn Tu return -EIO; 536*bf27502bSShawn Tu 537*bf27502bSShawn Tu *val = get_unaligned_be32(data_buf); 538*bf27502bSShawn Tu 539*bf27502bSShawn Tu return 0; 540*bf27502bSShawn Tu } 541*bf27502bSShawn Tu 542*bf27502bSShawn Tu static int ov5675_write_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 val) 543*bf27502bSShawn Tu { 544*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); 545*bf27502bSShawn Tu u8 buf[6]; 546*bf27502bSShawn Tu 547*bf27502bSShawn Tu if (len > 4) 548*bf27502bSShawn Tu return -EINVAL; 549*bf27502bSShawn Tu 550*bf27502bSShawn Tu put_unaligned_be16(reg, buf); 551*bf27502bSShawn Tu put_unaligned_be32(val << 8 * (4 - len), buf + 2); 552*bf27502bSShawn Tu if (i2c_master_send(client, buf, len + 2) != len + 2) 553*bf27502bSShawn Tu return -EIO; 554*bf27502bSShawn Tu 555*bf27502bSShawn Tu return 0; 556*bf27502bSShawn Tu } 557*bf27502bSShawn Tu 558*bf27502bSShawn Tu static int ov5675_write_reg_list(struct ov5675 *ov5675, 559*bf27502bSShawn Tu const struct ov5675_reg_list *r_list) 560*bf27502bSShawn Tu { 561*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); 562*bf27502bSShawn Tu unsigned int i; 563*bf27502bSShawn Tu int ret; 564*bf27502bSShawn Tu 565*bf27502bSShawn Tu for (i = 0; i < r_list->num_of_regs; i++) { 566*bf27502bSShawn Tu ret = ov5675_write_reg(ov5675, r_list->regs[i].address, 1, 567*bf27502bSShawn Tu r_list->regs[i].val); 568*bf27502bSShawn Tu if (ret) { 569*bf27502bSShawn Tu dev_err_ratelimited(&client->dev, 570*bf27502bSShawn Tu "failed to write reg 0x%4.4x. error = %d", 571*bf27502bSShawn Tu r_list->regs[i].address, ret); 572*bf27502bSShawn Tu return ret; 573*bf27502bSShawn Tu } 574*bf27502bSShawn Tu } 575*bf27502bSShawn Tu 576*bf27502bSShawn Tu return 0; 577*bf27502bSShawn Tu } 578*bf27502bSShawn Tu 579*bf27502bSShawn Tu static int ov5675_update_digital_gain(struct ov5675 *ov5675, u32 d_gain) 580*bf27502bSShawn Tu { 581*bf27502bSShawn Tu int ret; 582*bf27502bSShawn Tu 583*bf27502bSShawn Tu ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_R_GAIN, 584*bf27502bSShawn Tu OV5675_REG_VALUE_16BIT, d_gain); 585*bf27502bSShawn Tu if (ret) 586*bf27502bSShawn Tu return ret; 587*bf27502bSShawn Tu 588*bf27502bSShawn Tu ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_G_GAIN, 589*bf27502bSShawn Tu OV5675_REG_VALUE_16BIT, d_gain); 590*bf27502bSShawn Tu if (ret) 591*bf27502bSShawn Tu return ret; 592*bf27502bSShawn Tu 593*bf27502bSShawn Tu return ov5675_write_reg(ov5675, OV5675_REG_MWB_B_GAIN, 594*bf27502bSShawn Tu OV5675_REG_VALUE_16BIT, d_gain); 595*bf27502bSShawn Tu } 596*bf27502bSShawn Tu 597*bf27502bSShawn Tu static int ov5675_test_pattern(struct ov5675 *ov5675, u32 pattern) 598*bf27502bSShawn Tu { 599*bf27502bSShawn Tu if (pattern) 600*bf27502bSShawn Tu pattern = (pattern - 1) << OV5675_TEST_PATTERN_BAR_SHIFT | 601*bf27502bSShawn Tu OV5675_TEST_PATTERN_ENABLE; 602*bf27502bSShawn Tu 603*bf27502bSShawn Tu return ov5675_write_reg(ov5675, OV5675_REG_TEST_PATTERN, 604*bf27502bSShawn Tu OV5675_REG_VALUE_08BIT, pattern); 605*bf27502bSShawn Tu } 606*bf27502bSShawn Tu 607*bf27502bSShawn Tu static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl) 608*bf27502bSShawn Tu { 609*bf27502bSShawn Tu struct ov5675 *ov5675 = container_of(ctrl->handler, 610*bf27502bSShawn Tu struct ov5675, ctrl_handler); 611*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); 612*bf27502bSShawn Tu s64 exposure_max; 613*bf27502bSShawn Tu int ret = 0; 614*bf27502bSShawn Tu 615*bf27502bSShawn Tu /* Propagate change of current control to all related controls */ 616*bf27502bSShawn Tu if (ctrl->id == V4L2_CID_VBLANK) { 617*bf27502bSShawn Tu /* Update max exposure while meeting expected vblanking */ 618*bf27502bSShawn Tu exposure_max = (ov5675->cur_mode->height + ctrl->val - 619*bf27502bSShawn Tu OV5675_EXPOSURE_MAX_MARGIN) / 2; 620*bf27502bSShawn Tu __v4l2_ctrl_modify_range(ov5675->exposure, 621*bf27502bSShawn Tu ov5675->exposure->minimum, 622*bf27502bSShawn Tu exposure_max, ov5675->exposure->step, 623*bf27502bSShawn Tu exposure_max); 624*bf27502bSShawn Tu } 625*bf27502bSShawn Tu 626*bf27502bSShawn Tu /* V4L2 controls values will be applied only when power is already up */ 627*bf27502bSShawn Tu if (!pm_runtime_get_if_in_use(&client->dev)) 628*bf27502bSShawn Tu return 0; 629*bf27502bSShawn Tu 630*bf27502bSShawn Tu switch (ctrl->id) { 631*bf27502bSShawn Tu case V4L2_CID_ANALOGUE_GAIN: 632*bf27502bSShawn Tu ret = ov5675_write_reg(ov5675, OV5675_REG_ANALOG_GAIN, 633*bf27502bSShawn Tu OV5675_REG_VALUE_16BIT, ctrl->val); 634*bf27502bSShawn Tu break; 635*bf27502bSShawn Tu 636*bf27502bSShawn Tu case V4L2_CID_DIGITAL_GAIN: 637*bf27502bSShawn Tu ret = ov5675_update_digital_gain(ov5675, ctrl->val); 638*bf27502bSShawn Tu break; 639*bf27502bSShawn Tu 640*bf27502bSShawn Tu case V4L2_CID_EXPOSURE: 641*bf27502bSShawn Tu /* 3 least significant bits of expsoure are fractional part */ 642*bf27502bSShawn Tu ret = ov5675_write_reg(ov5675, OV5675_REG_EXPOSURE, 643*bf27502bSShawn Tu OV5675_REG_VALUE_24BIT, ctrl->val << 3); 644*bf27502bSShawn Tu break; 645*bf27502bSShawn Tu 646*bf27502bSShawn Tu case V4L2_CID_VBLANK: 647*bf27502bSShawn Tu ret = ov5675_write_reg(ov5675, OV5675_REG_VTS, 648*bf27502bSShawn Tu OV5675_REG_VALUE_16BIT, 649*bf27502bSShawn Tu ov5675->cur_mode->height + ctrl->val + 650*bf27502bSShawn Tu 10); 651*bf27502bSShawn Tu break; 652*bf27502bSShawn Tu 653*bf27502bSShawn Tu case V4L2_CID_TEST_PATTERN: 654*bf27502bSShawn Tu ret = ov5675_test_pattern(ov5675, ctrl->val); 655*bf27502bSShawn Tu break; 656*bf27502bSShawn Tu 657*bf27502bSShawn Tu default: 658*bf27502bSShawn Tu ret = -EINVAL; 659*bf27502bSShawn Tu break; 660*bf27502bSShawn Tu } 661*bf27502bSShawn Tu 662*bf27502bSShawn Tu pm_runtime_put(&client->dev); 663*bf27502bSShawn Tu 664*bf27502bSShawn Tu return ret; 665*bf27502bSShawn Tu } 666*bf27502bSShawn Tu 667*bf27502bSShawn Tu static const struct v4l2_ctrl_ops ov5675_ctrl_ops = { 668*bf27502bSShawn Tu .s_ctrl = ov5675_set_ctrl, 669*bf27502bSShawn Tu }; 670*bf27502bSShawn Tu 671*bf27502bSShawn Tu static int ov5675_init_controls(struct ov5675 *ov5675) 672*bf27502bSShawn Tu { 673*bf27502bSShawn Tu struct v4l2_ctrl_handler *ctrl_hdlr; 674*bf27502bSShawn Tu s64 exposure_max, h_blank; 675*bf27502bSShawn Tu int ret; 676*bf27502bSShawn Tu 677*bf27502bSShawn Tu ctrl_hdlr = &ov5675->ctrl_handler; 678*bf27502bSShawn Tu ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8); 679*bf27502bSShawn Tu if (ret) 680*bf27502bSShawn Tu return ret; 681*bf27502bSShawn Tu 682*bf27502bSShawn Tu ctrl_hdlr->lock = &ov5675->mutex; 683*bf27502bSShawn Tu ov5675->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov5675_ctrl_ops, 684*bf27502bSShawn Tu V4L2_CID_LINK_FREQ, 685*bf27502bSShawn Tu ARRAY_SIZE(link_freq_menu_items) - 1, 686*bf27502bSShawn Tu 0, link_freq_menu_items); 687*bf27502bSShawn Tu if (ov5675->link_freq) 688*bf27502bSShawn Tu ov5675->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 689*bf27502bSShawn Tu 690*bf27502bSShawn Tu ov5675->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, 691*bf27502bSShawn Tu V4L2_CID_PIXEL_RATE, 0, 692*bf27502bSShawn Tu to_pixel_rate(OV5675_LINK_FREQ_900MBPS), 693*bf27502bSShawn Tu 1, 694*bf27502bSShawn Tu to_pixel_rate(OV5675_LINK_FREQ_900MBPS)); 695*bf27502bSShawn Tu ov5675->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, 696*bf27502bSShawn Tu V4L2_CID_VBLANK, 697*bf27502bSShawn Tu ov5675->cur_mode->vts_min - ov5675->cur_mode->height, 698*bf27502bSShawn Tu OV5675_VTS_MAX - ov5675->cur_mode->height, 1, 699*bf27502bSShawn Tu ov5675->cur_mode->vts_def - ov5675->cur_mode->height); 700*bf27502bSShawn Tu h_blank = to_pixels_per_line(ov5675->cur_mode->hts, 701*bf27502bSShawn Tu ov5675->cur_mode->link_freq_index) - ov5675->cur_mode->width; 702*bf27502bSShawn Tu ov5675->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, 703*bf27502bSShawn Tu V4L2_CID_HBLANK, h_blank, h_blank, 1, 704*bf27502bSShawn Tu h_blank); 705*bf27502bSShawn Tu if (ov5675->hblank) 706*bf27502bSShawn Tu ov5675->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; 707*bf27502bSShawn Tu 708*bf27502bSShawn Tu v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 709*bf27502bSShawn Tu OV5675_ANAL_GAIN_MIN, OV5675_ANAL_GAIN_MAX, 710*bf27502bSShawn Tu OV5675_ANAL_GAIN_STEP, OV5675_ANAL_GAIN_MIN); 711*bf27502bSShawn Tu v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_DIGITAL_GAIN, 712*bf27502bSShawn Tu OV5675_DGTL_GAIN_MIN, OV5675_DGTL_GAIN_MAX, 713*bf27502bSShawn Tu OV5675_DGTL_GAIN_STEP, OV5675_DGTL_GAIN_DEFAULT); 714*bf27502bSShawn Tu exposure_max = (ov5675->cur_mode->vts_def - 715*bf27502bSShawn Tu OV5675_EXPOSURE_MAX_MARGIN) / 2; 716*bf27502bSShawn Tu ov5675->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, 717*bf27502bSShawn Tu V4L2_CID_EXPOSURE, 718*bf27502bSShawn Tu OV5675_EXPOSURE_MIN, exposure_max, 719*bf27502bSShawn Tu OV5675_EXPOSURE_STEP, 720*bf27502bSShawn Tu exposure_max); 721*bf27502bSShawn Tu v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov5675_ctrl_ops, 722*bf27502bSShawn Tu V4L2_CID_TEST_PATTERN, 723*bf27502bSShawn Tu ARRAY_SIZE(ov5675_test_pattern_menu) - 1, 724*bf27502bSShawn Tu 0, 0, ov5675_test_pattern_menu); 725*bf27502bSShawn Tu if (ctrl_hdlr->error) 726*bf27502bSShawn Tu return ctrl_hdlr->error; 727*bf27502bSShawn Tu 728*bf27502bSShawn Tu ov5675->sd.ctrl_handler = ctrl_hdlr; 729*bf27502bSShawn Tu 730*bf27502bSShawn Tu return 0; 731*bf27502bSShawn Tu } 732*bf27502bSShawn Tu 733*bf27502bSShawn Tu static void ov5675_update_pad_format(const struct ov5675_mode *mode, 734*bf27502bSShawn Tu struct v4l2_mbus_framefmt *fmt) 735*bf27502bSShawn Tu { 736*bf27502bSShawn Tu fmt->width = mode->width; 737*bf27502bSShawn Tu fmt->height = mode->height; 738*bf27502bSShawn Tu fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; 739*bf27502bSShawn Tu fmt->field = V4L2_FIELD_NONE; 740*bf27502bSShawn Tu } 741*bf27502bSShawn Tu 742*bf27502bSShawn Tu static int ov5675_start_streaming(struct ov5675 *ov5675) 743*bf27502bSShawn Tu { 744*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); 745*bf27502bSShawn Tu const struct ov5675_reg_list *reg_list; 746*bf27502bSShawn Tu int link_freq_index, ret; 747*bf27502bSShawn Tu 748*bf27502bSShawn Tu link_freq_index = ov5675->cur_mode->link_freq_index; 749*bf27502bSShawn Tu reg_list = &link_freq_configs[link_freq_index].reg_list; 750*bf27502bSShawn Tu ret = ov5675_write_reg_list(ov5675, reg_list); 751*bf27502bSShawn Tu if (ret) { 752*bf27502bSShawn Tu dev_err(&client->dev, "failed to set plls"); 753*bf27502bSShawn Tu return ret; 754*bf27502bSShawn Tu } 755*bf27502bSShawn Tu 756*bf27502bSShawn Tu reg_list = &ov5675->cur_mode->reg_list; 757*bf27502bSShawn Tu ret = ov5675_write_reg_list(ov5675, reg_list); 758*bf27502bSShawn Tu if (ret) { 759*bf27502bSShawn Tu dev_err(&client->dev, "failed to set mode"); 760*bf27502bSShawn Tu return ret; 761*bf27502bSShawn Tu } 762*bf27502bSShawn Tu 763*bf27502bSShawn Tu ret = __v4l2_ctrl_handler_setup(ov5675->sd.ctrl_handler); 764*bf27502bSShawn Tu if (ret) 765*bf27502bSShawn Tu return ret; 766*bf27502bSShawn Tu 767*bf27502bSShawn Tu ret = ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT, 768*bf27502bSShawn Tu OV5675_REG_VALUE_08BIT, OV5675_MODE_STREAMING); 769*bf27502bSShawn Tu if (ret) { 770*bf27502bSShawn Tu dev_err(&client->dev, "failed to set stream"); 771*bf27502bSShawn Tu return ret; 772*bf27502bSShawn Tu } 773*bf27502bSShawn Tu 774*bf27502bSShawn Tu return 0; 775*bf27502bSShawn Tu } 776*bf27502bSShawn Tu 777*bf27502bSShawn Tu static void ov5675_stop_streaming(struct ov5675 *ov5675) 778*bf27502bSShawn Tu { 779*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); 780*bf27502bSShawn Tu 781*bf27502bSShawn Tu if (ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT, 782*bf27502bSShawn Tu OV5675_REG_VALUE_08BIT, OV5675_MODE_STANDBY)) 783*bf27502bSShawn Tu dev_err(&client->dev, "failed to set stream"); 784*bf27502bSShawn Tu } 785*bf27502bSShawn Tu 786*bf27502bSShawn Tu static int ov5675_set_stream(struct v4l2_subdev *sd, int enable) 787*bf27502bSShawn Tu { 788*bf27502bSShawn Tu struct ov5675 *ov5675 = to_ov5675(sd); 789*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(sd); 790*bf27502bSShawn Tu int ret = 0; 791*bf27502bSShawn Tu 792*bf27502bSShawn Tu if (ov5675->streaming == enable) 793*bf27502bSShawn Tu return 0; 794*bf27502bSShawn Tu 795*bf27502bSShawn Tu mutex_lock(&ov5675->mutex); 796*bf27502bSShawn Tu if (enable) { 797*bf27502bSShawn Tu ret = pm_runtime_get_sync(&client->dev); 798*bf27502bSShawn Tu if (ret < 0) { 799*bf27502bSShawn Tu pm_runtime_put_noidle(&client->dev); 800*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 801*bf27502bSShawn Tu return ret; 802*bf27502bSShawn Tu } 803*bf27502bSShawn Tu 804*bf27502bSShawn Tu ret = ov5675_start_streaming(ov5675); 805*bf27502bSShawn Tu if (ret) { 806*bf27502bSShawn Tu enable = 0; 807*bf27502bSShawn Tu ov5675_stop_streaming(ov5675); 808*bf27502bSShawn Tu pm_runtime_put(&client->dev); 809*bf27502bSShawn Tu } 810*bf27502bSShawn Tu } else { 811*bf27502bSShawn Tu ov5675_stop_streaming(ov5675); 812*bf27502bSShawn Tu pm_runtime_put(&client->dev); 813*bf27502bSShawn Tu } 814*bf27502bSShawn Tu 815*bf27502bSShawn Tu ov5675->streaming = enable; 816*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 817*bf27502bSShawn Tu 818*bf27502bSShawn Tu return ret; 819*bf27502bSShawn Tu } 820*bf27502bSShawn Tu 821*bf27502bSShawn Tu static int __maybe_unused ov5675_suspend(struct device *dev) 822*bf27502bSShawn Tu { 823*bf27502bSShawn Tu struct i2c_client *client = to_i2c_client(dev); 824*bf27502bSShawn Tu struct v4l2_subdev *sd = i2c_get_clientdata(client); 825*bf27502bSShawn Tu struct ov5675 *ov5675 = to_ov5675(sd); 826*bf27502bSShawn Tu 827*bf27502bSShawn Tu mutex_lock(&ov5675->mutex); 828*bf27502bSShawn Tu if (ov5675->streaming) 829*bf27502bSShawn Tu ov5675_stop_streaming(ov5675); 830*bf27502bSShawn Tu 831*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 832*bf27502bSShawn Tu 833*bf27502bSShawn Tu return 0; 834*bf27502bSShawn Tu } 835*bf27502bSShawn Tu 836*bf27502bSShawn Tu static int __maybe_unused ov5675_resume(struct device *dev) 837*bf27502bSShawn Tu { 838*bf27502bSShawn Tu struct i2c_client *client = to_i2c_client(dev); 839*bf27502bSShawn Tu struct v4l2_subdev *sd = i2c_get_clientdata(client); 840*bf27502bSShawn Tu struct ov5675 *ov5675 = to_ov5675(sd); 841*bf27502bSShawn Tu int ret; 842*bf27502bSShawn Tu 843*bf27502bSShawn Tu mutex_lock(&ov5675->mutex); 844*bf27502bSShawn Tu if (ov5675->streaming) { 845*bf27502bSShawn Tu ret = ov5675_start_streaming(ov5675); 846*bf27502bSShawn Tu if (ret) { 847*bf27502bSShawn Tu ov5675->streaming = false; 848*bf27502bSShawn Tu ov5675_stop_streaming(ov5675); 849*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 850*bf27502bSShawn Tu return ret; 851*bf27502bSShawn Tu } 852*bf27502bSShawn Tu } 853*bf27502bSShawn Tu 854*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 855*bf27502bSShawn Tu 856*bf27502bSShawn Tu return 0; 857*bf27502bSShawn Tu } 858*bf27502bSShawn Tu 859*bf27502bSShawn Tu static int ov5675_set_format(struct v4l2_subdev *sd, 860*bf27502bSShawn Tu struct v4l2_subdev_pad_config *cfg, 861*bf27502bSShawn Tu struct v4l2_subdev_format *fmt) 862*bf27502bSShawn Tu { 863*bf27502bSShawn Tu struct ov5675 *ov5675 = to_ov5675(sd); 864*bf27502bSShawn Tu const struct ov5675_mode *mode; 865*bf27502bSShawn Tu s32 vblank_def, h_blank; 866*bf27502bSShawn Tu 867*bf27502bSShawn Tu mode = v4l2_find_nearest_size(supported_modes, 868*bf27502bSShawn Tu ARRAY_SIZE(supported_modes), width, 869*bf27502bSShawn Tu height, fmt->format.width, 870*bf27502bSShawn Tu fmt->format.height); 871*bf27502bSShawn Tu 872*bf27502bSShawn Tu mutex_lock(&ov5675->mutex); 873*bf27502bSShawn Tu ov5675_update_pad_format(mode, &fmt->format); 874*bf27502bSShawn Tu if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 875*bf27502bSShawn Tu *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; 876*bf27502bSShawn Tu } else { 877*bf27502bSShawn Tu ov5675->cur_mode = mode; 878*bf27502bSShawn Tu __v4l2_ctrl_s_ctrl(ov5675->link_freq, mode->link_freq_index); 879*bf27502bSShawn Tu __v4l2_ctrl_s_ctrl_int64(ov5675->pixel_rate, 880*bf27502bSShawn Tu to_pixel_rate(mode->link_freq_index)); 881*bf27502bSShawn Tu 882*bf27502bSShawn Tu /* Update limits and set FPS to default */ 883*bf27502bSShawn Tu vblank_def = mode->vts_def - mode->height; 884*bf27502bSShawn Tu __v4l2_ctrl_modify_range(ov5675->vblank, 885*bf27502bSShawn Tu mode->vts_min - mode->height, 886*bf27502bSShawn Tu OV5675_VTS_MAX - mode->height, 1, 887*bf27502bSShawn Tu vblank_def); 888*bf27502bSShawn Tu __v4l2_ctrl_s_ctrl(ov5675->vblank, vblank_def); 889*bf27502bSShawn Tu h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) - 890*bf27502bSShawn Tu mode->width; 891*bf27502bSShawn Tu __v4l2_ctrl_modify_range(ov5675->hblank, h_blank, h_blank, 1, 892*bf27502bSShawn Tu h_blank); 893*bf27502bSShawn Tu } 894*bf27502bSShawn Tu 895*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 896*bf27502bSShawn Tu 897*bf27502bSShawn Tu return 0; 898*bf27502bSShawn Tu } 899*bf27502bSShawn Tu 900*bf27502bSShawn Tu static int ov5675_get_format(struct v4l2_subdev *sd, 901*bf27502bSShawn Tu struct v4l2_subdev_pad_config *cfg, 902*bf27502bSShawn Tu struct v4l2_subdev_format *fmt) 903*bf27502bSShawn Tu { 904*bf27502bSShawn Tu struct ov5675 *ov5675 = to_ov5675(sd); 905*bf27502bSShawn Tu 906*bf27502bSShawn Tu mutex_lock(&ov5675->mutex); 907*bf27502bSShawn Tu if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) 908*bf27502bSShawn Tu fmt->format = *v4l2_subdev_get_try_format(&ov5675->sd, cfg, 909*bf27502bSShawn Tu fmt->pad); 910*bf27502bSShawn Tu else 911*bf27502bSShawn Tu ov5675_update_pad_format(ov5675->cur_mode, &fmt->format); 912*bf27502bSShawn Tu 913*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 914*bf27502bSShawn Tu 915*bf27502bSShawn Tu return 0; 916*bf27502bSShawn Tu } 917*bf27502bSShawn Tu 918*bf27502bSShawn Tu static int ov5675_enum_mbus_code(struct v4l2_subdev *sd, 919*bf27502bSShawn Tu struct v4l2_subdev_pad_config *cfg, 920*bf27502bSShawn Tu struct v4l2_subdev_mbus_code_enum *code) 921*bf27502bSShawn Tu { 922*bf27502bSShawn Tu if (code->index > 0) 923*bf27502bSShawn Tu return -EINVAL; 924*bf27502bSShawn Tu 925*bf27502bSShawn Tu code->code = MEDIA_BUS_FMT_SGRBG10_1X10; 926*bf27502bSShawn Tu 927*bf27502bSShawn Tu return 0; 928*bf27502bSShawn Tu } 929*bf27502bSShawn Tu 930*bf27502bSShawn Tu static int ov5675_enum_frame_size(struct v4l2_subdev *sd, 931*bf27502bSShawn Tu struct v4l2_subdev_pad_config *cfg, 932*bf27502bSShawn Tu struct v4l2_subdev_frame_size_enum *fse) 933*bf27502bSShawn Tu { 934*bf27502bSShawn Tu if (fse->index >= ARRAY_SIZE(supported_modes)) 935*bf27502bSShawn Tu return -EINVAL; 936*bf27502bSShawn Tu 937*bf27502bSShawn Tu if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) 938*bf27502bSShawn Tu return -EINVAL; 939*bf27502bSShawn Tu 940*bf27502bSShawn Tu fse->min_width = supported_modes[fse->index].width; 941*bf27502bSShawn Tu fse->max_width = fse->min_width; 942*bf27502bSShawn Tu fse->min_height = supported_modes[fse->index].height; 943*bf27502bSShawn Tu fse->max_height = fse->min_height; 944*bf27502bSShawn Tu 945*bf27502bSShawn Tu return 0; 946*bf27502bSShawn Tu } 947*bf27502bSShawn Tu 948*bf27502bSShawn Tu static int ov5675_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 949*bf27502bSShawn Tu { 950*bf27502bSShawn Tu struct ov5675 *ov5675 = to_ov5675(sd); 951*bf27502bSShawn Tu 952*bf27502bSShawn Tu mutex_lock(&ov5675->mutex); 953*bf27502bSShawn Tu ov5675_update_pad_format(&supported_modes[0], 954*bf27502bSShawn Tu v4l2_subdev_get_try_format(sd, fh->pad, 0)); 955*bf27502bSShawn Tu mutex_unlock(&ov5675->mutex); 956*bf27502bSShawn Tu 957*bf27502bSShawn Tu return 0; 958*bf27502bSShawn Tu } 959*bf27502bSShawn Tu 960*bf27502bSShawn Tu static const struct v4l2_subdev_video_ops ov5675_video_ops = { 961*bf27502bSShawn Tu .s_stream = ov5675_set_stream, 962*bf27502bSShawn Tu }; 963*bf27502bSShawn Tu 964*bf27502bSShawn Tu static const struct v4l2_subdev_pad_ops ov5675_pad_ops = { 965*bf27502bSShawn Tu .set_fmt = ov5675_set_format, 966*bf27502bSShawn Tu .get_fmt = ov5675_get_format, 967*bf27502bSShawn Tu .enum_mbus_code = ov5675_enum_mbus_code, 968*bf27502bSShawn Tu .enum_frame_size = ov5675_enum_frame_size, 969*bf27502bSShawn Tu }; 970*bf27502bSShawn Tu 971*bf27502bSShawn Tu static const struct v4l2_subdev_ops ov5675_subdev_ops = { 972*bf27502bSShawn Tu .video = &ov5675_video_ops, 973*bf27502bSShawn Tu .pad = &ov5675_pad_ops, 974*bf27502bSShawn Tu }; 975*bf27502bSShawn Tu 976*bf27502bSShawn Tu static const struct media_entity_operations ov5675_subdev_entity_ops = { 977*bf27502bSShawn Tu .link_validate = v4l2_subdev_link_validate, 978*bf27502bSShawn Tu }; 979*bf27502bSShawn Tu 980*bf27502bSShawn Tu static const struct v4l2_subdev_internal_ops ov5675_internal_ops = { 981*bf27502bSShawn Tu .open = ov5675_open, 982*bf27502bSShawn Tu }; 983*bf27502bSShawn Tu 984*bf27502bSShawn Tu static int ov5675_identify_module(struct ov5675 *ov5675) 985*bf27502bSShawn Tu { 986*bf27502bSShawn Tu struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); 987*bf27502bSShawn Tu int ret; 988*bf27502bSShawn Tu u32 val; 989*bf27502bSShawn Tu 990*bf27502bSShawn Tu ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID, 991*bf27502bSShawn Tu OV5675_REG_VALUE_24BIT, &val); 992*bf27502bSShawn Tu if (ret) 993*bf27502bSShawn Tu return ret; 994*bf27502bSShawn Tu 995*bf27502bSShawn Tu if (val != OV5675_CHIP_ID) { 996*bf27502bSShawn Tu dev_err(&client->dev, "chip id mismatch: %x!=%x", 997*bf27502bSShawn Tu OV5675_CHIP_ID, val); 998*bf27502bSShawn Tu return -ENXIO; 999*bf27502bSShawn Tu } 1000*bf27502bSShawn Tu 1001*bf27502bSShawn Tu return 0; 1002*bf27502bSShawn Tu } 1003*bf27502bSShawn Tu 1004*bf27502bSShawn Tu static int ov5675_check_hwcfg(struct device *dev) 1005*bf27502bSShawn Tu { 1006*bf27502bSShawn Tu struct fwnode_handle *ep; 1007*bf27502bSShawn Tu struct fwnode_handle *fwnode = dev_fwnode(dev); 1008*bf27502bSShawn Tu struct v4l2_fwnode_endpoint bus_cfg = { 1009*bf27502bSShawn Tu .bus_type = V4L2_MBUS_CSI2_DPHY 1010*bf27502bSShawn Tu }; 1011*bf27502bSShawn Tu u32 mclk; 1012*bf27502bSShawn Tu int ret; 1013*bf27502bSShawn Tu unsigned int i, j; 1014*bf27502bSShawn Tu 1015*bf27502bSShawn Tu if (!fwnode) 1016*bf27502bSShawn Tu return -ENXIO; 1017*bf27502bSShawn Tu 1018*bf27502bSShawn Tu ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); 1019*bf27502bSShawn Tu 1020*bf27502bSShawn Tu if (ret) { 1021*bf27502bSShawn Tu dev_err(dev, "can't get clock frequency"); 1022*bf27502bSShawn Tu return ret; 1023*bf27502bSShawn Tu } 1024*bf27502bSShawn Tu 1025*bf27502bSShawn Tu if (mclk != OV5675_MCLK) { 1026*bf27502bSShawn Tu dev_err(dev, "external clock %d is not supported", mclk); 1027*bf27502bSShawn Tu return -EINVAL; 1028*bf27502bSShawn Tu } 1029*bf27502bSShawn Tu 1030*bf27502bSShawn Tu ep = fwnode_graph_get_next_endpoint(fwnode, NULL); 1031*bf27502bSShawn Tu if (!ep) 1032*bf27502bSShawn Tu return -ENXIO; 1033*bf27502bSShawn Tu 1034*bf27502bSShawn Tu ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); 1035*bf27502bSShawn Tu fwnode_handle_put(ep); 1036*bf27502bSShawn Tu if (ret) 1037*bf27502bSShawn Tu return ret; 1038*bf27502bSShawn Tu 1039*bf27502bSShawn Tu if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV5675_DATA_LANES) { 1040*bf27502bSShawn Tu dev_err(dev, "number of CSI2 data lanes %d is not supported", 1041*bf27502bSShawn Tu bus_cfg.bus.mipi_csi2.num_data_lanes); 1042*bf27502bSShawn Tu ret = -EINVAL; 1043*bf27502bSShawn Tu goto check_hwcfg_error; 1044*bf27502bSShawn Tu } 1045*bf27502bSShawn Tu 1046*bf27502bSShawn Tu if (!bus_cfg.nr_of_link_frequencies) { 1047*bf27502bSShawn Tu dev_err(dev, "no link frequencies defined"); 1048*bf27502bSShawn Tu ret = -EINVAL; 1049*bf27502bSShawn Tu goto check_hwcfg_error; 1050*bf27502bSShawn Tu } 1051*bf27502bSShawn Tu 1052*bf27502bSShawn Tu for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) { 1053*bf27502bSShawn Tu for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) { 1054*bf27502bSShawn Tu if (link_freq_menu_items[i] == 1055*bf27502bSShawn Tu bus_cfg.link_frequencies[j]) 1056*bf27502bSShawn Tu break; 1057*bf27502bSShawn Tu } 1058*bf27502bSShawn Tu 1059*bf27502bSShawn Tu if (j == bus_cfg.nr_of_link_frequencies) { 1060*bf27502bSShawn Tu dev_err(dev, "no link frequency %lld supported", 1061*bf27502bSShawn Tu link_freq_menu_items[i]); 1062*bf27502bSShawn Tu ret = -EINVAL; 1063*bf27502bSShawn Tu goto check_hwcfg_error; 1064*bf27502bSShawn Tu } 1065*bf27502bSShawn Tu } 1066*bf27502bSShawn Tu 1067*bf27502bSShawn Tu check_hwcfg_error: 1068*bf27502bSShawn Tu v4l2_fwnode_endpoint_free(&bus_cfg); 1069*bf27502bSShawn Tu 1070*bf27502bSShawn Tu return ret; 1071*bf27502bSShawn Tu } 1072*bf27502bSShawn Tu 1073*bf27502bSShawn Tu static int ov5675_remove(struct i2c_client *client) 1074*bf27502bSShawn Tu { 1075*bf27502bSShawn Tu struct v4l2_subdev *sd = i2c_get_clientdata(client); 1076*bf27502bSShawn Tu struct ov5675 *ov5675 = to_ov5675(sd); 1077*bf27502bSShawn Tu 1078*bf27502bSShawn Tu v4l2_async_unregister_subdev(sd); 1079*bf27502bSShawn Tu media_entity_cleanup(&sd->entity); 1080*bf27502bSShawn Tu v4l2_ctrl_handler_free(sd->ctrl_handler); 1081*bf27502bSShawn Tu pm_runtime_disable(&client->dev); 1082*bf27502bSShawn Tu mutex_destroy(&ov5675->mutex); 1083*bf27502bSShawn Tu 1084*bf27502bSShawn Tu return 0; 1085*bf27502bSShawn Tu } 1086*bf27502bSShawn Tu 1087*bf27502bSShawn Tu static int ov5675_probe(struct i2c_client *client) 1088*bf27502bSShawn Tu { 1089*bf27502bSShawn Tu struct ov5675 *ov5675; 1090*bf27502bSShawn Tu int ret; 1091*bf27502bSShawn Tu 1092*bf27502bSShawn Tu ret = ov5675_check_hwcfg(&client->dev); 1093*bf27502bSShawn Tu if (ret) { 1094*bf27502bSShawn Tu dev_err(&client->dev, "failed to check HW configuration: %d", 1095*bf27502bSShawn Tu ret); 1096*bf27502bSShawn Tu return ret; 1097*bf27502bSShawn Tu } 1098*bf27502bSShawn Tu 1099*bf27502bSShawn Tu ov5675 = devm_kzalloc(&client->dev, sizeof(*ov5675), GFP_KERNEL); 1100*bf27502bSShawn Tu if (!ov5675) 1101*bf27502bSShawn Tu return -ENOMEM; 1102*bf27502bSShawn Tu 1103*bf27502bSShawn Tu v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops); 1104*bf27502bSShawn Tu ret = ov5675_identify_module(ov5675); 1105*bf27502bSShawn Tu if (ret) { 1106*bf27502bSShawn Tu dev_err(&client->dev, "failed to find sensor: %d", ret); 1107*bf27502bSShawn Tu return ret; 1108*bf27502bSShawn Tu } 1109*bf27502bSShawn Tu 1110*bf27502bSShawn Tu mutex_init(&ov5675->mutex); 1111*bf27502bSShawn Tu ov5675->cur_mode = &supported_modes[0]; 1112*bf27502bSShawn Tu ret = ov5675_init_controls(ov5675); 1113*bf27502bSShawn Tu if (ret) { 1114*bf27502bSShawn Tu dev_err(&client->dev, "failed to init controls: %d", ret); 1115*bf27502bSShawn Tu goto probe_error_v4l2_ctrl_handler_free; 1116*bf27502bSShawn Tu } 1117*bf27502bSShawn Tu 1118*bf27502bSShawn Tu ov5675->sd.internal_ops = &ov5675_internal_ops; 1119*bf27502bSShawn Tu ov5675->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1120*bf27502bSShawn Tu ov5675->sd.entity.ops = &ov5675_subdev_entity_ops; 1121*bf27502bSShawn Tu ov5675->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; 1122*bf27502bSShawn Tu ov5675->pad.flags = MEDIA_PAD_FL_SOURCE; 1123*bf27502bSShawn Tu ret = media_entity_pads_init(&ov5675->sd.entity, 1, &ov5675->pad); 1124*bf27502bSShawn Tu if (ret) { 1125*bf27502bSShawn Tu dev_err(&client->dev, "failed to init entity pads: %d", ret); 1126*bf27502bSShawn Tu goto probe_error_v4l2_ctrl_handler_free; 1127*bf27502bSShawn Tu } 1128*bf27502bSShawn Tu 1129*bf27502bSShawn Tu ret = v4l2_async_register_subdev_sensor_common(&ov5675->sd); 1130*bf27502bSShawn Tu if (ret < 0) { 1131*bf27502bSShawn Tu dev_err(&client->dev, "failed to register V4L2 subdev: %d", 1132*bf27502bSShawn Tu ret); 1133*bf27502bSShawn Tu goto probe_error_media_entity_cleanup; 1134*bf27502bSShawn Tu } 1135*bf27502bSShawn Tu 1136*bf27502bSShawn Tu /* 1137*bf27502bSShawn Tu * Device is already turned on by i2c-core with ACPI domain PM. 1138*bf27502bSShawn Tu * Enable runtime PM and turn off the device. 1139*bf27502bSShawn Tu */ 1140*bf27502bSShawn Tu pm_runtime_set_active(&client->dev); 1141*bf27502bSShawn Tu pm_runtime_enable(&client->dev); 1142*bf27502bSShawn Tu pm_runtime_idle(&client->dev); 1143*bf27502bSShawn Tu 1144*bf27502bSShawn Tu return 0; 1145*bf27502bSShawn Tu 1146*bf27502bSShawn Tu probe_error_media_entity_cleanup: 1147*bf27502bSShawn Tu media_entity_cleanup(&ov5675->sd.entity); 1148*bf27502bSShawn Tu 1149*bf27502bSShawn Tu probe_error_v4l2_ctrl_handler_free: 1150*bf27502bSShawn Tu v4l2_ctrl_handler_free(ov5675->sd.ctrl_handler); 1151*bf27502bSShawn Tu mutex_destroy(&ov5675->mutex); 1152*bf27502bSShawn Tu 1153*bf27502bSShawn Tu return ret; 1154*bf27502bSShawn Tu } 1155*bf27502bSShawn Tu 1156*bf27502bSShawn Tu static const struct dev_pm_ops ov5675_pm_ops = { 1157*bf27502bSShawn Tu SET_SYSTEM_SLEEP_PM_OPS(ov5675_suspend, ov5675_resume) 1158*bf27502bSShawn Tu }; 1159*bf27502bSShawn Tu 1160*bf27502bSShawn Tu #ifdef CONFIG_ACPI 1161*bf27502bSShawn Tu static const struct acpi_device_id ov5675_acpi_ids[] = { 1162*bf27502bSShawn Tu {"OVTI5675"}, 1163*bf27502bSShawn Tu {} 1164*bf27502bSShawn Tu }; 1165*bf27502bSShawn Tu 1166*bf27502bSShawn Tu MODULE_DEVICE_TABLE(acpi, ov5675_acpi_ids); 1167*bf27502bSShawn Tu #endif 1168*bf27502bSShawn Tu 1169*bf27502bSShawn Tu static struct i2c_driver ov5675_i2c_driver = { 1170*bf27502bSShawn Tu .driver = { 1171*bf27502bSShawn Tu .name = "ov5675", 1172*bf27502bSShawn Tu .pm = &ov5675_pm_ops, 1173*bf27502bSShawn Tu .acpi_match_table = ACPI_PTR(ov5675_acpi_ids), 1174*bf27502bSShawn Tu }, 1175*bf27502bSShawn Tu .probe_new = ov5675_probe, 1176*bf27502bSShawn Tu .remove = ov5675_remove, 1177*bf27502bSShawn Tu }; 1178*bf27502bSShawn Tu 1179*bf27502bSShawn Tu module_i2c_driver(ov5675_i2c_driver); 1180*bf27502bSShawn Tu 1181*bf27502bSShawn Tu MODULE_AUTHOR("Shawn Tu <shawnx.tu@intel.com>"); 1182*bf27502bSShawn Tu MODULE_DESCRIPTION("OmniVision OV5675 sensor driver"); 1183*bf27502bSShawn Tu MODULE_LICENSE("GPL v2"); 1184