^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (c) 2019 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <media/v4l2-fwnode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define OV5675_REG_VALUE_08BIT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define OV5675_REG_VALUE_16BIT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define OV5675_REG_VALUE_24BIT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define OV5675_LINK_FREQ_450MHZ 450000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define OV5675_SCLK 90000000LL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define OV5675_MCLK 19200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define OV5675_DATA_LANES 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define OV5675_RGB_DEPTH 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define OV5675_REG_CHIP_ID 0x300a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define OV5675_CHIP_ID 0x5675
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define OV5675_REG_MODE_SELECT 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define OV5675_MODE_STANDBY 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define OV5675_MODE_STREAMING 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* vertical-timings from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define OV5675_REG_VTS 0x380e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define OV5675_VTS_30FPS 0x07e4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define OV5675_VTS_30FPS_MIN 0x07e4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define OV5675_VTS_MAX 0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* horizontal-timings from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define OV5675_REG_HTS 0x380c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* Exposure controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define OV5675_REG_EXPOSURE 0x3500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define OV5675_EXPOSURE_MIN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define OV5675_EXPOSURE_MAX_MARGIN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define OV5675_EXPOSURE_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Analog gain controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define OV5675_REG_ANALOG_GAIN 0x3508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define OV5675_ANAL_GAIN_MIN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define OV5675_ANAL_GAIN_MAX 2047
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define OV5675_ANAL_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* Digital gain controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define OV5675_REG_MWB_R_GAIN 0x5019
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define OV5675_REG_MWB_G_GAIN 0x501b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define OV5675_REG_MWB_B_GAIN 0x501d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define OV5675_DGTL_GAIN_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define OV5675_DGTL_GAIN_MAX 4095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define OV5675_DGTL_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define OV5675_DGTL_GAIN_DEFAULT 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Test Pattern Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define OV5675_REG_TEST_PATTERN 0x4503
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define OV5675_TEST_PATTERN_ENABLE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define OV5675_TEST_PATTERN_BAR_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Flip Mirror Controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define OV5675_REG_FORMAT1 0x3820
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define OV5675_REG_FORMAT2 0x373d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define to_ov5675(_sd) container_of(_sd, struct ov5675, sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) OV5675_LINK_FREQ_900MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct ov5675_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u16 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct ov5675_reg_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u32 num_of_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const struct ov5675_reg *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct ov5675_link_freq_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) const struct ov5675_reg_list reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct ov5675_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Frame width in pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) u32 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* Frame height in pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* Horizontal timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u32 hts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Default vertical timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u32 vts_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Min vertical timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u32 vts_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Link frequency needed for this resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u32 link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Sensor register settings for this resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) const struct ov5675_reg_list reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static const struct ov5675_reg mipi_data_rate_900mbps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {0x0103, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {0x0100, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {0x0300, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {0x0302, 0x8d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {0x0303, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {0x030d, 0x26},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static const struct ov5675_reg mode_2592x1944_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {0x3002, 0x21},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {0x3107, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {0x3501, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {0x3503, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {0x3508, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {0x3509, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {0x3600, 0x66},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {0x3602, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {0x3610, 0xa5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {0x3612, 0x93},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {0x3620, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {0x3642, 0x0e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {0x3661, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {0x3662, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {0x3664, 0xf3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {0x3665, 0x9e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {0x3667, 0xa5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {0x366e, 0x55},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {0x366f, 0x55},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {0x3670, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {0x3671, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {0x3672, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {0x3673, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {0x3714, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {0x371a, 0x3e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {0x3733, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {0x3734, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {0x373d, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {0x3764, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {0x3765, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {0x3766, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {0x37a1, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {0x37a8, 0x1c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {0x37ab, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {0x37c2, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {0x37cb, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {0x37cc, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {0x37cd, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {0x37ce, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {0x37d8, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {0x37d9, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {0x37dc, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {0x3803, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {0x3804, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {0x3805, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {0x3806, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {0x3807, 0xb3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {0x3808, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {0x3809, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {0x380a, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {0x380b, 0x98},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {0x380c, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {0x380d, 0xee},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {0x380e, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {0x380f, 0xe4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {0x3811, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {0x3813, 0x0d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {0x3814, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {0x3815, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {0x3816, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {0x3817, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {0x381e, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {0x3820, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {0x3821, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {0x3832, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {0x3c80, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {0x3c82, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {0x3c83, 0xc8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {0x3c8c, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {0x3c8d, 0xa0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {0x3c90, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {0x3c91, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {0x3c92, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {0x3c93, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {0x3c94, 0xd0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {0x3c95, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {0x3c96, 0x35},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {0x3c97, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {0x4001, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {0x4008, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {0x4009, 0x0d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {0x400f, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {0x4013, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {0x4040, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {0x4041, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {0x404c, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {0x404e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {0x4500, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {0x4503, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {0x450a, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {0x4809, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {0x480c, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {0x4819, 0x70},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {0x4825, 0x32},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {0x4826, 0x32},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {0x482a, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {0x4833, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {0x4837, 0x0d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {0x5000, 0x77},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {0x5b00, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {0x5b01, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {0x5b02, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {0x5b03, 0xdb},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {0x5b05, 0x6c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {0x5e10, 0xfc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {0x3500, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {0x3501, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {0x3502, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {0x3503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {0x3508, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {0x3509, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {0x3832, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {0x5780, 0x3e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {0x5781, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {0x5782, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {0x5783, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {0x5784, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {0x5785, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {0x5786, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {0x5787, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {0x5788, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {0x5789, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {0x578a, 0xfd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {0x578b, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {0x578c, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {0x578d, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {0x578e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {0x578f, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0x5790, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0x5791, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0x5792, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0x5793, 0x52},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0x5794, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {0x4003, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {0x3107, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {0x3c80, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {0x3c83, 0xb1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {0x3c8c, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {0x3c8d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {0x3c90, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0x3c94, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {0x3c95, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {0x3c96, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {0x37cb, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0x37cc, 0x15},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {0x37cd, 0x1f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {0x37ce, 0x1f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static const struct ov5675_reg mode_1296x972_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {0x3002, 0x21},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {0x3107, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {0x3501, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {0x3503, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {0x3508, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {0x3509, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {0x3600, 0x66},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {0x3602, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {0x3610, 0xa5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {0x3612, 0x93},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {0x3620, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {0x3642, 0x0e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {0x3661, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {0x3662, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {0x3664, 0xf3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {0x3665, 0x9e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {0x3667, 0xa5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {0x366e, 0x55},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {0x366f, 0x55},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {0x3670, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {0x3671, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {0x3672, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {0x3673, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {0x3714, 0x28},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {0x371a, 0x3e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {0x3733, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {0x3734, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {0x373d, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {0x3764, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {0x3765, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {0x3766, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {0x37a1, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {0x37a8, 0x1c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {0x37ab, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {0x37c2, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {0x37cb, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {0x37cc, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {0x37cd, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {0x37ce, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {0x37d8, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {0x37d9, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {0x37dc, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {0x3803, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {0x3804, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {0x3805, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {0x3806, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {0x3807, 0xb7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {0x3808, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {0x3809, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {0x380a, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {0x380b, 0xcc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {0x380c, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {0x380d, 0xee},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {0x380e, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {0x380f, 0xd0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {0x3811, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {0x3813, 0x0d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {0x3814, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {0x3815, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {0x3816, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {0x3817, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {0x381e, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {0x3820, 0x8b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {0x3821, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {0x3832, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {0x3c80, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {0x3c82, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {0x3c83, 0xc8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {0x3c8c, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {0x3c8d, 0xa0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {0x3c90, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {0x3c91, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {0x3c92, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {0x3c93, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {0x3c94, 0xd0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {0x3c95, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {0x3c96, 0x35},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {0x3c97, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {0x4001, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {0x4008, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {0x4009, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {0x400f, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {0x4013, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {0x4040, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {0x4041, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {0x404c, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {0x404e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {0x4500, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {0x4503, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {0x450a, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {0x4809, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {0x480c, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {0x4819, 0x70},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {0x4825, 0x32},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {0x4826, 0x32},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {0x482a, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {0x4833, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {0x4837, 0x0d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {0x5000, 0x77},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {0x5b00, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {0x5b01, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {0x5b02, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {0x5b03, 0xdb},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {0x5b05, 0x6c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {0x5e10, 0xfc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {0x3500, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {0x3501, 0x1F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {0x3502, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {0x3503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {0x3508, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {0x3509, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {0x3832, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {0x5780, 0x3e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {0x5781, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {0x5782, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {0x5783, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {0x5784, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {0x5785, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {0x5786, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {0x5787, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {0x5788, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {0x5789, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {0x578a, 0xfd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {0x578b, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {0x578c, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {0x578d, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {0x578e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {0x578f, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {0x5790, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {0x5791, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {0x5792, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {0x5793, 0x52},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {0x5794, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {0x4003, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {0x3107, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {0x3c80, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {0x3c83, 0xb1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {0x3c8c, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {0x3c8d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {0x3c90, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {0x3c94, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {0x3c95, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {0x3c96, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {0x37cb, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {0x37cc, 0x15},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {0x37cd, 0x1f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {0x37ce, 0x1f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static const char * const ov5675_test_pattern_menu[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) "Disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) "Standard Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) "Top-Bottom Darker Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) "Right-Left Darker Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) "Bottom-Top Darker Color Bar"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static const s64 link_freq_menu_items[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) OV5675_LINK_FREQ_450MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static const struct ov5675_link_freq_config link_freq_configs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) [OV5675_LINK_FREQ_900MBPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .num_of_regs = ARRAY_SIZE(mipi_data_rate_900mbps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .regs = mipi_data_rate_900mbps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static const struct ov5675_mode supported_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .width = 2592,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .height = 1944,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .hts = 1500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .vts_def = OV5675_VTS_30FPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .vts_min = OV5675_VTS_30FPS_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .regs = mode_2592x1944_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .link_freq_index = OV5675_LINK_FREQ_900MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .width = 1296,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .height = 972,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .hts = 1500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .vts_def = OV5675_VTS_30FPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .vts_min = OV5675_VTS_30FPS_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .num_of_regs = ARRAY_SIZE(mode_1296x972_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .regs = mode_1296x972_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .link_freq_index = OV5675_LINK_FREQ_900MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct ov5675 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct v4l2_ctrl_handler ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* V4L2 Controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct v4l2_ctrl *link_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct v4l2_ctrl *pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct v4l2_ctrl *vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct v4l2_ctrl *hblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct v4l2_ctrl *exposure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* Current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) const struct ov5675_mode *cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* To serialize asynchronus callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* Streaming on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) bool streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static u64 to_pixel_rate(u32 f_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV5675_DATA_LANES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) do_div(pixel_rate, OV5675_RGB_DEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static u64 to_pixels_per_line(u32 hts, u32 f_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u64 ppl = hts * to_pixel_rate(f_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) do_div(ppl, OV5675_SCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return ppl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static int ov5675_read_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct i2c_msg msgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u8 addr_buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) u8 data_buf[4] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) put_unaligned_be16(reg, addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) msgs[0].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) msgs[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) msgs[0].len = sizeof(addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) msgs[0].buf = addr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) msgs[1].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) msgs[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) msgs[1].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) msgs[1].buf = &data_buf[4 - len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (ret != ARRAY_SIZE(msgs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) *val = get_unaligned_be32(data_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static int ov5675_write_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) u8 buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) put_unaligned_be16(reg, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) put_unaligned_be32(val << 8 * (4 - len), buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (i2c_master_send(client, buf, len + 2) != len + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int ov5675_write_reg_list(struct ov5675 *ov5675,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) const struct ov5675_reg_list *r_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) for (i = 0; i < r_list->num_of_regs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) ret = ov5675_write_reg(ov5675, r_list->regs[i].address, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) r_list->regs[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) dev_err_ratelimited(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) "failed to write reg 0x%4.4x. error = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) r_list->regs[i].address, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static int ov5675_update_digital_gain(struct ov5675 *ov5675, u32 d_gain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_R_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) OV5675_REG_VALUE_16BIT, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_G_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) OV5675_REG_VALUE_16BIT, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return ov5675_write_reg(ov5675, OV5675_REG_MWB_B_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) OV5675_REG_VALUE_16BIT, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int ov5675_test_pattern(struct ov5675 *ov5675, u32 pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) pattern = (pattern - 1) << OV5675_TEST_PATTERN_BAR_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) OV5675_TEST_PATTERN_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return ov5675_write_reg(ov5675, OV5675_REG_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) OV5675_REG_VALUE_08BIT, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * OV5675 supports keeping the pixel order by mirror and flip function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * The Bayer order isn't affected by the flip controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static int ov5675_set_ctrl_hflip(struct ov5675 *ov5675, u32 ctrl_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ret = ov5675_read_reg(ov5675, OV5675_REG_FORMAT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) OV5675_REG_VALUE_08BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return ov5675_write_reg(ov5675, OV5675_REG_FORMAT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) OV5675_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ctrl_val ? val & ~BIT(3) : val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static int ov5675_set_ctrl_vflip(struct ov5675 *ov5675, u8 ctrl_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = ov5675_read_reg(ov5675, OV5675_REG_FORMAT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) OV5675_REG_VALUE_08BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = ov5675_write_reg(ov5675, OV5675_REG_FORMAT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) OV5675_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ctrl_val ? val | BIT(4) | BIT(5) : val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ret = ov5675_read_reg(ov5675, OV5675_REG_FORMAT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) OV5675_REG_VALUE_08BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return ov5675_write_reg(ov5675, OV5675_REG_FORMAT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) OV5675_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ctrl_val ? val | BIT(1) : val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct ov5675 *ov5675 = container_of(ctrl->handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct ov5675, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) s64 exposure_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Propagate change of current control to all related controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (ctrl->id == V4L2_CID_VBLANK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* Update max exposure while meeting expected vblanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) exposure_max = ov5675->cur_mode->height + ctrl->val -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) OV5675_EXPOSURE_MAX_MARGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) __v4l2_ctrl_modify_range(ov5675->exposure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ov5675->exposure->minimum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) exposure_max, ov5675->exposure->step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) exposure_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* V4L2 controls values will be applied only when power is already up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (!pm_runtime_get_if_in_use(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case V4L2_CID_ANALOGUE_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ret = ov5675_write_reg(ov5675, OV5675_REG_ANALOG_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) OV5675_REG_VALUE_16BIT, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case V4L2_CID_DIGITAL_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = ov5675_update_digital_gain(ov5675, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* 4 least significant bits of expsoure are fractional part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * val = val << 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * for ov5675, the unit of exposure is differnt from other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * OmniVision sensors, its exposure value is twice of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * register value, the exposure should be divided by 2 before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * set register, e.g. val << 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ret = ov5675_write_reg(ov5675, OV5675_REG_EXPOSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) OV5675_REG_VALUE_24BIT, ctrl->val << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case V4L2_CID_VBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ret = ov5675_write_reg(ov5675, OV5675_REG_VTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) OV5675_REG_VALUE_16BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ov5675->cur_mode->height + ctrl->val +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) case V4L2_CID_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) ret = ov5675_test_pattern(ov5675, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ov5675_set_ctrl_hflip(ov5675, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case V4L2_CID_VFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ov5675_set_ctrl_vflip(ov5675, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static const struct v4l2_ctrl_ops ov5675_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .s_ctrl = ov5675_set_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static int ov5675_init_controls(struct ov5675 *ov5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct v4l2_ctrl_handler *ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) s64 exposure_max, h_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ctrl_hdlr = &ov5675->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) ctrl_hdlr->lock = &ov5675->mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ov5675->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) V4L2_CID_LINK_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ARRAY_SIZE(link_freq_menu_items) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 0, link_freq_menu_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (ov5675->link_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ov5675->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ov5675->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) V4L2_CID_PIXEL_RATE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) to_pixel_rate(OV5675_LINK_FREQ_900MBPS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) to_pixel_rate(OV5675_LINK_FREQ_900MBPS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ov5675->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) V4L2_CID_VBLANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) ov5675->cur_mode->vts_min - ov5675->cur_mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) OV5675_VTS_MAX - ov5675->cur_mode->height, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ov5675->cur_mode->vts_def - ov5675->cur_mode->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) h_blank = to_pixels_per_line(ov5675->cur_mode->hts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ov5675->cur_mode->link_freq_index) - ov5675->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) ov5675->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) V4L2_CID_HBLANK, h_blank, h_blank, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (ov5675->hblank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ov5675->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) OV5675_ANAL_GAIN_MIN, OV5675_ANAL_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) OV5675_ANAL_GAIN_STEP, OV5675_ANAL_GAIN_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) OV5675_DGTL_GAIN_MIN, OV5675_DGTL_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) OV5675_DGTL_GAIN_STEP, OV5675_DGTL_GAIN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) exposure_max = (ov5675->cur_mode->vts_def - OV5675_EXPOSURE_MAX_MARGIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ov5675->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) V4L2_CID_EXPOSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) OV5675_EXPOSURE_MIN, exposure_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) OV5675_EXPOSURE_STEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) exposure_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) V4L2_CID_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) ARRAY_SIZE(ov5675_test_pattern_menu) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 0, 0, ov5675_test_pattern_menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) V4L2_CID_HFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) V4L2_CID_VFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (ctrl_hdlr->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return ctrl_hdlr->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ov5675->sd.ctrl_handler = ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static void ov5675_update_pad_format(const struct ov5675_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct v4l2_mbus_framefmt *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) fmt->width = mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) fmt->height = mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) fmt->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static int ov5675_start_streaming(struct ov5675 *ov5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) const struct ov5675_reg_list *reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) int link_freq_index, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) link_freq_index = ov5675->cur_mode->link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) reg_list = &link_freq_configs[link_freq_index].reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ret = ov5675_write_reg_list(ov5675, reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev_err(&client->dev, "failed to set plls");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) reg_list = &ov5675->cur_mode->reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ret = ov5675_write_reg_list(ov5675, reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) dev_err(&client->dev, "failed to set mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ret = __v4l2_ctrl_handler_setup(ov5675->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ret = ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) OV5675_REG_VALUE_08BIT, OV5675_MODE_STREAMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dev_err(&client->dev, "failed to set stream");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static void ov5675_stop_streaming(struct ov5675 *ov5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) OV5675_REG_VALUE_08BIT, OV5675_MODE_STANDBY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) dev_err(&client->dev, "failed to set stream");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct ov5675 *ov5675 = to_ov5675(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (ov5675->streaming == enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) mutex_lock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ret = pm_runtime_get_sync(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) ret = ov5675_start_streaming(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ov5675_stop_streaming(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ov5675_stop_streaming(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ov5675->streaming = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static int __maybe_unused ov5675_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct ov5675 *ov5675 = to_ov5675(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) mutex_lock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (ov5675->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ov5675_stop_streaming(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static int __maybe_unused ov5675_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct ov5675 *ov5675 = to_ov5675(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) mutex_lock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (ov5675->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) ret = ov5675_start_streaming(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ov5675->streaming = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ov5675_stop_streaming(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return ret;
^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) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static int ov5675_set_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct ov5675 *ov5675 = to_ov5675(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) const struct ov5675_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) s32 vblank_def, h_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) mode = v4l2_find_nearest_size(supported_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ARRAY_SIZE(supported_modes), width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) height, fmt->format.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) fmt->format.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) mutex_lock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ov5675_update_pad_format(mode, &fmt->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ov5675->cur_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) __v4l2_ctrl_s_ctrl(ov5675->link_freq, mode->link_freq_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) __v4l2_ctrl_s_ctrl_int64(ov5675->pixel_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) to_pixel_rate(mode->link_freq_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) /* Update limits and set FPS to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) vblank_def = mode->vts_def - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) __v4l2_ctrl_modify_range(ov5675->vblank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) mode->vts_min - mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) OV5675_VTS_MAX - mode->height, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) __v4l2_ctrl_s_ctrl(ov5675->vblank, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) __v4l2_ctrl_modify_range(ov5675->hblank, h_blank, h_blank, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static int ov5675_get_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct ov5675 *ov5675 = to_ov5675(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) mutex_lock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) fmt->format = *v4l2_subdev_get_try_format(&ov5675->sd, cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) fmt->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ov5675_update_pad_format(ov5675->cur_mode, &fmt->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) static int ov5675_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (code->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) static int ov5675_enum_frame_size(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (fse->index >= ARRAY_SIZE(supported_modes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) fse->min_width = supported_modes[fse->index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) fse->max_width = fse->min_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) fse->min_height = supported_modes[fse->index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) fse->max_height = fse->min_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static int ov5675_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct ov5675 *ov5675 = to_ov5675(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) mutex_lock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ov5675_update_pad_format(&supported_modes[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) v4l2_subdev_get_try_format(sd, fh->pad, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) mutex_unlock(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static const struct v4l2_subdev_video_ops ov5675_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .s_stream = ov5675_set_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static const struct v4l2_subdev_pad_ops ov5675_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .set_fmt = ov5675_set_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .get_fmt = ov5675_get_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .enum_mbus_code = ov5675_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .enum_frame_size = ov5675_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static const struct v4l2_subdev_ops ov5675_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .video = &ov5675_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .pad = &ov5675_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static const struct media_entity_operations ov5675_subdev_entity_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) .link_validate = v4l2_subdev_link_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static const struct v4l2_subdev_internal_ops ov5675_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .open = ov5675_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static int ov5675_identify_module(struct ov5675 *ov5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) OV5675_REG_VALUE_24BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (val != OV5675_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) dev_err(&client->dev, "chip id mismatch: %x!=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) OV5675_CHIP_ID, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static int ov5675_check_hwcfg(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct fwnode_handle *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct fwnode_handle *fwnode = dev_fwnode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct v4l2_fwnode_endpoint bus_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .bus_type = V4L2_MBUS_CSI2_DPHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) u32 mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (!fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) dev_err(dev, "can't get clock frequency");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (mclk != OV5675_MCLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) dev_err(dev, "external clock %d is not supported", mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) fwnode_handle_put(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV5675_DATA_LANES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) dev_err(dev, "number of CSI2 data lanes %d is not supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) bus_cfg.bus.mipi_csi2.num_data_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (!bus_cfg.nr_of_link_frequencies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dev_err(dev, "no link frequencies defined");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (link_freq_menu_items[i] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) bus_cfg.link_frequencies[j])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) break;
^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) if (j == bus_cfg.nr_of_link_frequencies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) dev_err(dev, "no link frequency %lld supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) link_freq_menu_items[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) check_hwcfg_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) v4l2_fwnode_endpoint_free(&bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int ov5675_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct ov5675 *ov5675 = to_ov5675(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) v4l2_async_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) v4l2_ctrl_handler_free(sd->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) mutex_destroy(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) static int ov5675_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct ov5675 *ov5675;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) ret = ov5675_check_hwcfg(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) dev_err(&client->dev, "failed to check HW configuration: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ov5675 = devm_kzalloc(&client->dev, sizeof(*ov5675), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (!ov5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) ret = ov5675_identify_module(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) dev_err(&client->dev, "failed to find sensor: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) mutex_init(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ov5675->cur_mode = &supported_modes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ret = ov5675_init_controls(ov5675);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) dev_err(&client->dev, "failed to init controls: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) goto probe_error_v4l2_ctrl_handler_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) ov5675->sd.internal_ops = &ov5675_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ov5675->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) ov5675->sd.entity.ops = &ov5675_subdev_entity_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ov5675->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ov5675->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) ret = media_entity_pads_init(&ov5675->sd.entity, 1, &ov5675->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) dev_err(&client->dev, "failed to init entity pads: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) goto probe_error_v4l2_ctrl_handler_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ret = v4l2_async_register_subdev_sensor_common(&ov5675->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) dev_err(&client->dev, "failed to register V4L2 subdev: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) goto probe_error_media_entity_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * Device is already turned on by i2c-core with ACPI domain PM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * Enable runtime PM and turn off the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) pm_runtime_idle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) probe_error_media_entity_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) media_entity_cleanup(&ov5675->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) probe_error_v4l2_ctrl_handler_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) v4l2_ctrl_handler_free(ov5675->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) mutex_destroy(&ov5675->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static const struct dev_pm_ops ov5675_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) SET_SYSTEM_SLEEP_PM_OPS(ov5675_suspend, ov5675_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static const struct acpi_device_id ov5675_acpi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {"OVTI5675"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) MODULE_DEVICE_TABLE(acpi, ov5675_acpi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static struct i2c_driver ov5675_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .name = "ov5675",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .pm = &ov5675_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .acpi_match_table = ACPI_PTR(ov5675_acpi_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) .probe_new = ov5675_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .remove = ov5675_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) module_i2c_driver(ov5675_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) MODULE_AUTHOR("Shawn Tu <shawnx.tu@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) MODULE_DESCRIPTION("OmniVision OV5675 sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) MODULE_LICENSE("GPL v2");