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