linux/drivers/media/video/ov2640.c
<<
>>
Prefs
   1/*
   2 * ov2640 Camera Driver
   3 *
   4 * Copyright (C) 2010 Alberto Panizzo <maramaopercheseimorto@gmail.com>
   5 *
   6 * Based on ov772x, ov9640 drivers and previous non merged implementations.
   7 *
   8 * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
   9 * Copyright (C) 2006, OmniVision
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15
  16#include <linux/init.h>
  17#include <linux/module.h>
  18#include <linux/i2c.h>
  19#include <linux/slab.h>
  20#include <linux/delay.h>
  21#include <linux/v4l2-mediabus.h>
  22#include <linux/videodev2.h>
  23
  24#include <media/soc_camera.h>
  25#include <media/v4l2-chip-ident.h>
  26#include <media/v4l2-subdev.h>
  27#include <media/v4l2-ctrls.h>
  28
  29#define VAL_SET(x, mask, rshift, lshift)  \
  30                ((((x) >> rshift) & mask) << lshift)
  31/*
  32 * DSP registers
  33 * register offset for BANK_SEL == BANK_SEL_DSP
  34 */
  35#define R_BYPASS    0x05 /* Bypass DSP */
  36#define   R_BYPASS_DSP_BYPAS    0x01 /* Bypass DSP, sensor out directly */
  37#define   R_BYPASS_USE_DSP      0x00 /* Use the internal DSP */
  38#define QS          0x44 /* Quantization Scale Factor */
  39#define CTRLI       0x50
  40#define   CTRLI_LP_DP           0x80
  41#define   CTRLI_ROUND           0x40
  42#define   CTRLI_V_DIV_SET(x)    VAL_SET(x, 0x3, 0, 3)
  43#define   CTRLI_H_DIV_SET(x)    VAL_SET(x, 0x3, 0, 0)
  44#define HSIZE       0x51 /* H_SIZE[7:0] (real/4) */
  45#define   HSIZE_SET(x)          VAL_SET(x, 0xFF, 2, 0)
  46#define VSIZE       0x52 /* V_SIZE[7:0] (real/4) */
  47#define   VSIZE_SET(x)          VAL_SET(x, 0xFF, 2, 0)
  48#define XOFFL       0x53 /* OFFSET_X[7:0] */
  49#define   XOFFL_SET(x)          VAL_SET(x, 0xFF, 0, 0)
  50#define YOFFL       0x54 /* OFFSET_Y[7:0] */
  51#define   YOFFL_SET(x)          VAL_SET(x, 0xFF, 0, 0)
  52#define VHYX        0x55 /* Offset and size completion */
  53#define   VHYX_VSIZE_SET(x)     VAL_SET(x, 0x1, (8+2), 7)
  54#define   VHYX_HSIZE_SET(x)     VAL_SET(x, 0x1, (8+2), 3)
  55#define   VHYX_YOFF_SET(x)      VAL_SET(x, 0x3, 8, 4)
  56#define   VHYX_XOFF_SET(x)      VAL_SET(x, 0x3, 8, 0)
  57#define DPRP        0x56
  58#define TEST        0x57 /* Horizontal size completion */
  59#define   TEST_HSIZE_SET(x)     VAL_SET(x, 0x1, (9+2), 7)
  60#define ZMOW        0x5A /* Zoom: Out Width  OUTW[7:0] (real/4) */
  61#define   ZMOW_OUTW_SET(x)      VAL_SET(x, 0xFF, 2, 0)
  62#define ZMOH        0x5B /* Zoom: Out Height OUTH[7:0] (real/4) */
  63#define   ZMOH_OUTH_SET(x)      VAL_SET(x, 0xFF, 2, 0)
  64#define ZMHH        0x5C /* Zoom: Speed and H&W completion */
  65#define   ZMHH_ZSPEED_SET(x)    VAL_SET(x, 0x0F, 0, 4)
  66#define   ZMHH_OUTH_SET(x)      VAL_SET(x, 0x1, (8+2), 2)
  67#define   ZMHH_OUTW_SET(x)      VAL_SET(x, 0x3, (8+2), 0)
  68#define BPADDR      0x7C /* SDE Indirect Register Access: Address */
  69#define BPDATA      0x7D /* SDE Indirect Register Access: Data */
  70#define CTRL2       0x86 /* DSP Module enable 2 */
  71#define   CTRL2_DCW_EN          0x20
  72#define   CTRL2_SDE_EN          0x10
  73#define   CTRL2_UV_ADJ_EN       0x08
  74#define   CTRL2_UV_AVG_EN       0x04
  75#define   CTRL2_CMX_EN          0x01
  76#define CTRL3       0x87 /* DSP Module enable 3 */
  77#define   CTRL3_BPC_EN          0x80
  78#define   CTRL3_WPC_EN          0x40
  79#define SIZEL       0x8C /* Image Size Completion */
  80#define   SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6)
  81#define   SIZEL_HSIZE8_SET(x)    VAL_SET(x, 0x7, 0, 3)
  82#define   SIZEL_VSIZE8_SET(x)    VAL_SET(x, 0x7, 0, 0)
  83#define HSIZE8      0xC0 /* Image Horizontal Size HSIZE[10:3] */
  84#define   HSIZE8_SET(x)         VAL_SET(x, 0xFF, 3, 0)
  85#define VSIZE8      0xC1 /* Image Vertical Size VSIZE[10:3] */
  86#define   VSIZE8_SET(x)         VAL_SET(x, 0xFF, 3, 0)
  87#define CTRL0       0xC2 /* DSP Module enable 0 */
  88#define   CTRL0_AEC_EN       0x80
  89#define   CTRL0_AEC_SEL      0x40
  90#define   CTRL0_STAT_SEL     0x20
  91#define   CTRL0_VFIRST       0x10
  92#define   CTRL0_YUV422       0x08
  93#define   CTRL0_YUV_EN       0x04
  94#define   CTRL0_RGB_EN       0x02
  95#define   CTRL0_RAW_EN       0x01
  96#define CTRL1       0xC3 /* DSP Module enable 1 */
  97#define   CTRL1_CIP          0x80
  98#define   CTRL1_DMY          0x40
  99#define   CTRL1_RAW_GMA      0x20
 100#define   CTRL1_DG           0x10
 101#define   CTRL1_AWB          0x08
 102#define   CTRL1_AWB_GAIN     0x04
 103#define   CTRL1_LENC         0x02
 104#define   CTRL1_PRE          0x01
 105#define R_DVP_SP    0xD3 /* DVP output speed control */
 106#define   R_DVP_SP_AUTO_MODE 0x80
 107#define   R_DVP_SP_DVP_MASK  0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0);
 108                                   *          = sysclk (48)/(2*[6:0]) (RAW);*/
 109#define IMAGE_MODE  0xDA /* Image Output Format Select */
 110#define   IMAGE_MODE_Y8_DVP_EN   0x40
 111#define   IMAGE_MODE_JPEG_EN     0x10
 112#define   IMAGE_MODE_YUV422      0x00
 113#define   IMAGE_MODE_RAW10       0x04 /* (DVP) */
 114#define   IMAGE_MODE_RGB565      0x08
 115#define   IMAGE_MODE_HREF_VSYNC  0x02 /* HREF timing select in DVP JPEG output
 116                                       * mode (0 for HREF is same as sensor) */
 117#define   IMAGE_MODE_LBYTE_FIRST 0x01 /* Byte swap enable for DVP
 118                                       *    1: Low byte first UYVY (C2[4] =0)
 119                                       *        VYUY (C2[4] =1)
 120                                       *    0: High byte first YUYV (C2[4]=0)
 121                                       *        YVYU (C2[4] = 1) */
 122#define RESET       0xE0 /* Reset */
 123#define   RESET_MICROC       0x40
 124#define   RESET_SCCB         0x20
 125#define   RESET_JPEG         0x10
 126#define   RESET_DVP          0x04
 127#define   RESET_IPU          0x02
 128#define   RESET_CIF          0x01
 129#define REGED       0xED /* Register ED */
 130#define   REGED_CLK_OUT_DIS  0x10
 131#define MS_SP       0xF0 /* SCCB Master Speed */
 132#define SS_ID       0xF7 /* SCCB Slave ID */
 133#define SS_CTRL     0xF8 /* SCCB Slave Control */
 134#define   SS_CTRL_ADD_AUTO_INC  0x20
 135#define   SS_CTRL_EN            0x08
 136#define   SS_CTRL_DELAY_CLK     0x04
 137#define   SS_CTRL_ACC_EN        0x02
 138#define   SS_CTRL_SEN_PASS_THR  0x01
 139#define MC_BIST     0xF9 /* Microcontroller misc register */
 140#define   MC_BIST_RESET           0x80 /* Microcontroller Reset */
 141#define   MC_BIST_BOOT_ROM_SEL    0x40
 142#define   MC_BIST_12KB_SEL        0x20
 143#define   MC_BIST_12KB_MASK       0x30
 144#define   MC_BIST_512KB_SEL       0x08
 145#define   MC_BIST_512KB_MASK      0x0C
 146#define   MC_BIST_BUSY_BIT_R      0x02
 147#define   MC_BIST_MC_RES_ONE_SH_W 0x02
 148#define   MC_BIST_LAUNCH          0x01
 149#define BANK_SEL    0xFF /* Register Bank Select */
 150#define   BANK_SEL_DSP     0x00
 151#define   BANK_SEL_SENS    0x01
 152
 153/*
 154 * Sensor registers
 155 * register offset for BANK_SEL == BANK_SEL_SENS
 156 */
 157#define GAIN        0x00 /* AGC - Gain control gain setting */
 158#define COM1        0x03 /* Common control 1 */
 159#define   COM1_1_DUMMY_FR          0x40
 160#define   COM1_3_DUMMY_FR          0x80
 161#define   COM1_7_DUMMY_FR          0xC0
 162#define   COM1_VWIN_LSB_UXGA       0x0F
 163#define   COM1_VWIN_LSB_SVGA       0x0A
 164#define   COM1_VWIN_LSB_CIF        0x06
 165#define REG04       0x04 /* Register 04 */
 166#define   REG04_DEF             0x20 /* Always set */
 167#define   REG04_HFLIP_IMG       0x80 /* Horizontal mirror image ON/OFF */
 168#define   REG04_VFLIP_IMG       0x40 /* Vertical flip image ON/OFF */
 169#define   REG04_VREF_EN         0x10
 170#define   REG04_HREF_EN         0x08
 171#define   REG04_AEC_SET(x)      VAL_SET(x, 0x3, 0, 0)
 172#define REG08       0x08 /* Frame Exposure One-pin Control Pre-charge Row Num */
 173#define COM2        0x09 /* Common control 2 */
 174#define   COM2_SOFT_SLEEP_MODE  0x10 /* Soft sleep mode */
 175                                     /* Output drive capability */
 176#define   COM2_OCAP_Nx_SET(N)   (((N) - 1) & 0x03) /* N = [1x .. 4x] */
 177#define PID         0x0A /* Product ID Number MSB */
 178#define VER         0x0B /* Product ID Number LSB */
 179#define COM3        0x0C /* Common control 3 */
 180#define   COM3_BAND_50H        0x04 /* 0 For Banding at 60H */
 181#define   COM3_BAND_AUTO       0x02 /* Auto Banding */
 182#define   COM3_SING_FR_SNAPSH  0x01 /* 0 For enable live video output after the
 183                                     * snapshot sequence*/
 184#define AEC         0x10 /* AEC[9:2] Exposure Value */
 185#define CLKRC       0x11 /* Internal clock */
 186#define   CLKRC_EN             0x80
 187#define   CLKRC_DIV_SET(x)     (((x) - 1) & 0x1F) /* CLK = XVCLK/(x) */
 188#define COM7        0x12 /* Common control 7 */
 189#define   COM7_SRST            0x80 /* Initiates system reset. All registers are
 190                                     * set to factory default values after which
 191                                     * the chip resumes normal operation */
 192#define   COM7_RES_UXGA        0x00 /* Resolution selectors for UXGA */
 193#define   COM7_RES_SVGA        0x40 /* SVGA */
 194#define   COM7_RES_CIF         0x20 /* CIF */
 195#define   COM7_ZOOM_EN         0x04 /* Enable Zoom mode */
 196#define   COM7_COLOR_BAR_TEST  0x02 /* Enable Color Bar Test Pattern */
 197#define COM8        0x13 /* Common control 8 */
 198#define   COM8_DEF             0xC0 /* Banding filter ON/OFF */
 199#define   COM8_BNDF_EN         0x20 /* Banding filter ON/OFF */
 200#define   COM8_AGC_EN          0x04 /* AGC Auto/Manual control selection */
 201#define   COM8_AEC_EN          0x01 /* Auto/Manual Exposure control */
 202#define COM9        0x14 /* Common control 9
 203                          * Automatic gain ceiling - maximum AGC value [7:5]*/
 204#define   COM9_AGC_GAIN_2x     0x00 /* 000 :   2x */
 205#define   COM9_AGC_GAIN_4x     0x20 /* 001 :   4x */
 206#define   COM9_AGC_GAIN_8x     0x40 /* 010 :   8x */
 207#define   COM9_AGC_GAIN_16x    0x60 /* 011 :  16x */
 208#define   COM9_AGC_GAIN_32x    0x80 /* 100 :  32x */
 209#define   COM9_AGC_GAIN_64x    0xA0 /* 101 :  64x */
 210#define   COM9_AGC_GAIN_128x   0xC0 /* 110 : 128x */
 211#define COM10       0x15 /* Common control 10 */
 212#define   COM10_PCLK_HREF      0x20 /* PCLK output qualified by HREF */
 213#define   COM10_PCLK_RISE      0x10 /* Data is updated at the rising edge of
 214                                     * PCLK (user can latch data at the next
 215                                     * falling edge of PCLK).
 216                                     * 0 otherwise. */
 217#define   COM10_HREF_INV       0x08 /* Invert HREF polarity:
 218                                     * HREF negative for valid data*/
 219#define   COM10_VSINC_INV      0x02 /* Invert VSYNC polarity */
 220#define HSTART      0x17 /* Horizontal Window start MSB 8 bit */
 221#define HEND        0x18 /* Horizontal Window end MSB 8 bit */
 222#define VSTART      0x19 /* Vertical Window start MSB 8 bit */
 223#define VEND        0x1A /* Vertical Window end MSB 8 bit */
 224#define MIDH        0x1C /* Manufacturer ID byte - high */
 225#define MIDL        0x1D /* Manufacturer ID byte - low  */
 226#define AEW         0x24 /* AGC/AEC - Stable operating region (upper limit) */
 227#define AEB         0x25 /* AGC/AEC - Stable operating region (lower limit) */
 228#define VV          0x26 /* AGC/AEC Fast mode operating region */
 229#define   VV_HIGH_TH_SET(x)      VAL_SET(x, 0xF, 0, 4)
 230#define   VV_LOW_TH_SET(x)       VAL_SET(x, 0xF, 0, 0)
 231#define REG2A       0x2A /* Dummy pixel insert MSB */
 232#define FRARL       0x2B /* Dummy pixel insert LSB */
 233#define ADDVFL      0x2D /* LSB of insert dummy lines in Vertical direction */
 234#define ADDVFH      0x2E /* MSB of insert dummy lines in Vertical direction */
 235#define YAVG        0x2F /* Y/G Channel Average value */
 236#define REG32       0x32 /* Common Control 32 */
 237#define   REG32_PCLK_DIV_2    0x80 /* PCLK freq divided by 2 */
 238#define   REG32_PCLK_DIV_4    0xC0 /* PCLK freq divided by 4 */
 239#define ARCOM2      0x34 /* Zoom: Horizontal start point */
 240#define REG45       0x45 /* Register 45 */
 241#define FLL         0x46 /* Frame Length Adjustment LSBs */
 242#define FLH         0x47 /* Frame Length Adjustment MSBs */
 243#define COM19       0x48 /* Zoom: Vertical start point */
 244#define ZOOMS       0x49 /* Zoom: Vertical start point */
 245#define COM22       0x4B /* Flash light control */
 246#define COM25       0x4E /* For Banding operations */
 247#define BD50        0x4F /* 50Hz Banding AEC 8 LSBs */
 248#define BD60        0x50 /* 60Hz Banding AEC 8 LSBs */
 249#define REG5D       0x5D /* AVGsel[7:0],   16-zone average weight option */
 250#define REG5E       0x5E /* AVGsel[15:8],  16-zone average weight option */
 251#define REG5F       0x5F /* AVGsel[23:16], 16-zone average weight option */
 252#define REG60       0x60 /* AVGsel[31:24], 16-zone average weight option */
 253#define HISTO_LOW   0x61 /* Histogram Algorithm Low Level */
 254#define HISTO_HIGH  0x62 /* Histogram Algorithm High Level */
 255
 256/*
 257 * ID
 258 */
 259#define MANUFACTURER_ID 0x7FA2
 260#define PID_OV2640      0x2642
 261#define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF))
 262
 263/*
 264 * Struct
 265 */
 266struct regval_list {
 267        u8 reg_num;
 268        u8 value;
 269};
 270
 271/* Supported resolutions */
 272enum ov2640_width {
 273        W_QCIF  = 176,
 274        W_QVGA  = 320,
 275        W_CIF   = 352,
 276        W_VGA   = 640,
 277        W_SVGA  = 800,
 278        W_XGA   = 1024,
 279        W_SXGA  = 1280,
 280        W_UXGA  = 1600,
 281};
 282
 283enum ov2640_height {
 284        H_QCIF  = 144,
 285        H_QVGA  = 240,
 286        H_CIF   = 288,
 287        H_VGA   = 480,
 288        H_SVGA  = 600,
 289        H_XGA   = 768,
 290        H_SXGA  = 1024,
 291        H_UXGA  = 1200,
 292};
 293
 294struct ov2640_win_size {
 295        char                            *name;
 296        enum ov2640_width               width;
 297        enum ov2640_height              height;
 298        const struct regval_list        *regs;
 299};
 300
 301
 302struct ov2640_priv {
 303        struct v4l2_subdev              subdev;
 304        struct v4l2_ctrl_handler        hdl;
 305        enum v4l2_mbus_pixelcode        cfmt_code;
 306        const struct ov2640_win_size    *win;
 307        int                             model;
 308};
 309
 310/*
 311 * Registers settings
 312 */
 313
 314#define ENDMARKER { 0xff, 0xff }
 315
 316static const struct regval_list ov2640_init_regs[] = {
 317        { BANK_SEL, BANK_SEL_DSP },
 318        { 0x2c,   0xff },
 319        { 0x2e,   0xdf },
 320        { BANK_SEL, BANK_SEL_SENS },
 321        { 0x3c,   0x32 },
 322        { CLKRC, CLKRC_DIV_SET(1) },
 323        { COM2, COM2_OCAP_Nx_SET(3) },
 324        { REG04, REG04_DEF | REG04_HREF_EN },
 325        { COM8,  COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN },
 326        { COM9, COM9_AGC_GAIN_8x | 0x08},
 327        { 0x2c,   0x0c },
 328        { 0x33,   0x78 },
 329        { 0x3a,   0x33 },
 330        { 0x3b,   0xfb },
 331        { 0x3e,   0x00 },
 332        { 0x43,   0x11 },
 333        { 0x16,   0x10 },
 334        { 0x39,   0x02 },
 335        { 0x35,   0x88 },
 336        { 0x22,   0x0a },
 337        { 0x37,   0x40 },
 338        { 0x23,   0x00 },
 339        { ARCOM2, 0xa0 },
 340        { 0x06,   0x02 },
 341        { 0x06,   0x88 },
 342        { 0x07,   0xc0 },
 343        { 0x0d,   0xb7 },
 344        { 0x0e,   0x01 },
 345        { 0x4c,   0x00 },
 346        { 0x4a,   0x81 },
 347        { 0x21,   0x99 },
 348        { AEW,    0x40 },
 349        { AEB,    0x38 },
 350        { VV,     VV_HIGH_TH_SET(0x08) | VV_LOW_TH_SET(0x02) },
 351        { 0x5c,   0x00 },
 352        { 0x63,   0x00 },
 353        { FLL,    0x22 },
 354        { COM3,   0x38 | COM3_BAND_AUTO },
 355        { REG5D,  0x55 },
 356        { REG5E,  0x7d },
 357        { REG5F,  0x7d },
 358        { REG60,  0x55 },
 359        { HISTO_LOW,   0x70 },
 360        { HISTO_HIGH,  0x80 },
 361        { 0x7c,   0x05 },
 362        { 0x20,   0x80 },
 363        { 0x28,   0x30 },
 364        { 0x6c,   0x00 },
 365        { 0x6d,   0x80 },
 366        { 0x6e,   0x00 },
 367        { 0x70,   0x02 },
 368        { 0x71,   0x94 },
 369        { 0x73,   0xc1 },
 370        { 0x3d,   0x34 },
 371        { COM7, COM7_RES_UXGA | COM7_ZOOM_EN },
 372        { 0x5a,   0x57 },
 373        { BD50,   0xbb },
 374        { BD60,   0x9c },
 375        { BANK_SEL, BANK_SEL_DSP },
 376        { 0xe5,   0x7f },
 377        { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL },
 378        { 0x41,   0x24 },
 379        { RESET, RESET_JPEG | RESET_DVP },
 380        { 0x76,   0xff },
 381        { 0x33,   0xa0 },
 382        { 0x42,   0x20 },
 383        { 0x43,   0x18 },
 384        { 0x4c,   0x00 },
 385        { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 },
 386        { 0x88,   0x3f },
 387        { 0xd7,   0x03 },
 388        { 0xd9,   0x10 },
 389        { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 },
 390        { 0xc8,   0x08 },
 391        { 0xc9,   0x80 },
 392        { BPADDR, 0x00 },
 393        { BPDATA, 0x00 },
 394        { BPADDR, 0x03 },
 395        { BPDATA, 0x48 },
 396        { BPDATA, 0x48 },
 397        { BPADDR, 0x08 },
 398        { BPDATA, 0x20 },
 399        { BPDATA, 0x10 },
 400        { BPDATA, 0x0e },
 401        { 0x90,   0x00 },
 402        { 0x91,   0x0e },
 403        { 0x91,   0x1a },
 404        { 0x91,   0x31 },
 405        { 0x91,   0x5a },
 406        { 0x91,   0x69 },
 407        { 0x91,   0x75 },
 408        { 0x91,   0x7e },
 409        { 0x91,   0x88 },
 410        { 0x91,   0x8f },
 411        { 0x91,   0x96 },
 412        { 0x91,   0xa3 },
 413        { 0x91,   0xaf },
 414        { 0x91,   0xc4 },
 415        { 0x91,   0xd7 },
 416        { 0x91,   0xe8 },
 417        { 0x91,   0x20 },
 418        { 0x92,   0x00 },
 419        { 0x93,   0x06 },
 420        { 0x93,   0xe3 },
 421        { 0x93,   0x03 },
 422        { 0x93,   0x03 },
 423        { 0x93,   0x00 },
 424        { 0x93,   0x02 },
 425        { 0x93,   0x00 },
 426        { 0x93,   0x00 },
 427        { 0x93,   0x00 },
 428        { 0x93,   0x00 },
 429        { 0x93,   0x00 },
 430        { 0x93,   0x00 },
 431        { 0x93,   0x00 },
 432        { 0x96,   0x00 },
 433        { 0x97,   0x08 },
 434        { 0x97,   0x19 },
 435        { 0x97,   0x02 },
 436        { 0x97,   0x0c },
 437        { 0x97,   0x24 },
 438        { 0x97,   0x30 },
 439        { 0x97,   0x28 },
 440        { 0x97,   0x26 },
 441        { 0x97,   0x02 },
 442        { 0x97,   0x98 },
 443        { 0x97,   0x80 },
 444        { 0x97,   0x00 },
 445        { 0x97,   0x00 },
 446        { 0xa4,   0x00 },
 447        { 0xa8,   0x00 },
 448        { 0xc5,   0x11 },
 449        { 0xc6,   0x51 },
 450        { 0xbf,   0x80 },
 451        { 0xc7,   0x10 },
 452        { 0xb6,   0x66 },
 453        { 0xb8,   0xA5 },
 454        { 0xb7,   0x64 },
 455        { 0xb9,   0x7C },
 456        { 0xb3,   0xaf },
 457        { 0xb4,   0x97 },
 458        { 0xb5,   0xFF },
 459        { 0xb0,   0xC5 },
 460        { 0xb1,   0x94 },
 461        { 0xb2,   0x0f },
 462        { 0xc4,   0x5c },
 463        { 0xa6,   0x00 },
 464        { 0xa7,   0x20 },
 465        { 0xa7,   0xd8 },
 466        { 0xa7,   0x1b },
 467        { 0xa7,   0x31 },
 468        { 0xa7,   0x00 },
 469        { 0xa7,   0x18 },
 470        { 0xa7,   0x20 },
 471        { 0xa7,   0xd8 },
 472        { 0xa7,   0x19 },
 473        { 0xa7,   0x31 },
 474        { 0xa7,   0x00 },
 475        { 0xa7,   0x18 },
 476        { 0xa7,   0x20 },
 477        { 0xa7,   0xd8 },
 478        { 0xa7,   0x19 },
 479        { 0xa7,   0x31 },
 480        { 0xa7,   0x00 },
 481        { 0xa7,   0x18 },
 482        { 0x7f,   0x00 },
 483        { 0xe5,   0x1f },
 484        { 0xe1,   0x77 },
 485        { 0xdd,   0x7f },
 486        { CTRL0,  CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN },
 487        ENDMARKER,
 488};
 489
 490/*
 491 * Register settings for window size
 492 * The preamble, setup the internal DSP to input an UXGA (1600x1200) image.
 493 * Then the different zooming configurations will setup the output image size.
 494 */
 495static const struct regval_list ov2640_size_change_preamble_regs[] = {
 496        { BANK_SEL, BANK_SEL_DSP },
 497        { RESET, RESET_DVP },
 498        { HSIZE8, HSIZE8_SET(W_UXGA) },
 499        { VSIZE8, VSIZE8_SET(H_UXGA) },
 500        { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN |
 501                 CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN },
 502        { HSIZE, HSIZE_SET(W_UXGA) },
 503        { VSIZE, VSIZE_SET(H_UXGA) },
 504        { XOFFL, XOFFL_SET(0) },
 505        { YOFFL, YOFFL_SET(0) },
 506        { VHYX, VHYX_HSIZE_SET(W_UXGA) | VHYX_VSIZE_SET(H_UXGA) |
 507                VHYX_XOFF_SET(0) | VHYX_YOFF_SET(0)},
 508        { TEST, TEST_HSIZE_SET(W_UXGA) },
 509        ENDMARKER,
 510};
 511
 512#define PER_SIZE_REG_SEQ(x, y, v_div, h_div, pclk_div)  \
 513        { CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(v_div) | \
 514                 CTRLI_H_DIV_SET(h_div)},               \
 515        { ZMOW, ZMOW_OUTW_SET(x) },                     \
 516        { ZMOH, ZMOH_OUTH_SET(y) },                     \
 517        { ZMHH, ZMHH_OUTW_SET(x) | ZMHH_OUTH_SET(y) },  \
 518        { R_DVP_SP, pclk_div },                         \
 519        { RESET, 0x00}
 520
 521static const struct regval_list ov2640_qcif_regs[] = {
 522        PER_SIZE_REG_SEQ(W_QCIF, H_QCIF, 3, 3, 4),
 523        ENDMARKER,
 524};
 525
 526static const struct regval_list ov2640_qvga_regs[] = {
 527        PER_SIZE_REG_SEQ(W_QVGA, H_QVGA, 2, 2, 4),
 528        ENDMARKER,
 529};
 530
 531static const struct regval_list ov2640_cif_regs[] = {
 532        PER_SIZE_REG_SEQ(W_CIF, H_CIF, 2, 2, 8),
 533        ENDMARKER,
 534};
 535
 536static const struct regval_list ov2640_vga_regs[] = {
 537        PER_SIZE_REG_SEQ(W_VGA, H_VGA, 0, 0, 2),
 538        ENDMARKER,
 539};
 540
 541static const struct regval_list ov2640_svga_regs[] = {
 542        PER_SIZE_REG_SEQ(W_SVGA, H_SVGA, 1, 1, 2),
 543        ENDMARKER,
 544};
 545
 546static const struct regval_list ov2640_xga_regs[] = {
 547        PER_SIZE_REG_SEQ(W_XGA, H_XGA, 0, 0, 2),
 548        { CTRLI,    0x00},
 549        ENDMARKER,
 550};
 551
 552static const struct regval_list ov2640_sxga_regs[] = {
 553        PER_SIZE_REG_SEQ(W_SXGA, H_SXGA, 0, 0, 2),
 554        { CTRLI,    0x00},
 555        { R_DVP_SP, 2 | R_DVP_SP_AUTO_MODE },
 556        ENDMARKER,
 557};
 558
 559static const struct regval_list ov2640_uxga_regs[] = {
 560        PER_SIZE_REG_SEQ(W_UXGA, H_UXGA, 0, 0, 0),
 561        { CTRLI,    0x00},
 562        { R_DVP_SP, 0 | R_DVP_SP_AUTO_MODE },
 563        ENDMARKER,
 564};
 565
 566#define OV2640_SIZE(n, w, h, r) \
 567        {.name = n, .width = w , .height = h, .regs = r }
 568
 569static const struct ov2640_win_size ov2640_supported_win_sizes[] = {
 570        OV2640_SIZE("QCIF", W_QCIF, H_QCIF, ov2640_qcif_regs),
 571        OV2640_SIZE("QVGA", W_QVGA, H_QVGA, ov2640_qvga_regs),
 572        OV2640_SIZE("CIF", W_CIF, H_CIF, ov2640_cif_regs),
 573        OV2640_SIZE("VGA", W_VGA, H_VGA, ov2640_vga_regs),
 574        OV2640_SIZE("SVGA", W_SVGA, H_SVGA, ov2640_svga_regs),
 575        OV2640_SIZE("XGA", W_XGA, H_XGA, ov2640_xga_regs),
 576        OV2640_SIZE("SXGA", W_SXGA, H_SXGA, ov2640_sxga_regs),
 577        OV2640_SIZE("UXGA", W_UXGA, H_UXGA, ov2640_uxga_regs),
 578};
 579
 580/*
 581 * Register settings for pixel formats
 582 */
 583static const struct regval_list ov2640_format_change_preamble_regs[] = {
 584        { BANK_SEL, BANK_SEL_DSP },
 585        { R_BYPASS, R_BYPASS_USE_DSP },
 586        ENDMARKER,
 587};
 588
 589static const struct regval_list ov2640_yuv422_regs[] = {
 590        { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 },
 591        { 0xD7, 0x01 },
 592        { 0x33, 0xa0 },
 593        { 0xe1, 0x67 },
 594        { RESET,  0x00 },
 595        { R_BYPASS, R_BYPASS_USE_DSP },
 596        ENDMARKER,
 597};
 598
 599static const struct regval_list ov2640_rgb565_regs[] = {
 600        { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 },
 601        { 0xd7, 0x03 },
 602        { RESET,  0x00 },
 603        { R_BYPASS, R_BYPASS_USE_DSP },
 604        ENDMARKER,
 605};
 606
 607static enum v4l2_mbus_pixelcode ov2640_codes[] = {
 608        V4L2_MBUS_FMT_UYVY8_2X8,
 609        V4L2_MBUS_FMT_RGB565_2X8_LE,
 610};
 611
 612/*
 613 * General functions
 614 */
 615static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
 616{
 617        return container_of(i2c_get_clientdata(client), struct ov2640_priv,
 618                            subdev);
 619}
 620
 621static int ov2640_write_array(struct i2c_client *client,
 622                              const struct regval_list *vals)
 623{
 624        int ret;
 625
 626        while ((vals->reg_num != 0xff) || (vals->value != 0xff)) {
 627                ret = i2c_smbus_write_byte_data(client,
 628                                                vals->reg_num, vals->value);
 629                dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x",
 630                         vals->reg_num, vals->value);
 631
 632                if (ret < 0)
 633                        return ret;
 634                vals++;
 635        }
 636        return 0;
 637}
 638
 639static int ov2640_mask_set(struct i2c_client *client,
 640                           u8  reg, u8  mask, u8  set)
 641{
 642        s32 val = i2c_smbus_read_byte_data(client, reg);
 643        if (val < 0)
 644                return val;
 645
 646        val &= ~mask;
 647        val |= set & mask;
 648
 649        dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val);
 650
 651        return i2c_smbus_write_byte_data(client, reg, val);
 652}
 653
 654static int ov2640_reset(struct i2c_client *client)
 655{
 656        int ret;
 657        const struct regval_list reset_seq[] = {
 658                {BANK_SEL, BANK_SEL_SENS},
 659                {COM7, COM7_SRST},
 660                ENDMARKER,
 661        };
 662
 663        ret = ov2640_write_array(client, reset_seq);
 664        if (ret)
 665                goto err;
 666
 667        msleep(5);
 668err:
 669        dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret);
 670        return ret;
 671}
 672
 673/*
 674 * soc_camera_ops functions
 675 */
 676static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
 677{
 678        return 0;
 679}
 680
 681static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
 682{
 683        struct v4l2_subdev *sd =
 684                &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
 685        struct i2c_client  *client = v4l2_get_subdevdata(sd);
 686        u8 val;
 687
 688        switch (ctrl->id) {
 689        case V4L2_CID_VFLIP:
 690                val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
 691                return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
 692        case V4L2_CID_HFLIP:
 693                val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
 694                return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
 695        }
 696
 697        return -EINVAL;
 698}
 699
 700static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
 701                               struct v4l2_dbg_chip_ident *id)
 702{
 703        struct i2c_client *client = v4l2_get_subdevdata(sd);
 704        struct ov2640_priv *priv = to_ov2640(client);
 705
 706        id->ident    = priv->model;
 707        id->revision = 0;
 708
 709        return 0;
 710}
 711
 712#ifdef CONFIG_VIDEO_ADV_DEBUG
 713static int ov2640_g_register(struct v4l2_subdev *sd,
 714                             struct v4l2_dbg_register *reg)
 715{
 716        struct i2c_client *client = v4l2_get_subdevdata(sd);
 717        int ret;
 718
 719        reg->size = 1;
 720        if (reg->reg > 0xff)
 721                return -EINVAL;
 722
 723        ret = i2c_smbus_read_byte_data(client, reg->reg);
 724        if (ret < 0)
 725                return ret;
 726
 727        reg->val = ret;
 728
 729        return 0;
 730}
 731
 732static int ov2640_s_register(struct v4l2_subdev *sd,
 733                             struct v4l2_dbg_register *reg)
 734{
 735        struct i2c_client *client = v4l2_get_subdevdata(sd);
 736
 737        if (reg->reg > 0xff ||
 738            reg->val > 0xff)
 739                return -EINVAL;
 740
 741        return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
 742}
 743#endif
 744
 745/* Select the nearest higher resolution for capture */
 746static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height)
 747{
 748        int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1;
 749
 750        for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) {
 751                if (ov2640_supported_win_sizes[i].width  >= *width &&
 752                    ov2640_supported_win_sizes[i].height >= *height) {
 753                        *width = ov2640_supported_win_sizes[i].width;
 754                        *height = ov2640_supported_win_sizes[i].height;
 755                        return &ov2640_supported_win_sizes[i];
 756                }
 757        }
 758
 759        *width = ov2640_supported_win_sizes[default_size].width;
 760        *height = ov2640_supported_win_sizes[default_size].height;
 761        return &ov2640_supported_win_sizes[default_size];
 762}
 763
 764static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
 765                             enum v4l2_mbus_pixelcode code)
 766{
 767        struct ov2640_priv       *priv = to_ov2640(client);
 768        const struct regval_list *selected_cfmt_regs;
 769        int ret;
 770
 771        /* select win */
 772        priv->win = ov2640_select_win(width, height);
 773
 774        /* select format */
 775        priv->cfmt_code = 0;
 776        switch (code) {
 777        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 778                dev_dbg(&client->dev, "%s: Selected cfmt RGB565", __func__);
 779                selected_cfmt_regs = ov2640_rgb565_regs;
 780                break;
 781        default:
 782        case V4L2_MBUS_FMT_UYVY8_2X8:
 783                dev_dbg(&client->dev, "%s: Selected cfmt YUV422", __func__);
 784                selected_cfmt_regs = ov2640_yuv422_regs;
 785        }
 786
 787        /* reset hardware */
 788        ov2640_reset(client);
 789
 790        /* initialize the sensor with default data */
 791        dev_dbg(&client->dev, "%s: Init default", __func__);
 792        ret = ov2640_write_array(client, ov2640_init_regs);
 793        if (ret < 0)
 794                goto err;
 795
 796        /* select preamble */
 797        dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name);
 798        ret = ov2640_write_array(client, ov2640_size_change_preamble_regs);
 799        if (ret < 0)
 800                goto err;
 801
 802        /* set size win */
 803        ret = ov2640_write_array(client, priv->win->regs);
 804        if (ret < 0)
 805                goto err;
 806
 807        /* cfmt preamble */
 808        dev_dbg(&client->dev, "%s: Set cfmt", __func__);
 809        ret = ov2640_write_array(client, ov2640_format_change_preamble_regs);
 810        if (ret < 0)
 811                goto err;
 812
 813        /* set cfmt */
 814        ret = ov2640_write_array(client, selected_cfmt_regs);
 815        if (ret < 0)
 816                goto err;
 817
 818        priv->cfmt_code = code;
 819        *width = priv->win->width;
 820        *height = priv->win->height;
 821
 822        return 0;
 823
 824err:
 825        dev_err(&client->dev, "%s: Error %d", __func__, ret);
 826        ov2640_reset(client);
 827        priv->win = NULL;
 828
 829        return ret;
 830}
 831
 832static int ov2640_g_fmt(struct v4l2_subdev *sd,
 833                        struct v4l2_mbus_framefmt *mf)
 834{
 835        struct i2c_client  *client = v4l2_get_subdevdata(sd);
 836        struct ov2640_priv *priv = to_ov2640(client);
 837
 838        if (!priv->win) {
 839                u32 width = W_SVGA, height = H_SVGA;
 840                int ret = ov2640_set_params(client, &width, &height,
 841                                            V4L2_MBUS_FMT_UYVY8_2X8);
 842                if (ret < 0)
 843                        return ret;
 844        }
 845
 846        mf->width       = priv->win->width;
 847        mf->height      = priv->win->height;
 848        mf->code        = priv->cfmt_code;
 849
 850        switch (mf->code) {
 851        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 852                mf->colorspace = V4L2_COLORSPACE_SRGB;
 853                break;
 854        default:
 855        case V4L2_MBUS_FMT_UYVY8_2X8:
 856                mf->colorspace = V4L2_COLORSPACE_JPEG;
 857        }
 858        mf->field       = V4L2_FIELD_NONE;
 859
 860        return 0;
 861}
 862
 863static int ov2640_s_fmt(struct v4l2_subdev *sd,
 864                        struct v4l2_mbus_framefmt *mf)
 865{
 866        struct i2c_client *client = v4l2_get_subdevdata(sd);
 867        int ret;
 868
 869
 870        switch (mf->code) {
 871        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 872                mf->colorspace = V4L2_COLORSPACE_SRGB;
 873                break;
 874        default:
 875                mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
 876        case V4L2_MBUS_FMT_UYVY8_2X8:
 877                mf->colorspace = V4L2_COLORSPACE_JPEG;
 878        }
 879
 880        ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code);
 881
 882        return ret;
 883}
 884
 885static int ov2640_try_fmt(struct v4l2_subdev *sd,
 886                          struct v4l2_mbus_framefmt *mf)
 887{
 888        const struct ov2640_win_size *win;
 889
 890        /*
 891         * select suitable win
 892         */
 893        win = ov2640_select_win(&mf->width, &mf->height);
 894
 895        mf->field       = V4L2_FIELD_NONE;
 896
 897        switch (mf->code) {
 898        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 899                mf->colorspace = V4L2_COLORSPACE_SRGB;
 900                break;
 901        default:
 902                mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
 903        case V4L2_MBUS_FMT_UYVY8_2X8:
 904                mf->colorspace = V4L2_COLORSPACE_JPEG;
 905        }
 906
 907        return 0;
 908}
 909
 910static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
 911                           enum v4l2_mbus_pixelcode *code)
 912{
 913        if (index >= ARRAY_SIZE(ov2640_codes))
 914                return -EINVAL;
 915
 916        *code = ov2640_codes[index];
 917        return 0;
 918}
 919
 920static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 921{
 922        a->c.left       = 0;
 923        a->c.top        = 0;
 924        a->c.width      = W_UXGA;
 925        a->c.height     = H_UXGA;
 926        a->type         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 927
 928        return 0;
 929}
 930
 931static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 932{
 933        a->bounds.left                  = 0;
 934        a->bounds.top                   = 0;
 935        a->bounds.width                 = W_UXGA;
 936        a->bounds.height                = H_UXGA;
 937        a->defrect                      = a->bounds;
 938        a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 939        a->pixelaspect.numerator        = 1;
 940        a->pixelaspect.denominator      = 1;
 941
 942        return 0;
 943}
 944
 945static int ov2640_video_probe(struct i2c_client *client)
 946{
 947        struct ov2640_priv *priv = to_ov2640(client);
 948        u8 pid, ver, midh, midl;
 949        const char *devname;
 950        int ret;
 951
 952        /*
 953         * check and show product ID and manufacturer ID
 954         */
 955        i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
 956        pid  = i2c_smbus_read_byte_data(client, PID);
 957        ver  = i2c_smbus_read_byte_data(client, VER);
 958        midh = i2c_smbus_read_byte_data(client, MIDH);
 959        midl = i2c_smbus_read_byte_data(client, MIDL);
 960
 961        switch (VERSION(pid, ver)) {
 962        case PID_OV2640:
 963                devname     = "ov2640";
 964                priv->model = V4L2_IDENT_OV2640;
 965                break;
 966        default:
 967                dev_err(&client->dev,
 968                        "Product ID error %x:%x\n", pid, ver);
 969                ret = -ENODEV;
 970                goto err;
 971        }
 972
 973        dev_info(&client->dev,
 974                 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
 975                 devname, pid, ver, midh, midl);
 976
 977        return v4l2_ctrl_handler_setup(&priv->hdl);
 978
 979err:
 980        return ret;
 981}
 982
 983static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
 984        .s_ctrl = ov2640_s_ctrl,
 985};
 986
 987static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
 988        .g_chip_ident   = ov2640_g_chip_ident,
 989#ifdef CONFIG_VIDEO_ADV_DEBUG
 990        .g_register     = ov2640_g_register,
 991        .s_register     = ov2640_s_register,
 992#endif
 993};
 994
 995static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
 996                                struct v4l2_mbus_config *cfg)
 997{
 998        struct i2c_client *client = v4l2_get_subdevdata(sd);
 999        struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1000
1001        cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1002                V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1003                V4L2_MBUS_DATA_ACTIVE_HIGH;
1004        cfg->type = V4L2_MBUS_PARALLEL;
1005        cfg->flags = soc_camera_apply_board_flags(icl, cfg);
1006
1007        return 0;
1008}
1009
1010static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
1011        .s_stream       = ov2640_s_stream,
1012        .g_mbus_fmt     = ov2640_g_fmt,
1013        .s_mbus_fmt     = ov2640_s_fmt,
1014        .try_mbus_fmt   = ov2640_try_fmt,
1015        .cropcap        = ov2640_cropcap,
1016        .g_crop         = ov2640_g_crop,
1017        .enum_mbus_fmt  = ov2640_enum_fmt,
1018        .g_mbus_config  = ov2640_g_mbus_config,
1019};
1020
1021static struct v4l2_subdev_ops ov2640_subdev_ops = {
1022        .core   = &ov2640_subdev_core_ops,
1023        .video  = &ov2640_subdev_video_ops,
1024};
1025
1026/*
1027 * i2c_driver functions
1028 */
1029static int ov2640_probe(struct i2c_client *client,
1030                        const struct i2c_device_id *did)
1031{
1032        struct ov2640_priv      *priv;
1033        struct soc_camera_link  *icl = soc_camera_i2c_to_link(client);
1034        struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
1035        int                     ret;
1036
1037        if (!icl) {
1038                dev_err(&adapter->dev,
1039                        "OV2640: Missing platform_data for driver\n");
1040                return -EINVAL;
1041        }
1042
1043        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1044                dev_err(&adapter->dev,
1045                        "OV2640: I2C-Adapter doesn't support SMBUS\n");
1046                return -EIO;
1047        }
1048
1049        priv = kzalloc(sizeof(struct ov2640_priv), GFP_KERNEL);
1050        if (!priv) {
1051                dev_err(&adapter->dev,
1052                        "Failed to allocate memory for private data!\n");
1053                return -ENOMEM;
1054        }
1055
1056        v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
1057        v4l2_ctrl_handler_init(&priv->hdl, 2);
1058        v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1059                        V4L2_CID_VFLIP, 0, 1, 1, 0);
1060        v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1061                        V4L2_CID_HFLIP, 0, 1, 1, 0);
1062        priv->subdev.ctrl_handler = &priv->hdl;
1063        if (priv->hdl.error) {
1064                int err = priv->hdl.error;
1065
1066                kfree(priv);
1067                return err;
1068        }
1069
1070        ret = ov2640_video_probe(client);
1071        if (ret) {
1072                v4l2_ctrl_handler_free(&priv->hdl);
1073                kfree(priv);
1074        } else {
1075                dev_info(&adapter->dev, "OV2640 Probed\n");
1076        }
1077
1078        return ret;
1079}
1080
1081static int ov2640_remove(struct i2c_client *client)
1082{
1083        struct ov2640_priv       *priv = to_ov2640(client);
1084
1085        v4l2_device_unregister_subdev(&priv->subdev);
1086        v4l2_ctrl_handler_free(&priv->hdl);
1087        kfree(priv);
1088        return 0;
1089}
1090
1091static const struct i2c_device_id ov2640_id[] = {
1092        { "ov2640", 0 },
1093        { }
1094};
1095MODULE_DEVICE_TABLE(i2c, ov2640_id);
1096
1097static struct i2c_driver ov2640_i2c_driver = {
1098        .driver = {
1099                .name = "ov2640",
1100        },
1101        .probe    = ov2640_probe,
1102        .remove   = ov2640_remove,
1103        .id_table = ov2640_id,
1104};
1105
1106/*
1107 * Module functions
1108 */
1109static int __init ov2640_module_init(void)
1110{
1111        return i2c_add_driver(&ov2640_i2c_driver);
1112}
1113
1114static void __exit ov2640_module_exit(void)
1115{
1116        i2c_del_driver(&ov2640_i2c_driver);
1117}
1118
1119module_init(ov2640_module_init);
1120module_exit(ov2640_module_exit);
1121
1122MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor");
1123MODULE_AUTHOR("Alberto Panizzo");
1124MODULE_LICENSE("GPL v2");
1125