forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/imx415.c
....@@ -23,6 +23,12 @@
2323 * V0.0X01.0X06
2424 * 1. support DOL3 10bit 20fps 1485Mbps
2525 * 2. fixed linkfreq error
26
+ * V0.0X01.0X07
27
+ * 1. fix set_fmt & ioctl get mode unmatched issue.
28
+ * 2. need to set default vblank when change format.
29
+ * 3. enum all supported mode mbus_code, not just cur_mode.
30
+ * V0.0X01.0X08
31
+ * 1. add dcphy param for hdrx2 mode.
2632 */
2733
2834 #define DEBUG
....@@ -44,25 +50,30 @@
4450 #include <media/v4l2-subdev.h>
4551 #include <linux/pinctrl/consumer.h>
4652 #include <linux/rk-preisp.h>
53
+#include <media/v4l2-fwnode.h>
54
+#include <linux/of_graph.h>
4755 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
4856
49
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x06)
57
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x08)
5058
5159 #ifndef V4L2_CID_DIGITAL_GAIN
5260 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
5361 #endif
5462
63
+#define MIPI_FREQ_1188M 1188000000
5564 #define MIPI_FREQ_891M 891000000
5665 #define MIPI_FREQ_446M 446000000
5766 #define MIPI_FREQ_743M 743000000
5867 #define MIPI_FREQ_297M 297000000
5968
6069 #define IMX415_4LANES 4
70
+#define IMX415_2LANES 2
6171
6272 #define IMX415_MAX_PIXEL_RATE (MIPI_FREQ_891M / 10 * 2 * IMX415_4LANES)
6373 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
6474
6575 #define IMX415_XVCLK_FREQ_37M 37125000
76
+#define IMX415_XVCLK_FREQ_27M 27000000
6677
6778 /* TODO: Get the real chip id from reg */
6879 #define CHIP_ID 0xE0
....@@ -136,6 +147,7 @@
136147 #define IMX415_FLIP_REG 0x3030
137148
138149 #define REG_NULL 0xFFFF
150
+#define REG_DELAY 0xFFFE
139151
140152 #define IMX415_REG_VALUE_08BIT 1
141153 #define IMX415_REG_VALUE_16BIT 2
....@@ -158,6 +170,7 @@
158170
159171 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
160172 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
173
+#define RKMODULE_CAMERA_FASTBOOT_ENABLE "rockchip,camera_fastboot"
161174
162175 #define IMX415_NAME "imx415"
163176
....@@ -168,14 +181,6 @@
168181 };
169182
170183 #define IMX415_NUM_SUPPLIES ARRAY_SIZE(imx415_supply_names)
171
-
172
-enum imx415_max_pad {
173
- PAD0, /* link to isp */
174
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
175
- PAD2, /* link to csi wr1 | hdr x3:L */
176
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
177
- PAD_MAX,
178
-};
179184
180185 struct regval {
181186 u16 addr;
....@@ -196,6 +201,7 @@
196201 const struct regval *reg_list;
197202 u32 hdr_mode;
198203 u32 vc[PAD_MAX];
204
+ u32 xvclk;
199205 };
200206
201207 struct imx415 {
....@@ -222,9 +228,10 @@
222228 struct mutex mutex;
223229 bool streaming;
224230 bool power_on;
225
- bool is_thunderboot;
231
+ u32 is_thunderboot;
226232 bool is_thunderboot_ng;
227233 bool is_first_streamoff;
234
+ const struct imx415_mode *supported_modes;
228235 const struct imx415_mode *cur_mode;
229236 u32 module_index;
230237 u32 cfg_num;
....@@ -234,6 +241,18 @@
234241 u32 cur_vts;
235242 bool has_init_exp;
236243 struct preisp_hdrae_exp_s init_hdrae_exp;
244
+ struct v4l2_fwnode_endpoint bus_cfg;
245
+};
246
+
247
+static struct rkmodule_csi_dphy_param dcphy_param = {
248
+ .vendor = PHY_VENDOR_SAMSUNG,
249
+ .lp_vol_ref = 6,
250
+ .lp_hys_sw = {3, 0, 0, 0},
251
+ .lp_escclk_pol_sel = {1, 1, 1, 1},
252
+ .skew_data_cal_clk = {0, 3, 3, 3},
253
+ .clk_hs_term_sel = 2,
254
+ .data_hs_term_sel = {2, 2, 2, 2},
255
+ .reserved = {0},
237256 };
238257
239258 #define to_imx415(sd) container_of(sd, struct imx415, subdev)
....@@ -737,6 +756,311 @@
737756 };
738757
739758 /*
759
+ * Xclk 27Mhz
760
+ * 15fps
761
+ * CSI-2_2lane
762
+ * AD:12bit Output:12bit
763
+ * 891Mbps
764
+ * Master Mode
765
+ * Time 9.988ms Gain:6dB
766
+ * All-pixel
767
+ */
768
+static __maybe_unused const struct regval imx415_linear_12bit_3864x2192_891M_regs_2lane[] = {
769
+ {0x3008, 0x5D},
770
+ {0x300A, 0x42},
771
+ {0x3028, 0x98},
772
+ {0x3029, 0x08},
773
+ {0x3033, 0x05},
774
+ {0x3050, 0x79},
775
+ {0x3051, 0x07},
776
+ {0x3090, 0x14},
777
+ {0x30C1, 0x00},
778
+ {0x3116, 0x23},
779
+ {0x3118, 0xC6},
780
+ {0x311A, 0xE7},
781
+ {0x311E, 0x23},
782
+ {0x32D4, 0x21},
783
+ {0x32EC, 0xA1},
784
+ {0x344C, 0x2B},
785
+ {0x344D, 0x01},
786
+ {0x344E, 0xED},
787
+ {0x344F, 0x01},
788
+ {0x3450, 0xF6},
789
+ {0x3451, 0x02},
790
+ {0x3452, 0x7F},
791
+ {0x3453, 0x03},
792
+ {0x358A, 0x04},
793
+ {0x35A1, 0x02},
794
+ {0x35EC, 0x27},
795
+ {0x35EE, 0x8D},
796
+ {0x35F0, 0x8D},
797
+ {0x35F2, 0x29},
798
+ {0x36BC, 0x0C},
799
+ {0x36CC, 0x53},
800
+ {0x36CD, 0x00},
801
+ {0x36CE, 0x3C},
802
+ {0x36D0, 0x8C},
803
+ {0x36D1, 0x00},
804
+ {0x36D2, 0x71},
805
+ {0x36D4, 0x3C},
806
+ {0x36D6, 0x53},
807
+ {0x36D7, 0x00},
808
+ {0x36D8, 0x71},
809
+ {0x36DA, 0x8C},
810
+ {0x36DB, 0x00},
811
+ {0x3720, 0x00},
812
+ {0x3724, 0x02},
813
+ {0x3726, 0x02},
814
+ {0x3732, 0x02},
815
+ {0x3734, 0x03},
816
+ {0x3736, 0x03},
817
+ {0x3742, 0x03},
818
+ {0x3862, 0xE0},
819
+ {0x38CC, 0x30},
820
+ {0x38CD, 0x2F},
821
+ {0x395C, 0x0C},
822
+ {0x39A4, 0x07},
823
+ {0x39A8, 0x32},
824
+ {0x39AA, 0x32},
825
+ {0x39AC, 0x32},
826
+ {0x39AE, 0x32},
827
+ {0x39B0, 0x32},
828
+ {0x39B2, 0x2F},
829
+ {0x39B4, 0x2D},
830
+ {0x39B6, 0x28},
831
+ {0x39B8, 0x30},
832
+ {0x39BA, 0x30},
833
+ {0x39BC, 0x30},
834
+ {0x39BE, 0x30},
835
+ {0x39C0, 0x30},
836
+ {0x39C2, 0x2E},
837
+ {0x39C4, 0x2B},
838
+ {0x39C6, 0x25},
839
+ {0x3A42, 0xD1},
840
+ {0x3A4C, 0x77},
841
+ {0x3AE0, 0x02},
842
+ {0x3AEC, 0x0C},
843
+ {0x3B00, 0x2E},
844
+ {0x3B06, 0x29},
845
+ {0x3B98, 0x25},
846
+ {0x3B99, 0x21},
847
+ {0x3B9B, 0x13},
848
+ {0x3B9C, 0x13},
849
+ {0x3B9D, 0x13},
850
+ {0x3B9E, 0x13},
851
+ {0x3BA1, 0x00},
852
+ {0x3BA2, 0x06},
853
+ {0x3BA3, 0x0B},
854
+ {0x3BA4, 0x10},
855
+ {0x3BA5, 0x14},
856
+ {0x3BA6, 0x18},
857
+ {0x3BA7, 0x1A},
858
+ {0x3BA8, 0x1A},
859
+ {0x3BA9, 0x1A},
860
+ {0x3BAC, 0xED},
861
+ {0x3BAD, 0x01},
862
+ {0x3BAE, 0xF6},
863
+ {0x3BAF, 0x02},
864
+ {0x3BB0, 0xA2},
865
+ {0x3BB1, 0x03},
866
+ {0x3BB2, 0xE0},
867
+ {0x3BB3, 0x03},
868
+ {0x3BB4, 0xE0},
869
+ {0x3BB5, 0x03},
870
+ {0x3BB6, 0xE0},
871
+ {0x3BB7, 0x03},
872
+ {0x3BB8, 0xE0},
873
+ {0x3BBA, 0xE0},
874
+ {0x3BBC, 0xDA},
875
+ {0x3BBE, 0x88},
876
+ {0x3BC0, 0x44},
877
+ {0x3BC2, 0x7B},
878
+ {0x3BC4, 0xA2},
879
+ {0x3BC8, 0xBD},
880
+ {0x3BCA, 0xBD},
881
+ {0x4001, 0x01},
882
+ {0x4004, 0xC0},
883
+ {0x4005, 0x06},
884
+ {0x400C, 0x00},
885
+ {0x4018, 0x7F},
886
+ {0x401A, 0x37},
887
+ {0x401C, 0x37},
888
+ {0x401E, 0xF7},
889
+ {0x401F, 0x00},
890
+ {0x4020, 0x3F},
891
+ {0x4022, 0x6F},
892
+ {0x4024, 0x3F},
893
+ {0x4026, 0x5F},
894
+ {0x4028, 0x2F},
895
+ {0x4074, 0x01},
896
+ {0x3002, 0x00},
897
+ //{0x3000, 0x00},
898
+ {REG_DELAY, 0x1E},//wait_ms(30)
899
+ {REG_NULL, 0x00},
900
+};
901
+
902
+/*
903
+ * Xclk 27Mhz
904
+ * 90.059fps
905
+ * CSI-2_2lane
906
+ * AD:10bit Output:12bit
907
+ * 2376Mbps
908
+ * Master Mode
909
+ * Time 9.999ms Gain:6dB
910
+ * 2568x1440 2/2-line binning & Window cropping
911
+ */
912
+static __maybe_unused const struct regval imx415_linear_12bit_1284x720_2376M_regs_2lane[] = {
913
+ {0x3008, 0x5D},
914
+ {0x300A, 0x42},
915
+ {0x301C, 0x04},
916
+ {0x3020, 0x01},
917
+ {0x3021, 0x01},
918
+ {0x3022, 0x01},
919
+ {0x3024, 0xAB},
920
+ {0x3025, 0x07},
921
+ {0x3028, 0xA4},
922
+ {0x3029, 0x01},
923
+ {0x3031, 0x00},
924
+ {0x3033, 0x00},
925
+ {0x3040, 0x88},
926
+ {0x3041, 0x02},
927
+ {0x3042, 0x08},
928
+ {0x3043, 0x0A},
929
+ {0x3044, 0xF0},
930
+ {0x3045, 0x02},
931
+ {0x3046, 0x40},
932
+ {0x3047, 0x0B},
933
+ {0x3050, 0xC4},
934
+ {0x3090, 0x14},
935
+ {0x30C1, 0x00},
936
+ {0x30D9, 0x02},
937
+ {0x30DA, 0x01},
938
+ {0x3116, 0x23},
939
+ {0x3118, 0x08},
940
+ {0x3119, 0x01},
941
+ {0x311A, 0xE7},
942
+ {0x311E, 0x23},
943
+ {0x32D4, 0x21},
944
+ {0x32EC, 0xA1},
945
+ {0x344C, 0x2B},
946
+ {0x344D, 0x01},
947
+ {0x344E, 0xED},
948
+ {0x344F, 0x01},
949
+ {0x3450, 0xF6},
950
+ {0x3451, 0x02},
951
+ {0x3452, 0x7F},
952
+ {0x3453, 0x03},
953
+ {0x358A, 0x04},
954
+ {0x35A1, 0x02},
955
+ {0x35EC, 0x27},
956
+ {0x35EE, 0x8D},
957
+ {0x35F0, 0x8D},
958
+ {0x35F2, 0x29},
959
+ {0x36BC, 0x0C},
960
+ {0x36CC, 0x53},
961
+ {0x36CD, 0x00},
962
+ {0x36CE, 0x3C},
963
+ {0x36D0, 0x8C},
964
+ {0x36D1, 0x00},
965
+ {0x36D2, 0x71},
966
+ {0x36D4, 0x3C},
967
+ {0x36D6, 0x53},
968
+ {0x36D7, 0x00},
969
+ {0x36D8, 0x71},
970
+ {0x36DA, 0x8C},
971
+ {0x36DB, 0x00},
972
+ {0x3701, 0x00},
973
+ {0x3720, 0x00},
974
+ {0x3724, 0x02},
975
+ {0x3726, 0x02},
976
+ {0x3732, 0x02},
977
+ {0x3734, 0x03},
978
+ {0x3736, 0x03},
979
+ {0x3742, 0x03},
980
+ {0x3862, 0xE0},
981
+ {0x38CC, 0x30},
982
+ {0x38CD, 0x2F},
983
+ {0x395C, 0x0C},
984
+ {0x39A4, 0x07},
985
+ {0x39A8, 0x32},
986
+ {0x39AA, 0x32},
987
+ {0x39AC, 0x32},
988
+ {0x39AE, 0x32},
989
+ {0x39B0, 0x32},
990
+ {0x39B2, 0x2F},
991
+ {0x39B4, 0x2D},
992
+ {0x39B6, 0x28},
993
+ {0x39B8, 0x30},
994
+ {0x39BA, 0x30},
995
+ {0x39BC, 0x30},
996
+ {0x39BE, 0x30},
997
+ {0x39C0, 0x30},
998
+ {0x39C2, 0x2E},
999
+ {0x39C4, 0x2B},
1000
+ {0x39C6, 0x25},
1001
+ {0x3A42, 0xD1},
1002
+ {0x3A4C, 0x77},
1003
+ {0x3AE0, 0x02},
1004
+ {0x3AEC, 0x0C},
1005
+ {0x3B00, 0x2E},
1006
+ {0x3B06, 0x29},
1007
+ {0x3B98, 0x25},
1008
+ {0x3B99, 0x21},
1009
+ {0x3B9B, 0x13},
1010
+ {0x3B9C, 0x13},
1011
+ {0x3B9D, 0x13},
1012
+ {0x3B9E, 0x13},
1013
+ {0x3BA1, 0x00},
1014
+ {0x3BA2, 0x06},
1015
+ {0x3BA3, 0x0B},
1016
+ {0x3BA4, 0x10},
1017
+ {0x3BA5, 0x14},
1018
+ {0x3BA6, 0x18},
1019
+ {0x3BA7, 0x1A},
1020
+ {0x3BA8, 0x1A},
1021
+ {0x3BA9, 0x1A},
1022
+ {0x3BAC, 0xED},
1023
+ {0x3BAD, 0x01},
1024
+ {0x3BAE, 0xF6},
1025
+ {0x3BAF, 0x02},
1026
+ {0x3BB0, 0xA2},
1027
+ {0x3BB1, 0x03},
1028
+ {0x3BB2, 0xE0},
1029
+ {0x3BB3, 0x03},
1030
+ {0x3BB4, 0xE0},
1031
+ {0x3BB5, 0x03},
1032
+ {0x3BB6, 0xE0},
1033
+ {0x3BB7, 0x03},
1034
+ {0x3BB8, 0xE0},
1035
+ {0x3BBA, 0xE0},
1036
+ {0x3BBC, 0xDA},
1037
+ {0x3BBE, 0x88},
1038
+ {0x3BC0, 0x44},
1039
+ {0x3BC2, 0x7B},
1040
+ {0x3BC4, 0xA2},
1041
+ {0x3BC8, 0xBD},
1042
+ {0x3BCA, 0xBD},
1043
+ {0x4001, 0x01},
1044
+ {0x4004, 0xC0},
1045
+ {0x4005, 0x06},
1046
+ {0x4018, 0xE7},
1047
+ {0x401A, 0x8F},
1048
+ {0x401C, 0x8F},
1049
+ {0x401E, 0x7F},
1050
+ {0x401F, 0x02},
1051
+ {0x4020, 0x97},
1052
+ {0x4022, 0x0F},
1053
+ {0x4023, 0x01},
1054
+ {0x4024, 0x97},
1055
+ {0x4026, 0xF7},
1056
+ {0x4028, 0x7F},
1057
+ {0x3002, 0x00},
1058
+ //{0x3000, 0x00},
1059
+ {REG_DELAY, 0x1E},//wait_ms(30)
1060
+ {REG_NULL, 0x00},
1061
+};
1062
+
1063
+/*
7401064 * The width and height must be configured to be
7411065 * the same as the current output resolution of the sensor.
7421066 * The input width of the isp needs to be 16 aligned.
....@@ -769,6 +1093,8 @@
7691093 .hdr_mode = NO_HDR,
7701094 .mipi_freq_idx = 1,
7711095 .bpp = 10,
1096
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1097
+ .xvclk = IMX415_XVCLK_FREQ_37M,
7721098 },
7731099 {
7741100 .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
....@@ -794,6 +1120,7 @@
7941120 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
7951121 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
7961122 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
1123
+ .xvclk = IMX415_XVCLK_FREQ_37M,
7971124 },
7981125 {
7991126 .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
....@@ -819,6 +1146,7 @@
8191146 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
8201147 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
8211148 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
1149
+ .xvclk = IMX415_XVCLK_FREQ_37M,
8221150 },
8231151 {
8241152 .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
....@@ -844,6 +1172,7 @@
8441172 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
8451173 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
8461174 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
1175
+ .xvclk = IMX415_XVCLK_FREQ_37M,
8471176 },
8481177 {
8491178 /* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */
....@@ -862,6 +1191,8 @@
8621191 .hdr_mode = NO_HDR,
8631192 .mipi_freq_idx = 1,
8641193 .bpp = 12,
1194
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1195
+ .xvclk = IMX415_XVCLK_FREQ_37M,
8651196 },
8661197 {
8671198 .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
....@@ -887,6 +1218,7 @@
8871218 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
8881219 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
8891220 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
1221
+ .xvclk = IMX415_XVCLK_FREQ_37M,
8901222 },
8911223 {
8921224 .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
....@@ -912,6 +1244,7 @@
9121244 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
9131245 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
9141246 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
1247
+ .xvclk = IMX415_XVCLK_FREQ_37M,
9151248 },
9161249 {
9171250 .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
....@@ -929,6 +1262,8 @@
9291262 .hdr_mode = NO_HDR,
9301263 .mipi_freq_idx = 0,
9311264 .bpp = 12,
1265
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1266
+ .xvclk = IMX415_XVCLK_FREQ_37M,
9321267 },
9331268 {
9341269 .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
....@@ -954,6 +1289,50 @@
9541289 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
9551290 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
9561291 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
1292
+ .xvclk = IMX415_XVCLK_FREQ_37M,
1293
+ },
1294
+};
1295
+
1296
+static const struct imx415_mode supported_modes_2lane[] = {
1297
+ {
1298
+ /* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */
1299
+ .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
1300
+ .width = 3864,
1301
+ .height = 2192,
1302
+ .max_fps = {
1303
+ .numerator = 10000,
1304
+ .denominator = 150000,
1305
+ },
1306
+ .exp_def = 0x08ca - 0x08,
1307
+ .hts_def = 0x0898 * IMX415_2LANES * 2,
1308
+ .vts_def = 0x08ca,
1309
+ .global_reg_list = NULL,
1310
+ .reg_list = imx415_linear_12bit_3864x2192_891M_regs_2lane,
1311
+ .hdr_mode = NO_HDR,
1312
+ .mipi_freq_idx = 1,
1313
+ .bpp = 12,
1314
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1315
+ .xvclk = IMX415_XVCLK_FREQ_27M,
1316
+ },
1317
+ {
1318
+ /* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */
1319
+ .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
1320
+ .width = 1284,
1321
+ .height = 720,
1322
+ .max_fps = {
1323
+ .numerator = 10000,
1324
+ .denominator = 900000,
1325
+ },
1326
+ .exp_def = 0x07AB-8,
1327
+ .hts_def = 0x01A4 * IMX415_2LANES * 2,
1328
+ .vts_def = 0x07AB,
1329
+ .global_reg_list = NULL,
1330
+ .reg_list = imx415_linear_12bit_1284x720_2376M_regs_2lane,
1331
+ .hdr_mode = NO_HDR,
1332
+ .mipi_freq_idx = 4,
1333
+ .bpp = 12,
1334
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1335
+ .xvclk = IMX415_XVCLK_FREQ_27M,
9571336 },
9581337 };
9591338
....@@ -962,6 +1341,7 @@
9621341 MIPI_FREQ_446M,
9631342 MIPI_FREQ_743M,
9641343 MIPI_FREQ_891M,
1344
+ MIPI_FREQ_1188M,
9651345 };
9661346
9671347 /* Write registers up to 4 at a time */
....@@ -998,10 +1378,18 @@
9981378 {
9991379 u32 i;
10001380 int ret = 0;
1001
-
1381
+ if (!regs) {
1382
+ dev_err(&client->dev, "write reg array error\n");
1383
+ return ret;
1384
+ }
10021385 for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
1003
- ret = imx415_write_reg(client, regs[i].addr,
1004
- IMX415_REG_VALUE_08BIT, regs[i].val);
1386
+ if (regs[i].addr == REG_DELAY) {
1387
+ usleep_range(regs[i].val * 1000, regs[i].val * 1000 + 500);
1388
+ dev_info(&client->dev, "write reg array, sleep %dms\n", regs[i].val);
1389
+ } else {
1390
+ ret = imx415_write_reg(client, regs[i].addr,
1391
+ IMX415_REG_VALUE_08BIT, regs[i].val);
1392
+ }
10051393 }
10061394 return ret;
10071395 }
....@@ -1058,15 +1446,17 @@
10581446 unsigned int i;
10591447
10601448 for (i = 0; i < imx415->cfg_num; i++) {
1061
- dist = imx415_get_reso_dist(&supported_modes[i], framefmt);
1062
- if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
1063
- supported_modes[i].bus_fmt == framefmt->code) {
1449
+ dist = imx415_get_reso_dist(&imx415->supported_modes[i], framefmt);
1450
+ if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
1451
+ imx415->supported_modes[i].bus_fmt == framefmt->code) {
10641452 cur_best_fit_dist = dist;
10651453 cur_best_fit = i;
10661454 }
10671455 }
1456
+ dev_info(&imx415->client->dev, "%s: cur_best_fit(%d)",
1457
+ __func__, cur_best_fit);
10681458
1069
- return &supported_modes[cur_best_fit];
1459
+ return &imx415->supported_modes[cur_best_fit];
10701460 }
10711461
10721462 static int __imx415_power_on(struct imx415 *imx415);
....@@ -1080,8 +1470,8 @@
10801470 }
10811471 imx415->cur_mode = mode;
10821472 imx415->cur_vts = imx415->cur_mode->vts_def;
1083
- dev_dbg(&imx415->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n",
1084
- mode->width, mode->height, mode->hdr_mode);
1473
+ dev_info(&imx415->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d, bpp: %d\n",
1474
+ mode->width, mode->height, mode->hdr_mode, mode->bpp);
10851475 }
10861476
10871477 static int imx415_set_fmt(struct v4l2_subdev *sd,
....@@ -1092,6 +1482,7 @@
10921482 const struct imx415_mode *mode;
10931483 s64 h_blank, vblank_def, vblank_min;
10941484 u64 pixel_rate = 0;
1485
+ u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
10951486
10961487 mutex_lock(&imx415->mutex);
10971488
....@@ -1118,11 +1509,15 @@
11181509 __v4l2_ctrl_modify_range(imx415->vblank, vblank_min,
11191510 IMX415_VTS_MAX - mode->height,
11201511 1, vblank_def);
1512
+ __v4l2_ctrl_s_ctrl(imx415->vblank, vblank_def);
11211513 __v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
1122
- pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
1514
+ pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
1515
+ mode->bpp * 2 * lanes;
11231516 __v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
11241517 pixel_rate);
11251518 }
1519
+ dev_info(&imx415->client->dev, "%s: mode->mipi_freq_idx(%d)",
1520
+ __func__, mode->mipi_freq_idx);
11261521
11271522 mutex_unlock(&imx415->mutex);
11281523
....@@ -1165,9 +1560,10 @@
11651560 {
11661561 struct imx415 *imx415 = to_imx415(sd);
11671562
1168
- if (code->index != 0)
1563
+ if (code->index >= imx415->cfg_num)
11691564 return -EINVAL;
1170
- code->code = imx415->cur_mode->bus_fmt;
1565
+
1566
+ code->code = imx415->supported_modes[code->index].bus_fmt;
11711567
11721568 return 0;
11731569 }
....@@ -1181,13 +1577,13 @@
11811577 if (fse->index >= imx415->cfg_num)
11821578 return -EINVAL;
11831579
1184
- if (fse->code != supported_modes[fse->index].bus_fmt)
1580
+ if (fse->code != imx415->supported_modes[fse->index].bus_fmt)
11851581 return -EINVAL;
11861582
1187
- fse->min_width = supported_modes[fse->index].width;
1188
- fse->max_width = supported_modes[fse->index].width;
1189
- fse->max_height = supported_modes[fse->index].height;
1190
- fse->min_height = supported_modes[fse->index].height;
1583
+ fse->min_width = imx415->supported_modes[fse->index].width;
1584
+ fse->max_width = imx415->supported_modes[fse->index].width;
1585
+ fse->max_height = imx415->supported_modes[fse->index].height;
1586
+ fse->min_height = imx415->supported_modes[fse->index].height;
11911587
11921588 return 0;
11931589 }
....@@ -1198,28 +1594,27 @@
11981594 struct imx415 *imx415 = to_imx415(sd);
11991595 const struct imx415_mode *mode = imx415->cur_mode;
12001596
1201
- mutex_lock(&imx415->mutex);
12021597 fi->interval = mode->max_fps;
1203
- mutex_unlock(&imx415->mutex);
12041598
12051599 return 0;
12061600 }
12071601
1208
-static int imx415_g_mbus_config(struct v4l2_subdev *sd,
1602
+static int imx415_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
12091603 struct v4l2_mbus_config *config)
12101604 {
12111605 struct imx415 *imx415 = to_imx415(sd);
12121606 const struct imx415_mode *mode = imx415->cur_mode;
12131607 u32 val = 0;
1608
+ u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
12141609
1215
- val = 1 << (IMX415_4LANES - 1) |
1610
+ val = 1 << (lanes - 1) |
12161611 V4L2_MBUS_CSI2_CHANNEL_0 |
12171612 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
12181613 if (mode->hdr_mode != NO_HDR)
12191614 val |= V4L2_MBUS_CSI2_CHANNEL_1;
12201615 if (mode->hdr_mode == HDR_X3)
12211616 val |= V4L2_MBUS_CSI2_CHANNEL_2;
1222
- config->type = V4L2_MBUS_CSI2;
1617
+ config->type = V4L2_MBUS_CSI2_DPHY;
12231618 config->flags = val;
12241619
12251620 return 0;
....@@ -1650,14 +2045,28 @@
16502045 return ret;
16512046 }
16522047
2048
+static int imx415_get_channel_info(struct imx415 *imx415, struct rkmodule_channel_info *ch_info)
2049
+{
2050
+ if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
2051
+ return -EINVAL;
2052
+ ch_info->vc = imx415->cur_mode->vc[ch_info->index];
2053
+ ch_info->width = imx415->cur_mode->width;
2054
+ ch_info->height = imx415->cur_mode->height;
2055
+ ch_info->bus_fmt = imx415->cur_mode->bus_fmt;
2056
+ return 0;
2057
+}
2058
+
16532059 static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
16542060 {
16552061 struct imx415 *imx415 = to_imx415(sd);
16562062 struct rkmodule_hdr_cfg *hdr;
2063
+ struct rkmodule_channel_info *ch_info;
16572064 u32 i, h, w, stream;
16582065 long ret = 0;
16592066 const struct imx415_mode *mode;
16602067 u64 pixel_rate = 0;
2068
+ struct rkmodule_csi_dphy_param *dphy_param;
2069
+ u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
16612070
16622071 switch (cmd) {
16632072 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -1679,10 +2088,11 @@
16792088 w = imx415->cur_mode->width;
16802089 h = imx415->cur_mode->height;
16812090 for (i = 0; i < imx415->cfg_num; i++) {
1682
- if (w == supported_modes[i].width &&
1683
- h == supported_modes[i].height &&
1684
- supported_modes[i].hdr_mode == hdr->hdr_mode) {
1685
- imx415_change_mode(imx415, &supported_modes[i]);
2091
+ if (w == imx415->supported_modes[i].width &&
2092
+ h == imx415->supported_modes[i].height &&
2093
+ imx415->supported_modes[i].hdr_mode == hdr->hdr_mode) {
2094
+ dev_info(&imx415->client->dev, "set hdr cfg, set mode to %d\n", i);
2095
+ imx415_change_mode(imx415, &imx415->supported_modes[i]);
16862096 break;
16872097 }
16882098 }
....@@ -1706,14 +2116,17 @@
17062116 }
17072117 w = mode->hts_def - imx415->cur_mode->width;
17082118 h = mode->vts_def - mode->height;
2119
+ mutex_lock(&imx415->mutex);
17092120 __v4l2_ctrl_modify_range(imx415->hblank, w, w, 1, w);
17102121 __v4l2_ctrl_modify_range(imx415->vblank, h,
17112122 IMX415_VTS_MAX - mode->height,
17122123 1, h);
17132124 __v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
1714
- pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
2125
+ pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
2126
+ mode->bpp * 2 * lanes;
17152127 __v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
17162128 pixel_rate);
2129
+ mutex_unlock(&imx415->mutex);
17172130 }
17182131 break;
17192132 case RKMODULE_SET_QUICK_STREAM:
....@@ -1733,6 +2146,19 @@
17332146 else
17342147 *((u32 *)arg) = BRL_BINNING;
17352148 break;
2149
+ case RKMODULE_GET_CHANNEL_INFO:
2150
+ ch_info = (struct rkmodule_channel_info *)arg;
2151
+ ret = imx415_get_channel_info(imx415, ch_info);
2152
+ break;
2153
+ case RKMODULE_GET_CSI_DPHY_PARAM:
2154
+ if (imx415->cur_mode->hdr_mode == HDR_X2) {
2155
+ dphy_param = (struct rkmodule_csi_dphy_param *)arg;
2156
+ *dphy_param = dcphy_param;
2157
+ dev_info(&imx415->client->dev,
2158
+ "get sensor dphy param\n");
2159
+ } else
2160
+ ret = -EINVAL;
2161
+ break;
17362162 default:
17372163 ret = -ENOIOCTLCMD;
17382164 break;
....@@ -1750,9 +2176,11 @@
17502176 struct rkmodule_awb_cfg *cfg;
17512177 struct rkmodule_hdr_cfg *hdr;
17522178 struct preisp_hdrae_exp_s *hdrae;
2179
+ struct rkmodule_channel_info *ch_info;
17532180 long ret;
17542181 u32 stream;
17552182 u32 brl = 0;
2183
+ struct rkmodule_csi_dphy_param *dphy_param;
17562184
17572185 switch (cmd) {
17582186 case RKMODULE_GET_MODULE_INFO:
....@@ -1841,6 +2269,37 @@
18412269 return -EFAULT;
18422270 }
18432271 break;
2272
+ case RKMODULE_GET_CHANNEL_INFO:
2273
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2274
+ if (!ch_info) {
2275
+ ret = -ENOMEM;
2276
+ return ret;
2277
+ }
2278
+
2279
+ ret = imx415_ioctl(sd, cmd, ch_info);
2280
+ if (!ret) {
2281
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
2282
+ if (ret)
2283
+ ret = -EFAULT;
2284
+ }
2285
+ kfree(ch_info);
2286
+ break;
2287
+ case RKMODULE_GET_CSI_DPHY_PARAM:
2288
+ dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
2289
+ if (!dphy_param) {
2290
+ ret = -ENOMEM;
2291
+ return ret;
2292
+ }
2293
+
2294
+ ret = imx415_ioctl(sd, cmd, dphy_param);
2295
+ if (!ret) {
2296
+ ret = copy_to_user(up, dphy_param, sizeof(*dphy_param));
2297
+ if (ret)
2298
+ ret = -EFAULT;
2299
+ }
2300
+ kfree(dphy_param);
2301
+ break;
2302
+
18442303 default:
18452304 ret = -ENOIOCTLCMD;
18462305 break;
....@@ -1896,7 +2355,7 @@
18962355 struct i2c_client *client = imx415->client;
18972356 int ret = 0;
18982357
1899
- dev_dbg(&imx415->client->dev, "s_stream: %d. %dx%d, hdr: %d, bpp: %d\n",
2358
+ dev_info(&imx415->client->dev, "s_stream: %d. %dx%d, hdr: %d, bpp: %d\n",
19002359 on, imx415->cur_mode->width, imx415->cur_mode->height,
19012360 imx415->cur_mode->hdr_mode, imx415->cur_mode->bpp);
19022361
....@@ -1968,10 +2427,6 @@
19682427 {
19692428 int ret;
19702429 struct device *dev = &imx415->client->dev;
1971
-
1972
- if (imx415->is_thunderboot)
1973
- return 0;
1974
-
19752430 if (!IS_ERR_OR_NULL(imx415->pins_default)) {
19762431 ret = pinctrl_select_state(imx415->pinctrl,
19772432 imx415->pins_default);
....@@ -1979,26 +2434,28 @@
19792434 dev_err(dev, "could not set pins\n");
19802435 }
19812436
1982
- ret = regulator_bulk_enable(IMX415_NUM_SUPPLIES, imx415->supplies);
1983
- if (ret < 0) {
1984
- dev_err(dev, "Failed to enable regulators\n");
1985
- goto err_pinctrl;
1986
- }
1987
- if (!IS_ERR(imx415->power_gpio))
1988
- gpiod_direction_output(imx415->power_gpio, 1);
1989
- /* At least 500ns between power raising and XCLR */
1990
- /* fix power on timing if insmod this ko */
1991
- usleep_range(10 * 1000, 20 * 1000);
1992
- if (!IS_ERR(imx415->reset_gpio))
1993
- gpiod_direction_output(imx415->reset_gpio, 0);
2437
+ if (!imx415->is_thunderboot) {
2438
+ ret = regulator_bulk_enable(IMX415_NUM_SUPPLIES, imx415->supplies);
2439
+ if (ret < 0) {
2440
+ dev_err(dev, "Failed to enable regulators\n");
2441
+ goto err_pinctrl;
2442
+ }
2443
+ if (!IS_ERR(imx415->power_gpio))
2444
+ gpiod_direction_output(imx415->power_gpio, 1);
2445
+ /* At least 500ns between power raising and XCLR */
2446
+ /* fix power on timing if insmod this ko */
2447
+ usleep_range(10 * 1000, 20 * 1000);
2448
+ if (!IS_ERR(imx415->reset_gpio))
2449
+ gpiod_direction_output(imx415->reset_gpio, 0);
19942450
1995
- /* At least 1us between XCLR and clk */
1996
- /* fix power on timing if insmod this ko */
1997
- usleep_range(10 * 1000, 20 * 1000);
1998
- ret = clk_set_rate(imx415->xvclk, IMX415_XVCLK_FREQ_37M);
2451
+ /* At least 1us between XCLR and clk */
2452
+ /* fix power on timing if insmod this ko */
2453
+ usleep_range(10 * 1000, 20 * 1000);
2454
+ }
2455
+ ret = clk_set_rate(imx415->xvclk, imx415->cur_mode->xvclk);
19992456 if (ret < 0)
20002457 dev_warn(dev, "Failed to set xvclk rate\n");
2001
- if (clk_get_rate(imx415->xvclk) != IMX415_XVCLK_FREQ_37M)
2458
+ if (clk_get_rate(imx415->xvclk) != imx415->cur_mode->xvclk)
20022459 dev_warn(dev, "xvclk mismatched\n");
20032460 ret = clk_prepare_enable(imx415->xvclk);
20042461 if (ret < 0) {
....@@ -2007,7 +2464,8 @@
20072464 }
20082465
20092466 /* At least 20us between XCLR and I2C communication */
2010
- usleep_range(20*1000, 30*1000);
2467
+ if (!imx415->is_thunderboot)
2468
+ usleep_range(20*1000, 30*1000);
20112469
20122470 return 0;
20132471
....@@ -2051,7 +2509,7 @@
20512509 regulator_bulk_disable(IMX415_NUM_SUPPLIES, imx415->supplies);
20522510 }
20532511
2054
-static int imx415_runtime_resume(struct device *dev)
2512
+static int __maybe_unused imx415_runtime_resume(struct device *dev)
20552513 {
20562514 struct i2c_client *client = to_i2c_client(dev);
20572515 struct v4l2_subdev *sd = i2c_get_clientdata(client);
....@@ -2060,7 +2518,7 @@
20602518 return __imx415_power_on(imx415);
20612519 }
20622520
2063
-static int imx415_runtime_suspend(struct device *dev)
2521
+static int __maybe_unused imx415_runtime_suspend(struct device *dev)
20642522 {
20652523 struct i2c_client *client = to_i2c_client(dev);
20662524 struct v4l2_subdev *sd = i2c_get_clientdata(client);
....@@ -2077,7 +2535,7 @@
20772535 struct imx415 *imx415 = to_imx415(sd);
20782536 struct v4l2_mbus_framefmt *try_fmt =
20792537 v4l2_subdev_get_try_format(sd, fh->pad, 0);
2080
- const struct imx415_mode *def_mode = &supported_modes[0];
2538
+ const struct imx415_mode *def_mode = &imx415->supported_modes[0];
20812539
20822540 mutex_lock(&imx415->mutex);
20832541 /* Initialize try_fmt */
....@@ -2102,11 +2560,11 @@
21022560 if (fie->index >= imx415->cfg_num)
21032561 return -EINVAL;
21042562
2105
- fie->code = supported_modes[fie->index].bus_fmt;
2106
- fie->width = supported_modes[fie->index].width;
2107
- fie->height = supported_modes[fie->index].height;
2108
- fie->interval = supported_modes[fie->index].max_fps;
2109
- fie->reserved[0] = supported_modes[fie->index].hdr_mode;
2563
+ fie->code = imx415->supported_modes[fie->index].bus_fmt;
2564
+ fie->width = imx415->supported_modes[fie->index].width;
2565
+ fie->height = imx415->supported_modes[fie->index].height;
2566
+ fie->interval = imx415->supported_modes[fie->index].max_fps;
2567
+ fie->reserved[0] = imx415->supported_modes[fie->index].hdr_mode;
21102568 return 0;
21112569 }
21122570
....@@ -2175,7 +2633,6 @@
21752633 static const struct v4l2_subdev_video_ops imx415_video_ops = {
21762634 .s_stream = imx415_s_stream,
21772635 .g_frame_interval = imx415_g_frame_interval,
2178
- .g_mbus_config = imx415_g_mbus_config,
21792636 };
21802637
21812638 static const struct v4l2_subdev_pad_ops imx415_pad_ops = {
....@@ -2185,6 +2642,7 @@
21852642 .get_fmt = imx415_get_fmt,
21862643 .set_fmt = imx415_set_fmt,
21872644 .get_selection = imx415_get_selection,
2645
+ .get_mbus_config = imx415_g_mbus_config,
21882646 };
21892647
21902648 static const struct v4l2_subdev_ops imx415_subdev_ops = {
....@@ -2223,7 +2681,7 @@
22232681 switch (ctrl->id) {
22242682 case V4L2_CID_EXPOSURE:
22252683 if (imx415->cur_mode->hdr_mode != NO_HDR)
2226
- return ret;
2684
+ goto ctrl_end;
22272685 shr0 = imx415->cur_vts - ctrl->val;
22282686 ret = imx415_write_reg(imx415->client, IMX415_LF_EXPO_REG_L,
22292687 IMX415_REG_VALUE_08BIT,
....@@ -2239,7 +2697,7 @@
22392697 break;
22402698 case V4L2_CID_ANALOGUE_GAIN:
22412699 if (imx415->cur_mode->hdr_mode != NO_HDR)
2242
- return ret;
2700
+ goto ctrl_end;
22432701 ret = imx415_write_reg(imx415->client, IMX415_LF_GAIN_REG_H,
22442702 IMX415_REG_VALUE_08BIT,
22452703 IMX415_FETCH_GAIN_H(ctrl->val));
....@@ -2308,6 +2766,7 @@
23082766 break;
23092767 }
23102768
2769
+ctrl_end:
23112770 pm_runtime_put(&client->dev);
23122771
23132772 return ret;
....@@ -2323,8 +2782,10 @@
23232782 struct v4l2_ctrl_handler *handler;
23242783 s64 exposure_max, vblank_def;
23252784 u64 pixel_rate;
2785
+ u64 max_pixel_rate;
23262786 u32 h_blank;
23272787 int ret;
2788
+ u8 lanes = imx415->bus_cfg.bus.mipi_csi2.num_data_lanes;
23282789
23292790 handler = &imx415->ctrl_handler;
23302791 mode = imx415->cur_mode;
....@@ -2337,12 +2798,13 @@
23372798 V4L2_CID_LINK_FREQ,
23382799 ARRAY_SIZE(link_freq_items) - 1, 0,
23392800 link_freq_items);
2340
- __v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
2801
+ v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
23412802
23422803 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
2343
- pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
2804
+ pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * lanes;
2805
+ max_pixel_rate = MIPI_FREQ_1188M / mode->bpp * 2 * lanes;
23442806 imx415->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
2345
- V4L2_CID_PIXEL_RATE, 0, IMX415_MAX_PIXEL_RATE,
2807
+ V4L2_CID_PIXEL_RATE, 0, max_pixel_rate,
23462808 1, pixel_rate);
23472809
23482810 h_blank = mode->hts_def - mode->width;
....@@ -2433,6 +2895,7 @@
24332895 struct device_node *node = dev->of_node;
24342896 struct imx415 *imx415;
24352897 struct v4l2_subdev *sd;
2898
+ struct device_node *endpoint;
24362899 char facing[2];
24372900 int ret;
24382901 u32 i, hdr_mode = 0;
....@@ -2464,16 +2927,41 @@
24642927 hdr_mode = NO_HDR;
24652928 dev_warn(dev, " Get hdr mode failed! no hdr default\n");
24662929 }
2930
+
2931
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
2932
+ if (!endpoint) {
2933
+ dev_err(dev, "Failed to get endpoint\n");
2934
+ return -EINVAL;
2935
+ }
2936
+
2937
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
2938
+ &imx415->bus_cfg);
2939
+ of_node_put(endpoint);
2940
+ if (ret) {
2941
+ dev_err(dev, "Failed to get bus config\n");
2942
+ return -EINVAL;
2943
+ }
2944
+
24672945 imx415->client = client;
2468
- imx415->cfg_num = ARRAY_SIZE(supported_modes);
2946
+ if (imx415->bus_cfg.bus.mipi_csi2.num_data_lanes == IMX415_4LANES) {
2947
+ imx415->supported_modes = supported_modes;
2948
+ imx415->cfg_num = ARRAY_SIZE(supported_modes);
2949
+ } else {
2950
+ imx415->supported_modes = supported_modes_2lane;
2951
+ imx415->cfg_num = ARRAY_SIZE(supported_modes_2lane);
2952
+ }
2953
+ dev_info(dev, "detect imx415 lane %d\n",
2954
+ imx415->bus_cfg.bus.mipi_csi2.num_data_lanes);
2955
+
24692956 for (i = 0; i < imx415->cfg_num; i++) {
2470
- if (hdr_mode == supported_modes[i].hdr_mode) {
2471
- imx415->cur_mode = &supported_modes[i];
2957
+ if (hdr_mode == imx415->supported_modes[i].hdr_mode) {
2958
+ imx415->cur_mode = &imx415->supported_modes[i];
24722959 break;
24732960 }
24742961 }
24752962
2476
- imx415->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
2963
+ of_property_read_u32(node, RKMODULE_CAMERA_FASTBOOT_ENABLE,
2964
+ &imx415->is_thunderboot);
24772965
24782966 imx415->xvclk = devm_clk_get(dev, "xvclk");
24792967 if (IS_ERR(imx415->xvclk)) {