linux/drivers/media/i2c/ov2659.c
<<
>>
Prefs
   1/*
   2 * Omnivision OV2659 CMOS Image Sensor driver
   3 *
   4 * Copyright (C) 2015 Texas Instruments, Inc.
   5 *
   6 * Benoit Parrot <bparrot@ti.com>
   7 * Lad, Prabhakar <prabhakar.csengg@gmail.com>
   8 *
   9 * This program is free software; you may redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; version 2 of the License.
  12 *
  13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20 * SOFTWARE.
  21 */
  22
  23#include <linux/clk.h>
  24#include <linux/delay.h>
  25#include <linux/err.h>
  26#include <linux/init.h>
  27#include <linux/interrupt.h>
  28#include <linux/io.h>
  29#include <linux/i2c.h>
  30#include <linux/kernel.h>
  31#include <linux/media.h>
  32#include <linux/module.h>
  33#include <linux/of.h>
  34#include <linux/of_graph.h>
  35#include <linux/slab.h>
  36#include <linux/uaccess.h>
  37#include <linux/videodev2.h>
  38
  39#include <media/media-entity.h>
  40#include <media/i2c/ov2659.h>
  41#include <media/v4l2-common.h>
  42#include <media/v4l2-ctrls.h>
  43#include <media/v4l2-device.h>
  44#include <media/v4l2-event.h>
  45#include <media/v4l2-fwnode.h>
  46#include <media/v4l2-image-sizes.h>
  47#include <media/v4l2-mediabus.h>
  48#include <media/v4l2-subdev.h>
  49
  50#define DRIVER_NAME "ov2659"
  51
  52/*
  53 * OV2659 register definitions
  54 */
  55#define REG_SOFTWARE_STANDBY            0x0100
  56#define REG_SOFTWARE_RESET              0x0103
  57#define REG_IO_CTRL00                   0x3000
  58#define REG_IO_CTRL01                   0x3001
  59#define REG_IO_CTRL02                   0x3002
  60#define REG_OUTPUT_VALUE00              0x3008
  61#define REG_OUTPUT_VALUE01              0x3009
  62#define REG_OUTPUT_VALUE02              0x300d
  63#define REG_OUTPUT_SELECT00             0x300e
  64#define REG_OUTPUT_SELECT01             0x300f
  65#define REG_OUTPUT_SELECT02             0x3010
  66#define REG_OUTPUT_DRIVE                0x3011
  67#define REG_INPUT_READOUT00             0x302d
  68#define REG_INPUT_READOUT01             0x302e
  69#define REG_INPUT_READOUT02             0x302f
  70
  71#define REG_SC_PLL_CTRL0                0x3003
  72#define REG_SC_PLL_CTRL1                0x3004
  73#define REG_SC_PLL_CTRL2                0x3005
  74#define REG_SC_PLL_CTRL3                0x3006
  75#define REG_SC_CHIP_ID_H                0x300a
  76#define REG_SC_CHIP_ID_L                0x300b
  77#define REG_SC_PWC                      0x3014
  78#define REG_SC_CLKRST0                  0x301a
  79#define REG_SC_CLKRST1                  0x301b
  80#define REG_SC_CLKRST2                  0x301c
  81#define REG_SC_CLKRST3                  0x301d
  82#define REG_SC_SUB_ID                   0x302a
  83#define REG_SC_SCCB_ID                  0x302b
  84
  85#define REG_GROUP_ADDRESS_00            0x3200
  86#define REG_GROUP_ADDRESS_01            0x3201
  87#define REG_GROUP_ADDRESS_02            0x3202
  88#define REG_GROUP_ADDRESS_03            0x3203
  89#define REG_GROUP_ACCESS                0x3208
  90
  91#define REG_AWB_R_GAIN_H                0x3400
  92#define REG_AWB_R_GAIN_L                0x3401
  93#define REG_AWB_G_GAIN_H                0x3402
  94#define REG_AWB_G_GAIN_L                0x3403
  95#define REG_AWB_B_GAIN_H                0x3404
  96#define REG_AWB_B_GAIN_L                0x3405
  97#define REG_AWB_MANUAL_CONTROL          0x3406
  98
  99#define REG_TIMING_HS_H                 0x3800
 100#define REG_TIMING_HS_L                 0x3801
 101#define REG_TIMING_VS_H                 0x3802
 102#define REG_TIMING_VS_L                 0x3803
 103#define REG_TIMING_HW_H                 0x3804
 104#define REG_TIMING_HW_L                 0x3805
 105#define REG_TIMING_VH_H                 0x3806
 106#define REG_TIMING_VH_L                 0x3807
 107#define REG_TIMING_DVPHO_H              0x3808
 108#define REG_TIMING_DVPHO_L              0x3809
 109#define REG_TIMING_DVPVO_H              0x380a
 110#define REG_TIMING_DVPVO_L              0x380b
 111#define REG_TIMING_HTS_H                0x380c
 112#define REG_TIMING_HTS_L                0x380d
 113#define REG_TIMING_VTS_H                0x380e
 114#define REG_TIMING_VTS_L                0x380f
 115#define REG_TIMING_HOFFS_H              0x3810
 116#define REG_TIMING_HOFFS_L              0x3811
 117#define REG_TIMING_VOFFS_H              0x3812
 118#define REG_TIMING_VOFFS_L              0x3813
 119#define REG_TIMING_XINC                 0x3814
 120#define REG_TIMING_YINC                 0x3815
 121#define REG_TIMING_VERT_FORMAT          0x3820
 122#define REG_TIMING_HORIZ_FORMAT         0x3821
 123
 124#define REG_FORMAT_CTRL00               0x4300
 125
 126#define REG_VFIFO_READ_START_H          0x4608
 127#define REG_VFIFO_READ_START_L          0x4609
 128
 129#define REG_DVP_CTRL02                  0x4708
 130
 131#define REG_ISP_CTRL00                  0x5000
 132#define REG_ISP_CTRL01                  0x5001
 133#define REG_ISP_CTRL02                  0x5002
 134
 135#define REG_LENC_RED_X0_H               0x500c
 136#define REG_LENC_RED_X0_L               0x500d
 137#define REG_LENC_RED_Y0_H               0x500e
 138#define REG_LENC_RED_Y0_L               0x500f
 139#define REG_LENC_RED_A1                 0x5010
 140#define REG_LENC_RED_B1                 0x5011
 141#define REG_LENC_RED_A2_B2              0x5012
 142#define REG_LENC_GREEN_X0_H             0x5013
 143#define REG_LENC_GREEN_X0_L             0x5014
 144#define REG_LENC_GREEN_Y0_H             0x5015
 145#define REG_LENC_GREEN_Y0_L             0x5016
 146#define REG_LENC_GREEN_A1               0x5017
 147#define REG_LENC_GREEN_B1               0x5018
 148#define REG_LENC_GREEN_A2_B2            0x5019
 149#define REG_LENC_BLUE_X0_H              0x501a
 150#define REG_LENC_BLUE_X0_L              0x501b
 151#define REG_LENC_BLUE_Y0_H              0x501c
 152#define REG_LENC_BLUE_Y0_L              0x501d
 153#define REG_LENC_BLUE_A1                0x501e
 154#define REG_LENC_BLUE_B1                0x501f
 155#define REG_LENC_BLUE_A2_B2             0x5020
 156
 157#define REG_AWB_CTRL00                  0x5035
 158#define REG_AWB_CTRL01                  0x5036
 159#define REG_AWB_CTRL02                  0x5037
 160#define REG_AWB_CTRL03                  0x5038
 161#define REG_AWB_CTRL04                  0x5039
 162#define REG_AWB_LOCAL_LIMIT             0x503a
 163#define REG_AWB_CTRL12                  0x5049
 164#define REG_AWB_CTRL13                  0x504a
 165#define REG_AWB_CTRL14                  0x504b
 166
 167#define REG_SHARPENMT_THRESH1           0x5064
 168#define REG_SHARPENMT_THRESH2           0x5065
 169#define REG_SHARPENMT_OFFSET1           0x5066
 170#define REG_SHARPENMT_OFFSET2           0x5067
 171#define REG_DENOISE_THRESH1             0x5068
 172#define REG_DENOISE_THRESH2             0x5069
 173#define REG_DENOISE_OFFSET1             0x506a
 174#define REG_DENOISE_OFFSET2             0x506b
 175#define REG_SHARPEN_THRESH1             0x506c
 176#define REG_SHARPEN_THRESH2             0x506d
 177#define REG_CIP_CTRL00                  0x506e
 178#define REG_CIP_CTRL01                  0x506f
 179
 180#define REG_CMX_SIGN                    0x5079
 181#define REG_CMX_MISC_CTRL               0x507a
 182
 183#define REG_PRE_ISP_CTRL00              0x50a0
 184#define TEST_PATTERN_ENABLE             BIT(7)
 185#define VERTICAL_COLOR_BAR_MASK         0x53
 186
 187#define REG_NULL                        0x0000  /* Array end token */
 188
 189#define OV265X_ID(_msb, _lsb)           ((_msb) << 8 | (_lsb))
 190#define OV2659_ID                       0x2656
 191
 192struct sensor_register {
 193        u16 addr;
 194        u8 value;
 195};
 196
 197struct ov2659_framesize {
 198        u16 width;
 199        u16 height;
 200        u16 max_exp_lines;
 201        const struct sensor_register *regs;
 202};
 203
 204struct ov2659_pll_ctrl {
 205        u8 ctrl1;
 206        u8 ctrl2;
 207        u8 ctrl3;
 208};
 209
 210struct ov2659_pixfmt {
 211        u32 code;
 212        /* Output format Register Value (REG_FORMAT_CTRL00) */
 213        struct sensor_register *format_ctrl_regs;
 214};
 215
 216struct pll_ctrl_reg {
 217        unsigned int div;
 218        unsigned char reg;
 219};
 220
 221struct ov2659 {
 222        struct v4l2_subdev sd;
 223        struct media_pad pad;
 224        struct v4l2_mbus_framefmt format;
 225        unsigned int xvclk_frequency;
 226        const struct ov2659_platform_data *pdata;
 227        struct mutex lock;
 228        struct i2c_client *client;
 229        struct v4l2_ctrl_handler ctrls;
 230        struct v4l2_ctrl *link_frequency;
 231        const struct ov2659_framesize *frame_size;
 232        struct sensor_register *format_ctrl_regs;
 233        struct ov2659_pll_ctrl pll;
 234        int streaming;
 235};
 236
 237static const struct sensor_register ov2659_init_regs[] = {
 238        { REG_IO_CTRL00, 0x03 },
 239        { REG_IO_CTRL01, 0xff },
 240        { REG_IO_CTRL02, 0xe0 },
 241        { 0x3633, 0x3d },
 242        { 0x3620, 0x02 },
 243        { 0x3631, 0x11 },
 244        { 0x3612, 0x04 },
 245        { 0x3630, 0x20 },
 246        { 0x4702, 0x02 },
 247        { 0x370c, 0x34 },
 248        { REG_TIMING_HS_H, 0x00 },
 249        { REG_TIMING_HS_L, 0x00 },
 250        { REG_TIMING_VS_H, 0x00 },
 251        { REG_TIMING_VS_L, 0x00 },
 252        { REG_TIMING_HW_H, 0x06 },
 253        { REG_TIMING_HW_L, 0x5f },
 254        { REG_TIMING_VH_H, 0x04 },
 255        { REG_TIMING_VH_L, 0xb7 },
 256        { REG_TIMING_DVPHO_H, 0x03 },
 257        { REG_TIMING_DVPHO_L, 0x20 },
 258        { REG_TIMING_DVPVO_H, 0x02 },
 259        { REG_TIMING_DVPVO_L, 0x58 },
 260        { REG_TIMING_HTS_H, 0x05 },
 261        { REG_TIMING_HTS_L, 0x14 },
 262        { REG_TIMING_VTS_H, 0x02 },
 263        { REG_TIMING_VTS_L, 0x68 },
 264        { REG_TIMING_HOFFS_L, 0x08 },
 265        { REG_TIMING_VOFFS_L, 0x02 },
 266        { REG_TIMING_XINC, 0x31 },
 267        { REG_TIMING_YINC, 0x31 },
 268        { 0x3a02, 0x02 },
 269        { 0x3a03, 0x68 },
 270        { 0x3a08, 0x00 },
 271        { 0x3a09, 0x5c },
 272        { 0x3a0a, 0x00 },
 273        { 0x3a0b, 0x4d },
 274        { 0x3a0d, 0x08 },
 275        { 0x3a0e, 0x06 },
 276        { 0x3a14, 0x02 },
 277        { 0x3a15, 0x28 },
 278        { REG_DVP_CTRL02, 0x01 },
 279        { 0x3623, 0x00 },
 280        { 0x3634, 0x76 },
 281        { 0x3701, 0x44 },
 282        { 0x3702, 0x18 },
 283        { 0x3703, 0x24 },
 284        { 0x3704, 0x24 },
 285        { 0x3705, 0x0c },
 286        { REG_TIMING_VERT_FORMAT, 0x81 },
 287        { REG_TIMING_HORIZ_FORMAT, 0x01 },
 288        { 0x370a, 0x52 },
 289        { REG_VFIFO_READ_START_H, 0x00 },
 290        { REG_VFIFO_READ_START_L, 0x80 },
 291        { REG_FORMAT_CTRL00, 0x30 },
 292        { 0x5086, 0x02 },
 293        { REG_ISP_CTRL00, 0xfb },
 294        { REG_ISP_CTRL01, 0x1f },
 295        { REG_ISP_CTRL02, 0x00 },
 296        { 0x5025, 0x0e },
 297        { 0x5026, 0x18 },
 298        { 0x5027, 0x34 },
 299        { 0x5028, 0x4c },
 300        { 0x5029, 0x62 },
 301        { 0x502a, 0x74 },
 302        { 0x502b, 0x85 },
 303        { 0x502c, 0x92 },
 304        { 0x502d, 0x9e },
 305        { 0x502e, 0xb2 },
 306        { 0x502f, 0xc0 },
 307        { 0x5030, 0xcc },
 308        { 0x5031, 0xe0 },
 309        { 0x5032, 0xee },
 310        { 0x5033, 0xf6 },
 311        { 0x5034, 0x11 },
 312        { 0x5070, 0x1c },
 313        { 0x5071, 0x5b },
 314        { 0x5072, 0x05 },
 315        { 0x5073, 0x20 },
 316        { 0x5074, 0x94 },
 317        { 0x5075, 0xb4 },
 318        { 0x5076, 0xb4 },
 319        { 0x5077, 0xaf },
 320        { 0x5078, 0x05 },
 321        { REG_CMX_SIGN, 0x98 },
 322        { REG_CMX_MISC_CTRL, 0x21 },
 323        { REG_AWB_CTRL00, 0x6a },
 324        { REG_AWB_CTRL01, 0x11 },
 325        { REG_AWB_CTRL02, 0x92 },
 326        { REG_AWB_CTRL03, 0x21 },
 327        { REG_AWB_CTRL04, 0xe1 },
 328        { REG_AWB_LOCAL_LIMIT, 0x01 },
 329        { 0x503c, 0x05 },
 330        { 0x503d, 0x08 },
 331        { 0x503e, 0x08 },
 332        { 0x503f, 0x64 },
 333        { 0x5040, 0x58 },
 334        { 0x5041, 0x2a },
 335        { 0x5042, 0xc5 },
 336        { 0x5043, 0x2e },
 337        { 0x5044, 0x3a },
 338        { 0x5045, 0x3c },
 339        { 0x5046, 0x44 },
 340        { 0x5047, 0xf8 },
 341        { 0x5048, 0x08 },
 342        { REG_AWB_CTRL12, 0x70 },
 343        { REG_AWB_CTRL13, 0xf0 },
 344        { REG_AWB_CTRL14, 0xf0 },
 345        { REG_LENC_RED_X0_H, 0x03 },
 346        { REG_LENC_RED_X0_L, 0x20 },
 347        { REG_LENC_RED_Y0_H, 0x02 },
 348        { REG_LENC_RED_Y0_L, 0x5c },
 349        { REG_LENC_RED_A1, 0x48 },
 350        { REG_LENC_RED_B1, 0x00 },
 351        { REG_LENC_RED_A2_B2, 0x66 },
 352        { REG_LENC_GREEN_X0_H, 0x03 },
 353        { REG_LENC_GREEN_X0_L, 0x30 },
 354        { REG_LENC_GREEN_Y0_H, 0x02 },
 355        { REG_LENC_GREEN_Y0_L, 0x7c },
 356        { REG_LENC_GREEN_A1, 0x40 },
 357        { REG_LENC_GREEN_B1, 0x00 },
 358        { REG_LENC_GREEN_A2_B2, 0x66 },
 359        { REG_LENC_BLUE_X0_H, 0x03 },
 360        { REG_LENC_BLUE_X0_L, 0x10 },
 361        { REG_LENC_BLUE_Y0_H, 0x02 },
 362        { REG_LENC_BLUE_Y0_L, 0x7c },
 363        { REG_LENC_BLUE_A1, 0x3a },
 364        { REG_LENC_BLUE_B1, 0x00 },
 365        { REG_LENC_BLUE_A2_B2, 0x66 },
 366        { REG_CIP_CTRL00, 0x44 },
 367        { REG_SHARPENMT_THRESH1, 0x08 },
 368        { REG_SHARPENMT_THRESH2, 0x10 },
 369        { REG_SHARPENMT_OFFSET1, 0x12 },
 370        { REG_SHARPENMT_OFFSET2, 0x02 },
 371        { REG_SHARPEN_THRESH1, 0x08 },
 372        { REG_SHARPEN_THRESH2, 0x10 },
 373        { REG_CIP_CTRL01, 0xa6 },
 374        { REG_DENOISE_THRESH1, 0x08 },
 375        { REG_DENOISE_THRESH2, 0x10 },
 376        { REG_DENOISE_OFFSET1, 0x04 },
 377        { REG_DENOISE_OFFSET2, 0x12 },
 378        { 0x507e, 0x40 },
 379        { 0x507f, 0x20 },
 380        { 0x507b, 0x02 },
 381        { REG_CMX_MISC_CTRL, 0x01 },
 382        { 0x5084, 0x0c },
 383        { 0x5085, 0x3e },
 384        { 0x5005, 0x80 },
 385        { 0x3a0f, 0x30 },
 386        { 0x3a10, 0x28 },
 387        { 0x3a1b, 0x32 },
 388        { 0x3a1e, 0x26 },
 389        { 0x3a11, 0x60 },
 390        { 0x3a1f, 0x14 },
 391        { 0x5060, 0x69 },
 392        { 0x5061, 0x7d },
 393        { 0x5062, 0x7d },
 394        { 0x5063, 0x69 },
 395        { REG_NULL, 0x00 },
 396};
 397
 398/* 1280X720 720p */
 399static struct sensor_register ov2659_720p[] = {
 400        { REG_TIMING_HS_H, 0x00 },
 401        { REG_TIMING_HS_L, 0xa0 },
 402        { REG_TIMING_VS_H, 0x00 },
 403        { REG_TIMING_VS_L, 0xf0 },
 404        { REG_TIMING_HW_H, 0x05 },
 405        { REG_TIMING_HW_L, 0xbf },
 406        { REG_TIMING_VH_H, 0x03 },
 407        { REG_TIMING_VH_L, 0xcb },
 408        { REG_TIMING_DVPHO_H, 0x05 },
 409        { REG_TIMING_DVPHO_L, 0x00 },
 410        { REG_TIMING_DVPVO_H, 0x02 },
 411        { REG_TIMING_DVPVO_L, 0xd0 },
 412        { REG_TIMING_HTS_H, 0x06 },
 413        { REG_TIMING_HTS_L, 0x4c },
 414        { REG_TIMING_VTS_H, 0x02 },
 415        { REG_TIMING_VTS_L, 0xe8 },
 416        { REG_TIMING_HOFFS_L, 0x10 },
 417        { REG_TIMING_VOFFS_L, 0x06 },
 418        { REG_TIMING_XINC, 0x11 },
 419        { REG_TIMING_YINC, 0x11 },
 420        { REG_TIMING_VERT_FORMAT, 0x80 },
 421        { REG_TIMING_HORIZ_FORMAT, 0x00 },
 422        { 0x3a03, 0xe8 },
 423        { 0x3a09, 0x6f },
 424        { 0x3a0b, 0x5d },
 425        { 0x3a15, 0x9a },
 426        { REG_NULL, 0x00 },
 427};
 428
 429/* 1600X1200 UXGA */
 430static struct sensor_register ov2659_uxga[] = {
 431        { REG_TIMING_HS_H, 0x00 },
 432        { REG_TIMING_HS_L, 0x00 },
 433        { REG_TIMING_VS_H, 0x00 },
 434        { REG_TIMING_VS_L, 0x00 },
 435        { REG_TIMING_HW_H, 0x06 },
 436        { REG_TIMING_HW_L, 0x5f },
 437        { REG_TIMING_VH_H, 0x04 },
 438        { REG_TIMING_VH_L, 0xbb },
 439        { REG_TIMING_DVPHO_H, 0x06 },
 440        { REG_TIMING_DVPHO_L, 0x40 },
 441        { REG_TIMING_DVPVO_H, 0x04 },
 442        { REG_TIMING_DVPVO_L, 0xb0 },
 443        { REG_TIMING_HTS_H, 0x07 },
 444        { REG_TIMING_HTS_L, 0x9f },
 445        { REG_TIMING_VTS_H, 0x04 },
 446        { REG_TIMING_VTS_L, 0xd0 },
 447        { REG_TIMING_HOFFS_L, 0x10 },
 448        { REG_TIMING_VOFFS_L, 0x06 },
 449        { REG_TIMING_XINC, 0x11 },
 450        { REG_TIMING_YINC, 0x11 },
 451        { 0x3a02, 0x04 },
 452        { 0x3a03, 0xd0 },
 453        { 0x3a08, 0x00 },
 454        { 0x3a09, 0xb8 },
 455        { 0x3a0a, 0x00 },
 456        { 0x3a0b, 0x9a },
 457        { 0x3a0d, 0x08 },
 458        { 0x3a0e, 0x06 },
 459        { 0x3a14, 0x04 },
 460        { 0x3a15, 0x50 },
 461        { 0x3623, 0x00 },
 462        { 0x3634, 0x44 },
 463        { 0x3701, 0x44 },
 464        { 0x3702, 0x30 },
 465        { 0x3703, 0x48 },
 466        { 0x3704, 0x48 },
 467        { 0x3705, 0x18 },
 468        { REG_TIMING_VERT_FORMAT, 0x80 },
 469        { REG_TIMING_HORIZ_FORMAT, 0x00 },
 470        { 0x370a, 0x12 },
 471        { REG_VFIFO_READ_START_H, 0x00 },
 472        { REG_VFIFO_READ_START_L, 0x80 },
 473        { REG_ISP_CTRL02, 0x00 },
 474        { REG_NULL, 0x00 },
 475};
 476
 477/* 1280X1024 SXGA */
 478static struct sensor_register ov2659_sxga[] = {
 479        { REG_TIMING_HS_H, 0x00 },
 480        { REG_TIMING_HS_L, 0x00 },
 481        { REG_TIMING_VS_H, 0x00 },
 482        { REG_TIMING_VS_L, 0x00 },
 483        { REG_TIMING_HW_H, 0x06 },
 484        { REG_TIMING_HW_L, 0x5f },
 485        { REG_TIMING_VH_H, 0x04 },
 486        { REG_TIMING_VH_L, 0xb7 },
 487        { REG_TIMING_DVPHO_H, 0x05 },
 488        { REG_TIMING_DVPHO_L, 0x00 },
 489        { REG_TIMING_DVPVO_H, 0x04 },
 490        { REG_TIMING_DVPVO_L, 0x00 },
 491        { REG_TIMING_HTS_H, 0x07 },
 492        { REG_TIMING_HTS_L, 0x9c },
 493        { REG_TIMING_VTS_H, 0x04 },
 494        { REG_TIMING_VTS_L, 0xd0 },
 495        { REG_TIMING_HOFFS_L, 0x10 },
 496        { REG_TIMING_VOFFS_L, 0x06 },
 497        { REG_TIMING_XINC, 0x11 },
 498        { REG_TIMING_YINC, 0x11 },
 499        { 0x3a02, 0x02 },
 500        { 0x3a03, 0x68 },
 501        { 0x3a08, 0x00 },
 502        { 0x3a09, 0x5c },
 503        { 0x3a0a, 0x00 },
 504        { 0x3a0b, 0x4d },
 505        { 0x3a0d, 0x08 },
 506        { 0x3a0e, 0x06 },
 507        { 0x3a14, 0x02 },
 508        { 0x3a15, 0x28 },
 509        { 0x3623, 0x00 },
 510        { 0x3634, 0x76 },
 511        { 0x3701, 0x44 },
 512        { 0x3702, 0x18 },
 513        { 0x3703, 0x24 },
 514        { 0x3704, 0x24 },
 515        { 0x3705, 0x0c },
 516        { REG_TIMING_VERT_FORMAT, 0x80 },
 517        { REG_TIMING_HORIZ_FORMAT, 0x00 },
 518        { 0x370a, 0x52 },
 519        { REG_VFIFO_READ_START_H, 0x00 },
 520        { REG_VFIFO_READ_START_L, 0x80 },
 521        { REG_ISP_CTRL02, 0x00 },
 522        { REG_NULL, 0x00 },
 523};
 524
 525/* 1024X768 SXGA */
 526static struct sensor_register ov2659_xga[] = {
 527        { REG_TIMING_HS_H, 0x00 },
 528        { REG_TIMING_HS_L, 0x00 },
 529        { REG_TIMING_VS_H, 0x00 },
 530        { REG_TIMING_VS_L, 0x00 },
 531        { REG_TIMING_HW_H, 0x06 },
 532        { REG_TIMING_HW_L, 0x5f },
 533        { REG_TIMING_VH_H, 0x04 },
 534        { REG_TIMING_VH_L, 0xb7 },
 535        { REG_TIMING_DVPHO_H, 0x04 },
 536        { REG_TIMING_DVPHO_L, 0x00 },
 537        { REG_TIMING_DVPVO_H, 0x03 },
 538        { REG_TIMING_DVPVO_L, 0x00 },
 539        { REG_TIMING_HTS_H, 0x07 },
 540        { REG_TIMING_HTS_L, 0x9c },
 541        { REG_TIMING_VTS_H, 0x04 },
 542        { REG_TIMING_VTS_L, 0xd0 },
 543        { REG_TIMING_HOFFS_L, 0x10 },
 544        { REG_TIMING_VOFFS_L, 0x06 },
 545        { REG_TIMING_XINC, 0x11 },
 546        { REG_TIMING_YINC, 0x11 },
 547        { 0x3a02, 0x02 },
 548        { 0x3a03, 0x68 },
 549        { 0x3a08, 0x00 },
 550        { 0x3a09, 0x5c },
 551        { 0x3a0a, 0x00 },
 552        { 0x3a0b, 0x4d },
 553        { 0x3a0d, 0x08 },
 554        { 0x3a0e, 0x06 },
 555        { 0x3a14, 0x02 },
 556        { 0x3a15, 0x28 },
 557        { 0x3623, 0x00 },
 558        { 0x3634, 0x76 },
 559        { 0x3701, 0x44 },
 560        { 0x3702, 0x18 },
 561        { 0x3703, 0x24 },
 562        { 0x3704, 0x24 },
 563        { 0x3705, 0x0c },
 564        { REG_TIMING_VERT_FORMAT, 0x80 },
 565        { REG_TIMING_HORIZ_FORMAT, 0x00 },
 566        { 0x370a, 0x52 },
 567        { REG_VFIFO_READ_START_H, 0x00 },
 568        { REG_VFIFO_READ_START_L, 0x80 },
 569        { REG_ISP_CTRL02, 0x00 },
 570        { REG_NULL, 0x00 },
 571};
 572
 573/* 800X600 SVGA */
 574static struct sensor_register ov2659_svga[] = {
 575        { REG_TIMING_HS_H, 0x00 },
 576        { REG_TIMING_HS_L, 0x00 },
 577        { REG_TIMING_VS_H, 0x00 },
 578        { REG_TIMING_VS_L, 0x00 },
 579        { REG_TIMING_HW_H, 0x06 },
 580        { REG_TIMING_HW_L, 0x5f },
 581        { REG_TIMING_VH_H, 0x04 },
 582        { REG_TIMING_VH_L, 0xb7 },
 583        { REG_TIMING_DVPHO_H, 0x03 },
 584        { REG_TIMING_DVPHO_L, 0x20 },
 585        { REG_TIMING_DVPVO_H, 0x02 },
 586        { REG_TIMING_DVPVO_L, 0x58 },
 587        { REG_TIMING_HTS_H, 0x05 },
 588        { REG_TIMING_HTS_L, 0x14 },
 589        { REG_TIMING_VTS_H, 0x02 },
 590        { REG_TIMING_VTS_L, 0x68 },
 591        { REG_TIMING_HOFFS_L, 0x08 },
 592        { REG_TIMING_VOFFS_L, 0x02 },
 593        { REG_TIMING_XINC, 0x31 },
 594        { REG_TIMING_YINC, 0x31 },
 595        { 0x3a02, 0x02 },
 596        { 0x3a03, 0x68 },
 597        { 0x3a08, 0x00 },
 598        { 0x3a09, 0x5c },
 599        { 0x3a0a, 0x00 },
 600        { 0x3a0b, 0x4d },
 601        { 0x3a0d, 0x08 },
 602        { 0x3a0e, 0x06 },
 603        { 0x3a14, 0x02 },
 604        { 0x3a15, 0x28 },
 605        { 0x3623, 0x00 },
 606        { 0x3634, 0x76 },
 607        { 0x3701, 0x44 },
 608        { 0x3702, 0x18 },
 609        { 0x3703, 0x24 },
 610        { 0x3704, 0x24 },
 611        { 0x3705, 0x0c },
 612        { REG_TIMING_VERT_FORMAT, 0x81 },
 613        { REG_TIMING_HORIZ_FORMAT, 0x01 },
 614        { 0x370a, 0x52 },
 615        { REG_VFIFO_READ_START_H, 0x00 },
 616        { REG_VFIFO_READ_START_L, 0x80 },
 617        { REG_ISP_CTRL02, 0x00 },
 618        { REG_NULL, 0x00 },
 619};
 620
 621/* 640X480 VGA */
 622static struct sensor_register ov2659_vga[] = {
 623        { REG_TIMING_HS_H, 0x00 },
 624        { REG_TIMING_HS_L, 0x00 },
 625        { REG_TIMING_VS_H, 0x00 },
 626        { REG_TIMING_VS_L, 0x00 },
 627        { REG_TIMING_HW_H, 0x06 },
 628        { REG_TIMING_HW_L, 0x5f },
 629        { REG_TIMING_VH_H, 0x04 },
 630        { REG_TIMING_VH_L, 0xb7 },
 631        { REG_TIMING_DVPHO_H, 0x02 },
 632        { REG_TIMING_DVPHO_L, 0x80 },
 633        { REG_TIMING_DVPVO_H, 0x01 },
 634        { REG_TIMING_DVPVO_L, 0xe0 },
 635        { REG_TIMING_HTS_H, 0x05 },
 636        { REG_TIMING_HTS_L, 0x14 },
 637        { REG_TIMING_VTS_H, 0x02 },
 638        { REG_TIMING_VTS_L, 0x68 },
 639        { REG_TIMING_HOFFS_L, 0x08 },
 640        { REG_TIMING_VOFFS_L, 0x02 },
 641        { REG_TIMING_XINC, 0x31 },
 642        { REG_TIMING_YINC, 0x31 },
 643        { 0x3a02, 0x02 },
 644        { 0x3a03, 0x68 },
 645        { 0x3a08, 0x00 },
 646        { 0x3a09, 0x5c },
 647        { 0x3a0a, 0x00 },
 648        { 0x3a0b, 0x4d },
 649        { 0x3a0d, 0x08 },
 650        { 0x3a0e, 0x06 },
 651        { 0x3a14, 0x02 },
 652        { 0x3a15, 0x28 },
 653        { 0x3623, 0x00 },
 654        { 0x3634, 0x76 },
 655        { 0x3701, 0x44 },
 656        { 0x3702, 0x18 },
 657        { 0x3703, 0x24 },
 658        { 0x3704, 0x24 },
 659        { 0x3705, 0x0c },
 660        { REG_TIMING_VERT_FORMAT, 0x81 },
 661        { REG_TIMING_HORIZ_FORMAT, 0x01 },
 662        { 0x370a, 0x52 },
 663        { REG_VFIFO_READ_START_H, 0x00 },
 664        { REG_VFIFO_READ_START_L, 0x80 },
 665        { REG_ISP_CTRL02, 0x10 },
 666        { REG_NULL, 0x00 },
 667};
 668
 669/* 320X240 QVGA */
 670static  struct sensor_register ov2659_qvga[] = {
 671        { REG_TIMING_HS_H, 0x00 },
 672        { REG_TIMING_HS_L, 0x00 },
 673        { REG_TIMING_VS_H, 0x00 },
 674        { REG_TIMING_VS_L, 0x00 },
 675        { REG_TIMING_HW_H, 0x06 },
 676        { REG_TIMING_HW_L, 0x5f },
 677        { REG_TIMING_VH_H, 0x04 },
 678        { REG_TIMING_VH_L, 0xb7 },
 679        { REG_TIMING_DVPHO_H, 0x01 },
 680        { REG_TIMING_DVPHO_L, 0x40 },
 681        { REG_TIMING_DVPVO_H, 0x00 },
 682        { REG_TIMING_DVPVO_L, 0xf0 },
 683        { REG_TIMING_HTS_H, 0x05 },
 684        { REG_TIMING_HTS_L, 0x14 },
 685        { REG_TIMING_VTS_H, 0x02 },
 686        { REG_TIMING_VTS_L, 0x68 },
 687        { REG_TIMING_HOFFS_L, 0x08 },
 688        { REG_TIMING_VOFFS_L, 0x02 },
 689        { REG_TIMING_XINC, 0x31 },
 690        { REG_TIMING_YINC, 0x31 },
 691        { 0x3a02, 0x02 },
 692        { 0x3a03, 0x68 },
 693        { 0x3a08, 0x00 },
 694        { 0x3a09, 0x5c },
 695        { 0x3a0a, 0x00 },
 696        { 0x3a0b, 0x4d },
 697        { 0x3a0d, 0x08 },
 698        { 0x3a0e, 0x06 },
 699        { 0x3a14, 0x02 },
 700        { 0x3a15, 0x28 },
 701        { 0x3623, 0x00 },
 702        { 0x3634, 0x76 },
 703        { 0x3701, 0x44 },
 704        { 0x3702, 0x18 },
 705        { 0x3703, 0x24 },
 706        { 0x3704, 0x24 },
 707        { 0x3705, 0x0c },
 708        { REG_TIMING_VERT_FORMAT, 0x81 },
 709        { REG_TIMING_HORIZ_FORMAT, 0x01 },
 710        { 0x370a, 0x52 },
 711        { REG_VFIFO_READ_START_H, 0x00 },
 712        { REG_VFIFO_READ_START_L, 0x80 },
 713        { REG_ISP_CTRL02, 0x10 },
 714        { REG_NULL, 0x00 },
 715};
 716
 717static const struct pll_ctrl_reg ctrl3[] = {
 718        { 1, 0x00 },
 719        { 2, 0x02 },
 720        { 3, 0x03 },
 721        { 4, 0x06 },
 722        { 6, 0x0d },
 723        { 8, 0x0e },
 724        { 12, 0x0f },
 725        { 16, 0x12 },
 726        { 24, 0x13 },
 727        { 32, 0x16 },
 728        { 48, 0x1b },
 729        { 64, 0x1e },
 730        { 96, 0x1f },
 731        { 0, 0x00 },
 732};
 733
 734static const struct pll_ctrl_reg ctrl1[] = {
 735        { 2, 0x10 },
 736        { 4, 0x20 },
 737        { 6, 0x30 },
 738        { 8, 0x40 },
 739        { 10, 0x50 },
 740        { 12, 0x60 },
 741        { 14, 0x70 },
 742        { 16, 0x80 },
 743        { 18, 0x90 },
 744        { 20, 0xa0 },
 745        { 22, 0xb0 },
 746        { 24, 0xc0 },
 747        { 26, 0xd0 },
 748        { 28, 0xe0 },
 749        { 30, 0xf0 },
 750        { 0, 0x00 },
 751};
 752
 753static const struct ov2659_framesize ov2659_framesizes[] = {
 754        { /* QVGA */
 755                .width          = 320,
 756                .height         = 240,
 757                .regs           = ov2659_qvga,
 758                .max_exp_lines  = 248,
 759        }, { /* VGA */
 760                .width          = 640,
 761                .height         = 480,
 762                .regs           = ov2659_vga,
 763                .max_exp_lines  = 498,
 764        }, { /* SVGA */
 765                .width          = 800,
 766                .height         = 600,
 767                .regs           = ov2659_svga,
 768                .max_exp_lines  = 498,
 769        }, { /* XGA */
 770                .width          = 1024,
 771                .height         = 768,
 772                .regs           = ov2659_xga,
 773                .max_exp_lines  = 498,
 774        }, { /* 720P */
 775                .width          = 1280,
 776                .height         = 720,
 777                .regs           = ov2659_720p,
 778                .max_exp_lines  = 498,
 779        }, { /* SXGA */
 780                .width          = 1280,
 781                .height         = 1024,
 782                .regs           = ov2659_sxga,
 783                .max_exp_lines  = 1048,
 784        }, { /* UXGA */
 785                .width          = 1600,
 786                .height         = 1200,
 787                .regs           = ov2659_uxga,
 788                .max_exp_lines  = 498,
 789        },
 790};
 791
 792/* YUV422 YUYV*/
 793static struct sensor_register ov2659_format_yuyv[] = {
 794        { REG_FORMAT_CTRL00, 0x30 },
 795        { REG_NULL, 0x0 },
 796};
 797
 798/* YUV422 UYVY  */
 799static struct sensor_register ov2659_format_uyvy[] = {
 800        { REG_FORMAT_CTRL00, 0x32 },
 801        { REG_NULL, 0x0 },
 802};
 803
 804/* Raw Bayer BGGR */
 805static struct sensor_register ov2659_format_bggr[] = {
 806        { REG_FORMAT_CTRL00, 0x00 },
 807        { REG_NULL, 0x0 },
 808};
 809
 810/* RGB565 */
 811static struct sensor_register ov2659_format_rgb565[] = {
 812        { REG_FORMAT_CTRL00, 0x60 },
 813        { REG_NULL, 0x0 },
 814};
 815
 816static const struct ov2659_pixfmt ov2659_formats[] = {
 817        {
 818                .code = MEDIA_BUS_FMT_YUYV8_2X8,
 819                .format_ctrl_regs = ov2659_format_yuyv,
 820        }, {
 821                .code = MEDIA_BUS_FMT_UYVY8_2X8,
 822                .format_ctrl_regs = ov2659_format_uyvy,
 823        }, {
 824                .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
 825                .format_ctrl_regs = ov2659_format_rgb565,
 826        }, {
 827                .code = MEDIA_BUS_FMT_SBGGR8_1X8,
 828                .format_ctrl_regs = ov2659_format_bggr,
 829        },
 830};
 831
 832static inline struct ov2659 *to_ov2659(struct v4l2_subdev *sd)
 833{
 834        return container_of(sd, struct ov2659, sd);
 835}
 836
 837/* sensor register write */
 838static int ov2659_write(struct i2c_client *client, u16 reg, u8 val)
 839{
 840        struct i2c_msg msg;
 841        u8 buf[3];
 842        int ret;
 843
 844        buf[0] = reg >> 8;
 845        buf[1] = reg & 0xFF;
 846        buf[2] = val;
 847
 848        msg.addr = client->addr;
 849        msg.flags = client->flags;
 850        msg.buf = buf;
 851        msg.len = sizeof(buf);
 852
 853        ret = i2c_transfer(client->adapter, &msg, 1);
 854        if (ret >= 0)
 855                return 0;
 856
 857        dev_dbg(&client->dev,
 858                "ov2659 write reg(0x%x val:0x%x) failed !\n", reg, val);
 859
 860        return ret;
 861}
 862
 863/* sensor register read */
 864static int ov2659_read(struct i2c_client *client, u16 reg, u8 *val)
 865{
 866        struct i2c_msg msg[2];
 867        u8 buf[2];
 868        int ret;
 869
 870        buf[0] = reg >> 8;
 871        buf[1] = reg & 0xFF;
 872
 873        msg[0].addr = client->addr;
 874        msg[0].flags = client->flags;
 875        msg[0].buf = buf;
 876        msg[0].len = sizeof(buf);
 877
 878        msg[1].addr = client->addr;
 879        msg[1].flags = client->flags | I2C_M_RD;
 880        msg[1].buf = buf;
 881        msg[1].len = 1;
 882
 883        ret = i2c_transfer(client->adapter, msg, 2);
 884        if (ret >= 0) {
 885                *val = buf[0];
 886                return 0;
 887        }
 888
 889        dev_dbg(&client->dev,
 890                "ov2659 read reg(0x%x val:0x%x) failed !\n", reg, *val);
 891
 892        return ret;
 893}
 894
 895static int ov2659_write_array(struct i2c_client *client,
 896                              const struct sensor_register *regs)
 897{
 898        int i, ret = 0;
 899
 900        for (i = 0; ret == 0 && regs[i].addr; i++)
 901                ret = ov2659_write(client, regs[i].addr, regs[i].value);
 902
 903        return ret;
 904}
 905
 906static void ov2659_pll_calc_params(struct ov2659 *ov2659)
 907{
 908        const struct ov2659_platform_data *pdata = ov2659->pdata;
 909        u8 ctrl1_reg = 0, ctrl2_reg = 0, ctrl3_reg = 0;
 910        struct i2c_client *client = ov2659->client;
 911        unsigned int desired = pdata->link_frequency;
 912        u32 prediv, postdiv, mult;
 913        u32 bestdelta = -1;
 914        u32 delta, actual;
 915        int i, j;
 916
 917        for (i = 0; ctrl1[i].div != 0; i++) {
 918                postdiv = ctrl1[i].div;
 919                for (j = 0; ctrl3[j].div != 0; j++) {
 920                        prediv = ctrl3[j].div;
 921                        for (mult = 1; mult <= 63; mult++) {
 922                                actual  = ov2659->xvclk_frequency;
 923                                actual *= mult;
 924                                actual /= prediv;
 925                                actual /= postdiv;
 926                                delta = actual - desired;
 927                                delta = abs(delta);
 928
 929                                if ((delta < bestdelta) || (bestdelta == -1)) {
 930                                        bestdelta = delta;
 931                                        ctrl1_reg = ctrl1[i].reg;
 932                                        ctrl2_reg = mult;
 933                                        ctrl3_reg = ctrl3[j].reg;
 934                                }
 935                        }
 936                }
 937        }
 938
 939        ov2659->pll.ctrl1 = ctrl1_reg;
 940        ov2659->pll.ctrl2 = ctrl2_reg;
 941        ov2659->pll.ctrl3 = ctrl3_reg;
 942
 943        dev_dbg(&client->dev,
 944                "Actual reg config: ctrl1_reg: %02x ctrl2_reg: %02x ctrl3_reg: %02x\n",
 945                ctrl1_reg, ctrl2_reg, ctrl3_reg);
 946}
 947
 948static int ov2659_set_pixel_clock(struct ov2659 *ov2659)
 949{
 950        struct i2c_client *client = ov2659->client;
 951        struct sensor_register pll_regs[] = {
 952                {REG_SC_PLL_CTRL1, ov2659->pll.ctrl1},
 953                {REG_SC_PLL_CTRL2, ov2659->pll.ctrl2},
 954                {REG_SC_PLL_CTRL3, ov2659->pll.ctrl3},
 955                {REG_NULL, 0x00},
 956        };
 957
 958        dev_dbg(&client->dev, "%s\n", __func__);
 959
 960        return ov2659_write_array(client, pll_regs);
 961};
 962
 963static void ov2659_get_default_format(struct v4l2_mbus_framefmt *format)
 964{
 965        format->width = ov2659_framesizes[2].width;
 966        format->height = ov2659_framesizes[2].height;
 967        format->colorspace = V4L2_COLORSPACE_SRGB;
 968        format->code = ov2659_formats[0].code;
 969        format->field = V4L2_FIELD_NONE;
 970}
 971
 972static void ov2659_set_streaming(struct ov2659 *ov2659, int on)
 973{
 974        struct i2c_client *client = ov2659->client;
 975        int ret;
 976
 977        on = !!on;
 978
 979        dev_dbg(&client->dev, "%s: on: %d\n", __func__, on);
 980
 981        ret = ov2659_write(client, REG_SOFTWARE_STANDBY, on);
 982        if (ret)
 983                dev_err(&client->dev, "ov2659 soft standby failed\n");
 984}
 985
 986static int ov2659_init(struct v4l2_subdev *sd, u32 val)
 987{
 988        struct i2c_client *client = v4l2_get_subdevdata(sd);
 989
 990        return ov2659_write_array(client, ov2659_init_regs);
 991}
 992
 993/*
 994 * V4L2 subdev video and pad level operations
 995 */
 996
 997static int ov2659_enum_mbus_code(struct v4l2_subdev *sd,
 998                                 struct v4l2_subdev_pad_config *cfg,
 999                                 struct v4l2_subdev_mbus_code_enum *code)
