forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/sc530ai.c
....@@ -8,6 +8,7 @@
88 * V0.0X01.0X01 fix set vflip/hflip failed bug.
99 */
1010
11
+//#define DEBUG
1112 #include <linux/clk.h>
1213 #include <linux/device.h>
1314 #include <linux/delay.h>
....@@ -42,6 +43,7 @@
4243 #include <linux/printk.h>
4344
4445 #include <linux/rk-camera-module.h>
46
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
4547 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
4648
4749 #ifndef V4L2_CID_DIGITAL_GAIN
....@@ -51,6 +53,7 @@
5153 #define SC530AI_LINK_FREQ_396M 198000000 // 396Mbps
5254 #define SC530AI_LINK_FREQ_792M 396000000 // 792Mbps
5355 #define SC530AI_LINK_FREQ_792M_2LANE 396000000 // 792Mbps
56
+#define SC530AI_LINK_FREQ_936M_2LANE 468000000 // 936Mbps
5457
5558 #define SC530AI_LINEAR_PIXEL_RATES (SC530AI_LINK_FREQ_396M / 10 * 2 * 4)
5659 #define SC530AI_HDR_PIXEL_RATES (SC530AI_LINK_FREQ_792M / 10 * 2 * 4)
....@@ -59,7 +62,7 @@
5962
6063 #define SC530AI_XVCLK_FREQ 27000000
6164
62
-#define SC530AI_CHIP_ID 0x9e39
65
+#define SC530AI_CHIP_ID 0x8e39
6366 #define SC530AI_REG_CHIP_ID 0x3107
6467
6568 #define SC530AI_REG_CTRL_MODE 0x0100
....@@ -77,10 +80,10 @@
7780 #define SC530AI_REG_DIG_FINE_GAIN 0x3e07
7881 #define SC530AI_REG_ANA_GAIN 0x3e09
7982
80
-#define SC530AI_GAIN_MIN 0x800
81
-#define SC530AI_GAIN_MAX 0xa3300
83
+#define SC530AI_GAIN_MIN 0x20
84
+#define SC530AI_GAIN_MAX (32 * 326)
8285 #define SC530AI_GAIN_STEP 1
83
-#define SC530AI_GAIN_DEFAULT 0x800
86
+#define SC530AI_GAIN_DEFAULT 0x20
8487
8588 #define SC530AI_REG_VTS_H 0x320e
8689 #define SC530AI_REG_VTS_L 0x320f
....@@ -139,14 +142,6 @@
139142
140143 #define sc530ai_NUM_SUPPLIES ARRAY_SIZE(sc530ai_supply_names)
141144
142
-enum sc530ai_max_pad {
143
- PAD0, /* link to isp */
144
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
145
- PAD2, /* link to csi wr1 | hdr x3:L */
146
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
147
- PAD_MAX,
148
-};
149
-
150145 struct regval {
151146 u16 addr;
152147 u8 val;
....@@ -177,7 +172,8 @@
177172 struct pinctrl *pinctrl;
178173 struct pinctrl_state *pins_default;
179174 struct pinctrl_state *pins_sleep;
180
-
175
+ struct v4l2_fract cur_fps;
176
+ u32 cur_vts;
181177 struct v4l2_subdev subdev;
182178 struct media_pad pad;
183179 struct v4l2_ctrl_handler ctrl_handler;
....@@ -191,13 +187,17 @@
191187 struct mutex mutex;
192188 bool streaming;
193189 bool power_on;
190
+ const struct sc530ai_mode *support_modes;
194191 const struct sc530ai_mode *cur_mode;
192
+ u32 support_modes_num;
195193 unsigned int lane_num;
196194 u32 module_index;
197195 const char *module_facing;
198196 const char *module_name;
199197 const char *len_name;
200198 bool has_init_exp;
199
+ bool is_thunderboot;
200
+ bool is_first_streamoff;
201201 struct preisp_hdrae_exp_s init_hdrae_exp;
202202 };
203203
....@@ -208,7 +208,7 @@
208208 * max_framerate 30fps
209209 * mipi_datarate per lane 1008Mbps, 4lane
210210 */
211
-static const struct regval sc530ai_linear_10_30fps_2880x1620_regs[] = {
211
+static const struct regval sc530ai_linear_10_30fps_2880x1620_4lane_regs[] = {
212212 {0x0103, 0x01},
213213 {0x0100, 0x00},
214214 {0x36e9, 0x80},
....@@ -317,6 +317,7 @@
317317 {0x3e02, 0xa0},
318318 {0x440e, 0x02},
319319 {0x4509, 0x20},
320
+ {0x4800, 0x04},
320321 {0x4837, 0x28},
321322 {0x5010, 0x10},
322323 {0x5799, 0x06},
....@@ -356,7 +357,7 @@
356357 {REG_NULL, 0x00},
357358 };
358359
359
-static const struct regval sc530ai_hdr_10_30fps_2880x1620_regs[] = {
360
+static const struct regval sc530ai_hdr_10_30fps_2880x1620_4lane_regs[] = {
360361 {0x0103, 0x01},
361362 {0x0100, 0x00},
362363 {0x36e9, 0x80},
....@@ -471,6 +472,7 @@
471472 {0x3e24, 0xc8},
472473 {0x440e, 0x02},
473474 {0x4509, 0x20},
475
+ {0x4800, 0x04},
474476 {0x4816, 0x11},
475477 {0x5010, 0x10},
476478 {0x5799, 0x06},
....@@ -522,18 +524,22 @@
522524 {0x37f9, 0x80},
523525 {0x3018, 0x32},
524526 {0x3019, 0x0c},
525
- {0x301f, 0x18},
527
+ {0x301f, 0x42},
528
+ {0x320c, 0x06},
529
+ {0x320d, 0x27},
530
+ {0x320e, 0x07},
531
+ {0x320f, 0xbc},
526532 {0x3250, 0x40},
527533 {0x3251, 0x98},
528534 {0x3253, 0x0c},
529535 {0x325f, 0x20},
530536 {0x3301, 0x08},
531537 {0x3304, 0x50},
532
- {0x3306, 0x78},
538
+ {0x3306, 0x88},
533539 {0x3308, 0x14},
534540 {0x3309, 0x70},
535541 {0x330a, 0x00},
536
- {0x330b, 0xd8},
542
+ {0x330b, 0xf8},
537543 {0x330d, 0x10},
538544 {0x331e, 0x41},
539545 {0x331f, 0x61},
....@@ -562,18 +568,18 @@
562568 {0x33ae, 0x30},
563569 {0x33af, 0x50},
564570 {0x33b1, 0x80},
565
- {0x33b2, 0x80},
566
- {0x33b3, 0x40},
571
+ {0x33b2, 0x48},
572
+ {0x33b3, 0x30},
567573 {0x349f, 0x02},
568574 {0x34a6, 0x48},
569
- {0x34a7, 0x49},
570
- {0x34a8, 0x40},
571
- {0x34a9, 0x30},
572
- {0x34f8, 0x4b},
573
- {0x34f9, 0x30},
575
+ {0x34a7, 0x4b},
576
+ {0x34a8, 0x30},
577
+ {0x34a9, 0x18},
578
+ {0x34f8, 0x5f},
579
+ {0x34f9, 0x08},
574580 {0x3632, 0x48},
575581 {0x3633, 0x32},
576
- {0x3637, 0x2b},
582
+ {0x3637, 0x29},
577583 {0x3638, 0xc1},
578584 {0x363b, 0x20},
579585 {0x363d, 0x02},
....@@ -584,7 +590,7 @@
584590 {0x367c, 0x40},
585591 {0x367d, 0x48},
586592 {0x3690, 0x32},
587
- {0x3691, 0x32},
593
+ {0x3691, 0x43},
588594 {0x3692, 0x33},
589595 {0x3693, 0x40},
590596 {0x3694, 0x4b},
....@@ -596,7 +602,10 @@
596602 {0x36a3, 0x4b},
597603 {0x36a4, 0x4f},
598604 {0x36d0, 0x01},
605
+ {0x36ea, 0x0d},
606
+ {0x36eb, 0x04},
599607 {0x36ec, 0x03},
608
+ {0x36ed, 0x14},
600609 {0x370f, 0x01},
601610 {0x3722, 0x00},
602611 {0x3728, 0x10},
....@@ -605,8 +614,10 @@
605614 {0x37b2, 0x83},
606615 {0x37b3, 0x48},
607616 {0x37b4, 0x49},
608
- {0x37fb, 0x25},
617
+ {0x37fa, 0x0d},
618
+ {0x37fb, 0x24},
609619 {0x37fc, 0x01},
620
+ {0x37fd, 0x14},
610621 {0x3901, 0x00},
611622 {0x3902, 0xc5},
612623 {0x3904, 0x08},
....@@ -616,18 +627,20 @@
616627 {0x391f, 0x44},
617628 {0x3926, 0x21},
618629 {0x3929, 0x18},
619
- {0x3933, 0x81},
620
- {0x3934, 0x81},
621
- {0x3937, 0x69},
630
+ {0x3933, 0x82},
631
+ {0x3934, 0x0a},
632
+ {0x3937, 0x5f},
622633 {0x3939, 0x00},
623634 {0x393a, 0x00},
624635 {0x39dc, 0x02},
625
- {0x3e01, 0xcd},
626
- {0x3e02, 0xa0},
636
+ {0x3e01, 0xf6},
637
+ {0x3e02, 0xe0},
627638 {0x440e, 0x02},
628639 {0x4509, 0x20},
629
- {0x4837, 0x14},
640
+ {0x4837, 0x22},
630641 {0x5010, 0x10},
642
+ {0x5780, 0x66},
643
+ {0x578d, 0x40},
631644 {0x5799, 0x06},
632645 {0x57ad, 0x00},
633646 {0x5ae0, 0xfe},
....@@ -659,12 +672,11 @@
659672 {0x5afe, 0x30},
660673 {0x5aff, 0x28},
661674 {0x36e9, 0x44},
662
- {0x37f9, 0x34},
663
-// {0x0100, 0x01},
675
+ {0x37f9, 0x44},
664676 {REG_NULL, 0x00},
665677 };
666678
667
-static const struct sc530ai_mode supported_modes[] = {
679
+static const struct sc530ai_mode supported_modes_4lane[] = {
668680 {
669681 .width = 2880,
670682 .height = 1620,
....@@ -676,7 +688,7 @@
676688 .hts_def = 0xb40,
677689 .vts_def = 0x0672,
678690 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
679
- .reg_list = sc530ai_linear_10_30fps_2880x1620_regs,
691
+ .reg_list = sc530ai_linear_10_30fps_2880x1620_4lane_regs,
680692 .mipi_freq_idx = 0,
681693 .bpp = 10,
682694 .hdr_mode = NO_HDR,
....@@ -693,7 +705,7 @@
693705 .hts_def = 0xb40,
694706 .vts_def = 0x0ce4,
695707 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
696
- .reg_list = sc530ai_hdr_10_30fps_2880x1620_regs,
708
+ .reg_list = sc530ai_hdr_10_30fps_2880x1620_4lane_regs,
697709 .mipi_freq_idx = 1,
698710 .bpp = 10,
699711 .hdr_mode = HDR_X2,
....@@ -702,7 +714,10 @@
702714 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
703715 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
704716 },
705
- {
717
+};
718
+
719
+static const struct sc530ai_mode supported_modes_2lane[] = {
720
+{
706721 .width = 2880,
707722 .height = 1620,
708723 .max_fps = {
....@@ -711,10 +726,10 @@
711726 },
712727 .exp_def = 0xcda / 2,
713728 .hts_def = 0xb40,
714
- .vts_def = 0x0672,
729
+ .vts_def = 0x07bc,
715730 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
716731 .reg_list = sc530ai_10_30fps_2880x1620_2lane_regs,
717
- .mipi_freq_idx = 2,
732
+ .mipi_freq_idx = 3,
718733 .bpp = 10,
719734 .hdr_mode = NO_HDR,
720735 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
....@@ -725,6 +740,7 @@
725740 SC530AI_LINK_FREQ_396M,
726741 SC530AI_LINK_FREQ_792M,
727742 SC530AI_LINK_FREQ_792M_2LANE,
743
+ SC530AI_LINK_FREQ_936M_2LANE,
728744 };
729745
730746 /* Write registers up to 4 at a time */
....@@ -812,7 +828,7 @@
812828 }
813829
814830 static const struct sc530ai_mode *
815
-sc530ai_find_best_fit(struct v4l2_subdev_format *fmt)
831
+sc530ai_find_best_fit(struct sc530ai *sc530ai, struct v4l2_subdev_format *fmt)
816832 {
817833 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
818834 int dist;
....@@ -820,15 +836,15 @@
820836 int cur_best_fit_dist = -1;
821837 unsigned int i;
822838
823
- for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
824
- dist = sc530ai_get_reso_dist(&supported_modes[i], framefmt);
839
+ for (i = 0; i < sc530ai->support_modes_num; i++) {
840
+ dist = sc530ai_get_reso_dist(&sc530ai->support_modes[i], framefmt);
825841 if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
826842 cur_best_fit_dist = dist;
827843 cur_best_fit = i;
828844 }
829845 }
830846
831
- return &supported_modes[cur_best_fit];
847
+ return &sc530ai->support_modes[cur_best_fit];
832848 }
833849
834850 static int sc530ai_set_fmt(struct v4l2_subdev *sd,
....@@ -842,7 +858,7 @@
842858
843859 mutex_lock(&sc530ai->mutex);
844860
845
- mode = sc530ai_find_best_fit(fmt);
861
+ mode = sc530ai_find_best_fit(sc530ai, fmt);
846862 fmt->format.code = mode->bus_fmt;
847863 fmt->format.width = mode->width;
848864 fmt->format.height = mode->height;
....@@ -869,6 +885,8 @@
869885 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
870886 mode->bpp * 2 * sc530ai->lane_num;
871887 __v4l2_ctrl_s_ctrl_int64(sc530ai->pixel_rate, pixel_rate);
888
+ sc530ai->cur_vts = mode->vts_def;
889
+ sc530ai->cur_fps = mode->max_fps;
872890 }
873891
874892 mutex_unlock(&sc530ai->mutex);
....@@ -924,16 +942,18 @@
924942 struct v4l2_subdev_pad_config *cfg,
925943 struct v4l2_subdev_frame_size_enum *fse)
926944 {
927
- if (fse->index >= ARRAY_SIZE(supported_modes))
945
+ struct sc530ai *sc530ai = to_sc530ai(sd);
946
+
947
+ if (fse->index >= sc530ai->support_modes_num)
928948 return -EINVAL;
929949
930
- if (fse->code != supported_modes[0].bus_fmt)
950
+ if (fse->code != sc530ai->support_modes[fse->index].bus_fmt)
931951 return -EINVAL;
932952
933
- fse->min_width = supported_modes[fse->index].width;
934
- fse->max_width = supported_modes[fse->index].width;
935
- fse->max_height = supported_modes[fse->index].height;
936
- fse->min_height = supported_modes[fse->index].height;
953
+ fse->min_width = sc530ai->support_modes[fse->index].width;
954
+ fse->max_width = sc530ai->support_modes[fse->index].width;
955
+ fse->max_height = sc530ai->support_modes[fse->index].height;
956
+ fse->min_height = sc530ai->support_modes[fse->index].height;
937957
938958 return 0;
939959 }
....@@ -944,14 +964,15 @@
944964 struct sc530ai *sc530ai = to_sc530ai(sd);
945965 const struct sc530ai_mode *mode = sc530ai->cur_mode;
946966
947
- mutex_lock(&sc530ai->mutex);
948
- fi->interval = mode->max_fps;
949
- mutex_unlock(&sc530ai->mutex);
967
+ if (sc530ai->streaming)
968
+ fi->interval = sc530ai->cur_fps;
969
+ else
970
+ fi->interval = mode->max_fps;
950971
951972 return 0;
952973 }
953974
954
-static int sc530ai_g_mbus_config(struct v4l2_subdev *sd,
975
+static int sc530ai_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
955976 struct v4l2_mbus_config *config)
956977 {
957978 struct sc530ai *sc530ai = to_sc530ai(sd);
....@@ -965,7 +986,7 @@
965986 if (mode->hdr_mode == HDR_X3)
966987 val |= V4L2_MBUS_CSI2_CHANNEL_2;
967988
968
- config->type = V4L2_MBUS_CSI2;
989
+ config->type = V4L2_MBUS_CSI2_DPHY;
969990 config->flags = val;
970991
971992 return 0;
....@@ -984,42 +1005,50 @@
9841005 static void sc530ai_get_gain_reg(u32 total_gain, u32 *again, u32 *dgain,
9851006 u32 *dgain_fine)
9861007 {
987
- if (total_gain < 0x1000) { /* 1 - 2x gain */
1008
+ u32 gain_factor = 0;
1009
+
1010
+ if (total_gain < SC530AI_GAIN_MIN)
1011
+ total_gain = SC530AI_GAIN_MIN;
1012
+ else if (total_gain > SC530AI_GAIN_MAX)
1013
+ total_gain = SC530AI_GAIN_MAX;
1014
+
1015
+ gain_factor = total_gain * 1000 / 32;
1016
+ if (gain_factor < 2000) { /* 1 - 2x gain */
9881017 *again = 0x00;
9891018 *dgain = 0x00;
990
- *dgain_fine = total_gain >> 4;
991
- } else if (total_gain < 0x1466) { /* 2x - 2.55x gain */
1019
+ *dgain_fine = gain_factor * 128 / 1000;
1020
+ } else if (gain_factor < 2550) { /* 2x - 2.55x gain */
9921021 *again = 0x01;
9931022 *dgain = 0x00;
994
- *dgain_fine = total_gain >> 5;
995
- } else if (total_gain < 0x28cc) { /* 2.55x - 5.1x gain */
1023
+ *dgain_fine = gain_factor * 128 / 2000;
1024
+ } else if (gain_factor < 2550 * 2) { /* 2.55x - 5.1x gain */
9961025 *again = 0x40;
9971026 *dgain = 0x00;
998
- *dgain_fine = total_gain * 0x80 / 0x1466;
999
- } else if (total_gain < 0x5198) { /* 5.1x - 10.2x gain */
1027
+ *dgain_fine = gain_factor * 128 / 2550;
1028
+ } else if (gain_factor < 2550 * 4) { /* 5.1x - 10.2x gain */
10001029 *again = 0x48;
10011030 *dgain = 0x00;
1002
- *dgain_fine = (total_gain * 0x80 / 0x1466) >> 1;
1003
- } else if (total_gain < 0xa330) { /* 10.2x - 20.4x gain */
1031
+ *dgain_fine = gain_factor * 128 / 5110;
1032
+ } else if (gain_factor < 2550 * 8) { /* 10.2x - 20.4x gain */
10041033 *again = 0x49;
10051034 *dgain = 0x00;
1006
- *dgain_fine = (total_gain * 0x80 / 0x1466) >> 2;
1007
- } else if (total_gain < 0x14660) { /* 20.4x - 40.8x gain */
1035
+ *dgain_fine = gain_factor * 128 / 10200;
1036
+ } else if (gain_factor < 2550 * 16) { /* 20.4x - 40.8x gain */
10081037 *again = 0x4B;
10091038 *dgain = 0x00;
1010
- *dgain_fine = (total_gain * 0x80 / 0x1466) >> 3;
1011
- } else if (total_gain < 0x28cc0) { /* 40.8x - 81.6x gain */
1039
+ *dgain_fine = gain_factor * 128 / 20400;
1040
+ } else if (gain_factor < 2550 * 32) { /* 40.8x - 81.6x gain */
10121041 *again = 0x4f;
10131042 *dgain = 0x00;
1014
- *dgain_fine = (total_gain * 0x80 / 0x1466) >> 4;
1015
- } else if (total_gain < 0x51980) { /* 81.6x - 163.2x gain */
1043
+ *dgain_fine = gain_factor * 128 / 40800;
1044
+ } else if (gain_factor < 2550 * 64) { /* 81.6x - 163.2x gain */
10161045 *again = 0x5f;
10171046 *dgain = 0x00;
1018
- *dgain_fine = (total_gain * 0x80 / 0x1466) >> 5;
1019
- } else if (total_gain < 0xa3300) { /* 163.2x - 326.4x gain */
1047
+ *dgain_fine = gain_factor * 128 / 40800 / 2;
1048
+ } else if (gain_factor < 2550 * 128) { /* 163.2x - 326.4x gain */
10201049 *again = 0x5f;
10211050 *dgain = 0x01;
1022
- *dgain_fine = (total_gain * 0x80 / 0x1466) >> 6;
1051
+ *dgain_fine = gain_factor * 128 / 40800 / 4;
10231052 }
10241053 }
10251054
....@@ -1114,11 +1143,23 @@
11141143 return ret;
11151144 }
11161145
1146
+static int sc530ai_get_channel_info(struct sc530ai *sc530ai, struct rkmodule_channel_info *ch_info)
1147
+{
1148
+ if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
1149
+ return -EINVAL;
1150
+ ch_info->vc = sc530ai->cur_mode->vc[ch_info->index];
1151
+ ch_info->width = sc530ai->cur_mode->width;
1152
+ ch_info->height = sc530ai->cur_mode->height;
1153
+ ch_info->bus_fmt = sc530ai->cur_mode->bus_fmt;
1154
+ return 0;
1155
+}
1156
+
11171157 static long sc530ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
11181158 {
11191159 struct sc530ai *sc530ai = to_sc530ai(sd);
11201160 struct rkmodule_hdr_cfg *hdr;
11211161 const struct sc530ai_mode *mode;
1162
+ struct rkmodule_channel_info *ch_info;
11221163
11231164 long ret = 0;
11241165 u32 i, h = 0, w;
....@@ -1136,15 +1177,17 @@
11361177 break;
11371178 case RKMODULE_SET_HDR_CFG:
11381179 hdr = (struct rkmodule_hdr_cfg *)arg;
1139
- w = sc530ai->cur_mode->mipi_freq_idx;
1140
- for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1141
- if (w == supported_modes[i].mipi_freq_idx &&
1142
- supported_modes[i].hdr_mode == hdr->hdr_mode) {
1143
- sc530ai->cur_mode = &supported_modes[i];
1180
+ w = sc530ai->cur_mode->width;
1181
+ h = sc530ai->cur_mode->height;
1182
+ for (i = 0; i < sc530ai->support_modes_num; i++) {
1183
+ if (w == sc530ai->support_modes[i].width &&
1184
+ h == sc530ai->support_modes[i].height &&
1185
+ sc530ai->support_modes[i].hdr_mode == hdr->hdr_mode) {
1186
+ sc530ai->cur_mode = &sc530ai->support_modes[i];
11441187 break;
11451188 }
11461189 }
1147
- if (i == ARRAY_SIZE(supported_modes)) {
1190
+ if (i == sc530ai->support_modes_num) {
11481191 dev_err(&sc530ai->client->dev,
11491192 "not find hdr mode:%d %dx%d config\n",
11501193 hdr->hdr_mode, w, h);
....@@ -1169,7 +1212,8 @@
11691212
11701213 __v4l2_ctrl_s_ctrl_int64(sc530ai->pixel_rate,
11711214 pixel_rate);
1172
-
1215
+ sc530ai->cur_vts = mode->vts_def;
1216
+ sc530ai->cur_fps = mode->max_fps;
11731217 dev_info(&sc530ai->client->dev, "sensor mode: %d\n",
11741218 sc530ai->cur_mode->hdr_mode);
11751219 }
....@@ -1191,6 +1235,10 @@
11911235 SC530AI_REG_VALUE_08BIT,
11921236 SC530AI_MODE_SW_STANDBY);
11931237 break;
1238
+ case RKMODULE_GET_CHANNEL_INFO:
1239
+ ch_info = (struct rkmodule_channel_info *)arg;
1240
+ ret = sc530ai_get_channel_info(sc530ai, ch_info);
1241
+ break;
11941242 default:
11951243 ret = -ENOIOCTLCMD;
11961244 break;
....@@ -1207,6 +1255,7 @@
12071255 struct rkmodule_inf *inf;
12081256 struct rkmodule_hdr_cfg *hdr;
12091257 struct preisp_hdrae_exp_s *hdrae;
1258
+ struct rkmodule_channel_info *ch_info;
12101259 long ret = 0;
12111260 u32 stream = 0;
12121261
....@@ -1277,6 +1326,21 @@
12771326
12781327 ret = sc530ai_ioctl(sd, cmd, &stream);
12791328 break;
1329
+ case RKMODULE_GET_CHANNEL_INFO:
1330
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
1331
+ if (!ch_info) {
1332
+ ret = -ENOMEM;
1333
+ return ret;
1334
+ }
1335
+
1336
+ ret = sc530ai_ioctl(sd, cmd, ch_info);
1337
+ if (!ret) {
1338
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
1339
+ if (ret)
1340
+ ret = -EFAULT;
1341
+ }
1342
+ kfree(ch_info);
1343
+ break;
12801344 default:
12811345 ret = -ENOIOCTLCMD;
12821346 break;
....@@ -1290,21 +1354,23 @@
12901354 {
12911355 int ret;
12921356
1293
- ret = sc530ai_write_array(sc530ai->client, sc530ai->cur_mode->reg_list);
1294
- if (ret)
1295
- return ret;
1296
-
1297
- /* In case these controls are set before streaming */
1298
- ret = __v4l2_ctrl_handler_setup(&sc530ai->ctrl_handler);
1299
- if (ret)
1300
- return ret;
1301
- if (sc530ai->has_init_exp && sc530ai->cur_mode->hdr_mode != NO_HDR) {
1302
- ret = sc530ai_ioctl(&sc530ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1303
- &sc530ai->init_hdrae_exp);
1304
- if (ret) {
1305
- dev_err(&sc530ai->client->dev,
1306
- "init exp fail in hdr mode\n");
1357
+ if (!sc530ai->is_thunderboot) {
1358
+ ret = sc530ai_write_array(sc530ai->client, sc530ai->cur_mode->reg_list);
1359
+ if (ret)
13071360 return ret;
1361
+
1362
+ /* In case these controls are set before streaming */
1363
+ ret = __v4l2_ctrl_handler_setup(&sc530ai->ctrl_handler);
1364
+ if (ret)
1365
+ return ret;
1366
+ if (sc530ai->has_init_exp && sc530ai->cur_mode->hdr_mode != NO_HDR) {
1367
+ ret = sc530ai_ioctl(&sc530ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1368
+ &sc530ai->init_hdrae_exp);
1369
+ if (ret) {
1370
+ dev_err(&sc530ai->client->dev,
1371
+ "init exp fail in hdr mode\n");
1372
+ return ret;
1373
+ }
13081374 }
13091375 }
13101376 return sc530ai_write_reg(sc530ai->client, SC530AI_REG_CTRL_MODE,
....@@ -1315,11 +1381,16 @@
13151381 static int __sc530ai_stop_stream(struct sc530ai *sc530ai)
13161382 {
13171383 sc530ai->has_init_exp = false;
1384
+ if (sc530ai->is_thunderboot) {
1385
+ sc530ai->is_first_streamoff = true;
1386
+ pm_runtime_put(&sc530ai->client->dev);
1387
+ }
13181388 return sc530ai_write_reg(sc530ai->client, SC530AI_REG_CTRL_MODE,
13191389 SC530AI_REG_VALUE_08BIT,
13201390 SC530AI_MODE_SW_STANDBY);
13211391 }
13221392
1393
+static int __sc530ai_power_on(struct sc530ai *sc530ai);
13231394 static int sc530ai_s_stream(struct v4l2_subdev *sd, int on)
13241395 {
13251396 struct sc530ai *sc530ai = to_sc530ai(sd);
....@@ -1331,6 +1402,10 @@
13311402 if (on == sc530ai->streaming)
13321403 goto unlock_and_return;
13331404 if (on) {
1405
+ if (sc530ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
1406
+ sc530ai->is_thunderboot = false;
1407
+ __sc530ai_power_on(sc530ai);
1408
+ }
13341409 ret = pm_runtime_get_sync(&client->dev);
13351410 if (ret < 0) {
13361411 pm_runtime_put_noidle(&client->dev);
....@@ -1373,13 +1448,18 @@
13731448 pm_runtime_put_noidle(&client->dev);
13741449 goto unlock_and_return;
13751450 }
1376
-
1377
- ret |= sc530ai_write_reg(sc530ai->client,
1378
- SC530AI_SOFTWARE_RESET_REG,
1379
- SC530AI_REG_VALUE_08BIT,
1380
- 0x01);
1381
- usleep_range(100, 200);
1382
-
1451
+ if (!sc530ai->is_thunderboot) {
1452
+ ret |= sc530ai_write_reg(sc530ai->client,
1453
+ SC530AI_SOFTWARE_RESET_REG,
1454
+ SC530AI_REG_VALUE_08BIT,
1455
+ 0x01);
1456
+ if (ret) {
1457
+ v4l2_err(sd, "could not set init registers\n");
1458
+ pm_runtime_put_noidle(&client->dev);
1459
+ goto unlock_and_return;
1460
+ }
1461
+ usleep_range(100, 200);
1462
+ }
13831463 sc530ai->power_on = true;
13841464 } else {
13851465 pm_runtime_put(&client->dev);
....@@ -1413,6 +1493,10 @@
14131493 dev_err(dev, "Failed to enable xvclk\n");
14141494 return ret;
14151495 }
1496
+
1497
+ if (sc530ai->is_thunderboot)
1498
+ return 0;
1499
+
14161500 if (!IS_ERR(sc530ai->reset_gpio))
14171501 gpiod_set_value_cansleep(sc530ai->reset_gpio, 0);
14181502
....@@ -1443,6 +1527,15 @@
14431527 int ret;
14441528 struct device *dev = &sc530ai->client->dev;
14451529
1530
+ if (sc530ai->is_thunderboot) {
1531
+ if (sc530ai->is_first_streamoff) {
1532
+ sc530ai->is_thunderboot = false;
1533
+ sc530ai->is_first_streamoff = false;
1534
+ } else {
1535
+ return;
1536
+ }
1537
+ }
1538
+
14461539 if (!IS_ERR(sc530ai->pwdn_gpio))
14471540 gpiod_set_value_cansleep(sc530ai->pwdn_gpio, 0);
14481541 clk_disable_unprepare(sc530ai->xvclk);
....@@ -1457,7 +1550,7 @@
14571550 regulator_bulk_disable(sc530ai_NUM_SUPPLIES, sc530ai->supplies);
14581551 }
14591552
1460
-static int sc530ai_runtime_resume(struct device *dev)
1553
+static int __maybe_unused sc530ai_runtime_resume(struct device *dev)
14611554 {
14621555 struct i2c_client *client = to_i2c_client(dev);
14631556 struct v4l2_subdev *sd = i2c_get_clientdata(client);
....@@ -1466,7 +1559,7 @@
14661559 return __sc530ai_power_on(sc530ai);
14671560 }
14681561
1469
-static int sc530ai_runtime_suspend(struct device *dev)
1562
+static int __maybe_unused sc530ai_runtime_suspend(struct device *dev)
14701563 {
14711564 struct i2c_client *client = to_i2c_client(dev);
14721565 struct v4l2_subdev *sd = i2c_get_clientdata(client);
....@@ -1483,7 +1576,7 @@
14831576 struct sc530ai *sc530ai = to_sc530ai(sd);
14841577 struct v4l2_mbus_framefmt *try_fmt =
14851578 v4l2_subdev_get_try_format(sd, fh->pad, 0);
1486
- const struct sc530ai_mode *def_mode = &supported_modes[0];
1579
+ const struct sc530ai_mode *def_mode = &sc530ai->support_modes[0];
14871580
14881581 mutex_lock(&sc530ai->mutex);
14891582 /* Initialize try_fmt */
....@@ -1529,14 +1622,16 @@
15291622 struct v4l2_subdev_pad_config *cfg,
15301623 struct v4l2_subdev_frame_interval_enum *fie)
15311624 {
1532
- if (fie->index >= ARRAY_SIZE(supported_modes))
1625
+ struct sc530ai *sc530ai = to_sc530ai(sd);
1626
+
1627
+ if (fie->index >= sc530ai->support_modes_num)
15331628 return -EINVAL;
15341629
1535
- fie->code = supported_modes[fie->index].bus_fmt;
1536
- fie->width = supported_modes[fie->index].width;
1537
- fie->height = supported_modes[fie->index].height;
1538
- fie->interval = supported_modes[fie->index].max_fps;
1539
- fie->reserved[0] = supported_modes[fie->index].hdr_mode;
1630
+ fie->code = sc530ai->support_modes[fie->index].bus_fmt;
1631
+ fie->width = sc530ai->support_modes[fie->index].width;
1632
+ fie->height = sc530ai->support_modes[fie->index].height;
1633
+ fie->interval = sc530ai->support_modes[fie->index].max_fps;
1634
+ fie->reserved[0] = sc530ai->support_modes[fie->index].hdr_mode;
15401635 return 0;
15411636 }
15421637
....@@ -1562,7 +1657,6 @@
15621657 static const struct v4l2_subdev_video_ops sc530ai_video_ops = {
15631658 .s_stream = sc530ai_s_stream,
15641659 .g_frame_interval = sc530ai_g_frame_interval,
1565
- .g_mbus_config = sc530ai_g_mbus_config,
15661660 };
15671661
15681662 static const struct v4l2_subdev_pad_ops sc530ai_pad_ops = {
....@@ -1572,6 +1666,7 @@
15721666 .get_fmt = sc530ai_get_fmt,
15731667 .set_fmt = sc530ai_set_fmt,
15741668 .get_selection = sc530ai_get_selection,
1669
+ .get_mbus_config = sc530ai_g_mbus_config,
15751670 };
15761671
15771672 static const struct v4l2_subdev_ops sc530ai_subdev_ops = {
....@@ -1579,6 +1674,14 @@
15791674 .video = &sc530ai_video_ops,
15801675 .pad = &sc530ai_pad_ops,
15811676 };
1677
+
1678
+static void sc530ai_modify_fps_info(struct sc530ai *sc5330ai)
1679
+{
1680
+ const struct sc530ai_mode *mode = sc5330ai->cur_mode;
1681
+
1682
+ sc5330ai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1683
+ sc5330ai->cur_vts;
1684
+}
15821685
15831686 static int sc530ai_set_ctrl(struct v4l2_ctrl *ctrl)
15841687 {
....@@ -1608,7 +1711,7 @@
16081711 switch (ctrl->id) {
16091712 case V4L2_CID_EXPOSURE:
16101713 if (sc530ai->cur_mode->hdr_mode != NO_HDR)
1611
- return ret;
1714
+ goto ctrl_end;
16121715 val = ctrl->val << 1;
16131716 ret = sc530ai_write_reg(sc530ai->client,
16141717 SC530AI_REG_EXPOSURE_H,
....@@ -1627,7 +1730,7 @@
16271730 break;
16281731 case V4L2_CID_ANALOGUE_GAIN:
16291732 if (sc530ai->cur_mode->hdr_mode != NO_HDR)
1630
- return ret;
1733
+ goto ctrl_end;
16311734
16321735 sc530ai_get_gain_reg(ctrl->val, &again, &dgain, &dgain_fine);
16331736 ret = sc530ai_write_reg(sc530ai->client,
....@@ -1642,7 +1745,7 @@
16421745 SC530AI_REG_ANA_GAIN,
16431746 SC530AI_REG_VALUE_08BIT,
16441747 again);
1645
-
1748
+ dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
16461749 break;
16471750 case V4L2_CID_VBLANK:
16481751 vts = ctrl->val + sc530ai->cur_mode->height;
....@@ -1654,6 +1757,10 @@
16541757 SC530AI_REG_VTS_L,
16551758 SC530AI_REG_VALUE_08BIT,
16561759 vts & 0xff);
1760
+ if (!ret)
1761
+ sc530ai->cur_vts = vts;
1762
+ sc530ai_modify_fps_info(sc530ai);
1763
+ dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
16571764 break;
16581765 case V4L2_CID_HFLIP:
16591766 ret = sc530ai_read_reg(sc530ai->client, SC530AI_FLIP_MIRROR_REG,
....@@ -1691,6 +1798,7 @@
16911798 break;
16921799 }
16931800
1801
+ctrl_end:
16941802 pm_runtime_put(&client->dev);
16951803
16961804 return ret;
....@@ -1715,22 +1823,23 @@
17151823 fwnode = of_fwnode_handle(endpoint);
17161824 rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
17171825 if (rval <= 0) {
1718
- dev_warn(dev, " Get mipi lane num failed!\n");
1719
- return -1;
1826
+ dev_err(dev, " Get mipi lane num failed!\n");
1827
+ return -EINVAL;
17201828 }
17211829
17221830 sc530ai->lane_num = rval;
1831
+ dev_info(dev, "lane_num = %d\n", sc530ai->lane_num);
17231832
17241833 if (sc530ai->lane_num == 2) {
1725
- sc530ai->cur_mode = &supported_modes[2];
1726
- dev_info(dev, "lane_num(%d)\n", sc530ai->lane_num);
1727
- } else if (sc530ai->lane_num == 2) {
1728
- sc530ai->cur_mode = &supported_modes[0];
1729
- dev_info(dev, "lane_num(%d)\n", sc530ai->lane_num);
1730
- } else {
1731
- dev_err(dev, "unsupported lane_num(%d)\n", sc530ai->lane_num);
1732
- return -1;
1834
+ sc530ai->support_modes = supported_modes_2lane;
1835
+ sc530ai->support_modes_num = ARRAY_SIZE(supported_modes_2lane);
1836
+ } else if (sc530ai->lane_num == 4) {
1837
+ sc530ai->support_modes = supported_modes_4lane;
1838
+ sc530ai->support_modes_num = ARRAY_SIZE(supported_modes_4lane);
17331839 }
1840
+
1841
+ sc530ai->cur_mode = &sc530ai->support_modes[0];
1842
+
17341843 return 0;
17351844 }
17361845
....@@ -1809,6 +1918,8 @@
18091918 }
18101919 sc530ai->subdev.ctrl_handler = handler;
18111920 sc530ai->has_init_exp = false;
1921
+ sc530ai->cur_vts = mode->vts_def;
1922
+ sc530ai->cur_fps = mode->max_fps;
18121923
18131924 return 0;
18141925
....@@ -1824,6 +1935,10 @@
18241935 u32 id = 0;
18251936 int ret;
18261937
1938
+ if (sc530ai->is_thunderboot) {
1939
+ dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1940
+ return 0;
1941
+ }
18271942 ret = sc530ai_read_reg(client, SC530AI_REG_CHIP_ID,
18281943 SC530AI_REG_VALUE_16BIT, &id);
18291944 if (id != SC530AI_CHIP_ID) {
....@@ -1857,7 +1972,7 @@
18571972 struct v4l2_subdev *sd;
18581973 char facing[2];
18591974 int ret;
1860
- u32 i, hdr_mode = 0;
1975
+ u32 hdr_mode = 0;
18611976
18621977 dev_info(dev, "driver version: %02x.%02x.%02x",
18631978 DRIVER_VERSION >> 16,
....@@ -1882,15 +1997,12 @@
18821997 return -EINVAL;
18831998 }
18841999
2000
+ sc530ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
18852001 sc530ai->client = client;
1886
- for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1887
- if (hdr_mode == supported_modes[i].hdr_mode) {
1888
- sc530ai->cur_mode = &supported_modes[i];
1889
- break;
1890
- }
1891
- }
1892
- if (i == ARRAY_SIZE(supported_modes))
1893
- sc530ai->cur_mode = &supported_modes[0];
2002
+
2003
+ ret = sc530ai_parse_of(sc530ai);
2004
+ if (ret)
2005
+ return -EINVAL;
18942006
18952007 sc530ai->xvclk = devm_clk_get(dev, "xvclk");
18962008 if (IS_ERR(sc530ai->xvclk)) {
....@@ -1898,11 +2010,13 @@
18982010 return -EINVAL;
18992011 }
19002012
1901
- sc530ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
2013
+ sc530ai->reset_gpio = devm_gpiod_get(dev, "reset",
2014
+ sc530ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
19022015 if (IS_ERR(sc530ai->reset_gpio))
19032016 dev_warn(dev, "Failed to get reset-gpios\n");
19042017
1905
- sc530ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
2018
+ sc530ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn",
2019
+ sc530ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
19062020 if (IS_ERR(sc530ai->pwdn_gpio))
19072021 dev_warn(dev, "Failed to get pwdn-gpios\n");
19082022
....@@ -1928,10 +2042,6 @@
19282042 dev_err(dev, "Failed to get power regulators\n");
19292043 return ret;
19302044 }
1931
-
1932
- ret = sc530ai_parse_of(sc530ai);
1933
- if (ret != 0)
1934
- return -EINVAL;
19352045
19362046 mutex_init(&sc530ai->mutex);
19372047
....@@ -1980,7 +2090,10 @@
19802090
19812091 pm_runtime_set_active(dev);
19822092 pm_runtime_enable(dev);
1983
- pm_runtime_idle(dev);
2093
+ if (sc530ai->is_thunderboot)
2094
+ pm_runtime_get_sync(dev);
2095
+ else
2096
+ pm_runtime_idle(dev);
19842097
19852098 return 0;
19862099