hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/i2c/sc132gs.c
....@@ -8,6 +8,8 @@
88 * V0.0X01.0X03 add enum_frame_interval function.
99 * V0.0X01.0X04 add quick stream on/off
1010 * V0.0X01.0X05 add function g_mbus_config
11
+ * V0.0X01.0X06 add function reset gpio control
12
+ * V0.0X01.0X06 add 2-lane mode as default
1113 */
1214
1315 #include <linux/clk.h>
....@@ -28,12 +30,17 @@
2830 #include <media/v4l2-subdev.h>
2931 #include <linux/pinctrl/consumer.h>
3032
31
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x05)
33
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x07)
3234 #ifndef V4L2_CID_DIGITAL_GAIN
3335 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
3436 #endif
3537
36
-#define SC132GS_PIXEL_RATE (72 * 1000 * 1000)
38
+#define MIPI_FREQ_180M 180000000
39
+#define MIPI_FREQ_360M 360000000
40
+
41
+#define PIXEL_RATE_WITH_180M (MIPI_FREQ_180M * 2 / 10 * 2)
42
+#define PIXEL_RATE_WITH_360M (MIPI_FREQ_360M * 2 / 8 * 1)
43
+
3744 #define SC132GS_XVCLK_FREQ 24000000
3845
3946 #define CHIP_ID 0x0132
....@@ -69,13 +76,8 @@
6976
7077 #define SC132GS_NAME "sc132gs"
7178
72
-#define PIX_FORMAT MEDIA_BUS_FMT_Y8_1X8
73
-
7479 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
7580 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
76
-
77
-#define SC132GS_LANES 1
78
-#define SC132GS_BITS_PER_SAMPLE 8
7981
8082 static const char * const sc132gs_supply_names[] = {
8183 "avdd", /* Analog power */
....@@ -84,6 +86,11 @@
8486 };
8587
8688 #define SC132GS_NUM_SUPPLIES ARRAY_SIZE(sc132gs_supply_names)
89
+
90
+enum {
91
+ LINK_FREQ_180M_INDEX,
92
+ LINK_FREQ_360M_INDEX,
93
+};
8794
8895 struct regval {
8996 u16 addr;
....@@ -97,12 +104,17 @@
97104 u32 hts_def;
98105 u32 vts_def;
99106 u32 exp_def;
107
+ u32 link_freq_index;
108
+ u64 pixel_rate;
100109 const struct regval *reg_list;
110
+ u32 lanes;
111
+ u32 bus_fmt;
101112 };
102113
103114 struct sc132gs {
104115 struct i2c_client *client;
105116 struct clk *xvclk;
117
+ struct gpio_desc *reset_gpio;
106118 struct gpio_desc *pwdn_gpio;
107119 struct regulator_bulk_data supplies[SC132GS_NUM_SUPPLIES];
108120 struct pinctrl *pinctrl;
....@@ -117,7 +129,11 @@
117129 struct v4l2_ctrl *hblank;
118130 struct v4l2_ctrl *vblank;
119131 struct v4l2_ctrl *test_pattern;
132
+ struct v4l2_ctrl *pixel_rate;
133
+ struct v4l2_ctrl *link_freq;
120134 struct mutex mutex;
135
+ struct v4l2_fract cur_fps;
136
+ u32 cur_vts;
121137 bool streaming;
122138 bool power_on;
123139 const struct sc132gs_mode *cur_mode;
....@@ -131,7 +147,7 @@
131147
132148 /*
133149 * Xclk 24Mhz
134
- * Pclk 72Mhz
150
+ * Pclk 90Mhz
135151 * linelength 1696(0x06a0)
136152 * framelength 2122(0x084a)
137153 * grabwindow_width 1080
....@@ -140,7 +156,7 @@
140156 * max_framerate 30fps
141157 * mipi_datarate per lane 720Mbps
142158 */
143
-static const struct regval sc132gs_global_regs[] = {
159
+static const struct regval sc132gs_1lane_8bit_regs[] = {
144160 {0x0103, 0x01},
145161 {0x0100, 0x00},
146162
....@@ -247,6 +263,130 @@
247263 {REG_NULL, 0x00},
248264 };
249265
266
+/*
267
+ * Xclk 24Mhz
268
+ * Pclk 72Mhz
269
+ * linelength 1696(0x06a0)
270
+ * framelength 2122(0x084a)
271
+ * grabwindow_width 1080
272
+ * grabwindow_height 1280
273
+ * mipi 2 lane
274
+ * max_framerate 30fps
275
+ * mipi_datarate per lane 360Mbps
276
+ */
277
+static const struct regval sc132gs_2lane_10bit_regs[] = {
278
+ {0x0103, 0x01},
279
+ {0x0100, 0x00},
280
+
281
+ //PLL bypass
282
+ {0x36e9, 0x80},
283
+ {0x36f9, 0x80},
284
+
285
+ {0x3018, 0x32},
286
+ {0x3019, 0x0c},
287
+ {0x301a, 0xb4},
288
+ {0x3031, 0x0a},
289
+ {0x3032, 0x60},
290
+ {0x3038, 0x44},
291
+ {0x3207, 0x17},
292
+ {0x320c, 0x05},
293
+ {0x320d, 0xdc},
294
+ {0x320e, 0x09},
295
+ {0x320f, 0x60},
296
+ {0x3250, 0xcc},
297
+ {0x3251, 0x02},
298
+ {0x3252, 0x09},
299
+ {0x3253, 0x5b},
300
+ {0x3254, 0x05},
301
+ {0x3255, 0x3b},
302
+ {0x3306, 0x78},
303
+ {0x330a, 0x00},
304
+ {0x330b, 0xc8},
305
+ {0x330f, 0x24},
306
+ {0x3314, 0x80},
307
+ {0x3315, 0x40},
308
+ {0x3317, 0xf0},
309
+ {0x331f, 0x12},
310
+ {0x3364, 0x00},
311
+ {0x3385, 0x41},
312
+ {0x3387, 0x41},
313
+ {0x3389, 0x09},
314
+ {0x33ab, 0x00},
315
+ {0x33ac, 0x00},
316
+ {0x33b1, 0x03},
317
+ {0x33b2, 0x12},
318
+ {0x33f8, 0x02},
319
+ {0x33fa, 0x01},
320
+ {0x3409, 0x08},
321
+ {0x34f0, 0xc0},
322
+ {0x34f1, 0x20},
323
+ {0x34f2, 0x03},
324
+ {0x3622, 0xf5},
325
+ {0x3630, 0x5c},
326
+ {0x3631, 0x80},
327
+ {0x3632, 0xc8},
328
+ {0x3633, 0x32},
329
+ {0x3638, 0x2a},
330
+ {0x3639, 0x07},
331
+ {0x363b, 0x48},
332
+ {0x363c, 0x83},
333
+ {0x363d, 0x10},
334
+ {0x36ea, 0x38},
335
+ {0x36fa, 0x25},
336
+ {0x36fb, 0x05},
337
+ {0x36fd, 0x04},
338
+ {0x3900, 0x11},
339
+ {0x3901, 0x05},
340
+ {0x3902, 0xc5},
341
+ {0x3904, 0x04},
342
+ {0x3908, 0x91},
343
+ {0x391e, 0x00},
344
+ {0x3e01, 0x11},
345
+ {0x3e02, 0x20},
346
+ {0x3e09, 0x20},
347
+ {0x3e0e, 0xd2},
348
+ {0x3e14, 0xb0},
349
+ {0x3e1e, 0x7c},
350
+ {0x3e26, 0x20},
351
+ {0x4418, 0x38},
352
+ {0x4503, 0x10},
353
+ {0x4837, 0x21},
354
+ {0x5000, 0x0e},
355
+ {0x540c, 0x51},
356
+ {0x550f, 0x38},
357
+ {0x5780, 0x67},
358
+ {0x5784, 0x10},
359
+ {0x5785, 0x06},
360
+ {0x5787, 0x02},
361
+ {0x5788, 0x00},
362
+ {0x5789, 0x00},
363
+ {0x578a, 0x02},
364
+ {0x578b, 0x00},
365
+ {0x578c, 0x00},
366
+ {0x5790, 0x00},
367
+ {0x5791, 0x00},
368
+ {0x5792, 0x00},
369
+ {0x5793, 0x00},
370
+ {0x5794, 0x00},
371
+ {0x5795, 0x00},
372
+ {0x5799, 0x04},
373
+
374
+ //flip
375
+ //{0x3221, (0x3 << 5)},
376
+
377
+ //mirror
378
+ {0x3221, (0x3 << 1)},
379
+
380
+ //flip & mirror
381
+ //{0x3221, ((0x3 << 1)|(0x3 << 5))},
382
+
383
+ //PLL set
384
+ {0x36e9, 0x20},
385
+ {0x36f9, 0x24},
386
+
387
+ {REG_NULL, 0x00},
388
+};
389
+
250390 static const struct sc132gs_mode supported_modes[] = {
251391 {
252392 .width = 1080,
....@@ -258,7 +398,28 @@
258398 .exp_def = 0x0148,
259399 .hts_def = 0x06a0,
260400 .vts_def = 0x084a,
261
- .reg_list = sc132gs_global_regs,
401
+ .link_freq_index = LINK_FREQ_180M_INDEX,
402
+ .pixel_rate = PIXEL_RATE_WITH_180M,
403
+ .reg_list = sc132gs_2lane_10bit_regs,
404
+ .lanes = 2,
405
+ .bus_fmt = MEDIA_BUS_FMT_Y10_1X10,
406
+ },
407
+
408
+ {
409
+ .width = 1080,
410
+ .height = 1280,
411
+ .max_fps = {
412
+ .numerator = 10000,
413
+ .denominator = 300000,
414
+ },
415
+ .exp_def = 0x0148,
416
+ .hts_def = 0x06a0,
417
+ .vts_def = 0x084a,
418
+ .link_freq_index = LINK_FREQ_360M_INDEX,
419
+ .pixel_rate = PIXEL_RATE_WITH_360M,
420
+ .reg_list = sc132gs_1lane_8bit_regs,
421
+ .lanes = 1,
422
+ .bus_fmt = MEDIA_BUS_FMT_Y8_1X8,
262423 },
263424 };
264425
....@@ -270,10 +431,9 @@
270431 "Vertical Color Bar Type 4"
271432 };
272433
273
-#define SC132GS_LINK_FREQ_360MHZ (360 * 1000 * 1000)
274
-
275434 static const s64 link_freq_menu_items[] = {
276
- SC132GS_LINK_FREQ_360MHZ
435
+ MIPI_FREQ_180M,
436
+ MIPI_FREQ_360M,
277437 };
278438
279439 /* Write registers up to 4 at a time */
....@@ -374,7 +534,8 @@
374534
375535 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
376536 dist = sc132gs_get_reso_dist(&supported_modes[i], framefmt);
377
- if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
537
+ if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
538
+ (supported_modes[i].bus_fmt == framefmt->code)) {
378539 cur_best_fit_dist = dist;
379540 cur_best_fit = i;
380541 }
....@@ -393,7 +554,7 @@
393554 mutex_lock(&sc132gs->mutex);
394555
395556 mode = sc132gs_find_best_fit(fmt);
396
- fmt->format.code = PIX_FORMAT;
557
+ fmt->format.code = mode->bus_fmt;
397558 fmt->format.width = mode->width;
398559 fmt->format.height = mode->height;
399560 fmt->format.field = V4L2_FIELD_NONE;
....@@ -413,6 +574,10 @@
413574 __v4l2_ctrl_modify_range(sc132gs->vblank, vblank_def,
414575 SC132GS_VTS_MAX - mode->height,
415576 1, vblank_def);
577
+ __v4l2_ctrl_s_ctrl_int64(sc132gs->pixel_rate, mode->pixel_rate);
578
+ __v4l2_ctrl_s_ctrl(sc132gs->link_freq, mode->link_freq_index);
579
+ sc132gs->cur_fps = mode->max_fps;
580
+ sc132gs->cur_vts = mode->vts_def;
416581 }
417582
418583 mutex_unlock(&sc132gs->mutex);
....@@ -438,7 +603,7 @@
438603 } else {
439604 fmt->format.width = mode->width;
440605 fmt->format.height = mode->height;
441
- fmt->format.code = PIX_FORMAT;
606
+ fmt->format.code = mode->bus_fmt;
442607 fmt->format.field = V4L2_FIELD_NONE;
443608 }
444609 mutex_unlock(&sc132gs->mutex);
....@@ -450,9 +615,11 @@
450615 struct v4l2_subdev_pad_config *cfg,
451616 struct v4l2_subdev_mbus_code_enum *code)
452617 {
618
+ struct sc132gs *sc132gs = to_sc132gs(sd);
619
+
453620 if (code->index != 0)
454621 return -EINVAL;
455
- code->code = PIX_FORMAT;
622
+ code->code = sc132gs->cur_mode->bus_fmt;
456623
457624 return 0;
458625 }
....@@ -464,7 +631,7 @@
464631 if (fse->index >= ARRAY_SIZE(supported_modes))
465632 return -EINVAL;
466633
467
- if (fse->code != PIX_FORMAT)
634
+ if (fse->code != supported_modes[fse->index].bus_fmt)
468635 return -EINVAL;
469636
470637 fse->min_width = supported_modes[fse->index].width;
....@@ -533,7 +700,7 @@
533700 {
534701 void __user *up = compat_ptr(arg);
535702 struct rkmodule_inf *inf;
536
- long ret;
703
+ long ret = 0;
537704 u32 stream = 0;
538705
539706 switch (cmd) {
....@@ -545,14 +712,18 @@
545712 }
546713
547714 ret = sc132gs_ioctl(sd, cmd, inf);
548
- if (!ret)
715
+ if (!ret) {
549716 ret = copy_to_user(up, inf, sizeof(*inf));
717
+ if (ret)
718
+ ret = -EFAULT;
719
+ }
550720 kfree(inf);
551721 break;
552722 case RKMODULE_SET_QUICK_STREAM:
553
- ret = copy_from_user(&stream, up, sizeof(u32));
554
- if (!ret)
555
- ret = sc132gs_ioctl(sd, cmd, &stream);
723
+ if (copy_from_user(&stream, up, sizeof(u32)))
724
+ return -EFAULT;
725
+
726
+ ret = sc132gs_ioctl(sd, cmd, &stream);
556727 break;
557728 default:
558729 ret = -ENOIOCTLCMD;
....@@ -649,12 +820,21 @@
649820 {
650821 struct sc132gs *sc132gs = to_sc132gs(sd);
651822 struct i2c_client *client = sc132gs->client;
823
+ unsigned int fps;
652824 int ret = 0;
653825
654826 mutex_lock(&sc132gs->mutex);
655827 on = !!on;
656828 if (on == sc132gs->streaming)
657829 goto unlock_and_return;
830
+
831
+ fps = DIV_ROUND_CLOSEST(sc132gs->cur_mode->max_fps.denominator,
832
+ sc132gs->cur_mode->max_fps.numerator);
833
+
834
+ dev_info(&sc132gs->client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
835
+ sc132gs->cur_mode->width,
836
+ sc132gs->cur_mode->height,
837
+ fps);
658838
659839 if (on) {
660840 ret = pm_runtime_get_sync(&client->dev);
....@@ -718,9 +898,10 @@
718898 struct sc132gs *sc132gs = to_sc132gs(sd);
719899 const struct sc132gs_mode *mode = sc132gs->cur_mode;
720900
721
- mutex_lock(&sc132gs->mutex);
722
- fi->interval = mode->max_fps;
723
- mutex_unlock(&sc132gs->mutex);
901
+ if (sc132gs->streaming)
902
+ fi->interval = sc132gs->cur_fps;
903
+ else
904
+ fi->interval = mode->max_fps;
724905
725906 return 0;
726907 }
....@@ -761,8 +942,16 @@
761942 goto disable_clk;
762943 }
763944
945
+ if (!IS_ERR(sc132gs->reset_gpio))
946
+ gpiod_set_value_cansleep(sc132gs->reset_gpio, 1);
947
+
948
+ usleep_range(1000, 2000);
949
+
764950 if (!IS_ERR(sc132gs->pwdn_gpio))
765951 gpiod_set_value_cansleep(sc132gs->pwdn_gpio, 1);
952
+
953
+ if (!IS_ERR(sc132gs->reset_gpio))
954
+ gpiod_set_value_cansleep(sc132gs->reset_gpio, 0);
766955
767956 /* 8192 cycles prior to first SCCB transaction */
768957 delay_us = sc132gs_cal_delay(8192);
....@@ -779,6 +968,9 @@
779968 static void __sc132gs_power_off(struct sc132gs *sc132gs)
780969 {
781970 int ret;
971
+
972
+ if (!IS_ERR(sc132gs->reset_gpio))
973
+ gpiod_set_value_cansleep(sc132gs->reset_gpio, 1);
782974
783975 if (!IS_ERR(sc132gs->pwdn_gpio))
784976 gpiod_set_value_cansleep(sc132gs->pwdn_gpio, 0);
....@@ -824,7 +1016,7 @@
8241016 /* Initialize try_fmt */
8251017 try_fmt->width = def_mode->width;
8261018 try_fmt->height = def_mode->height;
827
- try_fmt->code = PIX_FORMAT;
1019
+ try_fmt->code = def_mode->bus_fmt;
8281020 try_fmt->field = V4L2_FIELD_NONE;
8291021
8301022 mutex_unlock(&sc132gs->mutex);
....@@ -841,24 +1033,23 @@
8411033 if (fie->index >= ARRAY_SIZE(supported_modes))
8421034 return -EINVAL;
8431035
844
- if (fie->code != PIX_FORMAT)
845
- return -EINVAL;
846
-
1036
+ fie->code = supported_modes[fie->index].bus_fmt;
8471037 fie->width = supported_modes[fie->index].width;
8481038 fie->height = supported_modes[fie->index].height;
8491039 fie->interval = supported_modes[fie->index].max_fps;
8501040 return 0;
8511041 }
8521042
853
-static int sc132gs_g_mbus_config(struct v4l2_subdev *sd,
1043
+static int sc132gs_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
8541044 struct v4l2_mbus_config *config)
8551045 {
8561046 u32 val = 0;
1047
+ struct sc132gs *sc132gs = to_sc132gs(sd);
8571048
858
- val = 1 << (SC132GS_LANES - 1) |
1049
+ val = 1 << (sc132gs->cur_mode->lanes - 1) |
8591050 V4L2_MBUS_CSI2_CHANNEL_0 |
8601051 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
861
- config->type = V4L2_MBUS_CSI2;
1052
+ config->type = V4L2_MBUS_CSI2_DPHY;
8621053 config->flags = val;
8631054
8641055 return 0;
....@@ -886,7 +1077,6 @@
8861077 static const struct v4l2_subdev_video_ops sc132gs_video_ops = {
8871078 .s_stream = sc132gs_s_stream,
8881079 .g_frame_interval = sc132gs_g_frame_interval,
889
- .g_mbus_config = sc132gs_g_mbus_config,
8901080 };
8911081
8921082 static const struct v4l2_subdev_pad_ops sc132gs_pad_ops = {
....@@ -895,6 +1085,7 @@
8951085 .enum_frame_interval = sc132gs_enum_frame_interval,
8961086 .get_fmt = sc132gs_get_fmt,
8971087 .set_fmt = sc132gs_set_fmt,
1088
+ .get_mbus_config = sc132gs_g_mbus_config,
8981089 };
8991090
9001091 static const struct v4l2_subdev_ops sc132gs_subdev_ops = {
....@@ -902,6 +1093,14 @@
9021093 .video = &sc132gs_video_ops,
9031094 .pad = &sc132gs_pad_ops,
9041095 };
1096
+
1097
+static void sc132gs_modify_fps_info(struct sc132gs *sc132gs)
1098
+{
1099
+ const struct sc132gs_mode *mode = sc132gs->cur_mode;
1100
+
1101
+ sc132gs->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1102
+ sc132gs->cur_vts;
1103
+}
9051104
9061105 static int sc132gs_set_ctrl(struct v4l2_ctrl *ctrl)
9071106 {
....@@ -939,6 +1138,11 @@
9391138 ret = sc132gs_write_reg(sc132gs->client, SC132GS_REG_VTS,
9401139 SC132GS_REG_VALUE_16BIT,
9411140 ctrl->val + sc132gs->cur_mode->height);
1141
+ if (!ret)
1142
+ sc132gs->cur_vts = ctrl->val + sc132gs->cur_mode->height;
1143
+ if (sc132gs->cur_vts != sc132gs->cur_mode->vts_def)
1144
+ sc132gs_modify_fps_info(sc132gs);
1145
+ break;
9421146 break;
9431147 case V4L2_CID_TEST_PATTERN:
9441148 ret = sc132gs_enable_test_pattern(sc132gs, ctrl->val);
....@@ -962,7 +1166,6 @@
9621166 {
9631167 const struct sc132gs_mode *mode;
9641168 struct v4l2_ctrl_handler *handler;
965
- struct v4l2_ctrl *ctrl;
9661169 s64 exposure_max, vblank_def;
9671170 u32 h_blank;
9681171 int ret;
....@@ -974,13 +1177,16 @@
9741177 return ret;
9751178 handler->lock = &sc132gs->mutex;
9761179
977
- ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
978
- 0, 0, link_freq_menu_items);
979
- if (ctrl)
980
- ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1180
+ sc132gs->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
1181
+ ARRAY_SIZE(link_freq_menu_items) - 1, 0,
1182
+ link_freq_menu_items);
9811183
982
- v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
983
- 0, SC132GS_PIXEL_RATE, 1, SC132GS_PIXEL_RATE);
1184
+ sc132gs->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
1185
+ V4L2_CID_PIXEL_RATE,
1186
+ 0, PIXEL_RATE_WITH_360M,
1187
+ 1, mode->pixel_rate);
1188
+
1189
+ __v4l2_ctrl_s_ctrl(sc132gs->link_freq, mode->pixel_rate);
9841190
9851191 h_blank = mode->hts_def - mode->width;
9861192 sc132gs->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
....@@ -1016,7 +1222,8 @@
10161222 "Failed to init controls(%d)\n", ret);
10171223 goto err_free_handler;
10181224 }
1019
-
1225
+ sc132gs->cur_fps = mode->max_fps;
1226
+ sc132gs->cur_vts = mode->vts_def;
10201227 sc132gs->subdev.ctrl_handler = handler;
10211228
10221229 return 0;
....@@ -1098,6 +1305,10 @@
10981305 return -EINVAL;
10991306 }
11001307
1308
+ sc132gs->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1309
+ if (IS_ERR(sc132gs->reset_gpio))
1310
+ dev_warn(dev, "Failed to get reset-gpios\n");
1311
+
11011312 sc132gs->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
11021313 if (IS_ERR(sc132gs->pwdn_gpio))
11031314 dev_warn(dev, "Failed to get pwdn-gpios\n");