1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * ov772x Camera Driver 4 * 5 * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org> 6 * 7 * Copyright (C) 2008 Renesas Solutions Corp. 8 * Kuninori Morimoto <morimoto.kuninori@renesas.com> 9 * 10 * Based on ov7670 and soc_camera_platform driver, 11 * 12 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> 13 * Copyright (C) 2008 Magnus Damm 14 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> 15 */ 16 17 #include <linux/clk.h> 18 #include <linux/delay.h> 19 #include <linux/gpio/consumer.h> 20 #include <linux/i2c.h> 21 #include <linux/init.h> 22 #include <linux/kernel.h> 23 #include <linux/module.h> 24 #include <linux/slab.h> 25 #include <linux/v4l2-mediabus.h> 26 #include <linux/videodev2.h> 27 28 #include <media/i2c/ov772x.h> 29 30 #include <media/v4l2-ctrls.h> 31 #include <media/v4l2-device.h> 32 #include <media/v4l2-image-sizes.h> 33 #include <media/v4l2-subdev.h> 34 35 /* 36 * register offset 37 */ 38 #define GAIN 0x00 /* AGC - Gain control gain setting */ 39 #define BLUE 0x01 /* AWB - Blue channel gain setting */ 40 #define RED 0x02 /* AWB - Red channel gain setting */ 41 #define GREEN 0x03 /* AWB - Green channel gain setting */ 42 #define COM1 0x04 /* Common control 1 */ 43 #define BAVG 0x05 /* U/B Average Level */ 44 #define GAVG 0x06 /* Y/Gb Average Level */ 45 #define RAVG 0x07 /* V/R Average Level */ 46 #define AECH 0x08 /* Exposure Value - AEC MSBs */ 47 #define COM2 0x09 /* Common control 2 */ 48 #define PID 0x0A /* Product ID Number MSB */ 49 #define VER 0x0B /* Product ID Number LSB */ 50 #define COM3 0x0C /* Common control 3 */ 51 #define COM4 0x0D /* Common control 4 */ 52 #define COM5 0x0E /* Common control 5 */ 53 #define COM6 0x0F /* Common control 6 */ 54 #define AEC 0x10 /* Exposure Value */ 55 #define CLKRC 0x11 /* Internal clock */ 56 #define COM7 0x12 /* Common control 7 */ 57 #define COM8 0x13 /* Common control 8 */ 58 #define COM9 0x14 /* Common control 9 */ 59 #define COM10 0x15 /* Common control 10 */ 60 #define REG16 0x16 /* Register 16 */ 61 #define HSTART 0x17 /* Horizontal sensor size */ 62 #define HSIZE 0x18 /* Horizontal frame (HREF column) end high 8-bit */ 63 #define VSTART 0x19 /* Vertical frame (row) start high 8-bit */ 64 #define VSIZE 0x1A /* Vertical sensor size */ 65 #define PSHFT 0x1B /* Data format - pixel delay select */ 66 #define MIDH 0x1C /* Manufacturer ID byte - high */ 67 #define MIDL 0x1D /* Manufacturer ID byte - low */ 68 #define LAEC 0x1F /* Fine AEC value */ 69 #define COM11 0x20 /* Common control 11 */ 70 #define BDBASE 0x22 /* Banding filter Minimum AEC value */ 71 #define DBSTEP 0x23 /* Banding filter Maximum Setp */ 72 #define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */ 73 #define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */ 74 #define VPT 0x26 /* AGC/AEC Fast mode operating region */ 75 #define REG28 0x28 /* Register 28 */ 76 #define HOUTSIZE 0x29 /* Horizontal data output size MSBs */ 77 #define EXHCH 0x2A /* Dummy pixel insert MSB */ 78 #define EXHCL 0x2B /* Dummy pixel insert LSB */ 79 #define VOUTSIZE 0x2C /* Vertical data output size MSBs */ 80 #define ADVFL 0x2D /* LSB of insert dummy lines in Vertical direction */ 81 #define ADVFH 0x2E /* MSG of insert dummy lines in Vertical direction */ 82 #define YAVE 0x2F /* Y/G Channel Average value */ 83 #define LUMHTH 0x30 /* Histogram AEC/AGC Luminance high level threshold */ 84 #define LUMLTH 0x31 /* Histogram AEC/AGC Luminance low level threshold */ 85 #define HREF 0x32 /* Image start and size control */ 86 #define DM_LNL 0x33 /* Dummy line low 8 bits */ 87 #define DM_LNH 0x34 /* Dummy line high 8 bits */ 88 #define ADOFF_B 0x35 /* AD offset compensation value for B channel */ 89 #define ADOFF_R 0x36 /* AD offset compensation value for R channel */ 90 #define ADOFF_GB 0x37 /* AD offset compensation value for Gb channel */ 91 #define ADOFF_GR 0x38 /* AD offset compensation value for Gr channel */ 92 #define OFF_B 0x39 /* Analog process B channel offset value */ 93 #define OFF_R 0x3A /* Analog process R channel offset value */ 94 #define OFF_GB 0x3B /* Analog process Gb channel offset value */ 95 #define OFF_GR 0x3C /* Analog process Gr channel offset value */ 96 #define COM12 0x3D /* Common control 12 */ 97 #define COM13 0x3E /* Common control 13 */ 98 #define COM14 0x3F /* Common control 14 */ 99 #define COM15 0x40 /* Common control 15*/ 100 #define COM16 0x41 /* Common control 16 */ 101 #define TGT_B 0x42 /* BLC blue channel target value */ 102 #define TGT_R 0x43 /* BLC red channel target value */ 103 #define TGT_GB 0x44 /* BLC Gb channel target value */ 104 #define TGT_GR 0x45 /* BLC Gr channel target value */ 105 /* for ov7720 */ 106 #define LCC0 0x46 /* Lens correction control 0 */ 107 #define LCC1 0x47 /* Lens correction option 1 - X coordinate */ 108 #define LCC2 0x48 /* Lens correction option 2 - Y coordinate */ 109 #define LCC3 0x49 /* Lens correction option 3 */ 110 #define LCC4 0x4A /* Lens correction option 4 - radius of the circular */ 111 #define LCC5 0x4B /* Lens correction option 5 */ 112 #define LCC6 0x4C /* Lens correction option 6 */ 113 /* for ov7725 */ 114 #define LC_CTR 0x46 /* Lens correction control */ 115 #define LC_XC 0x47 /* X coordinate of lens correction center relative */ 116 #define LC_YC 0x48 /* Y coordinate of lens correction center relative */ 117 #define LC_COEF 0x49 /* Lens correction coefficient */ 118 #define LC_RADI 0x4A /* Lens correction radius */ 119 #define LC_COEFB 0x4B /* Lens B channel compensation coefficient */ 120 #define LC_COEFR 0x4C /* Lens R channel compensation coefficient */ 121 122 #define FIXGAIN 0x4D /* Analog fix gain amplifer */ 123 #define AREF0 0x4E /* Sensor reference control */ 124 #define AREF1 0x4F /* Sensor reference current control */ 125 #define AREF2 0x50 /* Analog reference control */ 126 #define AREF3 0x51 /* ADC reference control */ 127 #define AREF4 0x52 /* ADC reference control */ 128 #define AREF5 0x53 /* ADC reference control */ 129 #define AREF6 0x54 /* Analog reference control */ 130 #define AREF7 0x55 /* Analog reference control */ 131 #define UFIX 0x60 /* U channel fixed value output */ 132 #define VFIX 0x61 /* V channel fixed value output */ 133 #define AWBB_BLK 0x62 /* AWB option for advanced AWB */ 134 #define AWB_CTRL0 0x63 /* AWB control byte 0 */ 135 #define DSP_CTRL1 0x64 /* DSP control byte 1 */ 136 #define DSP_CTRL2 0x65 /* DSP control byte 2 */ 137 #define DSP_CTRL3 0x66 /* DSP control byte 3 */ 138 #define DSP_CTRL4 0x67 /* DSP control byte 4 */ 139 #define AWB_BIAS 0x68 /* AWB BLC level clip */ 140 #define AWB_CTRL1 0x69 /* AWB control 1 */ 141 #define AWB_CTRL2 0x6A /* AWB control 2 */ 142 #define AWB_CTRL3 0x6B /* AWB control 3 */ 143 #define AWB_CTRL4 0x6C /* AWB control 4 */ 144 #define AWB_CTRL5 0x6D /* AWB control 5 */ 145 #define AWB_CTRL6 0x6E /* AWB control 6 */ 146 #define AWB_CTRL7 0x6F /* AWB control 7 */ 147 #define AWB_CTRL8 0x70 /* AWB control 8 */ 148 #define AWB_CTRL9 0x71 /* AWB control 9 */ 149 #define AWB_CTRL10 0x72 /* AWB control 10 */ 150 #define AWB_CTRL11 0x73 /* AWB control 11 */ 151 #define AWB_CTRL12 0x74 /* AWB control 12 */ 152 #define AWB_CTRL13 0x75 /* AWB control 13 */ 153 #define AWB_CTRL14 0x76 /* AWB control 14 */ 154 #define AWB_CTRL15 0x77 /* AWB control 15 */ 155 #define AWB_CTRL16 0x78 /* AWB control 16 */ 156 #define AWB_CTRL17 0x79 /* AWB control 17 */ 157 #define AWB_CTRL18 0x7A /* AWB control 18 */ 158 #define AWB_CTRL19 0x7B /* AWB control 19 */ 159 #define AWB_CTRL20 0x7C /* AWB control 20 */ 160 #define AWB_CTRL21 0x7D /* AWB control 21 */ 161 #define GAM1 0x7E /* Gamma Curve 1st segment input end point */ 162 #define GAM2 0x7F /* Gamma Curve 2nd segment input end point */ 163 #define GAM3 0x80 /* Gamma Curve 3rd segment input end point */ 164 #define GAM4 0x81 /* Gamma Curve 4th segment input end point */ 165 #define GAM5 0x82 /* Gamma Curve 5th segment input end point */ 166 #define GAM6 0x83 /* Gamma Curve 6th segment input end point */ 167 #define GAM7 0x84 /* Gamma Curve 7th segment input end point */ 168 #define GAM8 0x85 /* Gamma Curve 8th segment input end point */ 169 #define GAM9 0x86 /* Gamma Curve 9th segment input end point */ 170 #define GAM10 0x87 /* Gamma Curve 10th segment input end point */ 171 #define GAM11 0x88 /* Gamma Curve 11th segment input end point */ 172 #define GAM12 0x89 /* Gamma Curve 12th segment input end point */ 173 #define GAM13 0x8A /* Gamma Curve 13th segment input end point */ 174 #define GAM14 0x8B /* Gamma Curve 14th segment input end point */ 175 #define GAM15 0x8C /* Gamma Curve 15th segment input end point */ 176 #define SLOP 0x8D /* Gamma curve highest segment slope */ 177 #define DNSTH 0x8E /* De-noise threshold */ 178 #define EDGE_STRNGT 0x8F /* Edge strength control when manual mode */ 179 #define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */ 180 #define DNSOFF 0x91 /* Auto De-noise threshold control */ 181 #define EDGE_UPPER 0x92 /* Edge strength upper limit when Auto mode */ 182 #define EDGE_LOWER 0x93 /* Edge strength lower limit when Auto mode */ 183 #define MTX1 0x94 /* Matrix coefficient 1 */ 184 #define MTX2 0x95 /* Matrix coefficient 2 */ 185 #define MTX3 0x96 /* Matrix coefficient 3 */ 186 #define MTX4 0x97 /* Matrix coefficient 4 */ 187 #define MTX5 0x98 /* Matrix coefficient 5 */ 188 #define MTX6 0x99 /* Matrix coefficient 6 */ 189 #define MTX_CTRL 0x9A /* Matrix control */ 190 #define BRIGHT 0x9B /* Brightness control */ 191 #define CNTRST 0x9C /* Contrast contrast */ 192 #define CNTRST_CTRL 0x9D /* Contrast contrast center */ 193 #define UVAD_J0 0x9E /* Auto UV adjust contrast 0 */ 194 #define UVAD_J1 0x9F /* Auto UV adjust contrast 1 */ 195 #define SCAL0 0xA0 /* Scaling control 0 */ 196 #define SCAL1 0xA1 /* Scaling control 1 */ 197 #define SCAL2 0xA2 /* Scaling control 2 */ 198 #define FIFODLYM 0xA3 /* FIFO manual mode delay control */ 199 #define FIFODLYA 0xA4 /* FIFO auto mode delay control */ 200 #define SDE 0xA6 /* Special digital effect control */ 201 #define USAT 0xA7 /* U component saturation control */ 202 #define VSAT 0xA8 /* V component saturation control */ 203 /* for ov7720 */ 204 #define HUE0 0xA9 /* Hue control 0 */ 205 #define HUE1 0xAA /* Hue control 1 */ 206 /* for ov7725 */ 207 #define HUECOS 0xA9 /* Cosine value */ 208 #define HUESIN 0xAA /* Sine value */ 209 210 #define SIGN 0xAB /* Sign bit for Hue and contrast */ 211 #define DSPAUTO 0xAC /* DSP auto function ON/OFF control */ 212 213 /* 214 * register detail 215 */ 216 217 /* COM2 */ 218 #define SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */ 219 /* Output drive capability */ 220 #define OCAP_1x 0x00 /* 1x */ 221 #define OCAP_2x 0x01 /* 2x */ 222 #define OCAP_3x 0x02 /* 3x */ 223 #define OCAP_4x 0x03 /* 4x */ 224 225 /* COM3 */ 226 #define SWAP_MASK (SWAP_RGB | SWAP_YUV | SWAP_ML) 227 #define IMG_MASK (VFLIP_IMG | HFLIP_IMG) 228 229 #define VFLIP_IMG 0x80 /* Vertical flip image ON/OFF selection */ 230 #define HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF selection */ 231 #define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */ 232 #define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */ 233 #define SWAP_ML 0x08 /* Swap output MSB/LSB */ 234 /* Tri-state option for output clock */ 235 #define NOTRI_CLOCK 0x04 /* 0: Tri-state at this period */ 236 /* 1: No tri-state at this period */ 237 /* Tri-state option for output data */ 238 #define NOTRI_DATA 0x02 /* 0: Tri-state at this period */ 239 /* 1: No tri-state at this period */ 240 #define SCOLOR_TEST 0x01 /* Sensor color bar test pattern */ 241 242 /* COM4 */ 243 /* PLL frequency control */ 244 #define PLL_BYPASS 0x00 /* 00: Bypass PLL */ 245 #define PLL_4x 0x40 /* 01: PLL 4x */ 246 #define PLL_6x 0x80 /* 10: PLL 6x */ 247 #define PLL_8x 0xc0 /* 11: PLL 8x */ 248 /* AEC evaluate window */ 249 #define AEC_FULL 0x00 /* 00: Full window */ 250 #define AEC_1p2 0x10 /* 01: 1/2 window */ 251 #define AEC_1p4 0x20 /* 10: 1/4 window */ 252 #define AEC_2p3 0x30 /* 11: Low 2/3 window */ 253 254 /* COM5 */ 255 #define AFR_ON_OFF 0x80 /* Auto frame rate control ON/OFF selection */ 256 #define AFR_SPPED 0x40 /* Auto frame rate control speed selection */ 257 /* Auto frame rate max rate control */ 258 #define AFR_NO_RATE 0x00 /* No reduction of frame rate */ 259 #define AFR_1p2 0x10 /* Max reduction to 1/2 frame rate */ 260 #define AFR_1p4 0x20 /* Max reduction to 1/4 frame rate */ 261 #define AFR_1p8 0x30 /* Max reduction to 1/8 frame rate */ 262 /* Auto frame rate active point control */ 263 #define AF_2x 0x00 /* Add frame when AGC reaches 2x gain */ 264 #define AF_4x 0x04 /* Add frame when AGC reaches 4x gain */ 265 #define AF_8x 0x08 /* Add frame when AGC reaches 8x gain */ 266 #define AF_16x 0x0c /* Add frame when AGC reaches 16x gain */ 267 /* AEC max step control */ 268 #define AEC_NO_LIMIT 0x01 /* 0 : AEC incease step has limit */ 269 /* 1 : No limit to AEC increase step */ 270 271 /* COM7 */ 272 /* SCCB Register Reset */ 273 #define SCCB_RESET 0x80 /* 0 : No change */ 274 /* 1 : Resets all registers to default */ 275 /* Resolution selection */ 276 #define SLCT_MASK 0x40 /* Mask of VGA or QVGA */ 277 #define SLCT_VGA 0x00 /* 0 : VGA */ 278 #define SLCT_QVGA 0x40 /* 1 : QVGA */ 279 #define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */ 280 #define SENSOR_RAW 0x10 /* Sensor RAW */ 281 /* RGB output format control */ 282 #define FMT_MASK 0x0c /* Mask of color format */ 283 #define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */ 284 #define FMT_RGB565 0x04 /* 01 : RGB 565 */ 285 #define FMT_RGB555 0x08 /* 10 : RGB 555 */ 286 #define FMT_RGB444 0x0c /* 11 : RGB 444 */ 287 /* Output format control */ 288 #define OFMT_MASK 0x03 /* Mask of output format */ 289 #define OFMT_YUV 0x00 /* 00 : YUV */ 290 #define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */ 291 #define OFMT_RGB 0x02 /* 10 : RGB */ 292 #define OFMT_BRAW 0x03 /* 11 : Bayer RAW */ 293 294 /* COM8 */ 295 #define FAST_ALGO 0x80 /* Enable fast AGC/AEC algorithm */ 296 /* AEC Setp size limit */ 297 #define UNLMT_STEP 0x40 /* 0 : Step size is limited */ 298 /* 1 : Unlimited step size */ 299 #define BNDF_ON_OFF 0x20 /* Banding filter ON/OFF */ 300 #define AEC_BND 0x10 /* Enable AEC below banding value */ 301 #define AEC_ON_OFF 0x08 /* Fine AEC ON/OFF control */ 302 #define AGC_ON 0x04 /* AGC Enable */ 303 #define AWB_ON 0x02 /* AWB Enable */ 304 #define AEC_ON 0x01 /* AEC Enable */ 305 306 /* COM9 */ 307 #define BASE_AECAGC 0x80 /* Histogram or average based AEC/AGC */ 308 /* Automatic gain ceiling - maximum AGC value */ 309 #define GAIN_2x 0x00 /* 000 : 2x */ 310 #define GAIN_4x 0x10 /* 001 : 4x */ 311 #define GAIN_8x 0x20 /* 010 : 8x */ 312 #define GAIN_16x 0x30 /* 011 : 16x */ 313 #define GAIN_32x 0x40 /* 100 : 32x */ 314 #define GAIN_64x 0x50 /* 101 : 64x */ 315 #define GAIN_128x 0x60 /* 110 : 128x */ 316 #define DROP_VSYNC 0x04 /* Drop VSYNC output of corrupt frame */ 317 #define DROP_HREF 0x02 /* Drop HREF output of corrupt frame */ 318 319 /* COM11 */ 320 #define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */ 321 #define SGLF_TRIG 0x01 /* Single frame transfer trigger */ 322 323 /* HREF */ 324 #define HREF_VSTART_SHIFT 6 /* VSTART LSB */ 325 #define HREF_HSTART_SHIFT 4 /* HSTART 2 LSBs */ 326 #define HREF_VSIZE_SHIFT 2 /* VSIZE LSB */ 327 #define HREF_HSIZE_SHIFT 0 /* HSIZE 2 LSBs */ 328 329 /* EXHCH */ 330 #define EXHCH_VSIZE_SHIFT 2 /* VOUTSIZE LSB */ 331 #define EXHCH_HSIZE_SHIFT 0 /* HOUTSIZE 2 LSBs */ 332 333 /* DSP_CTRL1 */ 334 #define FIFO_ON 0x80 /* FIFO enable/disable selection */ 335 #define UV_ON_OFF 0x40 /* UV adjust function ON/OFF selection */ 336 #define YUV444_2_422 0x20 /* YUV444 to 422 UV channel option selection */ 337 #define CLR_MTRX_ON_OFF 0x10 /* Color matrix ON/OFF selection */ 338 #define INTPLT_ON_OFF 0x08 /* Interpolation ON/OFF selection */ 339 #define GMM_ON_OFF 0x04 /* Gamma function ON/OFF selection */ 340 #define AUTO_BLK_ON_OFF 0x02 /* Black defect auto correction ON/OFF */ 341 #define AUTO_WHT_ON_OFF 0x01 /* White define auto correction ON/OFF */ 342 343 /* DSP_CTRL3 */ 344 #define UV_MASK 0x80 /* UV output sequence option */ 345 #define UV_ON 0x80 /* ON */ 346 #define UV_OFF 0x00 /* OFF */ 347 #define CBAR_MASK 0x20 /* DSP Color bar mask */ 348 #define CBAR_ON 0x20 /* ON */ 349 #define CBAR_OFF 0x00 /* OFF */ 350 351 /* DSP_CTRL4 */ 352 #define DSP_OFMT_YUV 0x00 353 #define DSP_OFMT_RGB 0x00 354 #define DSP_OFMT_RAW8 0x02 355 #define DSP_OFMT_RAW10 0x03 356 357 /* DSPAUTO (DSP Auto Function ON/OFF Control) */ 358 #define AWB_ACTRL 0x80 /* AWB auto threshold control */ 359 #define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */ 360 #define EDGE_ACTRL 0x20 /* Edge enhancement auto strength control */ 361 #define UV_ACTRL 0x10 /* UV adjust auto slope control */ 362 #define SCAL0_ACTRL 0x08 /* Auto scaling factor control */ 363 #define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */ 364 365 #define OV772X_MAX_WIDTH VGA_WIDTH 366 #define OV772X_MAX_HEIGHT VGA_HEIGHT 367 368 /* 369 * ID 370 */ 371 #define OV7720 0x7720 372 #define OV7725 0x7721 373 #define VERSION(pid, ver) ((pid<<8)|(ver&0xFF)) 374 375 /* 376 * struct 377 */ 378 379 struct ov772x_color_format { 380 u32 code; 381 enum v4l2_colorspace colorspace; 382 u8 dsp3; 383 u8 dsp4; 384 u8 com3; 385 u8 com7; 386 }; 387 388 struct ov772x_win_size { 389 char *name; 390 unsigned char com7_bit; 391 struct v4l2_rect rect; 392 }; 393 394 struct ov772x_priv { 395 struct v4l2_subdev subdev; 396 struct v4l2_ctrl_handler hdl; 397 struct clk *clk; 398 struct ov772x_camera_info *info; 399 struct gpio_desc *pwdn_gpio; 400 struct gpio_desc *rstb_gpio; 401 const struct ov772x_color_format *cfmt; 402 const struct ov772x_win_size *win; 403 unsigned short flag_vflip:1; 404 unsigned short flag_hflip:1; 405 /* band_filter = COM8[5] ? 256 - BDBASE : 0 */ 406 unsigned short band_filter; 407 }; 408 409 /* 410 * supported color format list 411 */ 412 static const struct ov772x_color_format ov772x_cfmts[] = { 413 { 414 .code = MEDIA_BUS_FMT_YUYV8_2X8, 415 .colorspace = V4L2_COLORSPACE_SRGB, 416 .dsp3 = 0x0, 417 .dsp4 = DSP_OFMT_YUV, 418 .com3 = SWAP_YUV, 419 .com7 = OFMT_YUV, 420 }, 421 { 422 .code = MEDIA_BUS_FMT_YVYU8_2X8, 423 .colorspace = V4L2_COLORSPACE_SRGB, 424 .dsp3 = UV_ON, 425 .dsp4 = DSP_OFMT_YUV, 426 .com3 = SWAP_YUV, 427 .com7 = OFMT_YUV, 428 }, 429 { 430 .code = MEDIA_BUS_FMT_UYVY8_2X8, 431 .colorspace = V4L2_COLORSPACE_SRGB, 432 .dsp3 = 0x0, 433 .dsp4 = DSP_OFMT_YUV, 434 .com3 = 0x0, 435 .com7 = OFMT_YUV, 436 }, 437 { 438 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, 439 .colorspace = V4L2_COLORSPACE_SRGB, 440 .dsp3 = 0x0, 441 .dsp4 = DSP_OFMT_YUV, 442 .com3 = SWAP_RGB, 443 .com7 = FMT_RGB555 | OFMT_RGB, 444 }, 445 { 446 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, 447 .colorspace = V4L2_COLORSPACE_SRGB, 448 .dsp3 = 0x0, 449 .dsp4 = DSP_OFMT_YUV, 450 .com3 = 0x0, 451 .com7 = FMT_RGB555 | OFMT_RGB, 452 }, 453 { 454 .code = MEDIA_BUS_FMT_RGB565_2X8_LE, 455 .colorspace = V4L2_COLORSPACE_SRGB, 456 .dsp3 = 0x0, 457 .dsp4 = DSP_OFMT_YUV, 458 .com3 = SWAP_RGB, 459 .com7 = FMT_RGB565 | OFMT_RGB, 460 }, 461 { 462 .code = MEDIA_BUS_FMT_RGB565_2X8_BE, 463 .colorspace = V4L2_COLORSPACE_SRGB, 464 .dsp3 = 0x0, 465 .dsp4 = DSP_OFMT_YUV, 466 .com3 = 0x0, 467 .com7 = FMT_RGB565 | OFMT_RGB, 468 }, 469 { 470 /* Setting DSP4 to DSP_OFMT_RAW8 still gives 10-bit output, 471 * regardless of the COM7 value. We can thus only support 10-bit 472 * Bayer until someone figures it out. 473 */ 474 .code = MEDIA_BUS_FMT_SBGGR10_1X10, 475 .colorspace = V4L2_COLORSPACE_SRGB, 476 .dsp3 = 0x0, 477 .dsp4 = DSP_OFMT_RAW10, 478 .com3 = 0x0, 479 .com7 = SENSOR_RAW | OFMT_BRAW, 480 }, 481 }; 482 483 484 /* 485 * window size list 486 */ 487 488 static const struct ov772x_win_size ov772x_win_sizes[] = { 489 { 490 .name = "VGA", 491 .com7_bit = SLCT_VGA, 492 .rect = { 493 .left = 140, 494 .top = 14, 495 .width = VGA_WIDTH, 496 .height = VGA_HEIGHT, 497 }, 498 }, { 499 .name = "QVGA", 500 .com7_bit = SLCT_QVGA, 501 .rect = { 502 .left = 252, 503 .top = 6, 504 .width = QVGA_WIDTH, 505 .height = QVGA_HEIGHT, 506 }, 507 }, 508 }; 509 510 /* 511 * general function 512 */ 513 514 static struct ov772x_priv *to_ov772x(struct v4l2_subdev *sd) 515 { 516 return container_of(sd, struct ov772x_priv, subdev); 517 } 518 519 static inline int ov772x_read(struct i2c_client *client, u8 addr) 520 { 521 return i2c_smbus_read_byte_data(client, addr); 522 } 523 524 static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value) 525 { 526 return i2c_smbus_write_byte_data(client, addr, value); 527 } 528 529 static int ov772x_mask_set(struct i2c_client *client, u8 command, u8 mask, 530 u8 set) 531 { 532 s32 val = ov772x_read(client, command); 533 if (val < 0) 534 return val; 535 536 val &= ~mask; 537 val |= set & mask; 538 539 return ov772x_write(client, command, val); 540 } 541 542 static int ov772x_reset(struct i2c_client *client) 543 { 544 int ret; 545 546 ret = ov772x_write(client, COM7, SCCB_RESET); 547 if (ret < 0) 548 return ret; 549 550 msleep(1); 551 552 return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); 553 } 554 555 /* 556 * subdev ops 557 */ 558 559 static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) 560 { 561 struct i2c_client *client = v4l2_get_subdevdata(sd); 562 struct ov772x_priv *priv = to_ov772x(sd); 563 564 if (!enable) { 565 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); 566 return 0; 567 } 568 569 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); 570 571 dev_dbg(&client->dev, "format %d, win %s\n", 572 priv->cfmt->code, priv->win->name); 573 574 return 0; 575 } 576 577 static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl) 578 { 579 struct ov772x_priv *priv = container_of(ctrl->handler, 580 struct ov772x_priv, hdl); 581 struct v4l2_subdev *sd = &priv->subdev; 582 struct i2c_client *client = v4l2_get_subdevdata(sd); 583 int ret = 0; 584 u8 val; 585 586 switch (ctrl->id) { 587 case V4L2_CID_VFLIP: 588 val = ctrl->val ? VFLIP_IMG : 0x00; 589 priv->flag_vflip = ctrl->val; 590 if (priv->info->flags & OV772X_FLAG_VFLIP) 591 val ^= VFLIP_IMG; 592 return ov772x_mask_set(client, COM3, VFLIP_IMG, val); 593 case V4L2_CID_HFLIP: 594 val = ctrl->val ? HFLIP_IMG : 0x00; 595 priv->flag_hflip = ctrl->val; 596 if (priv->info->flags & OV772X_FLAG_HFLIP) 597 val ^= HFLIP_IMG; 598 return ov772x_mask_set(client, COM3, HFLIP_IMG, val); 599 case V4L2_CID_BAND_STOP_FILTER: 600 if (!ctrl->val) { 601 /* Switch the filter off, it is on now */ 602 ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff); 603 if (!ret) 604 ret = ov772x_mask_set(client, COM8, 605 BNDF_ON_OFF, 0); 606 } else { 607 /* Switch the filter on, set AEC low limit */ 608 val = 256 - ctrl->val; 609 ret = ov772x_mask_set(client, COM8, 610 BNDF_ON_OFF, BNDF_ON_OFF); 611 if (!ret) 612 ret = ov772x_mask_set(client, BDBASE, 613 0xff, val); 614 } 615 if (!ret) 616 priv->band_filter = ctrl->val; 617 return ret; 618 } 619 620 return -EINVAL; 621 } 622 623 #ifdef CONFIG_VIDEO_ADV_DEBUG 624 static int ov772x_g_register(struct v4l2_subdev *sd, 625 struct v4l2_dbg_register *reg) 626 { 627 struct i2c_client *client = v4l2_get_subdevdata(sd); 628 int ret; 629 630 reg->size = 1; 631 if (reg->reg > 0xff) 632 return -EINVAL; 633 634 ret = ov772x_read(client, reg->reg); 635 if (ret < 0) 636 return ret; 637 638 reg->val = (__u64)ret; 639 640 return 0; 641 } 642 643 static int ov772x_s_register(struct v4l2_subdev *sd, 644 const struct v4l2_dbg_register *reg) 645 { 646 struct i2c_client *client = v4l2_get_subdevdata(sd); 647 648 if (reg->reg > 0xff || 649 reg->val > 0xff) 650 return -EINVAL; 651 652 return ov772x_write(client, reg->reg, reg->val); 653 } 654 #endif 655 656 static int ov772x_power_on(struct ov772x_priv *priv) 657 { 658 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); 659 int ret; 660 661 if (priv->clk) { 662 ret = clk_prepare_enable(priv->clk); 663 if (ret) 664 return ret; 665 } 666 667 if (priv->pwdn_gpio) { 668 gpiod_set_value(priv->pwdn_gpio, 1); 669 usleep_range(500, 1000); 670 } 671 672 /* 673 * FIXME: The reset signal is connected to a shared GPIO on some 674 * platforms (namely the SuperH Migo-R). Until a framework becomes 675 * available to handle this cleanly, request the GPIO temporarily 676 * to avoid conflicts. 677 */ 678 priv->rstb_gpio = gpiod_get_optional(&client->dev, "rstb", 679 GPIOD_OUT_LOW); 680 if (IS_ERR(priv->rstb_gpio)) { 681 dev_info(&client->dev, "Unable to get GPIO \"rstb\""); 682 return PTR_ERR(priv->rstb_gpio); 683 } 684 685 if (priv->rstb_gpio) { 686 gpiod_set_value(priv->rstb_gpio, 1); 687 usleep_range(500, 1000); 688 gpiod_set_value(priv->rstb_gpio, 0); 689 usleep_range(500, 1000); 690 691 gpiod_put(priv->rstb_gpio); 692 } 693 694 return 0; 695 } 696 697 static int ov772x_power_off(struct ov772x_priv *priv) 698 { 699 clk_disable_unprepare(priv->clk); 700 701 if (priv->pwdn_gpio) { 702 gpiod_set_value(priv->pwdn_gpio, 0); 703 usleep_range(500, 1000); 704 } 705 706 return 0; 707 } 708 709 static int ov772x_s_power(struct v4l2_subdev *sd, int on) 710 { 711 struct ov772x_priv *priv = to_ov772x(sd); 712 713 return on ? ov772x_power_on(priv) : 714 ov772x_power_off(priv); 715 } 716 717 static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) 718 { 719 const struct ov772x_win_size *win = &ov772x_win_sizes[0]; 720 u32 best_diff = UINT_MAX; 721 unsigned int i; 722 723 for (i = 0; i < ARRAY_SIZE(ov772x_win_sizes); ++i) { 724 u32 diff = abs(width - ov772x_win_sizes[i].rect.width) 725 + abs(height - ov772x_win_sizes[i].rect.height); 726 if (diff < best_diff) { 727 best_diff = diff; 728 win = &ov772x_win_sizes[i]; 729 } 730 } 731 732 return win; 733 } 734 735 static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf, 736 const struct ov772x_color_format **cfmt, 737 const struct ov772x_win_size **win) 738 { 739 unsigned int i; 740 741 /* Select a format. */ 742 *cfmt = &ov772x_cfmts[0]; 743 744 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { 745 if (mf->code == ov772x_cfmts[i].code) { 746 *cfmt = &ov772x_cfmts[i]; 747 break; 748 } 749 } 750 751 /* Select a window size. */ 752 *win = ov772x_select_win(mf->width, mf->height); 753 } 754 755 static int ov772x_set_params(struct ov772x_priv *priv, 756 const struct ov772x_color_format *cfmt, 757 const struct ov772x_win_size *win) 758 { 759 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); 760 int ret; 761 u8 val; 762 763 /* 764 * reset hardware 765 */ 766 ov772x_reset(client); 767 768 /* 769 * Edge Ctrl 770 */ 771 if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) { 772 773 /* 774 * Manual Edge Control Mode 775 * 776 * Edge auto strength bit is set by default. 777 * Remove it when manual mode. 778 */ 779 780 ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00); 781 if (ret < 0) 782 goto ov772x_set_fmt_error; 783 784 ret = ov772x_mask_set(client, 785 EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK, 786 priv->info->edgectrl.threshold); 787 if (ret < 0) 788 goto ov772x_set_fmt_error; 789 790 ret = ov772x_mask_set(client, 791 EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK, 792 priv->info->edgectrl.strength); 793 if (ret < 0) 794 goto ov772x_set_fmt_error; 795 796 } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) { 797 /* 798 * Auto Edge Control Mode 799 * 800 * set upper and lower limit 801 */ 802 ret = ov772x_mask_set(client, 803 EDGE_UPPER, OV772X_EDGE_UPPER_MASK, 804 priv->info->edgectrl.upper); 805 if (ret < 0) 806 goto ov772x_set_fmt_error; 807 808 ret = ov772x_mask_set(client, 809 EDGE_LOWER, OV772X_EDGE_LOWER_MASK, 810 priv->info->edgectrl.lower); 811 if (ret < 0) 812 goto ov772x_set_fmt_error; 813 } 814 815 /* Format and window size */ 816 ret = ov772x_write(client, HSTART, win->rect.left >> 2); 817 if (ret < 0) 818 goto ov772x_set_fmt_error; 819 ret = ov772x_write(client, HSIZE, win->rect.width >> 2); 820 if (ret < 0) 821 goto ov772x_set_fmt_error; 822 ret = ov772x_write(client, VSTART, win->rect.top >> 1); 823 if (ret < 0) 824 goto ov772x_set_fmt_error; 825 ret = ov772x_write(client, VSIZE, win->rect.height >> 1); 826 if (ret < 0) 827 goto ov772x_set_fmt_error; 828 ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2); 829 if (ret < 0) 830 goto ov772x_set_fmt_error; 831 ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1); 832 if (ret < 0) 833 goto ov772x_set_fmt_error; 834 ret = ov772x_write(client, HREF, 835 ((win->rect.top & 1) << HREF_VSTART_SHIFT) | 836 ((win->rect.left & 3) << HREF_HSTART_SHIFT) | 837 ((win->rect.height & 1) << HREF_VSIZE_SHIFT) | 838 ((win->rect.width & 3) << HREF_HSIZE_SHIFT)); 839 if (ret < 0) 840 goto ov772x_set_fmt_error; 841 ret = ov772x_write(client, EXHCH, 842 ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) | 843 ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT)); 844 if (ret < 0) 845 goto ov772x_set_fmt_error; 846 847 /* 848 * set DSP_CTRL3 849 */ 850 val = cfmt->dsp3; 851 if (val) { 852 ret = ov772x_mask_set(client, 853 DSP_CTRL3, UV_MASK, val); 854 if (ret < 0) 855 goto ov772x_set_fmt_error; 856 } 857 858 /* DSP_CTRL4: AEC reference point and DSP output format. */ 859 if (cfmt->dsp4) { 860 ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4); 861 if (ret < 0) 862 goto ov772x_set_fmt_error; 863 } 864 865 /* 866 * set COM3 867 */ 868 val = cfmt->com3; 869 if (priv->info->flags & OV772X_FLAG_VFLIP) 870 val |= VFLIP_IMG; 871 if (priv->info->flags & OV772X_FLAG_HFLIP) 872 val |= HFLIP_IMG; 873 if (priv->flag_vflip) 874 val ^= VFLIP_IMG; 875 if (priv->flag_hflip) 876 val ^= HFLIP_IMG; 877 878 ret = ov772x_mask_set(client, 879 COM3, SWAP_MASK | IMG_MASK, val); 880 if (ret < 0) 881 goto ov772x_set_fmt_error; 882 883 /* COM7: Sensor resolution and output format control. */ 884 ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7); 885 if (ret < 0) 886 goto ov772x_set_fmt_error; 887 888 /* 889 * set COM8 890 */ 891 if (priv->band_filter) { 892 ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, 1); 893 if (!ret) 894 ret = ov772x_mask_set(client, BDBASE, 895 0xff, 256 - priv->band_filter); 896 if (ret < 0) 897 goto ov772x_set_fmt_error; 898 } 899 900 return ret; 901 902 ov772x_set_fmt_error: 903 904 ov772x_reset(client); 905 906 return ret; 907 } 908 909 static int ov772x_get_selection(struct v4l2_subdev *sd, 910 struct v4l2_subdev_pad_config *cfg, 911 struct v4l2_subdev_selection *sel) 912 { 913 struct ov772x_priv *priv = to_ov772x(sd); 914 915 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 916 return -EINVAL; 917 918 sel->r.left = 0; 919 sel->r.top = 0; 920 switch (sel->target) { 921 case V4L2_SEL_TGT_CROP_BOUNDS: 922 case V4L2_SEL_TGT_CROP_DEFAULT: 923 case V4L2_SEL_TGT_CROP: 924 sel->r.width = priv->win->rect.width; 925 sel->r.height = priv->win->rect.height; 926 return 0; 927 default: 928 return -EINVAL; 929 } 930 } 931 932 static int ov772x_get_fmt(struct v4l2_subdev *sd, 933 struct v4l2_subdev_pad_config *cfg, 934 struct v4l2_subdev_format *format) 935 { 936 struct v4l2_mbus_framefmt *mf = &format->format; 937 struct ov772x_priv *priv = to_ov772x(sd); 938 939 if (format->pad) 940 return -EINVAL; 941 942 mf->width = priv->win->rect.width; 943 mf->height = priv->win->rect.height; 944 mf->code = priv->cfmt->code; 945 mf->colorspace = priv->cfmt->colorspace; 946 mf->field = V4L2_FIELD_NONE; 947 948 return 0; 949 } 950 951 static int ov772x_set_fmt(struct v4l2_subdev *sd, 952 struct v4l2_subdev_pad_config *cfg, 953 struct v4l2_subdev_format *format) 954 { 955 struct ov772x_priv *priv = to_ov772x(sd); 956 struct v4l2_mbus_framefmt *mf = &format->format; 957 const struct ov772x_color_format *cfmt; 958 const struct ov772x_win_size *win; 959 int ret; 960 961 if (format->pad) 962 return -EINVAL; 963 964 ov772x_select_params(mf, &cfmt, &win); 965 966 mf->code = cfmt->code; 967 mf->width = win->rect.width; 968 mf->height = win->rect.height; 969 mf->field = V4L2_FIELD_NONE; 970 mf->colorspace = cfmt->colorspace; 971 mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 972 mf->quantization = V4L2_QUANTIZATION_DEFAULT; 973 mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; 974 975 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { 976 cfg->try_fmt = *mf; 977 return 0; 978 } 979 980 ret = ov772x_set_params(priv, cfmt, win); 981 if (ret < 0) 982 return ret; 983 984 priv->win = win; 985 priv->cfmt = cfmt; 986 return 0; 987 } 988 989 static int ov772x_video_probe(struct ov772x_priv *priv) 990 { 991 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); 992 u8 pid, ver; 993 const char *devname; 994 int ret; 995 996 ret = ov772x_s_power(&priv->subdev, 1); 997 if (ret < 0) 998 return ret; 999 1000 /* 1001 * check and show product ID and manufacturer ID 1002 */ 1003 pid = ov772x_read(client, PID); 1004 ver = ov772x_read(client, VER); 1005 1006 switch (VERSION(pid, ver)) { 1007 case OV7720: 1008 devname = "ov7720"; 1009 break; 1010 case OV7725: 1011 devname = "ov7725"; 1012 break; 1013 default: 1014 dev_err(&client->dev, 1015 "Product ID error %x:%x\n", pid, ver); 1016 ret = -ENODEV; 1017 goto done; 1018 } 1019 1020 dev_info(&client->dev, 1021 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 1022 devname, 1023 pid, 1024 ver, 1025 ov772x_read(client, MIDH), 1026 ov772x_read(client, MIDL)); 1027 ret = v4l2_ctrl_handler_setup(&priv->hdl); 1028 1029 done: 1030 ov772x_s_power(&priv->subdev, 0); 1031 return ret; 1032 } 1033 1034 static const struct v4l2_ctrl_ops ov772x_ctrl_ops = { 1035 .s_ctrl = ov772x_s_ctrl, 1036 }; 1037 1038 static const struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { 1039 #ifdef CONFIG_VIDEO_ADV_DEBUG 1040 .g_register = ov772x_g_register, 1041 .s_register = ov772x_s_register, 1042 #endif 1043 .s_power = ov772x_s_power, 1044 }; 1045 1046 static int ov772x_enum_mbus_code(struct v4l2_subdev *sd, 1047 struct v4l2_subdev_pad_config *cfg, 1048 struct v4l2_subdev_mbus_code_enum *code) 1049 { 1050 if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts)) 1051 return -EINVAL; 1052 1053 code->code = ov772x_cfmts[code->index].code; 1054 return 0; 1055 } 1056 1057 static const struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1058 .s_stream = ov772x_s_stream, 1059 }; 1060 1061 static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { 1062 .enum_mbus_code = ov772x_enum_mbus_code, 1063 .get_selection = ov772x_get_selection, 1064 .get_fmt = ov772x_get_fmt, 1065 .set_fmt = ov772x_set_fmt, 1066 }; 1067 1068 static const struct v4l2_subdev_ops ov772x_subdev_ops = { 1069 .core = &ov772x_subdev_core_ops, 1070 .video = &ov772x_subdev_video_ops, 1071 .pad = &ov772x_subdev_pad_ops, 1072 }; 1073 1074 /* 1075 * i2c_driver function 1076 */ 1077 1078 static int ov772x_probe(struct i2c_client *client, 1079 const struct i2c_device_id *did) 1080 { 1081 struct ov772x_priv *priv; 1082 struct i2c_adapter *adapter = client->adapter; 1083 int ret; 1084 1085 if (!client->dev.platform_data) { 1086 dev_err(&client->dev, "Missing ov772x platform data\n"); 1087 return -EINVAL; 1088 } 1089 1090 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 1091 I2C_FUNC_PROTOCOL_MANGLING)) { 1092 dev_err(&adapter->dev, 1093 "I2C-Adapter doesn't support SMBUS_BYTE_DATA or PROTOCOL_MANGLING\n"); 1094 return -EIO; 1095 } 1096 client->flags |= I2C_CLIENT_SCCB; 1097 1098 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); 1099 if (!priv) 1100 return -ENOMEM; 1101 1102 priv->info = client->dev.platform_data; 1103 1104 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); 1105 v4l2_ctrl_handler_init(&priv->hdl, 3); 1106 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, 1107 V4L2_CID_VFLIP, 0, 1, 1, 0); 1108 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, 1109 V4L2_CID_HFLIP, 0, 1, 1, 0); 1110 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, 1111 V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0); 1112 priv->subdev.ctrl_handler = &priv->hdl; 1113 if (priv->hdl.error) 1114 return priv->hdl.error; 1115 1116 priv->clk = clk_get(&client->dev, "xclk"); 1117 if (IS_ERR(priv->clk)) { 1118 dev_err(&client->dev, "Unable to get xclk clock\n"); 1119 ret = PTR_ERR(priv->clk); 1120 goto error_ctrl_free; 1121 } 1122 1123 priv->pwdn_gpio = gpiod_get_optional(&client->dev, "pwdn", 1124 GPIOD_OUT_LOW); 1125 if (IS_ERR(priv->pwdn_gpio)) { 1126 dev_info(&client->dev, "Unable to get GPIO \"pwdn\""); 1127 ret = PTR_ERR(priv->pwdn_gpio); 1128 goto error_clk_put; 1129 } 1130 1131 ret = ov772x_video_probe(priv); 1132 if (ret < 0) 1133 goto error_gpio_put; 1134 1135 priv->cfmt = &ov772x_cfmts[0]; 1136 priv->win = &ov772x_win_sizes[0]; 1137 1138 ret = v4l2_async_register_subdev(&priv->subdev); 1139 if (ret) 1140 goto error_gpio_put; 1141 1142 return 0; 1143 1144 error_gpio_put: 1145 if (priv->pwdn_gpio) 1146 gpiod_put(priv->pwdn_gpio); 1147 error_clk_put: 1148 clk_put(priv->clk); 1149 error_ctrl_free: 1150 v4l2_ctrl_handler_free(&priv->hdl); 1151 1152 return ret; 1153 } 1154 1155 static int ov772x_remove(struct i2c_client *client) 1156 { 1157 struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client)); 1158 1159 clk_put(priv->clk); 1160 if (priv->pwdn_gpio) 1161 gpiod_put(priv->pwdn_gpio); 1162 v4l2_device_unregister_subdev(&priv->subdev); 1163 v4l2_ctrl_handler_free(&priv->hdl); 1164 return 0; 1165 } 1166 1167 static const struct i2c_device_id ov772x_id[] = { 1168 { "ov772x", 0 }, 1169 { } 1170 }; 1171 MODULE_DEVICE_TABLE(i2c, ov772x_id); 1172 1173 static struct i2c_driver ov772x_i2c_driver = { 1174 .driver = { 1175 .name = "ov772x", 1176 }, 1177 .probe = ov772x_probe, 1178 .remove = ov772x_remove, 1179 .id_table = ov772x_id, 1180 }; 1181 1182 module_i2c_driver(ov772x_i2c_driver); 1183 1184 MODULE_DESCRIPTION("V4L2 driver for OV772x image sensor"); 1185 MODULE_AUTHOR("Kuninori Morimoto"); 1186 MODULE_LICENSE("GPL v2"); 1187