hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/i2c/sc031gs.c
....@@ -50,8 +50,8 @@
5050
5151 #define SC031GS_REG_COARSE_AGAIN 0x3e08
5252 #define SC031GS_REG_FINE_AGAIN 0x3e09
53
-#define ANALOG_GAIN_MIN 0x01
54
-#define ANALOG_GAIN_MAX 0xF8
53
+#define ANALOG_GAIN_MIN 0x10
54
+#define ANALOG_GAIN_MAX 0x7c0 // 124x
5555 #define ANALOG_GAIN_STEP 1
5656 #define ANALOG_GAIN_DEFAULT 0x1f
5757
....@@ -117,6 +117,8 @@
117117 struct v4l2_ctrl *vblank;
118118 struct v4l2_ctrl *test_pattern;
119119 struct mutex mutex;
120
+ struct v4l2_fract cur_fps;
121
+ u32 cur_vts;
120122 bool streaming;
121123 bool power_on;
122124 const struct sc031gs_mode *cur_mode;
....@@ -296,7 +298,7 @@
296298 {0x3d08, 0x01},
297299 {0x3e01, 0x14},
298300 {0x3e02, 0x80},
299
- {0x3e06, 0x0c},
301
+ {0x3e06, 0x00},
300302 {0x4500, 0x59},
301303 {0x4501, 0xc4},
302304 {0x4603, 0x00},
....@@ -477,6 +479,8 @@
477479 __v4l2_ctrl_modify_range(sc031gs->vblank, vblank_def,
478480 SC031GS_VTS_MAX - mode->height,
479481 1, vblank_def);
482
+ sc031gs->cur_fps = mode->max_fps;
483
+ sc031gs->cur_vts = mode->vts_def;
480484 }
481485
482486 mutex_unlock(&sc031gs->mutex);
....@@ -611,7 +615,10 @@
611615
612616 ret = sc031gs_ioctl(sd, cmd, inf);
613617 if (!ret)
614
- ret = copy_to_user(up, inf, sizeof(*inf));
618
+ if (copy_to_user(up, inf, sizeof(*inf))) {
619
+ kfree(inf);
620
+ return -EFAULT;
621
+ }
615622 kfree(inf);
616623 break;
617624 case RKMODULE_AWB_CFG:
....@@ -620,16 +627,17 @@
620627 ret = -ENOMEM;
621628 return ret;
622629 }
623
-
624
- ret = copy_from_user(cfg, up, sizeof(*cfg));
625
- if (!ret)
626
- ret = sc031gs_ioctl(sd, cmd, cfg);
630
+ if (copy_from_user(cfg, up, sizeof(*cfg))) {
631
+ kfree(cfg);
632
+ return -EFAULT;
633
+ }
634
+ ret = sc031gs_ioctl(sd, cmd, cfg);
627635 kfree(cfg);
628636 break;
629637 case RKMODULE_SET_QUICK_STREAM:
630
- ret = copy_from_user(&stream, up, sizeof(u32));
631
- if (!ret)
632
- ret = sc031gs_ioctl(sd, cmd, &stream);
638
+ if (copy_from_user(&stream, up, sizeof(u32)))
639
+ return -EFAULT;
640
+ ret = sc031gs_ioctl(sd, cmd, &stream);
633641 break;
634642 default:
635643 ret = -ENOIOCTLCMD;
....@@ -643,7 +651,7 @@
643651 static int sc031gs_set_ctrl_gain(struct sc031gs *sc031gs, u32 a_gain)
644652 {
645653 int ret = 0;
646
- u32 coarse_again, fine_again, fine_again_reg, coarse_again_reg;
654
+ u32 coarse_again, fine_again, fine_again_reg, coarse_again_reg, digital_gain_reg;
647655
648656 if (a_gain < 0x20) { /*1x ~ 2x*/
649657 fine_again = a_gain - 16;
....@@ -651,24 +659,40 @@
651659 fine_again_reg = ((0x01 << 4) & 0x10) |
652660 (fine_again & 0x0f);
653661 coarse_again_reg = coarse_again & 0x1F;
662
+ digital_gain_reg = 0x80;
654663 } else if (a_gain < 0x40) { /*2x ~ 4x*/
655664 fine_again = (a_gain >> 1) - 16;
656665 coarse_again = 0x7;
657666 fine_again_reg = ((0x01 << 4) & 0x10) |
658667 (fine_again & 0x0f);
659668 coarse_again_reg = coarse_again & 0x1F;
669
+ digital_gain_reg = 0x80;
660670 } else if (a_gain < 0x80) { /*4x ~ 8x*/
661671 fine_again = (a_gain >> 2) - 16;
662672 coarse_again = 0xf;
663673 fine_again_reg = ((0x01 << 4) & 0x10) |
664674 (fine_again & 0x0f);
665675 coarse_again_reg = coarse_again & 0x1F;
666
- } else { /*8x ~ 16x*/
676
+ digital_gain_reg = 0x80;
677
+ } else if (a_gain < 0x100) { /*8x ~ 16x*/
667678 fine_again = (a_gain >> 3) - 16;
668679 coarse_again = 0x1f;
669680 fine_again_reg = ((0x01 << 4) & 0x10) |
670681 (fine_again & 0x0f);
671682 coarse_again_reg = coarse_again & 0x1F;
683
+ digital_gain_reg = 0x80;
684
+ } else if (a_gain < 0x200) { /*16x ~ 32x*/
685
+ fine_again_reg = 0x1f;
686
+ coarse_again_reg = 0x1f;
687
+ digital_gain_reg = (a_gain * 0x80 / 0x100) & 0xf8;
688
+ } else if (a_gain < 0x400) { /*32x ~ 64x*/
689
+ fine_again_reg = 0x1f;
690
+ coarse_again_reg = 0x1f;
691
+ digital_gain_reg = (a_gain * 0x80 / 0x200) & 0x1f8;
692
+ } else { /*64x ~ 124*/
693
+ fine_again_reg = 0x1f;
694
+ coarse_again_reg = 0x1f;
695
+ digital_gain_reg = (a_gain * 0x80 / 0x400) & 0x3f8;
672696 }
673697
674698 if (a_gain < 0x20) {
....@@ -690,6 +714,9 @@
690714 SC031GS_REG_FINE_AGAIN,
691715 SC031GS_REG_VALUE_08BIT,
692716 fine_again_reg);
717
+
718
+ ret |= sc031gs_write_reg(sc031gs->client, 0x3e06,
719
+ SC031GS_REG_VALUE_16BIT, digital_gain_reg);
693720
694721 return ret;
695722 }
....@@ -765,9 +792,10 @@
765792 struct sc031gs *sc031gs = to_sc031gs(sd);
766793 const struct sc031gs_mode *mode = sc031gs->cur_mode;
767794
768
- mutex_lock(&sc031gs->mutex);
769
- fi->interval = mode->max_fps;
770
- mutex_unlock(&sc031gs->mutex);
795
+ if (sc031gs->streaming)
796
+ fi->interval = sc031gs->cur_fps;
797
+ else
798
+ fi->interval = mode->max_fps;
771799
772800 return 0;
773801 }
....@@ -917,8 +945,7 @@
917945 if (fie->index >= ARRAY_SIZE(supported_modes))
918946 return -EINVAL;
919947
920
- if (fie->code != PIX_FORMAT)
921
- return -EINVAL;
948
+ fie->code = PIX_FORMAT;
922949
923950 fie->width = supported_modes[fie->index].width;
924951 fie->height = supported_modes[fie->index].height;
....@@ -967,6 +994,14 @@
967994 .pad = &sc031gs_pad_ops,
968995 };
969996
997
+static void sc031gs_modify_fps_info(struct sc031gs *sc031gs)
998
+{
999
+ const struct sc031gs_mode *mode = sc031gs->cur_mode;
1000
+
1001
+ sc031gs->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1002
+ sc031gs->cur_vts;
1003
+}
1004
+
9701005 static int sc031gs_set_ctrl(struct v4l2_ctrl *ctrl)
9711006 {
9721007 struct sc031gs *sc031gs = container_of(ctrl->handler,
....@@ -1003,6 +1038,10 @@
10031038 ret = sc031gs_write_reg(sc031gs->client, SC031GS_REG_VTS,
10041039 SC031GS_REG_VALUE_16BIT,
10051040 ctrl->val + sc031gs->cur_mode->height);
1041
+ if (!ret)
1042
+ sc031gs->cur_vts = ctrl->val + sc031gs->cur_mode->height;
1043
+ if (sc031gs->cur_vts != sc031gs->cur_mode->vts_def)
1044
+ sc031gs_modify_fps_info(sc031gs);
10061045 break;
10071046 case V4L2_CID_TEST_PATTERN:
10081047 ret = sc031gs_enable_test_pattern(sc031gs, ctrl->val);
....@@ -1053,6 +1092,7 @@
10531092 sc031gs->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
10541093
10551094 vblank_def = mode->vts_def - mode->height;
1095
+ sc031gs->cur_vts = mode->vts_def;
10561096 sc031gs->vblank = v4l2_ctrl_new_std(handler, &sc031gs_ctrl_ops,
10571097 V4L2_CID_VBLANK, vblank_def,
10581098 SC031GS_VTS_MAX - mode->height,
....@@ -1082,6 +1122,7 @@
10821122 }
10831123
10841124 sc031gs->subdev.ctrl_handler = handler;
1125
+ sc031gs->cur_fps = mode->max_fps;
10851126
10861127 return 0;
10871128