cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ov2659.c (38509B)


      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#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
   1035		struct v4l2_mbus_framefmt *mf;
   1036
   1037		mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
   1038		mutex_lock(&ov2659->lock);
   1039		fmt->format = *mf;
   1040		mutex_unlock(&ov2659->lock);
   1041		return 0;
   1042#else
   1043		return -EINVAL;
   1044#endif
   1045	}
   1046
   1047	mutex_lock(&ov2659->lock);
   1048	fmt->format = ov2659->format;
   1049	mutex_unlock(&ov2659->lock);
   1050
   1051	dev_dbg(&client->dev, "ov2659_get_fmt: %x %dx%d\n",
   1052		ov2659->format.code, ov2659->format.width,
   1053		ov2659->format.height);
   1054
   1055	return 0;
   1056}
   1057
   1058static void __ov2659_try_frame_size(struct v4l2_mbus_framefmt *mf,
   1059				    const struct ov2659_framesize **size)
   1060{
   1061	const struct ov2659_framesize *fsize = &ov2659_framesizes[0];
   1062	const struct ov2659_framesize *match = NULL;
   1063	int i = ARRAY_SIZE(ov2659_framesizes);
   1064	unsigned int min_err = UINT_MAX;
   1065
   1066	while (i--) {
   1067		int err = abs(fsize->width - mf->width)
   1068				+ abs(fsize->height - mf->height);
   1069		if ((err < min_err) && (fsize->regs[0].addr)) {
   1070			min_err = err;
   1071			match = fsize;
   1072		}
   1073		fsize++;
   1074	}
   1075
   1076	if (!match)
   1077		match = &ov2659_framesizes[2];
   1078
   1079	mf->width  = match->width;
   1080	mf->height = match->height;
   1081
   1082	if (size)
   1083		*size = match;
   1084}
   1085
   1086static int ov2659_set_fmt(struct v4l2_subdev *sd,
   1087			  struct v4l2_subdev_state *sd_state,
   1088			  struct v4l2_subdev_format *fmt)
   1089{
   1090	struct i2c_client *client = v4l2_get_subdevdata(sd);
   1091	int index = ARRAY_SIZE(ov2659_formats);
   1092	struct v4l2_mbus_framefmt *mf = &fmt->format;
   1093	const struct ov2659_framesize *size = NULL;
   1094	struct ov2659 *ov2659 = to_ov2659(sd);
   1095	int ret = 0;
   1096
   1097	dev_dbg(&client->dev, "ov2659_set_fmt\n");
   1098
   1099	__ov2659_try_frame_size(mf, &size);
   1100
   1101	while (--index >= 0)
   1102		if (ov2659_formats[index].code == mf->code)
   1103			break;
   1104
   1105	if (index < 0) {
   1106		index = 0;
   1107		mf->code = ov2659_formats[index].code;
   1108	}
   1109
   1110	mf->colorspace = V4L2_COLORSPACE_SRGB;
   1111	mf->field = V4L2_FIELD_NONE;
   1112
   1113	mutex_lock(&ov2659->lock);
   1114
   1115	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
   1116#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
   1117		mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
   1118		*mf = fmt->format;
   1119#endif
   1120	} else {
   1121		s64 val;
   1122
   1123		if (ov2659->streaming) {
   1124			mutex_unlock(&ov2659->lock);
   1125			return -EBUSY;
   1126		}
   1127
   1128		ov2659->frame_size = size;
   1129		ov2659->format = fmt->format;
   1130		ov2659->format_ctrl_regs =
   1131			ov2659_formats[index].format_ctrl_regs;
   1132
   1133		if (ov2659->format.code != MEDIA_BUS_FMT_SBGGR8_1X8)
   1134			val = ov2659->pdata->link_frequency / 2;
   1135		else
   1136			val = ov2659->pdata->link_frequency;
   1137
   1138		ret = v4l2_ctrl_s_ctrl_int64(ov2659->link_frequency, val);
   1139		if (ret < 0)
   1140			dev_warn(&client->dev,
   1141				 "failed to set link_frequency rate (%d)\n",
   1142				 ret);
   1143	}
   1144
   1145	mutex_unlock(&ov2659->lock);
   1146	return ret;
   1147}
   1148
   1149static int ov2659_set_frame_size(struct ov2659 *ov2659)
   1150{
   1151	struct i2c_client *client = ov2659->client;
   1152
   1153	dev_dbg(&client->dev, "%s\n", __func__);
   1154
   1155	return ov2659_write_array(ov2659->client, ov2659->frame_size->regs);
   1156}
   1157
   1158static int ov2659_set_format(struct ov2659 *ov2659)
   1159{
   1160	struct i2c_client *client = ov2659->client;
   1161
   1162	dev_dbg(&client->dev, "%s\n", __func__);
   1163
   1164	return ov2659_write_array(ov2659->client, ov2659->format_ctrl_regs);
   1165}
   1166
   1167static int ov2659_s_stream(struct v4l2_subdev *sd, int on)
   1168{
   1169	struct i2c_client *client = v4l2_get_subdevdata(sd);
   1170	struct ov2659 *ov2659 = to_ov2659(sd);
   1171	int ret = 0;
   1172
   1173	dev_dbg(&client->dev, "%s: on: %d\n", __func__, on);
   1174
   1175	mutex_lock(&ov2659->lock);
   1176
   1177	on = !!on;
   1178
   1179	if (ov2659->streaming == on)
   1180		goto unlock;
   1181
   1182	if (!on) {
   1183		/* Stop Streaming Sequence */
   1184		ov2659_set_streaming(ov2659, 0);
   1185		ov2659->streaming = on;
   1186		pm_runtime_put(&client->dev);
   1187		goto unlock;
   1188	}
   1189
   1190	ret = pm_runtime_resume_and_get(&client->dev);
   1191	if (ret < 0)
   1192		goto unlock;
   1193
   1194	ret = ov2659_init(sd, 0);
   1195	if (!ret)
   1196		ret = ov2659_set_pixel_clock(ov2659);
   1197	if (!ret)
   1198		ret = ov2659_set_frame_size(ov2659);
   1199	if (!ret)
   1200		ret = ov2659_set_format(ov2659);
   1201	if (!ret) {
   1202		ov2659_set_streaming(ov2659, 1);
   1203		ov2659->streaming = on;
   1204	}
   1205
   1206unlock:
   1207	mutex_unlock(&ov2659->lock);
   1208	return ret;
   1209}
   1210
   1211static int ov2659_set_test_pattern(struct ov2659 *ov2659, int value)
   1212{
   1213	struct i2c_client *client = v4l2_get_subdevdata(&ov2659->sd);
   1214	int ret;
   1215	u8 val;
   1216
   1217	ret = ov2659_read(client, REG_PRE_ISP_CTRL00, &val);
   1218	if (ret < 0)
   1219		return ret;
   1220
   1221	switch (value) {
   1222	case 0:
   1223		val &= ~TEST_PATTERN_ENABLE;
   1224		break;
   1225	case 1:
   1226		val &= VERTICAL_COLOR_BAR_MASK;
   1227		val |= TEST_PATTERN_ENABLE;
   1228		break;
   1229	}
   1230
   1231	return ov2659_write(client, REG_PRE_ISP_CTRL00, val);
   1232}
   1233
   1234static int ov2659_s_ctrl(struct v4l2_ctrl *ctrl)
   1235{
   1236	struct ov2659 *ov2659 =
   1237			container_of(ctrl->handler, struct ov2659, ctrls);
   1238	struct i2c_client *client = ov2659->client;
   1239
   1240	/* V4L2 controls values will be applied only when power is already up */
   1241	if (!pm_runtime_get_if_in_use(&client->dev))
   1242		return 0;
   1243
   1244	switch (ctrl->id) {
   1245	case V4L2_CID_TEST_PATTERN:
   1246		return ov2659_set_test_pattern(ov2659, ctrl->val);
   1247	}
   1248
   1249	pm_runtime_put(&client->dev);
   1250	return 0;
   1251}
   1252
   1253static const struct v4l2_ctrl_ops ov2659_ctrl_ops = {
   1254	.s_ctrl = ov2659_s_ctrl,
   1255};
   1256
   1257static const char * const ov2659_test_pattern_menu[] = {
   1258	"Disabled",
   1259	"Vertical Color Bars",
   1260};
   1261
   1262static int ov2659_power_off(struct device *dev)
   1263{
   1264	struct i2c_client *client = to_i2c_client(dev);
   1265	struct v4l2_subdev *sd = i2c_get_clientdata(client);
   1266	struct ov2659 *ov2659 = to_ov2659(sd);
   1267
   1268	dev_dbg(&client->dev, "%s:\n", __func__);
   1269
   1270	gpiod_set_value(ov2659->pwdn_gpio, 1);
   1271
   1272	clk_disable_unprepare(ov2659->clk);
   1273
   1274	return 0;
   1275}
   1276
   1277static int ov2659_power_on(struct device *dev)
   1278{
   1279	struct i2c_client *client = to_i2c_client(dev);
   1280	struct v4l2_subdev *sd = i2c_get_clientdata(client);
   1281	struct ov2659 *ov2659 = to_ov2659(sd);
   1282	int ret;
   1283
   1284	dev_dbg(&client->dev, "%s:\n", __func__);
   1285
   1286	ret = clk_prepare_enable(ov2659->clk);
   1287	if (ret) {
   1288		dev_err(&client->dev, "%s: failed to enable clock\n",
   1289			__func__);
   1290		return ret;
   1291	}
   1292
   1293	gpiod_set_value(ov2659->pwdn_gpio, 0);
   1294
   1295	if (ov2659->resetb_gpio) {
   1296		gpiod_set_value(ov2659->resetb_gpio, 1);
   1297		usleep_range(500, 1000);
   1298		gpiod_set_value(ov2659->resetb_gpio, 0);
   1299		usleep_range(3000, 5000);
   1300	}
   1301
   1302	return 0;
   1303}
   1304
   1305/* -----------------------------------------------------------------------------
   1306 * V4L2 subdev internal operations
   1307 */
   1308
   1309#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
   1310static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
   1311{
   1312	struct i2c_client *client = v4l2_get_subdevdata(sd);
   1313	struct v4l2_mbus_framefmt *format =
   1314				v4l2_subdev_get_try_format(sd, fh->state, 0);
   1315
   1316	dev_dbg(&client->dev, "%s:\n", __func__);
   1317
   1318	ov2659_get_default_format(format);
   1319
   1320	return 0;
   1321}
   1322#endif
   1323
   1324static const struct v4l2_subdev_core_ops ov2659_subdev_core_ops = {
   1325	.log_status = v4l2_ctrl_subdev_log_status,
   1326	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
   1327	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
   1328};
   1329
   1330static const struct v4l2_subdev_video_ops ov2659_subdev_video_ops = {
   1331	.s_stream = ov2659_s_stream,
   1332};
   1333
   1334static const struct v4l2_subdev_pad_ops ov2659_subdev_pad_ops = {
   1335	.enum_mbus_code = ov2659_enum_mbus_code,
   1336	.enum_frame_size = ov2659_enum_frame_sizes,
   1337	.get_fmt = ov2659_get_fmt,
   1338	.set_fmt = ov2659_set_fmt,
   1339};
   1340
   1341#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
   1342static const struct v4l2_subdev_ops ov2659_subdev_ops = {
   1343	.core  = &ov2659_subdev_core_ops,
   1344	.video = &ov2659_subdev_video_ops,
   1345	.pad   = &ov2659_subdev_pad_ops,
   1346};
   1347
   1348static const struct v4l2_subdev_internal_ops ov2659_subdev_internal_ops = {
   1349	.open = ov2659_open,
   1350};
   1351#endif
   1352
   1353static int ov2659_detect(struct v4l2_subdev *sd)
   1354{
   1355	struct i2c_client *client = v4l2_get_subdevdata(sd);
   1356	u8 pid = 0;
   1357	u8 ver = 0;
   1358	int ret;
   1359
   1360	dev_dbg(&client->dev, "%s:\n", __func__);
   1361
   1362	ret = ov2659_write(client, REG_SOFTWARE_RESET, 0x01);
   1363	if (ret != 0) {
   1364		dev_err(&client->dev, "Sensor soft reset failed\n");
   1365		return -ENODEV;
   1366	}
   1367	usleep_range(1000, 2000);
   1368
   1369	/* Check sensor revision */
   1370	ret = ov2659_read(client, REG_SC_CHIP_ID_H, &pid);
   1371	if (!ret)
   1372		ret = ov2659_read(client, REG_SC_CHIP_ID_L, &ver);
   1373
   1374	if (!ret) {
   1375		unsigned short id;
   1376
   1377		id = OV265X_ID(pid, ver);
   1378		if (id != OV2659_ID) {
   1379			dev_err(&client->dev,
   1380				"Sensor detection failed (%04X)\n", id);
   1381			ret = -ENODEV;
   1382		} else {
   1383			dev_info(&client->dev, "Found OV%04X sensor\n", id);
   1384		}
   1385	}
   1386
   1387	return ret;
   1388}
   1389
   1390static struct ov2659_platform_data *
   1391ov2659_get_pdata(struct i2c_client *client)
   1392{
   1393	struct ov2659_platform_data *pdata;
   1394	struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
   1395	struct device_node *endpoint;
   1396	int ret;
   1397
   1398	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
   1399		return client->dev.platform_data;
   1400
   1401	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
   1402	if (!endpoint)
   1403		return NULL;
   1404
   1405	ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint),
   1406					       &bus_cfg);
   1407	if (ret) {
   1408		pdata = NULL;
   1409		goto done;
   1410	}
   1411
   1412	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
   1413	if (!pdata)
   1414		goto done;
   1415
   1416	if (!bus_cfg.nr_of_link_frequencies) {
   1417		dev_err(&client->dev,
   1418			"link-frequencies property not found or too many\n");
   1419		pdata = NULL;
   1420		goto done;
   1421	}
   1422
   1423	pdata->link_frequency = bus_cfg.link_frequencies[0];
   1424
   1425done:
   1426	v4l2_fwnode_endpoint_free(&bus_cfg);
   1427	of_node_put(endpoint);
   1428	return pdata;
   1429}
   1430
   1431static int ov2659_probe(struct i2c_client *client)
   1432{
   1433	const struct ov2659_platform_data *pdata = ov2659_get_pdata(client);
   1434	struct v4l2_subdev *sd;
   1435	struct ov2659 *ov2659;
   1436	int ret;
   1437
   1438	if (!pdata) {
   1439		dev_err(&client->dev, "platform data not specified\n");
   1440		return -EINVAL;
   1441	}
   1442
   1443	ov2659 = devm_kzalloc(&client->dev, sizeof(*ov2659), GFP_KERNEL);
   1444	if (!ov2659)
   1445		return -ENOMEM;
   1446
   1447	ov2659->pdata = pdata;
   1448	ov2659->client = client;
   1449
   1450	ov2659->clk = devm_clk_get(&client->dev, "xvclk");
   1451	if (IS_ERR(ov2659->clk))
   1452		return PTR_ERR(ov2659->clk);
   1453
   1454	ov2659->xvclk_frequency = clk_get_rate(ov2659->clk);
   1455	if (ov2659->xvclk_frequency < 6000000 ||
   1456	    ov2659->xvclk_frequency > 27000000)
   1457		return -EINVAL;
   1458
   1459	/* Optional gpio don't fail if not present */
   1460	ov2659->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
   1461						    GPIOD_OUT_LOW);
   1462	if (IS_ERR(ov2659->pwdn_gpio))
   1463		return PTR_ERR(ov2659->pwdn_gpio);
   1464
   1465	/* Optional gpio don't fail if not present */
   1466	ov2659->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
   1467						      GPIOD_OUT_HIGH);
   1468	if (IS_ERR(ov2659->resetb_gpio))
   1469		return PTR_ERR(ov2659->resetb_gpio);
   1470
   1471	v4l2_ctrl_handler_init(&ov2659->ctrls, 2);
   1472	ov2659->link_frequency =
   1473			v4l2_ctrl_new_std(&ov2659->ctrls, &ov2659_ctrl_ops,
   1474					  V4L2_CID_PIXEL_RATE,
   1475					  pdata->link_frequency / 2,
   1476					  pdata->link_frequency, 1,
   1477					  pdata->link_frequency);
   1478	v4l2_ctrl_new_std_menu_items(&ov2659->ctrls, &ov2659_ctrl_ops,
   1479				     V4L2_CID_TEST_PATTERN,
   1480				     ARRAY_SIZE(ov2659_test_pattern_menu) - 1,
   1481				     0, 0, ov2659_test_pattern_menu);
   1482	ov2659->sd.ctrl_handler = &ov2659->ctrls;
   1483
   1484	if (ov2659->ctrls.error) {
   1485		dev_err(&client->dev, "%s: control initialization error %d\n",
   1486			__func__, ov2659->ctrls.error);
   1487		return  ov2659->ctrls.error;
   1488	}
   1489
   1490	sd = &ov2659->sd;
   1491	client->flags |= I2C_CLIENT_SCCB;
   1492#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
   1493	v4l2_i2c_subdev_init(sd, client, &ov2659_subdev_ops);
   1494
   1495	sd->internal_ops = &ov2659_subdev_internal_ops;
   1496	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
   1497		     V4L2_SUBDEV_FL_HAS_EVENTS;
   1498#endif
   1499
   1500#if defined(CONFIG_MEDIA_CONTROLLER)
   1501	ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
   1502	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
   1503	ret = media_entity_pads_init(&sd->entity, 1, &ov2659->pad);
   1504	if (ret < 0) {
   1505		v4l2_ctrl_handler_free(&ov2659->ctrls);
   1506		return ret;
   1507	}
   1508#endif
   1509
   1510	mutex_init(&ov2659->lock);
   1511
   1512	ov2659_get_default_format(&ov2659->format);
   1513	ov2659->frame_size = &ov2659_framesizes[2];
   1514	ov2659->format_ctrl_regs = ov2659_formats[0].format_ctrl_regs;
   1515
   1516	ret = ov2659_power_on(&client->dev);
   1517	if (ret < 0)
   1518		goto error;
   1519
   1520	ret = ov2659_detect(sd);
   1521	if (ret < 0)
   1522		goto error;
   1523
   1524	/* Calculate the PLL register value needed */
   1525	ov2659_pll_calc_params(ov2659);
   1526
   1527	ret = v4l2_async_register_subdev(&ov2659->sd);
   1528	if (ret)
   1529		goto error;
   1530
   1531	dev_info(&client->dev, "%s sensor driver registered !!\n", sd->name);
   1532
   1533	pm_runtime_set_active(&client->dev);
   1534	pm_runtime_enable(&client->dev);
   1535	pm_runtime_idle(&client->dev);
   1536
   1537	return 0;
   1538
   1539error:
   1540	v4l2_ctrl_handler_free(&ov2659->ctrls);
   1541	ov2659_power_off(&client->dev);
   1542	media_entity_cleanup(&sd->entity);
   1543	mutex_destroy(&ov2659->lock);
   1544	return ret;
   1545}
   1546
   1547static int ov2659_remove(struct i2c_client *client)
   1548{
   1549	struct v4l2_subdev *sd = i2c_get_clientdata(client);
   1550	struct ov2659 *ov2659 = to_ov2659(sd);
   1551
   1552	v4l2_ctrl_handler_free(&ov2659->ctrls);
   1553	v4l2_async_unregister_subdev(sd);
   1554	media_entity_cleanup(&sd->entity);
   1555	mutex_destroy(&ov2659->lock);
   1556
   1557	pm_runtime_disable(&client->dev);
   1558	if (!pm_runtime_status_suspended(&client->dev))
   1559		ov2659_power_off(&client->dev);
   1560	pm_runtime_set_suspended(&client->dev);
   1561
   1562	return 0;
   1563}
   1564
   1565static const struct dev_pm_ops ov2659_pm_ops = {
   1566	SET_RUNTIME_PM_OPS(ov2659_power_off, ov2659_power_on, NULL)
   1567};
   1568
   1569static const struct i2c_device_id ov2659_id[] = {
   1570	{ "ov2659", 0 },
   1571	{ /* sentinel */ },
   1572};
   1573MODULE_DEVICE_TABLE(i2c, ov2659_id);
   1574
   1575#if IS_ENABLED(CONFIG_OF)
   1576static const struct of_device_id ov2659_of_match[] = {
   1577	{ .compatible = "ovti,ov2659", },
   1578	{ /* sentinel */ },
   1579};
   1580MODULE_DEVICE_TABLE(of, ov2659_of_match);
   1581#endif
   1582
   1583static struct i2c_driver ov2659_i2c_driver = {
   1584	.driver = {
   1585		.name	= DRIVER_NAME,
   1586		.pm	= &ov2659_pm_ops,
   1587		.of_match_table = of_match_ptr(ov2659_of_match),
   1588	},
   1589	.probe_new	= ov2659_probe,
   1590	.remove		= ov2659_remove,
   1591	.id_table	= ov2659_id,
   1592};
   1593
   1594module_i2c_driver(ov2659_i2c_driver);
   1595
   1596MODULE_AUTHOR("Benoit Parrot <bparrot@ti.com>");
   1597MODULE_DESCRIPTION("OV2659 CMOS Image Sensor driver");
   1598MODULE_LICENSE("GPL v2");