1000{
1001        struct i2c_client *client = v4l2_get_subdevdata(sd);
1002
1003        dev_dbg(&client->dev, "%s:\n", __func__);
1004
1005        if (code->index >= ARRAY_SIZE(ov2659_formats))
1006                return -EINVAL;
1007
1008        code->code = ov2659_formats[code->index].code;
1009
1010        return 0;
1011}
1012
1013static int ov2659_enum_frame_sizes(struct v4l2_subdev *sd,
1014                                   struct v4l2_subdev_pad_config *cfg,
1015                                   struct v4l2_subdev_frame_size_enum *fse)
1016{
1017        struct i2c_client *client = v4l2_get_subdevdata(sd);
1018        int i = ARRAY_SIZE(ov2659_formats);
1019
1020        dev_dbg(&client->dev, "%s:\n", __func__);
1021
1022        if (fse->index >= ARRAY_SIZE(ov2659_framesizes))
1023                return -EINVAL;
1024
1025        while (--i)
1026                if (fse->code == ov2659_formats[i].code)
1027                        break;
1028
1029        fse->code = ov2659_formats[i].code;
1030
1031        fse->min_width  = ov2659_framesizes[fse->index].width;
1032        fse->max_width  = fse->min_width;
1033        fse->max_height = ov2659_framesizes[fse->index].height;
1034        fse->min_height = fse->max_height;
1035
1036        return 0;
1037}
1038
1039static int ov2659_get_fmt(struct v4l2_subdev *sd,
1040                          struct v4l2_subdev_pad_config *cfg,
1041                          struct v4l2_subdev_format *fmt)
1042{
1043        struct i2c_client *client = v4l2_get_subdevdata(sd);
1044        struct ov2659 *ov2659 = to_ov2659(sd);
1045
1046        dev_dbg(&client->dev, "ov2659_get_fmt\n");
1047
1048        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1049#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1050                struct v4l2_mbus_framefmt *mf;
1051
1052                mf = v4l2_subdev_get_try_format(sd, cfg, 0);
1053                mutex_lock(&ov2659->lock);
1054                fmt->format = *mf;
1055                mutex_unlock(&ov2659->lock);
1056                return 0;
1057#else
1058        return -ENOTTY;
1059#endif
1060        }
1061
1062        mutex_lock(&ov2659->lock);
1063        fmt->format = ov2659->format;
1064        mutex_unlock(&ov2659->lock);
1065
1066        dev_dbg(&client->dev, "ov2659_get_fmt: %x %dx%d\n",
1067                ov2659->format.code, ov2659->format.width,
1068                ov2659->format.height);
1069
1070        return 0;
1071}
1072
1073static void __ov2659_try_frame_size(struct v4l2_mbus_framefmt *mf,
1074                                    const struct ov2659_framesize **size)
1075{
1076        const struct ov2659_framesize *fsize = &ov2659_framesizes[0];
1077        const struct ov2659_framesize *match = NULL;
1078        int i = ARRAY_SIZE(ov2659_framesizes);
1079        unsigned int min_err = UINT_MAX;
1080
1081        while (i--) {
1082                int err = abs(fsize->width - mf->width)
1083                                + abs(fsize->height - mf->height);
1084                if ((err < min_err) && (fsize->regs[0].addr)) {
1085                        min_err = err;
1086                        match = fsize;
1087                }
1088                fsize++;
1089        }
1090
1091        if (!match)
1092                match = &ov2659_framesizes[2];
1093
1094        mf->width  = match->width;
1095        mf->height = match->height;
1096
1097        if (size)
1098                *size = match;
1099}
1100
1101static int ov2659_set_fmt(struct v4l2_subdev *sd,
1102                          struct v4l2_subdev_pad_config *cfg,
1103                          struct v4l2_subdev_format *fmt)
1104{
1105        struct i2c_client *client = v4l2_get_subdevdata(sd);
1106        int index = ARRAY_SIZE(ov2659_formats);
1107        struct v4l2_mbus_framefmt *mf = &fmt->format;
1108        const struct ov2659_framesize *size = NULL;
1109        struct ov2659 *ov2659 = to_ov2659(sd);
1110        int ret = 0;
1111
1112        dev_dbg(&client->dev, "ov2659_set_fmt\n");
1113
1114        __ov2659_try_frame_size(mf, &size);
1115
1116        while (--index >= 0)
1117                if (ov2659_formats[index].code == mf->code)
1118                        break;
1119
1120        if (index < 0)
1121                return -EINVAL;
1122
1123        mf->colorspace = V4L2_COLORSPACE_SRGB;
1124        mf->field = V4L2_FIELD_NONE;
1125
1126        mutex_lock(&ov2659->lock);
1127
1128        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1129#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1130                mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1131                *mf = fmt->format;
1132#else
1133                return -ENOTTY;
1134#endif
1135        } else {
1136                s64 val;
1137
1138                if (ov2659->streaming) {
1139                        mutex_unlock(&ov2659->lock);
1140                        return -EBUSY;
1141                }
1142
1143                ov2659->frame_size = size;
1144                ov2659->format = fmt->format;
1145                ov2659->format_ctrl_regs =
1146                        ov2659_formats[index].format_ctrl_regs;
1147
1148                if (ov2659->format.code != MEDIA_BUS_FMT_SBGGR8_1X8)
1149                        val = ov2659->pdata->link_frequency / 2;
1150                else
1151                        val = ov2659->pdata->link_frequency;
1152
1153                ret = v4l2_ctrl_s_ctrl_int64(ov2659->link_frequency, val);
1154                if (ret < 0)
1155                        dev_warn(&client->dev,
1156                                 "failed to set link_frequency rate (%d)\n",
1157                                 ret);
1158        }
1159
1160        mutex_unlock(&ov2659->lock);
1161        return ret;
1162}
1163
1164static int ov2659_set_frame_size(struct ov2659 *ov2659)
1165{
1166        struct i2c_client *client = ov2659->client;
1167
1168        dev_dbg(&client->dev, "%s\n", __func__);
1169
1170        return ov2659_write_array(ov2659->client, ov2659->frame_size->regs);
1171}
1172
1173static int ov2659_set_format(struct ov2659 *ov2659)
1174{
1175        struct i2c_client *client = ov2659->client;
1176
1177        dev_dbg(&client->dev, "%s\n", __func__);
1178
1179        return ov2659_write_array(ov2659->client, ov2659->format_ctrl_regs);
1180}
1181
1182static int ov2659_s_stream(struct v4l2_subdev *sd, int on)
1183{
1184        struct i2c_client *client = v4l2_get_subdevdata(sd);
1185        struct ov2659 *ov2659 = to_ov2659(sd);
1186        int ret = 0;
1187
1188        dev_dbg(&client->dev, "%s: on: %d\n", __func__, on);
1189
1190        mutex_lock(&ov2659->lock);
1191
1192        on = !!on;
1193
1194        if (ov2659->streaming == on)
1195                goto unlock;
1196
1197        if (!on) {
1198                /* Stop Streaming Sequence */
1199                ov2659_set_streaming(ov2659, 0);
1200                ov2659->streaming = on;
1201                goto unlock;
1202        }
1203
1204        ov2659_set_pixel_clock(ov2659);
1205        ov2659_set_frame_size(ov2659);
1206        ov2659_set_format(ov2659);
1207        ov2659_set_streaming(ov2659, 1);
1208        ov2659->streaming = on;
1209
1210unlock:
1211        mutex_unlock(&ov2659->lock);
1212        return ret;
1213}
1214
1215static int ov2659_set_test_pattern(struct ov2659 *ov2659, int value)
1216{
1217        struct i2c_client *client = v4l2_get_subdevdata(&ov2659->sd);
1218        int ret;
1219        u8 val;
1220
1221        ret = ov2659_read(client, REG_PRE_ISP_CTRL00, &val);
1222        if (ret < 0)
1223                return ret;
1224
1225        switch (value) {
1226        case 0:
1227                val &= ~TEST_PATTERN_ENABLE;
1228                break;
1229        case 1:
1230                val &= VERTICAL_COLOR_BAR_MASK;
1231                val |= TEST_PATTERN_ENABLE;
1232                break;
1233        }
1234
1235        return ov2659_write(client, REG_PRE_ISP_CTRL00, val);
1236}
1237
1238static int ov2659_s_ctrl(struct v4l2_ctrl *ctrl)
1239{
1240        struct ov2659 *ov2659 =
1241                        container_of(ctrl->handler, struct ov2659, ctrls);
1242
1243        switch (ctrl->id) {
1244        case V4L2_CID_TEST_PATTERN:
1245                return ov2659_set_test_pattern(ov2659, ctrl->val);
1246        }
1247
1248        return 0;
1249}
1250
1251static const struct v4l2_ctrl_ops ov2659_ctrl_ops = {
1252        .s_ctrl = ov2659_s_ctrl,
1253};
1254
1255static const char * const ov2659_test_pattern_menu[] = {
1256        "Disabled",
1257        "Vertical Color Bars",
1258};
1259
1260/* -----------------------------------------------------------------------------
1261 * V4L2 subdev internal operations
1262 */
1263
1264#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1265static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1266{
1267        struct i2c_client *client = v4l2_get_subdevdata(sd);
1268        struct v4l2_mbus_framefmt *format =
1269                                v4l2_subdev_get_try_format(sd, fh->pad, 0);
1270
1271        dev_dbg(&client->dev, "%s:\n", __func__);
1272
1273        ov2659_get_default_format(format);
1274
1275        return 0;
1276}
1277#endif
1278
1279static const struct v4l2_subdev_core_ops ov2659_subdev_core_ops = {
1280        .log_status = v4l2_ctrl_subdev_log_status,
1281        .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1282        .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1283};
1284
1285static const struct v4l2_subdev_video_ops ov2659_subdev_video_ops = {
1286        .s_stream = ov2659_s_stream,
1287};
1288
1289static const struct v4l2_subdev_pad_ops ov2659_subdev_pad_ops = {
1290        .enum_mbus_code = ov2659_enum_mbus_code,
1291        .enum_frame_size = ov2659_enum_frame_sizes,
1292        .get_fmt = ov2659_get_fmt,
1293        .set_fmt = ov2659_set_fmt,
1294};
1295
1296#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1297static const struct v4l2_subdev_ops ov2659_subdev_ops = {
1298        .core  = &ov2659_subdev_core_ops,
1299        .video = &ov2659_subdev_video_ops,
1300        .pad   = &ov2659_subdev_pad_ops,
1301};
1302
1303static const struct v4l2_subdev_internal_ops ov2659_subdev_internal_ops = {
1304        .open = ov2659_open,
1305};
1306#endif
1307
1308static int ov2659_detect(struct v4l2_subdev *sd)
1309{
1310        struct i2c_client *client = v4l2_get_subdevdata(sd);
1311        u8 pid = 0;
1312        u8 ver = 0;
1313        int ret;
1314
1315        dev_dbg(&client->dev, "%s:\n", __func__);
1316
1317        ret = ov2659_write(client, REG_SOFTWARE_RESET, 0x01);
1318        if (ret != 0) {
1319                dev_err(&client->dev, "Sensor soft reset failed\n");
1320                return -ENODEV;
1321        }
1322        usleep_range(1000, 2000);
1323
1324        /* Check sensor revision */
1325        ret = ov2659_read(client, REG_SC_CHIP_ID_H, &pid);
1326        if (!ret)
1327                ret = ov2659_read(client, REG_SC_CHIP_ID_L, &ver);
1328
1329        if (!ret) {
1330                unsigned short id;
1331
1332                id = OV265X_ID(pid, ver);
1333                if (id != OV2659_ID)
1334                        dev_err(&client->dev,
1335                                "Sensor detection failed (%04X, %d)\n",
1336                                id, ret);
1337                else {
1338                        dev_info(&client->dev, "Found OV%04X sensor\n", id);
1339                        ret = ov2659_init(sd, 0);
1340                }
1341        }
1342
1343        return ret;
1344}
1345
1346static struct ov2659_platform_data *
1347ov2659_get_pdata(struct i2c_client *client)
1348{
1349        struct ov2659_platform_data *pdata;
1350        struct v4l2_fwnode_endpoint *bus_cfg;
1351        struct device_node *endpoint;
1352
1353        if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
1354                return client->dev.platform_data;
1355
1356        endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
1357        if (!endpoint)
1358                return NULL;
1359
1360        bus_cfg = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint));
1361        if (IS_ERR(bus_cfg)) {
1362                pdata = NULL;
1363                goto done;
1364        }
1365
1366        pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1367        if (!pdata)
1368                goto done;
1369
1370        if (!bus_cfg->nr_of_link_frequencies) {
1371                dev_err(&client->dev,
1372                        "link-frequencies property not found or too many\n");
1373                pdata = NULL;
1374                goto done;
1375        }
1376
1377        pdata->link_frequency = bus_cfg->link_frequencies[0];
1378
1379done:
1380        v4l2_fwnode_endpoint_free(bus_cfg);
1381        of_node_put(endpoint);
1382        return pdata;
1383}
1384
1385static int ov2659_probe(struct i2c_client *client,
1386                        const struct i2c_device_id *id)
1387{
1388        const struct ov2659_platform_data *pdata = ov2659_get_pdata(client);
1389        struct v4l2_subdev *sd;
1390        struct ov2659 *ov2659;
1391        struct clk *clk;
1392        int ret;
1393
1394        if (!pdata) {
1395                dev_err(&client->dev, "platform data not specified\n");
1396                return -EINVAL;
1397        }
1398
1399        ov2659 = devm_kzalloc(&client->dev, sizeof(*ov2659), GFP_KERNEL);
1400        if (!ov2659)
1401                return -ENOMEM;
1402
1403        ov2659->pdata = pdata;
1404        ov2659->client = client;
1405
1406        clk = devm_clk_get(&client->dev, "xvclk");
1407        if (IS_ERR(clk))
1408                return PTR_ERR(clk);
1409
1410        ov2659->xvclk_frequency = clk_get_rate(clk);
1411        if (ov2659->xvclk_frequency < 6000000 ||
1412            ov2659->xvclk_frequency > 27000000)
1413                return -EINVAL;
1414
1415        v4l2_ctrl_handler_init(&ov2659->ctrls, 2);
1416        ov2659->link_frequency =
1417                        v4l2_ctrl_new_std(&ov2659->ctrls, &ov2659_ctrl_ops,
1418                                          V4L2_CID_PIXEL_RATE,
1419                                          pdata->link_frequency / 2,
1420                                          pdata->link_frequency, 1,
1421                                          pdata->link_frequency);
1422        v4l2_ctrl_new_std_menu_items(&ov2659->ctrls, &ov2659_ctrl_ops,
1423                                     V4L2_CID_TEST_PATTERN,
1424                                     ARRAY_SIZE(ov2659_test_pattern_menu) - 1,
1425                                     0, 0, ov2659_test_pattern_menu);
1426        ov2659->sd.ctrl_handler = &ov2659->ctrls;
1427
1428        if (ov2659->ctrls.error) {
1429                dev_err(&client->dev, "%s: control initialization error %d\n",
1430                        __func__, ov2659->ctrls.error);
1431                return  ov2659->ctrls.error;
1432        }
1433
1434        sd = &ov2659->sd;
1435        client->flags |= I2C_CLIENT_SCCB;
1436#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1437        v4l2_i2c_subdev_init(sd, client, &ov2659_subdev_ops);
1438
1439        sd->internal_ops = &ov2659_subdev_internal_ops;
1440        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1441                     V4L2_SUBDEV_FL_HAS_EVENTS;
1442#endif
1443
1444#if defined(CONFIG_MEDIA_CONTROLLER)
1445        ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
1446        sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1447        ret = media_entity_pads_init(&sd->entity, 1, &ov2659->pad);
1448        if (ret < 0) {
1449                v4l2_ctrl_handler_free(&ov2659->ctrls);
1450                return ret;
1451        }
1452#endif
1453
1454        mutex_init(&ov2659->lock);
1455
1456        ov2659_get_default_format(&ov2659->format);
1457        ov2659->frame_size = &ov2659_framesizes[2];
1458        ov2659->format_ctrl_regs = ov2659_formats[0].format_ctrl_regs;
1459
1460        ret = ov2659_detect(sd);
1461        if (ret < 0)
1462                goto error;
1463
1464        /* Calculate the PLL register value needed */
1465        ov2659_pll_calc_params(ov2659);
1466
1467        ret = v4l2_async_register_subdev(&ov2659->sd);
1468        if (ret)
1469                goto error;
1470
1471        dev_info(&client->dev, "%s sensor driver registered !!\n", sd->name);
1472
1473        return 0;
1474
1475error:
1476        v4l2_ctrl_handler_free(&ov2659->ctrls);
1477        media_entity_cleanup(&sd->entity);
1478        mutex_destroy(&ov2659->lock);
1479        return ret;
1480}
1481
1482static int ov2659_remove(struct i2c_client *client)
1483{
1484        struct v4l2_subdev *sd = i2c_get_clientdata(client);
1485        struct ov2659 *ov2659 = to_ov2659(sd);
1486
1487        v4l2_ctrl_handler_free(&ov2659->ctrls);
1488        v4l2_async_unregister_subdev(sd);
1489        media_entity_cleanup(&sd->entity);
1490        mutex_destroy(&ov2659->lock);
1491
1492        return 0;
1493}
1494
1495static const struct i2c_device_id ov2659_id[] = {
1496        { "ov2659", 0 },
1497        { /* sentinel */ },
1498};
1499MODULE_DEVICE_TABLE(i2c, ov2659_id);
1500
1501#if IS_ENABLED(CONFIG_OF)
1502static const struct of_device_id ov2659_of_match[] = {
1503        { .compatible = "ovti,ov2659", },
1504        { /* sentinel */ },
1505};
1506MODULE_DEVICE_TABLE(of, ov2659_of_match);
1507#endif
1508
1509static struct i2c_driver ov2659_i2c_driver = {
1510        .driver = {
1511                .name   = DRIVER_NAME,
1512                .of_match_table = of_match_ptr(ov2659_of_match),
1513        },
1514        .probe          = ov2659_probe,
1515        .remove         = ov2659_remove,
1516        .id_table       = ov2659_id,
1517};
1518
1519module_i2c_driver(ov2659_i2c_driver);
1520
1521MODULE_AUTHOR("Benoit Parrot <bparrot@ti.com>");
1522MODULE_DESCRIPTION("OV2659 CMOS Image Sensor driver");
1523MODULE_LICENSE("GPL v2");
1524