^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) 2018 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/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <media/v4l2-event.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 IMX355_REG_MODE_SELECT 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define IMX355_MODE_STANDBY 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define IMX355_MODE_STREAMING 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* Chip ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define IMX355_REG_CHIP_ID 0x0016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define IMX355_CHIP_ID 0x0355
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* V_TIMING internal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define IMX355_REG_FLL 0x0340
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define IMX355_FLL_MAX 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Exposure control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define IMX355_REG_EXPOSURE 0x0202
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define IMX355_EXPOSURE_MIN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define IMX355_EXPOSURE_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define IMX355_EXPOSURE_DEFAULT 0x0282
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Analog gain control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define IMX355_REG_ANALOG_GAIN 0x0204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define IMX355_ANA_GAIN_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define IMX355_ANA_GAIN_MAX 960
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define IMX355_ANA_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define IMX355_ANA_GAIN_DEFAULT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Digital gain control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define IMX355_REG_DPGA_USE_GLOBAL_GAIN 0x3070
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define IMX355_REG_DIG_GAIN_GLOBAL 0x020e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define IMX355_DGTL_GAIN_MIN 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define IMX355_DGTL_GAIN_MAX 4095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define IMX355_DGTL_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define IMX355_DGTL_GAIN_DEFAULT 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Test Pattern Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define IMX355_REG_TEST_PATTERN 0x0600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define IMX355_TEST_PATTERN_DISABLED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define IMX355_TEST_PATTERN_SOLID_COLOR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define IMX355_TEST_PATTERN_COLOR_BARS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define IMX355_TEST_PATTERN_PN9 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Flip Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define IMX355_REG_ORIENTATION 0x0101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* default link frequency and external clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IMX355_LINK_FREQ_DEFAULT 360000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IMX355_EXT_CLK 19200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IMX355_LINK_FREQ_INDEX 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct imx355_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u16 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct imx355_reg_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u32 num_of_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) const struct imx355_reg *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* Mode : resolution and related config&values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct imx355_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Frame width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u32 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Frame height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u32 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* V-timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u32 fll_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u32 fll_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* H-timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u32 llp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* index of link frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u32 link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Default register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct imx355_reg_list reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct imx355_hwcfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 ext_clk; /* sensor external clk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) s64 *link_freqs; /* CSI-2 link frequencies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned int nr_of_link_freqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct imx355 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct v4l2_ctrl_handler ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* V4L2 Controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct v4l2_ctrl *link_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct v4l2_ctrl *pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct v4l2_ctrl *vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct v4l2_ctrl *hblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct v4l2_ctrl *exposure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct v4l2_ctrl *vflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct v4l2_ctrl *hflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const struct imx355_mode *cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct imx355_hwcfg *hwcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) s64 link_def_freq; /* CSI-2 link default frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Mutex for serialized access:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Protect sensor set pad format and start/stop streaming safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * Protect access to sensor v4l2 controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Streaming on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) bool streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static const struct imx355_reg imx355_global_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) { 0x0136, 0x13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { 0x0137, 0x33 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { 0x304e, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { 0x4348, 0x16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { 0x4350, 0x19 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { 0x4408, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { 0x440c, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { 0x4411, 0x5f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { 0x4412, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { 0x4623, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { 0x462c, 0x0f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { 0x462d, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { 0x462e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { 0x4684, 0x54 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { 0x480a, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { 0x4908, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { 0x4909, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) { 0x490d, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { 0x491e, 0x0f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) { 0x4921, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { 0x4923, 0x28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) { 0x4924, 0x28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { 0x4925, 0x29 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) { 0x4926, 0x29 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { 0x4927, 0x1f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) { 0x4928, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { 0x4929, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { 0x492a, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { 0x492c, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { 0x492d, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { 0x492e, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) { 0x492f, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) { 0x4930, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) { 0x4931, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { 0x4932, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) { 0x4933, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { 0x595e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) { 0x5963, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { 0x3030, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) { 0x3031, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) { 0x3045, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) { 0x4010, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { 0x4011, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) { 0x4012, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { 0x4013, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) { 0x68a8, 0xfe },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { 0x68a9, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { 0x6888, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) { 0x6889, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) { 0x68b0, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { 0x3058, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { 0x305a, 0x00 },
^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) static const struct imx355_reg_list imx355_global_setting = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .num_of_regs = ARRAY_SIZE(imx355_global_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .regs = imx355_global_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static const struct imx355_reg mode_3268x2448_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { 0x0340, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) { 0x0341, 0x37 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) { 0x0344, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) { 0x0345, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) { 0x0346, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) { 0x0347, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) { 0x0348, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) { 0x0349, 0xcb },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) { 0x034a, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) { 0x034b, 0x97 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) { 0x0900, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) { 0x0901, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) { 0x034c, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { 0x034d, 0xc4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) { 0x034e, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) { 0x034f, 0x90 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static const struct imx355_reg mode_3264x2448_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) { 0x0340, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) { 0x0341, 0x37 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) { 0x0344, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { 0x0345, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { 0x0346, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { 0x0347, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { 0x0348, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { 0x0349, 0xc7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { 0x034a, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { 0x034b, 0x97 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { 0x0900, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { 0x0901, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { 0x034c, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { 0x034d, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) { 0x034e, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) { 0x034f, 0x90 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static const struct imx355_reg mode_3280x2464_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { 0x0340, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { 0x0341, 0x37 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { 0x0344, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { 0x0345, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { 0x0346, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { 0x0347, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) { 0x0348, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { 0x0349, 0xcf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) { 0x034a, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { 0x034b, 0x9f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) { 0x0900, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) { 0x0901, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) { 0x034c, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) { 0x034d, 0xd0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { 0x034e, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { 0x034f, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static const struct imx355_reg mode_1940x1096_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) { 0x0344, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) { 0x0345, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) { 0x0346, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) { 0x0347, 0xac },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) { 0x0348, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) { 0x0349, 0x33 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) { 0x034a, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) { 0x034b, 0xf3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) { 0x0900, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) { 0x0901, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) { 0x034c, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) { 0x034d, 0x94 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) { 0x034e, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) { 0x034f, 0x48 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static const struct imx355_reg mode_1936x1096_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) { 0x0344, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) { 0x0345, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) { 0x0346, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) { 0x0347, 0xac },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) { 0x0348, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) { 0x0349, 0x2f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { 0x034a, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) { 0x034b, 0xf3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { 0x0900, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { 0x0901, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) { 0x034c, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) { 0x034d, 0x90 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) { 0x034e, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) { 0x034f, 0x48 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) { 0x684f, 0x04 },
^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 struct imx355_reg mode_1924x1080_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) { 0x0344, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) { 0x0345, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) { 0x0346, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) { 0x0347, 0xb4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) { 0x0348, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) { 0x0349, 0x2b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) { 0x034a, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) { 0x034b, 0xeb },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) { 0x0900, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) { 0x0901, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) { 0x034c, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) { 0x034d, 0x84 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) { 0x034e, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) { 0x034f, 0x38 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static const struct imx355_reg mode_1920x1080_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) { 0x0344, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) { 0x0345, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) { 0x0346, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) { 0x0347, 0xb4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) { 0x0348, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) { 0x0349, 0x27 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) { 0x034a, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) { 0x034b, 0xeb },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) { 0x0900, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) { 0x0901, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { 0x034c, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) { 0x034d, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) { 0x034e, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) { 0x034f, 0x38 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static const struct imx355_reg mode_1640x1232_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) { 0x0342, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) { 0x0343, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) { 0x0344, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) { 0x0345, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) { 0x0346, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) { 0x0347, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) { 0x0348, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) { 0x0349, 0xcf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) { 0x034a, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) { 0x034b, 0x9f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) { 0x0900, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) { 0x0901, 0x22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) { 0x034c, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) { 0x034d, 0x68 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) { 0x034e, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) { 0x034f, 0xd0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) { 0x684f, 0x04 },
^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 const struct imx355_reg mode_1640x922_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) { 0x0342, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) { 0x0343, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) { 0x0344, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) { 0x0345, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) { 0x0346, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) { 0x0347, 0x30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) { 0x0348, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) { 0x0349, 0xcf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) { 0x034a, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) { 0x034b, 0x63 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) { 0x0900, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) { 0x0901, 0x22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) { 0x034c, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) { 0x034d, 0x68 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) { 0x034e, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) { 0x034f, 0x9a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static const struct imx355_reg mode_1300x736_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) { 0x0342, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) { 0x0343, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) { 0x0344, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) { 0x0345, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) { 0x0346, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) { 0x0347, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) { 0x0348, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) { 0x0349, 0x7f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) { 0x034a, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) { 0x034b, 0xaf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) { 0x0900, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) { 0x0901, 0x22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) { 0x034c, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) { 0x034d, 0x14 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) { 0x034e, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) { 0x034f, 0xe0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static const struct imx355_reg mode_1296x736_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) { 0x0342, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) { 0x0343, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) { 0x0344, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) { 0x0345, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) { 0x0346, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) { 0x0347, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) { 0x0348, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) { 0x0349, 0x77 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) { 0x034a, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) { 0x034b, 0xaf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) { 0x0900, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) { 0x0901, 0x22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) { 0x034c, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) { 0x034d, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) { 0x034e, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) { 0x034f, 0xe0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static const struct imx355_reg mode_1284x720_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) { 0x0342, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) { 0x0343, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) { 0x0344, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) { 0x0345, 0x68 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) { 0x0346, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) { 0x0347, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) { 0x0348, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) { 0x0349, 0x6f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) { 0x034a, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) { 0x034b, 0x9f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) { 0x0900, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) { 0x0901, 0x22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) { 0x034c, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) { 0x034d, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) { 0x034e, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) { 0x034f, 0xd0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static const struct imx355_reg mode_1280x720_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) { 0x0342, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) { 0x0343, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) { 0x0340, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) { 0x0341, 0x1a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) { 0x0344, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) { 0x0345, 0x68 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) { 0x0346, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) { 0x0347, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) { 0x0348, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) { 0x0349, 0x67 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) { 0x034a, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) { 0x034b, 0x9f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) { 0x0900, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) { 0x0901, 0x22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) { 0x034c, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) { 0x034d, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) { 0x034e, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) { 0x034f, 0xd0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) { 0x0700, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) { 0x0701, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static const struct imx355_reg mode_820x616_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) { 0x0112, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) { 0x0113, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) { 0x0114, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) { 0x0342, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) { 0x0343, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) { 0x0340, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) { 0x0341, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) { 0x0344, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) { 0x0345, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) { 0x0346, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) { 0x0347, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) { 0x0348, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) { 0x0349, 0xcf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) { 0x034a, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) { 0x034b, 0x9f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) { 0x0220, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) { 0x0222, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) { 0x0900, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) { 0x0901, 0x44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) { 0x0902, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) { 0x034c, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) { 0x034d, 0x34 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) { 0x034e, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) { 0x034f, 0x68 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) { 0x0301, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) { 0x0303, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) { 0x0305, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) { 0x0306, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) { 0x0307, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) { 0x030b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) { 0x030d, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) { 0x030e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) { 0x030f, 0x4b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) { 0x0310, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) { 0x0700, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) { 0x0701, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) { 0x0820, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) { 0x0821, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) { 0x3088, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) { 0x6813, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) { 0x6835, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) { 0x6836, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) { 0x6837, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) { 0x684d, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) { 0x684e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) { 0x684f, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static const char * const imx355_test_pattern_menu[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) "Disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) "Solid Colour",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) "Eight Vertical Colour Bars",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) "Colour Bars With Fade to Grey",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) "Pseudorandom Sequence (PN9)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /* supported link frequencies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static const s64 link_freq_menu_items[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) IMX355_LINK_FREQ_DEFAULT,
^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) /* Mode configs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static const struct imx355_mode supported_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .width = 3280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .height = 2464,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .fll_def = 2615,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .fll_min = 2615,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .regs = mode_3280x2464_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) },
^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) .width = 3268,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .height = 2448,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .fll_def = 2615,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .fll_min = 2615,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .regs = mode_3268x2448_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .width = 3264,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .height = 2448,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .fll_def = 2615,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .fll_min = 2615,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .regs = mode_3264x2448_regs,
^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) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .width = 1940,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) .height = 1096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .regs = mode_1940x1096_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .width = 1936,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .height = 1096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .regs = mode_1936x1096_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .width = 1924,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .height = 1080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .regs = mode_1924x1080_regs,
^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) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .width = 1920,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .height = 1080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .regs = mode_1920x1080_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .width = 1640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .height = 1232,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .llp = 1836,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .regs = mode_1640x1232_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .width = 1640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .height = 922,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) .llp = 1836,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) .regs = mode_1640x922_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .width = 1300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .height = 736,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .llp = 1836,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .regs = mode_1300x736_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) .width = 1296,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) .height = 736,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) .llp = 1836,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .regs = mode_1296x736_regs,
^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) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .width = 1284,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .height = 720,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .llp = 1836,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .regs = mode_1284x720_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .width = 1280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .height = 720,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .fll_def = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .fll_min = 1306,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .llp = 1836,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .regs = mode_1280x720_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) },
^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) .width = 820,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .height = 616,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .fll_def = 652,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .fll_min = 652,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .llp = 3672,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .link_freq_index = IMX355_LINK_FREQ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .regs = mode_820x616_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static inline struct imx355 *to_imx355(struct v4l2_subdev *_sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return container_of(_sd, struct imx355, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) /* Get bayer order based on flip setting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static u32 imx355_get_format_code(struct imx355 *imx355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * Only one bayer order is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * It depends on the flip settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) u32 code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static const u32 codes[2][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) lockdep_assert_held(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) code = codes[imx355->vflip->val][imx355->hflip->val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return code;
^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) /* Read registers up to 4 at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct i2c_msg msgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) u8 addr_buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) u8 data_buf[4] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (len > 4)
^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) put_unaligned_be16(reg, addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) /* Write register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) msgs[0].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) msgs[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) msgs[0].len = ARRAY_SIZE(addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) msgs[0].buf = addr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /* Read data from register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) msgs[1].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) msgs[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) msgs[1].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) msgs[1].buf = &data_buf[4 - len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (ret != ARRAY_SIZE(msgs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) *val = get_unaligned_be32(data_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /* Write registers up to 4 at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) u8 buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) put_unaligned_be16(reg, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (i2c_master_send(client, buf, len + 2) != len + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) /* Write a list of registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static int imx355_write_regs(struct imx355 *imx355,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) const struct imx355_reg *regs, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) dev_err_ratelimited(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) "write reg 0x%4.4x return err %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) regs[i].address, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /* Open sub-device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct v4l2_mbus_framefmt *try_fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) v4l2_subdev_get_try_format(sd, fh->pad, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) mutex_lock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /* Initialize try_fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) try_fmt->width = imx355->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) try_fmt->height = imx355->cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) try_fmt->code = imx355_get_format_code(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) try_fmt->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return 0;
^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) static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct imx355 *imx355 = container_of(ctrl->handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct imx355, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) s64 max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /* Propagate change of current control to all related controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) case V4L2_CID_VBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* Update max exposure while meeting expected vblanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) max = imx355->cur_mode->height + ctrl->val - 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) __v4l2_ctrl_modify_range(imx355->exposure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) imx355->exposure->minimum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) max, imx355->exposure->step, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) break;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * Applying V4L2 control value only happens
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * when power is up for streaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (!pm_runtime_get_if_in_use(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) case V4L2_CID_ANALOGUE_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) /* Analog gain = 1024/(1024 - ctrl->val) times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) case V4L2_CID_DIGITAL_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) case V4L2_CID_VBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* Update FLL that meets expected vertical blanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) imx355->cur_mode->height + ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) case V4L2_CID_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 2, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) case V4L2_CID_VFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) imx355->hflip->val |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) imx355->vflip->val << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) ctrl->id, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static const struct v4l2_ctrl_ops imx355_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .s_ctrl = imx355_set_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static int imx355_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (code->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) mutex_lock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) code->code = imx355_get_format_code(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static int imx355_enum_frame_size(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (fse->index >= ARRAY_SIZE(supported_modes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) mutex_lock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (fse->code != imx355_get_format_code(imx355)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) fse->min_width = supported_modes[fse->index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) fse->max_width = fse->min_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) fse->min_height = supported_modes[fse->index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) fse->max_height = fse->min_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) static void imx355_update_pad_format(struct imx355 *imx355,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) const struct imx355_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) fmt->format.width = mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) fmt->format.height = mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) fmt->format.code = imx355_get_format_code(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) fmt->format.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) static int imx355_do_get_pad_format(struct imx355 *imx355,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) struct v4l2_mbus_framefmt *framefmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) struct v4l2_subdev *sd = &imx355->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) fmt->format = *framefmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) imx355_update_pad_format(imx355, imx355->cur_mode, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) static int imx355_get_pad_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) mutex_lock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) ret = imx355_do_get_pad_format(imx355, cfg, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) imx355_set_pad_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) const struct imx355_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) struct v4l2_mbus_framefmt *framefmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) s32 vblank_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) s32 vblank_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) s64 h_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) u64 pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) u32 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) mutex_lock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * Only one bayer order is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) * It depends on the flip settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) fmt->format.code = imx355_get_format_code(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) mode = v4l2_find_nearest_size(supported_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) ARRAY_SIZE(supported_modes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) width, height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) fmt->format.width, fmt->format.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) imx355_update_pad_format(imx355, mode, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) *framefmt = fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) imx355->cur_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) pixel_rate = imx355->link_def_freq * 2 * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) do_div(pixel_rate, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) /* Update limits and set FPS to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) height = imx355->cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) vblank_def = imx355->cur_mode->fll_def - height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) vblank_min = imx355->cur_mode->fll_min - height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) height = IMX355_FLL_MAX - height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) h_blank = mode->llp - imx355->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * Currently hblank is not changeable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) * So FPS control is done only by vblank.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) __v4l2_ctrl_modify_range(imx355->hblank, h_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) h_blank, 1, h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /* Start streaming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static int imx355_start_streaming(struct imx355 *imx355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) const struct imx355_reg_list *reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /* Global Setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) reg_list = &imx355_global_setting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) dev_err(&client->dev, "failed to set global settings");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* Apply default values of current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) reg_list = &imx355->cur_mode->reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) dev_err(&client->dev, "failed to set mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) /* set digital gain control to all color mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /* Apply customized values from user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 1, IMX355_MODE_STREAMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /* Stop streaming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) static int imx355_stop_streaming(struct imx355 *imx355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 1, IMX355_MODE_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) mutex_lock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (imx355->streaming == enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) ret = pm_runtime_get_sync(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * Apply default & customized values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * and then start streaming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) ret = imx355_start_streaming(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) goto err_rpm_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) imx355_stop_streaming(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) imx355->streaming = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /* vflip and hflip cannot change during streaming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) __v4l2_ctrl_grab(imx355->vflip, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) __v4l2_ctrl_grab(imx355->hflip, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) err_rpm_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) mutex_unlock(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) static int __maybe_unused imx355_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (imx355->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) imx355_stop_streaming(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) return 0;
^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) static int __maybe_unused imx355_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (imx355->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) ret = imx355_start_streaming(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) imx355_stop_streaming(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) imx355->streaming = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) /* Verify chip ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) static int imx355_identify_module(struct imx355 *imx355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (val != IMX355_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) dev_err(&client->dev, "chip id mismatch: %x!=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) IMX355_CHIP_ID, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) static const struct v4l2_subdev_core_ops imx355_subdev_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) .unsubscribe_event = v4l2_event_subdev_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) static const struct v4l2_subdev_video_ops imx355_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) .s_stream = imx355_set_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) .enum_mbus_code = imx355_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) .get_fmt = imx355_get_pad_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) .set_fmt = imx355_set_pad_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) .enum_frame_size = imx355_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) static const struct v4l2_subdev_ops imx355_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) .core = &imx355_subdev_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) .video = &imx355_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) .pad = &imx355_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static const struct media_entity_operations imx355_subdev_entity_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) .link_validate = v4l2_subdev_link_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) .open = imx355_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) /* Initialize control handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) static int imx355_init_controls(struct imx355 *imx355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) struct v4l2_ctrl_handler *ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) s64 exposure_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) s64 vblank_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) s64 vblank_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) s64 hblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) u64 pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) const struct imx355_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) u32 max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) ctrl_hdlr = &imx355->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) ctrl_hdlr->lock = &imx355->mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) max = ARRAY_SIZE(link_freq_menu_items) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) V4L2_CID_LINK_FREQ, max, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) link_freq_menu_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (imx355->link_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) pixel_rate = imx355->link_def_freq * 2 * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) do_div(pixel_rate, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) /* By default, PIXEL_RATE is read only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) V4L2_CID_PIXEL_RATE, pixel_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) pixel_rate, 1, pixel_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* Initialize vblank/hblank/exposure parameters based on current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) mode = imx355->cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) vblank_def = mode->fll_def - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) vblank_min = mode->fll_min - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) V4L2_CID_VBLANK, vblank_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) IMX355_FLL_MAX - mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 1, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) hblank = mode->llp - mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) V4L2_CID_HBLANK, hblank, hblank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 1, hblank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (imx355->hblank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) /* fll >= exposure time + adjust parameter (default value is 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) exposure_max = mode->fll_def - 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) V4L2_CID_EXPOSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) IMX355_EXPOSURE_MIN, exposure_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) IMX355_EXPOSURE_STEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) IMX355_EXPOSURE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) imx355->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) V4L2_CID_HFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) imx355->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) V4L2_CID_VFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) IMX355_ANA_GAIN_MIN, IMX355_ANA_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) IMX355_ANA_GAIN_STEP, IMX355_ANA_GAIN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) /* Digital gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) IMX355_DGTL_GAIN_MIN, IMX355_DGTL_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) IMX355_DGTL_GAIN_STEP, IMX355_DGTL_GAIN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx355_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) V4L2_CID_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) ARRAY_SIZE(imx355_test_pattern_menu) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 0, 0, imx355_test_pattern_menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (ctrl_hdlr->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) ret = ctrl_hdlr->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) dev_err(&client->dev, "control init failed: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) imx355->sd.ctrl_handler = ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) v4l2_ctrl_handler_free(ctrl_hdlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) struct imx355_hwcfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct v4l2_fwnode_endpoint bus_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .bus_type = V4L2_MBUS_CSI2_DPHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) struct fwnode_handle *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) struct fwnode_handle *fwnode = dev_fwnode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if (!fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (!cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) &cfg->ext_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) dev_err(dev, "can't get clock frequency");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) if (cfg->ext_clk != IMX355_EXT_CLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) dev_err(dev, "external clock %d is not supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) cfg->ext_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) if (!bus_cfg.nr_of_link_frequencies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) dev_warn(dev, "no link frequencies defined");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) cfg->link_freqs = devm_kcalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) bus_cfg.nr_of_link_frequencies + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) sizeof(*cfg->link_freqs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (!cfg->link_freqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) v4l2_fwnode_endpoint_free(&bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) fwnode_handle_put(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) return cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) v4l2_fwnode_endpoint_free(&bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) fwnode_handle_put(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) static int imx355_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) struct imx355 *imx355;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (!imx355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) mutex_init(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) /* Initialize subdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) /* Check module identity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) ret = imx355_identify_module(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) dev_err(&client->dev, "failed to find sensor: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) goto error_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) imx355->hwcfg = imx355_get_hwcfg(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) if (!imx355->hwcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) dev_err(&client->dev, "failed to get hwcfg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) goto error_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) dev_dbg(&client->dev, "link freq index %d matched", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if (i == imx355->hwcfg->nr_of_link_freqs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) dev_err(&client->dev, "no link frequency supported");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) goto error_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) /* Set default mode to max resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) imx355->cur_mode = &supported_modes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) ret = imx355_init_controls(imx355);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) dev_err(&client->dev, "failed to init controls: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) goto error_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) /* Initialize subdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) imx355->sd.internal_ops = &imx355_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) imx355->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) V4L2_SUBDEV_FL_HAS_EVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) imx355->sd.entity.ops = &imx355_subdev_entity_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) imx355->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) /* Initialize source pad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) dev_err(&client->dev, "failed to init entity pads: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) goto error_handler_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) ret = v4l2_async_register_subdev_sensor_common(&imx355->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) goto error_media_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) * Device is already turned on by i2c-core with ACPI domain PM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) * Enable runtime PM and turn off the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) pm_runtime_idle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) error_media_entity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) media_entity_cleanup(&imx355->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) error_handler_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) v4l2_ctrl_handler_free(imx355->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) error_probe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) mutex_destroy(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) static int imx355_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) struct imx355 *imx355 = to_imx355(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) v4l2_async_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) v4l2_ctrl_handler_free(sd->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) pm_runtime_set_suspended(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) mutex_destroy(&imx355->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) static const struct dev_pm_ops imx355_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) static const struct acpi_device_id imx355_acpi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) { "SONY355A" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) static struct i2c_driver imx355_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) .name = "imx355",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) .pm = &imx355_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) .acpi_match_table = ACPI_PTR(imx355_acpi_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) .probe_new = imx355_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) .remove = imx355_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) module_i2c_driver(imx355_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) MODULE_DESCRIPTION("Sony imx355 sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) MODULE_LICENSE("GPL v2");