linux/drivers/media/i2c/soc_camera/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_yuyv_regs[] = {
 590        { IMAGE_MODE, IMAGE_MODE_YUV422 },
 591        { 0xd7, 0x03 },
 592        { 0x33, 0xa0 },
 593        { 0xe5, 0x1f },
 594        { 0xe1, 0x67 },
 595        { RESET,  0x00 },
 596        { R_BYPASS, R_BYPASS_USE_DSP },
 597        ENDMARKER,
 598};
 599
 600static const struct regval_list ov2640_uyvy_regs[] = {
 601        { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 },
 602        { 0xd7, 0x01 },
 603        { 0x33, 0xa0 },
 604        { 0xe1, 0x67 },
 605        { RESET,  0x00 },
 606        { R_BYPASS, R_BYPASS_USE_DSP },
 607        ENDMARKER,
 608};
 609
 610static const struct regval_list ov2640_rgb565_be_regs[] = {
 611        { IMAGE_MODE, IMAGE_MODE_RGB565 },
 612        { 0xd7, 0x03 },
 613        { RESET,  0x00 },
 614        { R_BYPASS, R_BYPASS_USE_DSP },
 615        ENDMARKER,
 616};
 617
 618static const struct regval_list ov2640_rgb565_le_regs[] = {
 619        { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 },
 620        { 0xd7, 0x03 },
 621        { RESET,  0x00 },
 622        { R_BYPASS, R_BYPASS_USE_DSP },
 623        ENDMARKER,
 624};
 625
 626static enum v4l2_mbus_pixelcode ov2640_codes[] = {
 627        V4L2_MBUS_FMT_YUYV8_2X8,
 628        V4L2_MBUS_FMT_UYVY8_2X8,
 629        V4L2_MBUS_FMT_RGB565_2X8_BE,
 630        V4L2_MBUS_FMT_RGB565_2X8_LE,
 631};
 632
 633/*
 634 * General functions
 635 */
 636static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
 637{
 638        return container_of(i2c_get_clientdata(client), struct ov2640_priv,
 639                            subdev);
 640}
 641
 642static int ov2640_write_array(struct i2c_client *client,
 643                              const struct regval_list *vals)
 644{
 645        int ret;
 646
 647        while ((vals->reg_num != 0xff) || (vals->value != 0xff)) {
 648                ret = i2c_smbus_write_byte_data(client,
 649                                                vals->reg_num, vals->value);
 650                dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x",
 651                         vals->reg_num, vals->value);
 652
 653                if (ret < 0)
 654                        return ret;
 655                vals++;
 656        }
 657        return 0;
 658}
 659
 660static int ov2640_mask_set(struct i2c_client *client,
 661                           u8  reg, u8  mask, u8  set)
 662{
 663        s32 val = i2c_smbus_read_byte_data(client, reg);
 664        if (val < 0)
 665                return val;
 666
 667        val &= ~mask;
 668        val |= set & mask;
 669
 670        dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val);
 671
 672        return i2c_smbus_write_byte_data(client, reg, val);
 673}
 674
 675static int ov2640_reset(struct i2c_client *client)
 676{
 677        int ret;
 678        const struct regval_list reset_seq[] = {
 679                {BANK_SEL, BANK_SEL_SENS},
 680                {COM7, COM7_SRST},
 681                ENDMARKER,
 682        };
 683
 684        ret = ov2640_write_array(client, reset_seq);
 685        if (ret)
 686                goto err;
 687
 688        msleep(5);
 689err:
 690        dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret);
 691        return ret;
 692}
 693
 694/*
 695 * soc_camera_ops functions
 696 */
 697static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
 698{
 699        return 0;
 700}
 701
 702static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
 703{
 704        struct v4l2_subdev *sd =
 705                &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
 706        struct i2c_client  *client = v4l2_get_subdevdata(sd);
 707        u8 val;
 708        int ret;
 709
 710        ret = i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
 711        if (ret < 0)
 712                return ret;
 713
 714        switch (ctrl->id) {
 715        case V4L2_CID_VFLIP:
 716                val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
 717                return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
 718        case V4L2_CID_HFLIP:
 719                val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
 720                return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
 721        }
 722
 723        return -EINVAL;
 724}
 725
 726static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
 727                               struct v4l2_dbg_chip_ident *id)
 728{
 729        struct i2c_client *client = v4l2_get_subdevdata(sd);
 730        struct ov2640_priv *priv = to_ov2640(client);
 731
 732        id->ident    = priv->model;
 733        id->revision = 0;
 734
 735        return 0;
 736}
 737
 738#ifdef CONFIG_VIDEO_ADV_DEBUG
 739static int ov2640_g_register(struct v4l2_subdev *sd,
 740                             struct v4l2_dbg_register *reg)
 741{
 742        struct i2c_client *client = v4l2_get_subdevdata(sd);
 743        int ret;
 744
 745        reg->size = 1;
 746        if (reg->reg > 0xff)
 747                return -EINVAL;
 748
 749        ret = i2c_smbus_read_byte_data(client, reg->reg);
 750        if (ret < 0)
 751                return ret;
 752
 753        reg->val = ret;
 754
 755        return 0;
 756}
 757
 758static int ov2640_s_register(struct v4l2_subdev *sd,
 759                             const struct v4l2_dbg_register *reg)
 760{
 761        struct i2c_client *client = v4l2_get_subdevdata(sd);
 762
 763        if (reg->reg > 0xff ||
 764            reg->val > 0xff)
 765                return -EINVAL;
 766
 767        return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
 768}
 769#endif
 770
 771static int ov2640_s_power(struct v4l2_subdev *sd, int on)
 772{
 773        struct i2c_client *client = v4l2_get_subdevdata(sd);
 774        struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 775
 776        return soc_camera_set_power(&client->dev, ssdd, on);
 777}
 778
 779/* Select the nearest higher resolution for capture */
 780static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height)
 781{
 782        int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1;
 783
 784        for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) {
 785                if (ov2640_supported_win_sizes[i].width  >= *width &&
 786                    ov2640_supported_win_sizes[i].height >= *height) {
 787                        *width = ov2640_supported_win_sizes[i].width;
 788                        *height = ov2640_supported_win_sizes[i].height;
 789                        return &ov2640_supported_win_sizes[i];
 790                }
 791        }
 792
 793        *width = ov2640_supported_win_sizes[default_size].width;
 794        *height = ov2640_supported_win_sizes[default_size].height;
 795        return &ov2640_supported_win_sizes[default_size];
 796}
 797
 798static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
 799                             enum v4l2_mbus_pixelcode code)
 800{
 801        struct ov2640_priv       *priv = to_ov2640(client);
 802        const struct regval_list *selected_cfmt_regs;
 803        int ret;
 804
 805        /* select win */
 806        priv->win = ov2640_select_win(width, height);
 807
 808        /* select format */
 809        priv->cfmt_code = 0;
 810        switch (code) {
 811        case V4L2_MBUS_FMT_RGB565_2X8_BE:
 812                dev_dbg(&client->dev, "%s: Selected cfmt RGB565 BE", __func__);
 813                selected_cfmt_regs = ov2640_rgb565_be_regs;
 814                break;
 815        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 816                dev_dbg(&client->dev, "%s: Selected cfmt RGB565 LE", __func__);
 817                selected_cfmt_regs = ov2640_rgb565_le_regs;
 818                break;
 819        case V4L2_MBUS_FMT_YUYV8_2X8:
 820                dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__);
 821                selected_cfmt_regs = ov2640_yuyv_regs;
 822                break;
 823        default:
 824        case V4L2_MBUS_FMT_UYVY8_2X8:
 825                dev_dbg(&client->dev, "%s: Selected cfmt UYVY", __func__);
 826                selected_cfmt_regs = ov2640_uyvy_regs;
 827        }
 828
 829        /* reset hardware */
 830        ov2640_reset(client);
 831
 832        /* initialize the sensor with default data */
 833        dev_dbg(&client->dev, "%s: Init default", __func__);
 834        ret = ov2640_write_array(client, ov2640_init_regs);
 835        if (ret < 0)
 836                goto err;
 837
 838        /* select preamble */
 839        dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name);
 840        ret = ov2640_write_array(client, ov2640_size_change_preamble_regs);
 841        if (ret < 0)
 842                goto err;
 843
 844        /* set size win */
 845        ret = ov2640_write_array(client, priv->win->regs);
 846        if (ret < 0)
 847                goto err;
 848
 849        /* cfmt preamble */
 850        dev_dbg(&client->dev, "%s: Set cfmt", __func__);
 851        ret = ov2640_write_array(client, ov2640_format_change_preamble_regs);
 852        if (ret < 0)
 853                goto err;
 854
 855        /* set cfmt */
 856        ret = ov2640_write_array(client, selected_cfmt_regs);
 857        if (ret < 0)
 858                goto err;
 859
 860        priv->cfmt_code = code;
 861        *width = priv->win->width;
 862        *height = priv->win->height;
 863
 864        return 0;
 865
 866err:
 867        dev_err(&client->dev, "%s: Error %d", __func__, ret);
 868        ov2640_reset(client);
 869        priv->win = NULL;
 870
 871        return ret;
 872}
 873
 874static int ov2640_g_fmt(struct v4l2_subdev *sd,
 875                        struct v4l2_mbus_framefmt *mf)
 876{
 877        struct i2c_client  *client = v4l2_get_subdevdata(sd);
 878        struct ov2640_priv *priv = to_ov2640(client);
 879
 880        if (!priv->win) {
 881                u32 width = W_SVGA, height = H_SVGA;
 882                priv->win = ov2640_select_win(&width, &height);
 883                priv->cfmt_code = V4L2_MBUS_FMT_UYVY8_2X8;
 884        }
 885
 886        mf->width       = priv->win->width;
 887        mf->height      = priv->win->height;
 888        mf->code        = priv->cfmt_code;
 889
 890        switch (mf->code) {
 891        case V4L2_MBUS_FMT_RGB565_2X8_BE:
 892        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 893                mf->colorspace = V4L2_COLORSPACE_SRGB;
 894                break;
 895        default:
 896        case V4L2_MBUS_FMT_YUYV8_2X8:
 897        case V4L2_MBUS_FMT_UYVY8_2X8:
 898                mf->colorspace = V4L2_COLORSPACE_JPEG;
 899        }
 900        mf->field       = V4L2_FIELD_NONE;
 901
 902        return 0;
 903}
 904
 905static int ov2640_s_fmt(struct v4l2_subdev *sd,
 906                        struct v4l2_mbus_framefmt *mf)
 907{
 908        struct i2c_client *client = v4l2_get_subdevdata(sd);
 909        int ret;
 910
 911
 912        switch (mf->code) {
 913        case V4L2_MBUS_FMT_RGB565_2X8_BE:
 914        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 915                mf->colorspace = V4L2_COLORSPACE_SRGB;
 916                break;
 917        default:
 918                mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
 919        case V4L2_MBUS_FMT_YUYV8_2X8:
 920        case V4L2_MBUS_FMT_UYVY8_2X8:
 921                mf->colorspace = V4L2_COLORSPACE_JPEG;
 922        }
 923
 924        ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code);
 925
 926        return ret;
 927}
 928
 929static int ov2640_try_fmt(struct v4l2_subdev *sd,
 930                          struct v4l2_mbus_framefmt *mf)
 931{
 932        /*
 933         * select suitable win, but don't store it
 934         */
 935        ov2640_select_win(&mf->width, &mf->height);
 936
 937        mf->field       = V4L2_FIELD_NONE;
 938
 939        switch (mf->code) {
 940        case V4L2_MBUS_FMT_RGB565_2X8_BE:
 941        case V4L2_MBUS_FMT_RGB565_2X8_LE:
 942                mf->colorspace = V4L2_COLORSPACE_SRGB;
 943                break;
 944        default:
 945                mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
 946        case V4L2_MBUS_FMT_YUYV8_2X8:
 947        case V4L2_MBUS_FMT_UYVY8_2X8:
 948                mf->colorspace = V4L2_COLORSPACE_JPEG;
 949        }
 950
 951        return 0;
 952}
 953
 954static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
 955                           enum v4l2_mbus_pixelcode *code)
 956{
 957        if (index >= ARRAY_SIZE(ov2640_codes))
 958                return -EINVAL;
 959
 960        *code = ov2640_codes[index];
 961        return 0;
 962}
 963
 964static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 965{
 966        a->c.left       = 0;
 967        a->c.top        = 0;
 968        a->c.width      = W_UXGA;
 969        a->c.height     = H_UXGA;
 970        a->type         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 971
 972        return 0;
 973}
 974
 975static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 976{
 977        a->bounds.left                  = 0;
 978        a->bounds.top                   = 0;
 979        a->bounds.width                 = W_UXGA;
 980        a->bounds.height                = H_UXGA;
 981        a->defrect                      = a->bounds;
 982        a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 983        a->pixelaspect.numerator        = 1;
 984        a->pixelaspect.denominator      = 1;
 985
 986        return 0;
 987}
 988
 989static int ov2640_video_probe(struct i2c_client *client)
 990{
 991        struct ov2640_priv *priv = to_ov2640(client);
 992        u8 pid, ver, midh, midl;
 993        const char *devname;
 994        int ret;
 995
 996        ret = ov2640_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        i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
1004        pid  = i2c_smbus_read_byte_data(client, PID);
1005        ver  = i2c_smbus_read_byte_data(client, VER);
1006        midh = i2c_smbus_read_byte_data(client, MIDH);
1007        midl = i2c_smbus_read_byte_data(client, MIDL);
1008
1009        switch (VERSION(pid, ver)) {
1010        case PID_OV2640:
1011                devname     = "ov2640";
1012                priv->model = V4L2_IDENT_OV2640;
1013                break;
1014        default:
1015                dev_err(&client->dev,
1016                        "Product ID error %x:%x\n", pid, ver);
1017                ret = -ENODEV;
1018                goto done;
1019        }
1020
1021        dev_info(&client->dev,
1022                 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
1023                 devname, pid, ver, midh, midl);
1024
1025        ret = v4l2_ctrl_handler_setup(&priv->hdl);
1026
1027done:
1028        ov2640_s_power(&priv->subdev, 0);
1029        return ret;
1030}
1031
1032static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
1033        .s_ctrl = ov2640_s_ctrl,
1034};
1035
1036static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
1037        .g_chip_ident   = ov2640_g_chip_ident,
1038#ifdef CONFIG_VIDEO_ADV_DEBUG
1039        .g_register     = ov2640_g_register,
1040        .s_register     = ov2640_s_register,
1041#endif
1042        .s_power        = ov2640_s_power,
1043};
1044
1045static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
1046                                struct v4l2_mbus_config *cfg)
1047{
1048        struct i2c_client *client = v4l2_get_subdevdata(sd);
1049        struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1050
1051        cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1052                V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1053                V4L2_MBUS_DATA_ACTIVE_HIGH;
1054        cfg->type = V4L2_MBUS_PARALLEL;
1055        cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
1056
1057        return 0;
1058}
1059
1060static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
1061        .s_stream       = ov2640_s_stream,
1062        .g_mbus_fmt     = ov2640_g_fmt,
1063        .s_mbus_fmt     = ov2640_s_fmt,
1064        .try_mbus_fmt   = ov2640_try_fmt,
1065        .cropcap        = ov2640_cropcap,
1066        .g_crop         = ov2640_g_crop,
1067        .enum_mbus_fmt  = ov2640_enum_fmt,
1068        .g_mbus_config  = ov2640_g_mbus_config,
1069};
1070
1071static struct v4l2_subdev_ops ov2640_subdev_ops = {
1072        .core   = &ov2640_subdev_core_ops,
1073        .video  = &ov2640_subdev_video_ops,
1074};
1075
1076/*
1077 * i2c_driver functions
1078 */
1079static int ov2640_probe(struct i2c_client *client,
1080                        const struct i2c_device_id *did)
1081{
1082        struct ov2640_priv      *priv;
1083        struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1084        struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
1085        int                     ret;
1086
1087        if (!ssdd) {
1088                dev_err(&adapter->dev,
1089                        "OV2640: Missing platform_data for driver\n");
1090                return -EINVAL;
1091        }
1092
1093        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1094                dev_err(&adapter->dev,
1095                        "OV2640: I2C-Adapter doesn't support SMBUS\n");
1096                return -EIO;
1097        }
1098
1099        priv = devm_kzalloc(&client->dev, sizeof(struct ov2640_priv), GFP_KERNEL);
1100        if (!priv) {
1101                dev_err(&adapter->dev,
1102                        "Failed to allocate memory for private data!\n");
1103                return -ENOMEM;
1104        }
1105
1106        v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
1107        v4l2_ctrl_handler_init(&priv->hdl, 2);
1108        v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1109                        V4L2_CID_VFLIP, 0, 1, 1, 0);
1110        v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1111                        V4L2_CID_HFLIP, 0, 1, 1, 0);
1112        priv->subdev.ctrl_handler = &priv->hdl;
1113        if (priv->hdl.error)
1114                return priv->hdl.error;
1115
1116        ret = ov2640_video_probe(client);
1117        if (ret)
1118                v4l2_ctrl_handler_free(&priv->hdl);
1119        else
1120                dev_info(&adapter->dev, "OV2640 Probed\n");
1121
1122        return ret;
1123}
1124
1125static int ov2640_remove(struct i2c_client *client)
1126{
1127        struct ov2640_priv       *priv = to_ov2640(client);
1128
1129        v4l2_device_unregister_subdev(&priv->subdev);
1130        v4l2_ctrl_handler_free(&priv->hdl);
1131        return 0;
1132}
1133
1134static const struct i2c_device_id ov2640_id[] = {
1135        { "ov2640", 0 },
1136        { }
1137};
1138MODULE_DEVICE_TABLE(i2c, ov2640_id);
1139
1140static struct i2c_driver ov2640_i2c_driver = {
1141        .driver = {
1142                .name = "ov2640",
1143        },
1144        .probe    = ov2640_probe,
1145        .remove   = ov2640_remove,
1146        .id_table = ov2640_id,
1147};
1148
1149module_i2c_driver(ov2640_i2c_driver);
1150
1151MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor");
1152MODULE_AUTHOR("Alberto Panizzo");
1153MODULE_LICENSE("GPL v2");
1154