File Index
Files and directories
Sign in
FILE

ov2659.c

File preview with syntax highlighting.

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