0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/clk.h>
0012 #include <linux/delay.h>
0013 #include <linux/gpio/consumer.h>
0014 #include <linux/i2c.h>
0015 #include <linux/module.h>
0016 #include <linux/of_graph.h>
0017 #include <linux/pm_runtime.h>
0018
0019 #include <media/i2c/ov2659.h>
0020 #include <media/v4l2-ctrls.h>
0021 #include <media/v4l2-event.h>
0022 #include <media/v4l2-fwnode.h>
0023 #include <media/v4l2-image-sizes.h>
0024 #include <media/v4l2-subdev.h>
0025
0026 #define DRIVER_NAME "ov2659"
0027
0028
0029
0030
0031 #define REG_SOFTWARE_STANDBY 0x0100
0032 #define REG_SOFTWARE_RESET 0x0103
0033 #define REG_IO_CTRL00 0x3000
0034 #define REG_IO_CTRL01 0x3001
0035 #define REG_IO_CTRL02 0x3002
0036 #define REG_OUTPUT_VALUE00 0x3008
0037 #define REG_OUTPUT_VALUE01 0x3009
0038 #define REG_OUTPUT_VALUE02 0x300d
0039 #define REG_OUTPUT_SELECT00 0x300e
0040 #define REG_OUTPUT_SELECT01 0x300f
0041 #define REG_OUTPUT_SELECT02 0x3010
0042 #define REG_OUTPUT_DRIVE 0x3011
0043 #define REG_INPUT_READOUT00 0x302d
0044 #define REG_INPUT_READOUT01 0x302e
0045 #define REG_INPUT_READOUT02 0x302f
0046
0047 #define REG_SC_PLL_CTRL0 0x3003
0048 #define REG_SC_PLL_CTRL1 0x3004
0049 #define REG_SC_PLL_CTRL2 0x3005
0050 #define REG_SC_PLL_CTRL3 0x3006
0051 #define REG_SC_CHIP_ID_H 0x300a
0052 #define REG_SC_CHIP_ID_L 0x300b
0053 #define REG_SC_PWC 0x3014
0054 #define REG_SC_CLKRST0 0x301a
0055 #define REG_SC_CLKRST1 0x301b
0056 #define REG_SC_CLKRST2 0x301c
0057 #define REG_SC_CLKRST3 0x301d
0058 #define REG_SC_SUB_ID 0x302a
0059 #define REG_SC_SCCB_ID 0x302b
0060
0061 #define REG_GROUP_ADDRESS_00 0x3200
0062 #define REG_GROUP_ADDRESS_01 0x3201
0063 #define REG_GROUP_ADDRESS_02 0x3202
0064 #define REG_GROUP_ADDRESS_03 0x3203
0065 #define REG_GROUP_ACCESS 0x3208
0066
0067 #define REG_AWB_R_GAIN_H 0x3400
0068 #define REG_AWB_R_GAIN_L 0x3401
0069 #define REG_AWB_G_GAIN_H 0x3402
0070 #define REG_AWB_G_GAIN_L 0x3403
0071 #define REG_AWB_B_GAIN_H 0x3404
0072 #define REG_AWB_B_GAIN_L 0x3405
0073 #define REG_AWB_MANUAL_CONTROL 0x3406
0074
0075 #define REG_TIMING_HS_H 0x3800
0076 #define REG_TIMING_HS_L 0x3801
0077 #define REG_TIMING_VS_H 0x3802
0078 #define REG_TIMING_VS_L 0x3803
0079 #define REG_TIMING_HW_H 0x3804
0080 #define REG_TIMING_HW_L 0x3805
0081 #define REG_TIMING_VH_H 0x3806
0082 #define REG_TIMING_VH_L 0x3807
0083 #define REG_TIMING_DVPHO_H 0x3808
0084 #define REG_TIMING_DVPHO_L 0x3809
0085 #define REG_TIMING_DVPVO_H 0x380a
0086 #define REG_TIMING_DVPVO_L 0x380b
0087 #define REG_TIMING_HTS_H 0x380c
0088 #define REG_TIMING_HTS_L 0x380d
0089 #define REG_TIMING_VTS_H 0x380e
0090 #define REG_TIMING_VTS_L 0x380f
0091 #define REG_TIMING_HOFFS_H 0x3810
0092 #define REG_TIMING_HOFFS_L 0x3811
0093 #define REG_TIMING_VOFFS_H 0x3812
0094 #define REG_TIMING_VOFFS_L 0x3813
0095 #define REG_TIMING_XINC 0x3814
0096 #define REG_TIMING_YINC 0x3815
0097 #define REG_TIMING_VERT_FORMAT 0x3820
0098 #define REG_TIMING_HORIZ_FORMAT 0x3821
0099
0100 #define REG_FORMAT_CTRL00 0x4300
0101
0102 #define REG_VFIFO_READ_START_H 0x4608
0103 #define REG_VFIFO_READ_START_L 0x4609
0104
0105 #define REG_DVP_CTRL02 0x4708
0106
0107 #define REG_ISP_CTRL00 0x5000
0108 #define REG_ISP_CTRL01 0x5001
0109 #define REG_ISP_CTRL02 0x5002
0110
0111 #define REG_LENC_RED_X0_H 0x500c
0112 #define REG_LENC_RED_X0_L 0x500d
0113 #define REG_LENC_RED_Y0_H 0x500e
0114 #define REG_LENC_RED_Y0_L 0x500f
0115 #define REG_LENC_RED_A1 0x5010
0116 #define REG_LENC_RED_B1 0x5011
0117 #define REG_LENC_RED_A2_B2 0x5012
0118 #define REG_LENC_GREEN_X0_H 0x5013
0119 #define REG_LENC_GREEN_X0_L 0x5014
0120 #define REG_LENC_GREEN_Y0_H 0x5015
0121 #define REG_LENC_GREEN_Y0_L 0x5016
0122 #define REG_LENC_GREEN_A1 0x5017
0123 #define REG_LENC_GREEN_B1 0x5018
0124 #define REG_LENC_GREEN_A2_B2 0x5019
0125 #define REG_LENC_BLUE_X0_H 0x501a
0126 #define REG_LENC_BLUE_X0_L 0x501b
0127 #define REG_LENC_BLUE_Y0_H 0x501c
0128 #define REG_LENC_BLUE_Y0_L 0x501d
0129 #define REG_LENC_BLUE_A1 0x501e
0130 #define REG_LENC_BLUE_B1 0x501f
0131 #define REG_LENC_BLUE_A2_B2 0x5020
0132
0133 #define REG_AWB_CTRL00 0x5035
0134 #define REG_AWB_CTRL01 0x5036
0135 #define REG_AWB_CTRL02 0x5037
0136 #define REG_AWB_CTRL03 0x5038
0137 #define REG_AWB_CTRL04 0x5039
0138 #define REG_AWB_LOCAL_LIMIT 0x503a
0139 #define REG_AWB_CTRL12 0x5049
0140 #define REG_AWB_CTRL13 0x504a
0141 #define REG_AWB_CTRL14 0x504b
0142
0143 #define REG_SHARPENMT_THRESH1 0x5064
0144 #define REG_SHARPENMT_THRESH2 0x5065
0145 #define REG_SHARPENMT_OFFSET1 0x5066
0146 #define REG_SHARPENMT_OFFSET2 0x5067
0147 #define REG_DENOISE_THRESH1 0x5068
0148 #define REG_DENOISE_THRESH2 0x5069
0149 #define REG_DENOISE_OFFSET1 0x506a
0150 #define REG_DENOISE_OFFSET2 0x506b
0151 #define REG_SHARPEN_THRESH1 0x506c
0152 #define REG_SHARPEN_THRESH2 0x506d
0153 #define REG_CIP_CTRL00 0x506e
0154 #define REG_CIP_CTRL01 0x506f
0155
0156 #define REG_CMX_SIGN 0x5079
0157 #define REG_CMX_MISC_CTRL 0x507a
0158
0159 #define REG_PRE_ISP_CTRL00 0x50a0
0160 #define TEST_PATTERN_ENABLE BIT(7)
0161 #define VERTICAL_COLOR_BAR_MASK 0x53
0162
0163 #define REG_NULL 0x0000
0164
0165 #define OV265X_ID(_msb, _lsb) ((_msb) << 8 | (_lsb))
0166 #define OV2659_ID 0x2656
0167
0168 struct sensor_register {
0169 u16 addr;
0170 u8 value;
0171 };
0172
0173 struct ov2659_framesize {
0174 u16 width;
0175 u16 height;
0176 u16 max_exp_lines;
0177 const struct sensor_register *regs;
0178 };
0179
0180 struct ov2659_pll_ctrl {
0181 u8 ctrl1;
0182 u8 ctrl2;
0183 u8 ctrl3;
0184 };
0185
0186 struct ov2659_pixfmt {
0187 u32 code;
0188
0189 struct sensor_register *format_ctrl_regs;
0190 };
0191
0192 struct pll_ctrl_reg {
0193 unsigned int div;
0194 unsigned char reg;
0195 };
0196
0197 struct ov2659 {
0198 struct v4l2_subdev sd;
0199 struct media_pad pad;
0200 struct v4l2_mbus_framefmt format;
0201 unsigned int xvclk_frequency;
0202 const struct ov2659_platform_data *pdata;
0203 struct mutex lock;
0204 struct i2c_client *client;
0205 struct v4l2_ctrl_handler ctrls;
0206 struct v4l2_ctrl *link_frequency;
0207 struct clk *clk;
0208 const struct ov2659_framesize *frame_size;
0209 struct sensor_register *format_ctrl_regs;
0210 struct ov2659_pll_ctrl pll;
0211 int streaming;
0212
0213 struct gpio_desc *pwdn_gpio;
0214
0215 struct gpio_desc *resetb_gpio;
0216 };
0217
0218 static const struct sensor_register ov2659_init_regs[] = {
0219 { REG_IO_CTRL00, 0x03 },
0220 { REG_IO_CTRL01, 0xff },
0221 { REG_IO_CTRL02, 0xe0 },
0222 { 0x3633, 0x3d },
0223 { 0x3620, 0x02 },
0224 { 0x3631, 0x11 },
0225 { 0x3612, 0x04 },
0226 { 0x3630, 0x20 },
0227 { 0x4702, 0x02 },
0228 { 0x370c, 0x34 },
0229 { REG_TIMING_HS_H, 0x00 },
0230 { REG_TIMING_HS_L, 0x00 },
0231 { REG_TIMING_VS_H, 0x00 },
0232 { REG_TIMING_VS_L, 0x00 },
0233 { REG_TIMING_HW_H, 0x06 },
0234 { REG_TIMING_HW_L, 0x5f },
0235 { REG_TIMING_VH_H, 0x04 },
0236 { REG_TIMING_VH_L, 0xb7 },
0237 { REG_TIMING_DVPHO_H, 0x03 },
0238 { REG_TIMING_DVPHO_L, 0x20 },
0239 { REG_TIMING_DVPVO_H, 0x02 },
0240 { REG_TIMING_DVPVO_L, 0x58 },
0241 { REG_TIMING_HTS_H, 0x05 },
0242 { REG_TIMING_HTS_L, 0x14 },
0243 { REG_TIMING_VTS_H, 0x02 },
0244 { REG_TIMING_VTS_L, 0x68 },
0245 { REG_TIMING_HOFFS_L, 0x08 },
0246 { REG_TIMING_VOFFS_L, 0x02 },
0247 { REG_TIMING_XINC, 0x31 },
0248 { REG_TIMING_YINC, 0x31 },
0249 { 0x3a02, 0x02 },
0250 { 0x3a03, 0x68 },
0251 { 0x3a08, 0x00 },
0252 { 0x3a09, 0x5c },
0253 { 0x3a0a, 0x00 },
0254 { 0x3a0b, 0x4d },
0255 { 0x3a0d, 0x08 },
0256 { 0x3a0e, 0x06 },
0257 { 0x3a14, 0x02 },
0258 { 0x3a15, 0x28 },
0259 { REG_DVP_CTRL02, 0x01 },
0260 { 0x3623, 0x00 },
0261 { 0x3634, 0x76 },
0262 { 0x3701, 0x44 },
0263 { 0x3702, 0x18 },
0264 { 0x3703, 0x24 },
0265 { 0x3704, 0x24 },
0266 { 0x3705, 0x0c },
0267 { REG_TIMING_VERT_FORMAT, 0x81 },
0268 { REG_TIMING_HORIZ_FORMAT, 0x01 },
0269 { 0x370a, 0x52 },
0270 { REG_VFIFO_READ_START_H, 0x00 },
0271 { REG_VFIFO_READ_START_L, 0x80 },
0272 { REG_FORMAT_CTRL00, 0x30 },
0273 { 0x5086, 0x02 },
0274 { REG_ISP_CTRL00, 0xfb },
0275 { REG_ISP_CTRL01, 0x1f },
0276 { REG_ISP_CTRL02, 0x00 },
0277 { 0x5025, 0x0e },
0278 { 0x5026, 0x18 },
0279 { 0x5027, 0x34 },
0280 { 0x5028, 0x4c },
0281 { 0x5029, 0x62 },
0282 { 0x502a, 0x74 },
0283 { 0x502b, 0x85 },
0284 { 0x502c, 0x92 },
0285 { 0x502d, 0x9e },
0286 { 0x502e, 0xb2 },
0287 { 0x502f, 0xc0 },
0288 { 0x5030, 0xcc },
0289 { 0x5031, 0xe0 },
0290 { 0x5032, 0xee },
0291 { 0x5033, 0xf6 },
0292 { 0x5034, 0x11 },
0293 { 0x5070, 0x1c },
0294 { 0x5071, 0x5b },
0295 { 0x5072, 0x05 },
0296 { 0x5073, 0x20 },
0297 { 0x5074, 0x94 },
0298 { 0x5075, 0xb4 },
0299 { 0x5076, 0xb4 },
0300 { 0x5077, 0xaf },
0301 { 0x5078, 0x05 },
0302 { REG_CMX_SIGN, 0x98 },
0303 { REG_CMX_MISC_CTRL, 0x21 },
0304 { REG_AWB_CTRL00, 0x6a },
0305 { REG_AWB_CTRL01, 0x11 },
0306 { REG_AWB_CTRL02, 0x92 },
0307 { REG_AWB_CTRL03, 0x21 },
0308 { REG_AWB_CTRL04, 0xe1 },
0309 { REG_AWB_LOCAL_LIMIT, 0x01 },
0310 { 0x503c, 0x05 },
0311 { 0x503d, 0x08 },
0312 { 0x503e, 0x08 },
0313 { 0x503f, 0x64 },
0314 { 0x5040, 0x58 },
0315 { 0x5041, 0x2a },
0316 { 0x5042, 0xc5 },
0317 { 0x5043, 0x2e },
0318 { 0x5044, 0x3a },
0319 { 0x5045, 0x3c },
0320 { 0x5046, 0x44 },
0321 { 0x5047, 0xf8 },
0322 { 0x5048, 0x08 },
0323 { REG_AWB_CTRL12, 0x70 },
0324 { REG_AWB_CTRL13, 0xf0 },
0325 { REG_AWB_CTRL14, 0xf0 },
0326 { REG_LENC_RED_X0_H, 0x03 },
0327 { REG_LENC_RED_X0_L, 0x20 },
0328 { REG_LENC_RED_Y0_H, 0x02 },
0329 { REG_LENC_RED_Y0_L, 0x5c },
0330 { REG_LENC_RED_A1, 0x48 },
0331 { REG_LENC_RED_B1, 0x00 },
0332 { REG_LENC_RED_A2_B2, 0x66 },
0333 { REG_LENC_GREEN_X0_H, 0x03 },
0334 { REG_LENC_GREEN_X0_L, 0x30 },
0335 { REG_LENC_GREEN_Y0_H, 0x02 },
0336 { REG_LENC_GREEN_Y0_L, 0x7c },
0337 { REG_LENC_GREEN_A1, 0x40 },
0338 { REG_LENC_GREEN_B1, 0x00 },
0339 { REG_LENC_GREEN_A2_B2, 0x66 },
0340 { REG_LENC_BLUE_X0_H, 0x03 },
0341 { REG_LENC_BLUE_X0_L, 0x10 },
0342 { REG_LENC_BLUE_Y0_H, 0x02 },
0343 { REG_LENC_BLUE_Y0_L, 0x7c },
0344 { REG_LENC_BLUE_A1, 0x3a },
0345 { REG_LENC_BLUE_B1, 0x00 },
0346 { REG_LENC_BLUE_A2_B2, 0x66 },
0347 { REG_CIP_CTRL00, 0x44 },
0348 { REG_SHARPENMT_THRESH1, 0x08 },
0349 { REG_SHARPENMT_THRESH2, 0x10 },
0350 { REG_SHARPENMT_OFFSET1, 0x12 },
0351 { REG_SHARPENMT_OFFSET2, 0x02 },
0352 { REG_SHARPEN_THRESH1, 0x08 },
0353 { REG_SHARPEN_THRESH2, 0x10 },
0354 { REG_CIP_CTRL01, 0xa6 },
0355 { REG_DENOISE_THRESH1, 0x08 },
0356 { REG_DENOISE_THRESH2, 0x10 },
0357 { REG_DENOISE_OFFSET1, 0x04 },
0358 { REG_DENOISE_OFFSET2, 0x12 },
0359 { 0x507e, 0x40 },
0360 { 0x507f, 0x20 },
0361 { 0x507b, 0x02 },
0362 { REG_CMX_MISC_CTRL, 0x01 },
0363 { 0x5084, 0x0c },
0364 { 0x5085, 0x3e },
0365 { 0x5005, 0x80 },
0366 { 0x3a0f, 0x30 },
0367 { 0x3a10, 0x28 },
0368 { 0x3a1b, 0x32 },
0369 { 0x3a1e, 0x26 },
0370 { 0x3a11, 0x60 },
0371 { 0x3a1f, 0x14 },
0372 { 0x5060, 0x69 },
0373 { 0x5061, 0x7d },
0374 { 0x5062, 0x7d },
0375 { 0x5063, 0x69 },
0376 { REG_NULL, 0x00 },
0377 };
0378
0379
0380 static struct sensor_register ov2659_720p[] = {
0381 { REG_TIMING_HS_H, 0x00 },
0382 { REG_TIMING_HS_L, 0xa0 },
0383 { REG_TIMING_VS_H, 0x00 },
0384 { REG_TIMING_VS_L, 0xf0 },
0385 { REG_TIMING_HW_H, 0x05 },
0386 { REG_TIMING_HW_L, 0xbf },
0387 { REG_TIMING_VH_H, 0x03 },
0388 { REG_TIMING_VH_L, 0xcb },
0389 { REG_TIMING_DVPHO_H, 0x05 },
0390 { REG_TIMING_DVPHO_L, 0x00 },
0391 { REG_TIMING_DVPVO_H, 0x02 },
0392 { REG_TIMING_DVPVO_L, 0xd0 },
0393 { REG_TIMING_HTS_H, 0x06 },
0394 { REG_TIMING_HTS_L, 0x4c },
0395 { REG_TIMING_VTS_H, 0x02 },
0396 { REG_TIMING_VTS_L, 0xe8 },
0397 { REG_TIMING_HOFFS_L, 0x10 },
0398 { REG_TIMING_VOFFS_L, 0x06 },
0399 { REG_TIMING_XINC, 0x11 },
0400 { REG_TIMING_YINC, 0x11 },
0401 { REG_TIMING_VERT_FORMAT, 0x80 },
0402 { REG_TIMING_HORIZ_FORMAT, 0x00 },
0403 { 0x370a, 0x12 },
0404 { 0x3a03, 0xe8 },
0405 { 0x3a09, 0x6f },
0406 { 0x3a0b, 0x5d },
0407 { 0x3a15, 0x9a },
0408 { REG_VFIFO_READ_START_H, 0x00 },
0409 { REG_VFIFO_READ_START_L, 0x80 },
0410 { REG_ISP_CTRL02, 0x00 },
0411 { REG_NULL, 0x00 },
0412 };
0413
0414
0415 static struct sensor_register ov2659_uxga[] = {
0416 { REG_TIMING_HS_H, 0x00 },
0417 { REG_TIMING_HS_L, 0x00 },
0418 { REG_TIMING_VS_H, 0x00 },
0419 { REG_TIMING_VS_L, 0x00 },
0420 { REG_TIMING_HW_H, 0x06 },
0421 { REG_TIMING_HW_L, 0x5f },
0422 { REG_TIMING_VH_H, 0x04 },
0423 { REG_TIMING_VH_L, 0xbb },
0424 { REG_TIMING_DVPHO_H, 0x06 },
0425 { REG_TIMING_DVPHO_L, 0x40 },
0426 { REG_TIMING_DVPVO_H, 0x04 },
0427 { REG_TIMING_DVPVO_L, 0xb0 },
0428 { REG_TIMING_HTS_H, 0x07 },
0429 { REG_TIMING_HTS_L, 0x9f },
0430 { REG_TIMING_VTS_H, 0x04 },
0431 { REG_TIMING_VTS_L, 0xd0 },
0432 { REG_TIMING_HOFFS_L, 0x10 },
0433 { REG_TIMING_VOFFS_L, 0x06 },
0434 { REG_TIMING_XINC, 0x11 },
0435 { REG_TIMING_YINC, 0x11 },
0436 { 0x3a02, 0x04 },
0437 { 0x3a03, 0xd0 },
0438 { 0x3a08, 0x00 },
0439 { 0x3a09, 0xb8 },
0440 { 0x3a0a, 0x00 },
0441 { 0x3a0b, 0x9a },
0442 { 0x3a0d, 0x08 },
0443 { 0x3a0e, 0x06 },
0444 { 0x3a14, 0x04 },
0445 { 0x3a15, 0x50 },
0446 { 0x3623, 0x00 },
0447 { 0x3634, 0x44 },
0448 { 0x3701, 0x44 },
0449 { 0x3702, 0x30 },
0450 { 0x3703, 0x48 },
0451 { 0x3704, 0x48 },
0452 { 0x3705, 0x18 },
0453 { REG_TIMING_VERT_FORMAT, 0x80 },
0454 { REG_TIMING_HORIZ_FORMAT, 0x00 },
0455 { 0x370a, 0x12 },
0456 { REG_VFIFO_READ_START_H, 0x00 },
0457 { REG_VFIFO_READ_START_L, 0x80 },
0458 { REG_ISP_CTRL02, 0x00 },
0459 { REG_NULL, 0x00 },
0460 };
0461
0462
0463 static struct sensor_register ov2659_sxga[] = {
0464 { REG_TIMING_HS_H, 0x00 },
0465 { REG_TIMING_HS_L, 0x00 },
0466 { REG_TIMING_VS_H, 0x00 },
0467 { REG_TIMING_VS_L, 0x00 },
0468 { REG_TIMING_HW_H, 0x06 },
0469 { REG_TIMING_HW_L, 0x5f },
0470 { REG_TIMING_VH_H, 0x04 },
0471 { REG_TIMING_VH_L, 0xb7 },
0472 { REG_TIMING_DVPHO_H, 0x05 },
0473 { REG_TIMING_DVPHO_L, 0x00 },
0474 { REG_TIMING_DVPVO_H, 0x04 },
0475 { REG_TIMING_DVPVO_L, 0x00 },
0476 { REG_TIMING_HTS_H, 0x07 },
0477 { REG_TIMING_HTS_L, 0x9c },
0478 { REG_TIMING_VTS_H, 0x04 },
0479 { REG_TIMING_VTS_L, 0xd0 },
0480 { REG_TIMING_HOFFS_L, 0x10 },
0481 { REG_TIMING_VOFFS_L, 0x06 },
0482 { REG_TIMING_XINC, 0x11 },
0483 { REG_TIMING_YINC, 0x11 },
0484 { 0x3a02, 0x02 },
0485 { 0x3a03, 0x68 },
0486 { 0x3a08, 0x00 },
0487 { 0x3a09, 0x5c },
0488 { 0x3a0a, 0x00 },
0489 { 0x3a0b, 0x4d },
0490 { 0x3a0d, 0x08 },
0491 { 0x3a0e, 0x06 },
0492 { 0x3a14, 0x02 },
0493 { 0x3a15, 0x28 },
0494 { 0x3623, 0x00 },
0495 { 0x3634, 0x76 },
0496 { 0x3701, 0x44 },
0497 { 0x3702, 0x18 },
0498 { 0x3703, 0x24 },
0499 { 0x3704, 0x24 },
0500 { 0x3705, 0x0c },
0501 { REG_TIMING_VERT_FORMAT, 0x80 },
0502 { REG_TIMING_HORIZ_FORMAT, 0x00 },
0503 { 0x370a, 0x52 },
0504 { REG_VFIFO_READ_START_H, 0x00 },
0505 { REG_VFIFO_READ_START_L, 0x80 },
0506 { REG_ISP_CTRL02, 0x00 },
0507 { REG_NULL, 0x00 },
0508 };
0509
0510
0511 static struct sensor_register ov2659_xga[] = {
0512 { REG_TIMING_HS_H, 0x00 },
0513 { REG_TIMING_HS_L, 0x00 },
0514 { REG_TIMING_VS_H, 0x00 },
0515 { REG_TIMING_VS_L, 0x00 },
0516 { REG_TIMING_HW_H, 0x06 },
0517 { REG_TIMING_HW_L, 0x5f },
0518 { REG_TIMING_VH_H, 0x04 },
0519 { REG_TIMING_VH_L, 0xb7 },
0520 { REG_TIMING_DVPHO_H, 0x04 },
0521 { REG_TIMING_DVPHO_L, 0x00 },
0522 { REG_TIMING_DVPVO_H, 0x03 },
0523 { REG_TIMING_DVPVO_L, 0x00 },
0524 { REG_TIMING_HTS_H, 0x07 },
0525 { REG_TIMING_HTS_L, 0x9c },
0526 { REG_TIMING_VTS_H, 0x04 },
0527 { REG_TIMING_VTS_L, 0xd0 },
0528 { REG_TIMING_HOFFS_L, 0x10 },
0529 { REG_TIMING_VOFFS_L, 0x06 },
0530 { REG_TIMING_XINC, 0x11 },
0531 { REG_TIMING_YINC, 0x11 },
0532 { 0x3a02, 0x02 },
0533 { 0x3a03, 0x68 },
0534 { 0x3a08, 0x00 },
0535 { 0x3a09, 0x5c },
0536 { 0x3a0a, 0x00 },
0537 { 0x3a0b, 0x4d },
0538 { 0x3a0d, 0x08 },
0539 { 0x3a0e, 0x06 },
0540 { 0x3a14, 0x02 },
0541 { 0x3a15, 0x28 },
0542 { 0x3623, 0x00 },
0543 { 0x3634, 0x76 },
0544 { 0x3701, 0x44 },
0545 { 0x3702, 0x18 },
0546 { 0x3703, 0x24 },
0547 { 0x3704, 0x24 },
0548 { 0x3705, 0x0c },
0549 { REG_TIMING_VERT_FORMAT, 0x80 },
0550 { REG_TIMING_HORIZ_FORMAT, 0x00 },
0551 { 0x370a, 0x52 },
0552 { REG_VFIFO_READ_START_H, 0x00 },
0553 { REG_VFIFO_READ_START_L, 0x80 },
0554 { REG_ISP_CTRL02, 0x00 },
0555 { REG_NULL, 0x00 },
0556 };
0557
0558
0559 static struct sensor_register ov2659_svga[] = {
0560 { REG_TIMING_HS_H, 0x00 },
0561 { REG_TIMING_HS_L, 0x00 },
0562 { REG_TIMING_VS_H, 0x00 },
0563 { REG_TIMING_VS_L, 0x00 },
0564 { REG_TIMING_HW_H, 0x06 },
0565 { REG_TIMING_HW_L, 0x5f },
0566 { REG_TIMING_VH_H, 0x04 },
0567 { REG_TIMING_VH_L, 0xb7 },
0568 { REG_TIMING_DVPHO_H, 0x03 },
0569 { REG_TIMING_DVPHO_L, 0x20 },
0570 { REG_TIMING_DVPVO_H, 0x02 },
0571 { REG_TIMING_DVPVO_L, 0x58 },
0572 { REG_TIMING_HTS_H, 0x05 },
0573 { REG_TIMING_HTS_L, 0x14 },
0574 { REG_TIMING_VTS_H, 0x02 },
0575 { REG_TIMING_VTS_L, 0x68 },
0576 { REG_TIMING_HOFFS_L, 0x08 },
0577 { REG_TIMING_VOFFS_L, 0x02 },
0578 { REG_TIMING_XINC, 0x31 },
0579 { REG_TIMING_YINC, 0x31 },
0580 { 0x3a02, 0x02 },
0581 { 0x3a03, 0x68 },
0582 { 0x3a08, 0x00 },
0583 { 0x3a09, 0x5c },
0584 { 0x3a0a, 0x00 },
0585 { 0x3a0b, 0x4d },
0586 { 0x3a0d, 0x08 },
0587 { 0x3a0e, 0x06 },
0588 { 0x3a14, 0x02 },
0589 { 0x3a15, 0x28 },
0590 { 0x3623, 0x00 },
0591 { 0x3634, 0x76 },
0592 { 0x3701, 0x44 },
0593 { 0x3702, 0x18 },
0594 { 0x3703, 0x24 },
0595 { 0x3704, 0x24 },
0596 { 0x3705, 0x0c },
0597 { REG_TIMING_VERT_FORMAT, 0x81 },
0598 { REG_TIMING_HORIZ_FORMAT, 0x01 },
0599 { 0x370a, 0x52 },
0600 { REG_VFIFO_READ_START_H, 0x00 },
0601 { REG_VFIFO_READ_START_L, 0x80 },
0602 { REG_ISP_CTRL02, 0x00 },
0603 { REG_NULL, 0x00 },
0604 };
0605
0606
0607 static struct sensor_register ov2659_vga[] = {
0608 { REG_TIMING_HS_H, 0x00 },
0609 { REG_TIMING_HS_L, 0x00 },
0610 { REG_TIMING_VS_H, 0x00 },
0611 { REG_TIMING_VS_L, 0x00 },
0612 { REG_TIMING_HW_H, 0x06 },
0613 { REG_TIMING_HW_L, 0x5f },
0614 { REG_TIMING_VH_H, 0x04 },
0615 { REG_TIMING_VH_L, 0xb7 },
0616 { REG_TIMING_DVPHO_H, 0x02 },
0617 { REG_TIMING_DVPHO_L, 0x80 },
0618 { REG_TIMING_DVPVO_H, 0x01 },
0619 { REG_TIMING_DVPVO_L, 0xe0 },
0620 { REG_TIMING_HTS_H, 0x05 },
0621 { REG_TIMING_HTS_L, 0x14 },
0622 { REG_TIMING_VTS_H, 0x02 },
0623 { REG_TIMING_VTS_L, 0x68 },
0624 { REG_TIMING_HOFFS_L, 0x08 },
0625 { REG_TIMING_VOFFS_L, 0x02 },
0626 { REG_TIMING_XINC, 0x31 },
0627 { REG_TIMING_YINC, 0x31 },
0628 { 0x3a02, 0x02 },
0629 { 0x3a03, 0x68 },
0630 { 0x3a08, 0x00 },
0631 { 0x3a09, 0x5c },
0632 { 0x3a0a, 0x00 },
0633 { 0x3a0b, 0x4d },
0634 { 0x3a0d, 0x08 },
0635 { 0x3a0e, 0x06 },
0636 { 0x3a14, 0x02 },
0637 { 0x3a15, 0x28 },
0638 { 0x3623, 0x00 },
0639 { 0x3634, 0x76 },
0640 { 0x3701, 0x44 },
0641 { 0x3702, 0x18 },
0642 { 0x3703, 0x24 },
0643 { 0x3704, 0x24 },
0644 { 0x3705, 0x0c },
0645 { REG_TIMING_VERT_FORMAT, 0x81 },
0646 { REG_TIMING_HORIZ_FORMAT, 0x01 },
0647 { 0x370a, 0x52 },
0648 { REG_VFIFO_READ_START_H, 0x00 },
0649 { REG_VFIFO_READ_START_L, 0xa0 },
0650 { REG_ISP_CTRL02, 0x10 },
0651 { REG_NULL, 0x00 },
0652 };
0653
0654
0655 static struct sensor_register ov2659_qvga[] = {
0656 { REG_TIMING_HS_H, 0x00 },
0657 { REG_TIMING_HS_L, 0x00 },
0658 { REG_TIMING_VS_H, 0x00 },
0659 { REG_TIMING_VS_L, 0x00 },
0660 { REG_TIMING_HW_H, 0x06 },
0661 { REG_TIMING_HW_L, 0x5f },
0662 { REG_TIMING_VH_H, 0x04 },
0663 { REG_TIMING_VH_L, 0xb7 },
0664 { REG_TIMING_DVPHO_H, 0x01 },
0665 { REG_TIMING_DVPHO_L, 0x40 },
0666 { REG_TIMING_DVPVO_H, 0x00 },
0667 { REG_TIMING_DVPVO_L, 0xf0 },
0668 { REG_TIMING_HTS_H, 0x05 },
0669 { REG_TIMING_HTS_L, 0x14 },
0670 { REG_TIMING_VTS_H, 0x02 },
0671 { REG_TIMING_VTS_L, 0x68 },
0672 { REG_TIMING_HOFFS_L, 0x08 },
0673 { REG_TIMING_VOFFS_L, 0x02 },
0674 { REG_TIMING_XINC, 0x31 },
0675 { REG_TIMING_YINC, 0x31 },
0676 { 0x3a02, 0x02 },
0677 { 0x3a03, 0x68 },
0678 { 0x3a08, 0x00 },
0679 { 0x3a09, 0x5c },
0680 { 0x3a0a, 0x00 },
0681 { 0x3a0b, 0x4d },
0682 { 0x3a0d, 0x08 },
0683 { 0x3a0e, 0x06 },
0684 { 0x3a14, 0x02 },
0685 { 0x3a15, 0x28 },
0686 { 0x3623, 0x00 },
0687 { 0x3634, 0x76 },
0688 { 0x3701, 0x44 },
0689 { 0x3702, 0x18 },
0690 { 0x3703, 0x24 },
0691 { 0x3704, 0x24 },
0692 { 0x3705, 0x0c },
0693 { REG_TIMING_VERT_FORMAT, 0x81 },
0694 { REG_TIMING_HORIZ_FORMAT, 0x01 },
0695 { 0x370a, 0x52 },
0696 { REG_VFIFO_READ_START_H, 0x00 },
0697 { REG_VFIFO_READ_START_L, 0xa0 },
0698 { REG_ISP_CTRL02, 0x10 },
0699 { REG_NULL, 0x00 },
0700 };
0701
0702 static const struct pll_ctrl_reg ctrl3[] = {
0703 { 1, 0x00 },
0704 { 2, 0x02 },
0705 { 3, 0x03 },
0706 { 4, 0x06 },
0707 { 6, 0x0d },
0708 { 8, 0x0e },
0709 { 12, 0x0f },
0710 { 16, 0x12 },
0711 { 24, 0x13 },
0712 { 32, 0x16 },
0713 { 48, 0x1b },
0714 { 64, 0x1e },
0715 { 96, 0x1f },
0716 { 0, 0x00 },
0717 };
0718
0719 static const struct pll_ctrl_reg ctrl1[] = {
0720 { 2, 0x10 },
0721 { 4, 0x20 },
0722 { 6, 0x30 },
0723 { 8, 0x40 },
0724 { 10, 0x50 },
0725 { 12, 0x60 },
0726 { 14, 0x70 },
0727 { 16, 0x80 },
0728 { 18, 0x90 },
0729 { 20, 0xa0 },
0730 { 22, 0xb0 },
0731 { 24, 0xc0 },
0732 { 26, 0xd0 },
0733 { 28, 0xe0 },
0734 { 30, 0xf0 },
0735 { 0, 0x00 },
0736 };
0737
0738 static const struct ov2659_framesize ov2659_framesizes[] = {
0739 {
0740 .width = 320,
0741 .height = 240,
0742 .regs = ov2659_qvga,
0743 .max_exp_lines = 248,
0744 }, {
0745 .width = 640,
0746 .height = 480,
0747 .regs = ov2659_vga,
0748 .max_exp_lines = 498,
0749 }, {
0750 .width = 800,
0751 .height = 600,
0752 .regs = ov2659_svga,
0753 .max_exp_lines = 498,
0754 }, {
0755 .width = 1024,
0756 .height = 768,
0757 .regs = ov2659_xga,
0758 .max_exp_lines = 498,
0759 }, {
0760 .width = 1280,
0761 .height = 720,
0762 .regs = ov2659_720p,
0763 .max_exp_lines = 498,
0764 }, {
0765 .width = 1280,
0766 .height = 1024,
0767 .regs = ov2659_sxga,
0768 .max_exp_lines = 1048,
0769 }, {
0770 .width = 1600,
0771 .height = 1200,
0772 .regs = ov2659_uxga,
0773 .max_exp_lines = 498,
0774 },
0775 };
0776
0777
0778 static struct sensor_register ov2659_format_yuyv[] = {
0779 { REG_FORMAT_CTRL00, 0x30 },
0780 { REG_NULL, 0x0 },
0781 };
0782
0783
0784 static struct sensor_register ov2659_format_uyvy[] = {
0785 { REG_FORMAT_CTRL00, 0x32 },
0786 { REG_NULL, 0x0 },
0787 };
0788
0789
0790 static struct sensor_register ov2659_format_bggr[] = {
0791 { REG_FORMAT_CTRL00, 0x00 },
0792 { REG_NULL, 0x0 },
0793 };
0794
0795
0796 static struct sensor_register ov2659_format_rgb565[] = {
0797 { REG_FORMAT_CTRL00, 0x60 },
0798 { REG_NULL, 0x0 },
0799 };
0800
0801 static const struct ov2659_pixfmt ov2659_formats[] = {
0802 {
0803 .code = MEDIA_BUS_FMT_YUYV8_2X8,
0804 .format_ctrl_regs = ov2659_format_yuyv,
0805 }, {
0806 .code = MEDIA_BUS_FMT_UYVY8_2X8,
0807 .format_ctrl_regs = ov2659_format_uyvy,
0808 }, {
0809 .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
0810 .format_ctrl_regs = ov2659_format_rgb565,
0811 }, {
0812 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
0813 .format_ctrl_regs = ov2659_format_bggr,
0814 },
0815 };
0816
0817 static inline struct ov2659 *to_ov2659(struct v4l2_subdev *sd)
0818 {
0819 return container_of(sd, struct ov2659, sd);
0820 }
0821
0822
0823 static int ov2659_write(struct i2c_client *client, u16 reg, u8 val)
0824 {
0825 struct i2c_msg msg;
0826 u8 buf[3];
0827 int ret;
0828
0829 buf[0] = reg >> 8;
0830 buf[1] = reg & 0xFF;
0831 buf[2] = val;
0832
0833 msg.addr = client->addr;
0834 msg.flags = client->flags;
0835 msg.buf = buf;
0836 msg.len = sizeof(buf);
0837
0838 ret = i2c_transfer(client->adapter, &msg, 1);
0839 if (ret >= 0)
0840 return 0;
0841
0842 dev_dbg(&client->dev,
0843 "ov2659 write reg(0x%x val:0x%x) failed !\n", reg, val);
0844
0845 return ret;
0846 }
0847
0848
0849 static int ov2659_read(struct i2c_client *client, u16 reg, u8 *val)
0850 {
0851 struct i2c_msg msg[2];
0852 u8 buf[2];
0853 int ret;
0854
0855 buf[0] = reg >> 8;
0856 buf[1] = reg & 0xFF;
0857
0858 msg[0].addr = client->addr;
0859 msg[0].flags = client->flags;
0860 msg[0].buf = buf;
0861 msg[0].len = sizeof(buf);
0862
0863 msg[1].addr = client->addr;
0864 msg[1].flags = client->flags | I2C_M_RD;
0865 msg[1].buf = buf;
0866 msg[1].len = 1;
0867
0868 ret = i2c_transfer(client->adapter, msg, 2);
0869 if (ret >= 0) {
0870 *val = buf[0];
0871 return 0;
0872 }
0873
0874 dev_dbg(&client->dev,
0875 "ov2659 read reg(0x%x val:0x%x) failed !\n", reg, *val);
0876
0877 return ret;
0878 }
0879
0880 static int ov2659_write_array(struct i2c_client *client,
0881 const struct sensor_register *regs)
0882 {
0883 int i, ret = 0;
0884
0885 for (i = 0; ret == 0 && regs[i].addr; i++)
0886 ret = ov2659_write(client, regs[i].addr, regs[i].value);
0887
0888 return ret;
0889 }
0890
0891 static void ov2659_pll_calc_params(struct ov2659 *ov2659)
0892 {
0893 const struct ov2659_platform_data *pdata = ov2659->pdata;
0894 u8 ctrl1_reg = 0, ctrl2_reg = 0, ctrl3_reg = 0;
0895 struct i2c_client *client = ov2659->client;
0896 unsigned int desired = pdata->link_frequency;
0897 u32 prediv, postdiv, mult;
0898 u32 bestdelta = -1;
0899 u32 delta, actual;
0900 int i, j;
0901
0902 for (i = 0; ctrl1[i].div != 0; i++) {
0903 postdiv = ctrl1[i].div;
0904 for (j = 0; ctrl3[j].div != 0; j++) {
0905 prediv = ctrl3[j].div;
0906 for (mult = 1; mult <= 63; mult++) {
0907 actual = ov2659->xvclk_frequency;
0908 actual *= mult;
0909 actual /= prediv;
0910 actual /= postdiv;
0911 delta = actual - desired;
0912 delta = abs(delta);
0913
0914 if ((delta < bestdelta) || (bestdelta == -1)) {
0915 bestdelta = delta;
0916 ctrl1_reg = ctrl1[i].reg;
0917 ctrl2_reg = mult;
0918 ctrl3_reg = ctrl3[j].reg;
0919 }
0920 }
0921 }
0922 }
0923
0924 ov2659->pll.ctrl1 = ctrl1_reg;
0925 ov2659->pll.ctrl2 = ctrl2_reg;
0926 ov2659->pll.ctrl3 = ctrl3_reg;
0927
0928 dev_dbg(&client->dev,
0929 "Actual reg config: ctrl1_reg: %02x ctrl2_reg: %02x ctrl3_reg: %02x\n",
0930 ctrl1_reg, ctrl2_reg, ctrl3_reg);
0931 }
0932
0933 static int ov2659_set_pixel_clock(struct ov2659 *ov2659)
0934 {
0935 struct i2c_client *client = ov2659->client;
0936 struct sensor_register pll_regs[] = {
0937 {REG_SC_PLL_CTRL1, ov2659->pll.ctrl1},
0938 {REG_SC_PLL_CTRL2, ov2659->pll.ctrl2},
0939 {REG_SC_PLL_CTRL3, ov2659->pll.ctrl3},
0940 {REG_NULL, 0x00},
0941 };
0942
0943 dev_dbg(&client->dev, "%s\n", __func__);
0944
0945 return ov2659_write_array(client, pll_regs);
0946 };
0947
0948 static void ov2659_get_default_format(struct v4l2_mbus_framefmt *format)
0949 {
0950 format->width = ov2659_framesizes[2].width;
0951 format->height = ov2659_framesizes[2].height;
0952 format->colorspace = V4L2_COLORSPACE_SRGB;
0953 format->code = ov2659_formats[0].code;
0954 format->field = V4L2_FIELD_NONE;
0955 }
0956
0957 static void ov2659_set_streaming(struct ov2659 *ov2659, int on)
0958 {
0959 struct i2c_client *client = ov2659->client;
0960 int ret;
0961
0962 on = !!on;
0963
0964 dev_dbg(&client->dev, "%s: on: %d\n", __func__, on);
0965
0966 ret = ov2659_write(client, REG_SOFTWARE_STANDBY, on);
0967 if (ret)
0968 dev_err(&client->dev, "ov2659 soft standby failed\n");
0969 }
0970
0971 static int ov2659_init(struct v4l2_subdev *sd, u32 val)
0972 {
0973 struct i2c_client *client = v4l2_get_subdevdata(sd);
0974
0975 return ov2659_write_array(client, ov2659_init_regs);
0976 }
0977
0978
0979
0980
0981
0982 static int ov2659_enum_mbus_code(struct v4l2_subdev *sd,
0983 struct v4l2_subdev_state *sd_state,
0984 struct v4l2_subdev_mbus_code_enum *code)
0985 {
0986 struct i2c_client *client = v4l2_get_subdevdata(sd);
0987
0988 dev_dbg(&client->dev, "%s:\n", __func__);
0989
0990 if (code->index >= ARRAY_SIZE(ov2659_formats))
0991 return -EINVAL;
0992
0993 code->code = ov2659_formats[code->index].code;
0994
0995 return 0;
0996 }
0997
0998 static int ov2659_enum_frame_sizes(struct v4l2_subdev *sd,
0999 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
1024 static 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
1058 static 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
1086 static 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
1149 static 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
1158 static 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
1167 static 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
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
1206 unlock:
1207 mutex_unlock(&ov2659->lock);
1208 return ret;
1209 }
1210
1211 static 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
1234 static 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
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
1253 static const struct v4l2_ctrl_ops ov2659_ctrl_ops = {
1254 .s_ctrl = ov2659_s_ctrl,
1255 };
1256
1257 static const char * const ov2659_test_pattern_menu[] = {
1258 "Disabled",
1259 "Vertical Color Bars",
1260 };
1261
1262 static 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
1277 static 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
1307
1308
1309 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1310 static 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
1324 static 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
1330 static const struct v4l2_subdev_video_ops ov2659_subdev_video_ops = {
1331 .s_stream = ov2659_s_stream,
1332 };
1333
1334 static 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
1342 static 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
1348 static const struct v4l2_subdev_internal_ops ov2659_subdev_internal_ops = {
1349 .open = ov2659_open,
1350 };
1351 #endif
1352
1353 static 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
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
1390 static struct ov2659_platform_data *
1391 ov2659_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
1425 done:
1426 v4l2_fwnode_endpoint_free(&bus_cfg);
1427 of_node_put(endpoint);
1428 return pdata;
1429 }
1430
1431 static 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
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
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
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
1539 error:
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
1547 static 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
1565 static const struct dev_pm_ops ov2659_pm_ops = {
1566 SET_RUNTIME_PM_OPS(ov2659_power_off, ov2659_power_on, NULL)
1567 };
1568
1569 static const struct i2c_device_id ov2659_id[] = {
1570 { "ov2659", 0 },
1571 { },
1572 };
1573 MODULE_DEVICE_TABLE(i2c, ov2659_id);
1574
1575 #if IS_ENABLED(CONFIG_OF)
1576 static const struct of_device_id ov2659_of_match[] = {
1577 { .compatible = "ovti,ov2659", },
1578 { },
1579 };
1580 MODULE_DEVICE_TABLE(of, ov2659_of_match);
1581 #endif
1582
1583 static 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
1594 module_i2c_driver(ov2659_i2c_driver);
1595
1596 MODULE_AUTHOR("Benoit Parrot <bparrot@ti.com>");
1597 MODULE_DESCRIPTION("OV2659 CMOS Image Sensor driver");
1598 MODULE_LICENSE("GPL v2");