hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/i2c/smiapp/smiapp-core.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * drivers/media/i2c/smiapp/smiapp-core.c
34 *
....@@ -9,15 +10,6 @@
910 * Based on smiapp driver by Vimarsh Zutshi
1011 * Based on jt8ev1.c by Vimarsh Zutshi
1112 * Based on smia-sensor.c by Tuukka Toivonen <tuukkat76@gmail.com>
12
- *
13
- * This program is free software; you can redistribute it and/or
14
- * modify it under the terms of the GNU General Public License
15
- * version 2 as published by the Free Software Foundation.
16
- *
17
- * This program is distributed in the hope that it will be useful, but
18
- * WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
- * General Public License for more details.
2113 */
2214
2315 #include <linux/clk.h>
....@@ -64,6 +56,45 @@
6456 * Dynamic Capability Identification
6557 *
6658 */
59
+
60
+static u32 smiapp_get_limit(struct smiapp_sensor *sensor,
61
+ unsigned int limit)
62
+{
63
+ if (WARN_ON(limit >= SMIAPP_LIMIT_LAST))
64
+ return 1;
65
+
66
+ return sensor->limits[limit];
67
+}
68
+
69
+#define SMIA_LIM(sensor, limit) \
70
+ smiapp_get_limit(sensor, SMIAPP_LIMIT_##limit)
71
+
72
+static int smiapp_read_all_smia_limits(struct smiapp_sensor *sensor)
73
+{
74
+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
75
+ unsigned int i;
76
+ int rval;
77
+
78
+ for (i = 0; i < SMIAPP_LIMIT_LAST; i++) {
79
+ u32 val;
80
+
81
+ rval = smiapp_read(
82
+ sensor, smiapp_reg_limits[i].addr, &val);
83
+ if (rval)
84
+ return rval;
85
+
86
+ sensor->limits[i] = val;
87
+
88
+ dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n",
89
+ smiapp_reg_limits[i].addr,
90
+ smiapp_reg_limits[i].what, val, val);
91
+ }
92
+
93
+ if (SMIA_LIM(sensor, SCALER_N_MIN) == 0)
94
+ smiapp_replace_limit(sensor, SMIAPP_LIMIT_SCALER_N_MIN, 16);
95
+
96
+ return 0;
97
+}
6798
6899 static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor)
69100 {
....@@ -248,35 +279,35 @@
248279 {
249280 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
250281 struct smiapp_pll_limits lim = {
251
- .min_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_PRE_PLL_CLK_DIV],
252
- .max_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_PRE_PLL_CLK_DIV],
253
- .min_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ],
254
- .max_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_IP_FREQ_HZ],
255
- .min_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MIN_PLL_MULTIPLIER],
256
- .max_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MAX_PLL_MULTIPLIER],
257
- .min_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_OP_FREQ_HZ],
258
- .max_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_OP_FREQ_HZ],
282
+ .min_pre_pll_clk_div = SMIA_LIM(sensor, MIN_PRE_PLL_CLK_DIV),
283
+ .max_pre_pll_clk_div = SMIA_LIM(sensor, MAX_PRE_PLL_CLK_DIV),
284
+ .min_pll_ip_freq_hz = SMIA_LIM(sensor, MIN_PLL_IP_FREQ_HZ),
285
+ .max_pll_ip_freq_hz = SMIA_LIM(sensor, MAX_PLL_IP_FREQ_HZ),
286
+ .min_pll_multiplier = SMIA_LIM(sensor, MIN_PLL_MULTIPLIER),
287
+ .max_pll_multiplier = SMIA_LIM(sensor, MAX_PLL_MULTIPLIER),
288
+ .min_pll_op_freq_hz = SMIA_LIM(sensor, MIN_PLL_OP_FREQ_HZ),
289
+ .max_pll_op_freq_hz = SMIA_LIM(sensor, MAX_PLL_OP_FREQ_HZ),
259290
260
- .op.min_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV],
261
- .op.max_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV],
262
- .op.min_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV],
263
- .op.max_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV],
264
- .op.min_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ],
265
- .op.max_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ],
266
- .op.min_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ],
267
- .op.max_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ],
291
+ .op.min_sys_clk_div = SMIA_LIM(sensor, MIN_OP_SYS_CLK_DIV),
292
+ .op.max_sys_clk_div = SMIA_LIM(sensor, MAX_OP_SYS_CLK_DIV),
293
+ .op.min_pix_clk_div = SMIA_LIM(sensor, MIN_OP_PIX_CLK_DIV),
294
+ .op.max_pix_clk_div = SMIA_LIM(sensor, MAX_OP_PIX_CLK_DIV),
295
+ .op.min_sys_clk_freq_hz = SMIA_LIM(sensor, MIN_OP_SYS_CLK_FREQ_HZ),
296
+ .op.max_sys_clk_freq_hz = SMIA_LIM(sensor, MAX_OP_SYS_CLK_FREQ_HZ),
297
+ .op.min_pix_clk_freq_hz = SMIA_LIM(sensor, MIN_OP_PIX_CLK_FREQ_HZ),
298
+ .op.max_pix_clk_freq_hz = SMIA_LIM(sensor, MAX_OP_PIX_CLK_FREQ_HZ),
268299
269
- .vt.min_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV],
270
- .vt.max_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV],
271
- .vt.min_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV],
272
- .vt.max_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV],
273
- .vt.min_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ],
274
- .vt.max_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ],
275
- .vt.min_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ],
276
- .vt.max_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ],
300
+ .vt.min_sys_clk_div = SMIA_LIM(sensor, MIN_VT_SYS_CLK_DIV),
301
+ .vt.max_sys_clk_div = SMIA_LIM(sensor, MAX_VT_SYS_CLK_DIV),
302
+ .vt.min_pix_clk_div = SMIA_LIM(sensor, MIN_VT_PIX_CLK_DIV),
303
+ .vt.max_pix_clk_div = SMIA_LIM(sensor, MAX_VT_PIX_CLK_DIV),
304
+ .vt.min_sys_clk_freq_hz = SMIA_LIM(sensor, MIN_VT_SYS_CLK_FREQ_HZ),
305
+ .vt.max_sys_clk_freq_hz = SMIA_LIM(sensor, MAX_VT_SYS_CLK_FREQ_HZ),
306
+ .vt.min_pix_clk_freq_hz = SMIA_LIM(sensor, MIN_VT_PIX_CLK_FREQ_HZ),
307
+ .vt.max_pix_clk_freq_hz = SMIA_LIM(sensor, MAX_VT_PIX_CLK_FREQ_HZ),
277308
278
- .min_line_length_pck_bin = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN],
279
- .min_line_length_pck = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK],
309
+ .min_line_length_pck_bin = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK_BIN),
310
+ .min_line_length_pck = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK),
280311 };
281312
282313 return smiapp_pll_calculate(&client->dev, &lim, pll);
....@@ -319,7 +350,7 @@
319350
320351 max = sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
321352 + sensor->vblank->val
322
- - sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
353
+ - SMIA_LIM(sensor, COARSE_INTEGRATION_TIME_MAX_MARGIN);
323354
324355 __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max);
325356 }
....@@ -421,21 +452,14 @@
421452 struct smiapp_sensor *sensor =
422453 container_of(ctrl->handler, struct smiapp_subdev, ctrl_handler)
423454 ->sensor;
455
+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
456
+ int pm_status;
424457 u32 orient = 0;
458
+ unsigned int i;
425459 int exposure;
426460 int rval;
427461
428462 switch (ctrl->id) {
429
- case V4L2_CID_ANALOGUE_GAIN:
430
- return smiapp_write(
431
- sensor,
432
- SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
433
-
434
- case V4L2_CID_EXPOSURE:
435
- return smiapp_write(
436
- sensor,
437
- SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
438
-
439463 case V4L2_CID_HFLIP:
440464 case V4L2_CID_VFLIP:
441465 if (sensor->streaming)
....@@ -448,15 +472,10 @@
448472 orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
449473
450474 orient ^= sensor->hvflip_inv_mask;
451
- rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
452
- orient);
453
- if (rval < 0)
454
- return rval;
455475
456476 smiapp_update_mbus_formats(sensor);
457477
458
- return 0;
459
-
478
+ break;
460479 case V4L2_CID_VBLANK:
461480 exposure = sensor->exposure->val;
462481
....@@ -469,59 +488,103 @@
469488 return rval;
470489 }
471490
472
- return smiapp_write(
473
- sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
474
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
475
- + ctrl->val);
476
-
477
- case V4L2_CID_HBLANK:
478
- return smiapp_write(
479
- sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
480
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
481
- + ctrl->val);
482
-
491
+ break;
483492 case V4L2_CID_LINK_FREQ:
484493 if (sensor->streaming)
485494 return -EBUSY;
486495
487
- return smiapp_pll_update(sensor);
496
+ rval = smiapp_pll_update(sensor);
497
+ if (rval)
498
+ return rval;
488499
489
- case V4L2_CID_TEST_PATTERN: {
490
- unsigned int i;
491
-
500
+ return 0;
501
+ case V4L2_CID_TEST_PATTERN:
492502 for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
493503 v4l2_ctrl_activate(
494504 sensor->test_data[i],
495505 ctrl->val ==
496506 V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
497507
498
- return smiapp_write(
499
- sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
508
+ break;
500509 }
501510
502
- case V4L2_CID_TEST_PATTERN_RED:
503
- return smiapp_write(
504
- sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
505
-
506
- case V4L2_CID_TEST_PATTERN_GREENR:
507
- return smiapp_write(
508
- sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
509
-
510
- case V4L2_CID_TEST_PATTERN_BLUE:
511
- return smiapp_write(
512
- sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
513
-
514
- case V4L2_CID_TEST_PATTERN_GREENB:
515
- return smiapp_write(
516
- sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
517
-
518
- case V4L2_CID_PIXEL_RATE:
519
- /* For v4l2_ctrl_s_ctrl_int64() used internally. */
511
+ pm_status = pm_runtime_get_if_active(&client->dev, true);
512
+ if (!pm_status)
520513 return 0;
521514
515
+ switch (ctrl->id) {
516
+ case V4L2_CID_ANALOGUE_GAIN:
517
+ rval = smiapp_write(
518
+ sensor,
519
+ SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
520
+
521
+ break;
522
+ case V4L2_CID_EXPOSURE:
523
+ rval = smiapp_write(
524
+ sensor,
525
+ SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
526
+
527
+ break;
528
+ case V4L2_CID_HFLIP:
529
+ case V4L2_CID_VFLIP:
530
+ rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
531
+ orient);
532
+
533
+ break;
534
+ case V4L2_CID_VBLANK:
535
+ rval = smiapp_write(
536
+ sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
537
+ sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
538
+ + ctrl->val);
539
+
540
+ break;
541
+ case V4L2_CID_HBLANK:
542
+ rval = smiapp_write(
543
+ sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
544
+ sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
545
+ + ctrl->val);
546
+
547
+ break;
548
+ case V4L2_CID_TEST_PATTERN:
549
+ rval = smiapp_write(
550
+ sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
551
+
552
+ break;
553
+ case V4L2_CID_TEST_PATTERN_RED:
554
+ rval = smiapp_write(
555
+ sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
556
+
557
+ break;
558
+ case V4L2_CID_TEST_PATTERN_GREENR:
559
+ rval = smiapp_write(
560
+ sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
561
+
562
+ break;
563
+ case V4L2_CID_TEST_PATTERN_BLUE:
564
+ rval = smiapp_write(
565
+ sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
566
+
567
+ break;
568
+ case V4L2_CID_TEST_PATTERN_GREENB:
569
+ rval = smiapp_write(
570
+ sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
571
+
572
+ break;
573
+ case V4L2_CID_PIXEL_RATE:
574
+ /* For v4l2_ctrl_s_ctrl_int64() used internally. */
575
+ rval = 0;
576
+
577
+ break;
522578 default:
523
- return -EINVAL;
579
+ rval = -EINVAL;
524580 }
581
+
582
+ if (pm_status > 0) {
583
+ pm_runtime_mark_last_busy(&client->dev);
584
+ pm_runtime_put_autosuspend(&client->dev);
585
+ }
586
+
587
+ return rval;
525588 }
526589
527590 static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
....@@ -542,10 +605,10 @@
542605 sensor->analog_gain = v4l2_ctrl_new_std(
543606 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
544607 V4L2_CID_ANALOGUE_GAIN,
545
- sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN],
546
- sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX],
547
- max(sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_STEP], 1U),
548
- sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN]);
608
+ SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_MIN),
609
+ SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_MAX),
610
+ max(SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_STEP), 1U),
611
+ SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_MIN));
549612
550613 /* Exposure limits will be updated soon, use just something here. */
551614 sensor->exposure = v4l2_ctrl_new_std(
....@@ -624,7 +687,7 @@
624687 {
625688 unsigned long *valid_link_freqs = &sensor->valid_link_freqs[
626689 sensor->csi_format->compressed - sensor->compressed_min_bpp];
627
- unsigned int max, i;
690
+ unsigned int i;
628691
629692 for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) {
630693 int max_value = (1 << sensor->csi_format->width) - 1;
....@@ -634,8 +697,6 @@
634697 &smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN_RED + i,
635698 0, max_value, 1, max_value);
636699 }
637
-
638
- for (max = 0; sensor->hwcfg->op_sys_clock[max + 1]; max++);
639700
640701 sensor->link_freq = v4l2_ctrl_new_int_menu(
641702 &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
....@@ -651,105 +712,6 @@
651712
652713 for (i = 0; i < sensor->ssds_used; i++)
653714 v4l2_ctrl_handler_free(&sensor->ssds[i].ctrl_handler);
654
-}
655
-
656
-static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit,
657
- unsigned int n)
658
-{
659
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
660
- unsigned int i;
661
- u32 val;
662
- int rval;
663
-
664
- for (i = 0; i < n; i++) {
665
- rval = smiapp_read(
666
- sensor, smiapp_reg_limits[limit[i]].addr, &val);
667
- if (rval)
668
- return rval;
669
- sensor->limits[limit[i]] = val;
670
- dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n",
671
- smiapp_reg_limits[limit[i]].addr,
672
- smiapp_reg_limits[limit[i]].what, val, val);
673
- }
674
-
675
- return 0;
676
-}
677
-
678
-static int smiapp_get_all_limits(struct smiapp_sensor *sensor)
679
-{
680
- unsigned int i;
681
- int rval;
682
-
683
- for (i = 0; i < SMIAPP_LIMIT_LAST; i++) {
684
- rval = smiapp_get_limits(sensor, &i, 1);
685
- if (rval < 0)
686
- return rval;
687
- }
688
-
689
- if (sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] == 0)
690
- smiapp_replace_limit(sensor, SMIAPP_LIMIT_SCALER_N_MIN, 16);
691
-
692
- return 0;
693
-}
694
-
695
-static int smiapp_get_limits_binning(struct smiapp_sensor *sensor)
696
-{
697
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
698
- static u32 const limits[] = {
699
- SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN,
700
- SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN,
701
- SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN,
702
- SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN,
703
- SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN,
704
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN_BIN,
705
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN,
706
- };
707
- static u32 const limits_replace[] = {
708
- SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES,
709
- SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES,
710
- SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK,
711
- SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK,
712
- SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK,
713
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN,
714
- SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN,
715
- };
716
- unsigned int i;
717
- int rval;
718
-
719
- if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY] ==
720
- SMIAPP_BINNING_CAPABILITY_NO) {
721
- for (i = 0; i < ARRAY_SIZE(limits); i++)
722
- sensor->limits[limits[i]] =
723
- sensor->limits[limits_replace[i]];
724
-
725
- return 0;
726
- }
727
-
728
- rval = smiapp_get_limits(sensor, limits, ARRAY_SIZE(limits));
729
- if (rval < 0)
730
- return rval;
731
-
732
- /*
733
- * Sanity check whether the binning limits are valid. If not,
734
- * use the non-binning ones.
735
- */
736
- if (sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN]
737
- && sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN]
738
- && sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN])
739
- return 0;
740
-
741
- for (i = 0; i < ARRAY_SIZE(limits); i++) {
742
- dev_dbg(&client->dev,
743
- "replace limit 0x%8.8x \"%s\" = %d, 0x%x\n",
744
- smiapp_reg_limits[limits[i]].addr,
745
- smiapp_reg_limits[limits[i]].what,
746
- sensor->limits[limits_replace[i]],
747
- sensor->limits[limits_replace[i]]);
748
- sensor->limits[limits[i]] =
749
- sensor->limits[limits_replace[i]];
750
- }
751
-
752
- return 0;
753715 }
754716
755717 static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
....@@ -901,59 +863,46 @@
901863 {
902864 struct v4l2_ctrl *vblank = sensor->vblank;
903865 struct v4l2_ctrl *hblank = sensor->hblank;
866
+ uint16_t min_fll, max_fll, min_llp, max_llp, min_lbp;
904867 int min, max;
905868
869
+ if (sensor->binning_vertical > 1 || sensor->binning_horizontal > 1) {
870
+ min_fll = SMIA_LIM(sensor, MIN_FRAME_LENGTH_LINES_BIN);
871
+ max_fll = SMIA_LIM(sensor, MAX_FRAME_LENGTH_LINES_BIN);
872
+ min_llp = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK_BIN);
873
+ max_llp = SMIA_LIM(sensor, MAX_LINE_LENGTH_PCK_BIN);
874
+ min_lbp = SMIA_LIM(sensor, MIN_LINE_BLANKING_PCK_BIN);
875
+ } else {
876
+ min_fll = SMIA_LIM(sensor, MIN_FRAME_LENGTH_LINES);
877
+ max_fll = SMIA_LIM(sensor, MAX_FRAME_LENGTH_LINES);
878
+ min_llp = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK);
879
+ max_llp = SMIA_LIM(sensor, MAX_LINE_LENGTH_PCK);
880
+ min_lbp = SMIA_LIM(sensor, MIN_LINE_BLANKING_PCK);
881
+ }
882
+
906883 min = max_t(int,
907
- sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],
908
- sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN] -
884
+ SMIA_LIM(sensor, MIN_FRAME_BLANKING_LINES),
885
+ min_fll -
909886 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
910
- max = sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN] -
911
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;
887
+ max = max_fll - sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;
912888
913889 __v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min);
914890
915891 min = max_t(int,
916
- sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN] -
892
+ min_llp -
917893 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width,
918
- sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN]);
919
- max = sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN] -
920
- sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width;
894
+ min_lbp);
895
+ max = max_llp - sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width;
921896
922897 __v4l2_ctrl_modify_range(hblank, min, max, hblank->step, min);
923898
924899 __smiapp_update_exposure_limits(sensor);
925900 }
926901
927
-static int smiapp_update_mode(struct smiapp_sensor *sensor)
902
+static int smiapp_pll_blanking_update(struct smiapp_sensor *sensor)
928903 {
929904 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
930
- unsigned int binning_mode;
931905 int rval;
932
-
933
- /* Binning has to be set up here; it affects limits */
934
- if (sensor->binning_horizontal == 1 &&
935
- sensor->binning_vertical == 1) {
936
- binning_mode = 0;
937
- } else {
938
- u8 binning_type =
939
- (sensor->binning_horizontal << 4)
940
- | sensor->binning_vertical;
941
-
942
- rval = smiapp_write(
943
- sensor, SMIAPP_REG_U8_BINNING_TYPE, binning_type);
944
- if (rval < 0)
945
- return rval;
946
-
947
- binning_mode = 1;
948
- }
949
- rval = smiapp_write(sensor, SMIAPP_REG_U8_BINNING_MODE, binning_mode);
950
- if (rval < 0)
951
- return rval;
952
-
953
- /* Get updated limits due to binning */
954
- rval = smiapp_get_limits_binning(sensor);
955
- if (rval < 0)
956
- return rval;
957906
958907 rval = smiapp_pll_update(sensor);
959908 if (rval < 0)
....@@ -980,62 +929,91 @@
980929 * SMIA++ NVM handling
981930 *
982931 */
983
-static int smiapp_read_nvm(struct smiapp_sensor *sensor,
984
- unsigned char *nvm)
932
+
933
+static int smiapp_read_nvm_page(struct smiapp_sensor *sensor, u32 p, u8 *nvm,
934
+ u8 *status)
985935 {
986
- u32 i, s, p, np, v;
987
- int rval = 0, rval2;
936
+ unsigned int i;
937
+ int rval;
938
+ u32 s;
988939
989
- np = sensor->nvm_size / SMIAPP_NVM_PAGE_SIZE;
990
- for (p = 0; p < np; p++) {
991
- rval = smiapp_write(
992
- sensor,
993
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT, p);
994
- if (rval)
995
- goto out;
940
+ *status = 0;
996941
997
- rval = smiapp_write(sensor,
998
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL,
999
- SMIAPP_DATA_TRANSFER_IF_1_CTRL_EN |
1000
- SMIAPP_DATA_TRANSFER_IF_1_CTRL_RD_EN);
1001
- if (rval)
1002
- goto out;
942
+ rval = smiapp_write(sensor,
943
+ SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT, p);
944
+ if (rval)
945
+ return rval;
1003946
947
+ rval = smiapp_write(sensor, SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL,
948
+ SMIAPP_DATA_TRANSFER_IF_1_CTRL_EN);
949
+ if (rval)
950
+ return rval;
951
+
952
+ rval = smiapp_read(sensor, SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS,
953
+ &s);
954
+ if (rval)
955
+ return rval;
956
+
957
+ if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_EUSAGE) {
958
+ *status = s;
959
+ return -ENODATA;
960
+ }
961
+
962
+ if (SMIA_LIM(sensor, DATA_TRANSFER_IF_CAPABILITY) &
963
+ SMIAPP_DATA_TRANSFER_IF_CAPABILITY_POLL) {
1004964 for (i = 1000; i > 0; i--) {
1005
- rval = smiapp_read(
1006
- sensor,
1007
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS, &s);
1008
-
1009
- if (rval)
1010
- goto out;
1011
-
1012965 if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY)
1013966 break;
1014967
1015
- }
1016
- if (!i) {
1017
- rval = -ETIMEDOUT;
1018
- goto out;
1019
- }
1020
-
1021
- for (i = 0; i < SMIAPP_NVM_PAGE_SIZE; i++) {
1022968 rval = smiapp_read(
1023969 sensor,
1024
- SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 + i,
1025
- &v);
1026
- if (rval)
1027
- goto out;
970
+ SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS,
971
+ &s);
1028972
1029
- *nvm++ = v;
973
+ if (rval)
974
+ return rval;
1030975 }
976
+
977
+ if (!i)
978
+ return -ETIMEDOUT;
1031979 }
1032980
1033
-out:
981
+ for (i = 0; i < SMIAPP_NVM_PAGE_SIZE; i++) {
982
+ u32 v;
983
+
984
+ rval = smiapp_read(sensor,
985
+ SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 + i,
986
+ &v);
987
+ if (rval)
988
+ return rval;
989
+
990
+ *nvm++ = v;
991
+ }
992
+
993
+ return 0;
994
+}
995
+
996
+static int smiapp_read_nvm(struct smiapp_sensor *sensor, unsigned char *nvm,
997
+ size_t nvm_size)
998
+{
999
+ u8 status = 0;
1000
+ u32 p;
1001
+ int rval = 0, rval2;
1002
+
1003
+ for (p = 0; p < nvm_size / SMIAPP_NVM_PAGE_SIZE && !rval; p++) {
1004
+ rval = smiapp_read_nvm_page(sensor, p, nvm, &status);
1005
+ nvm += SMIAPP_NVM_PAGE_SIZE;
1006
+ }
1007
+
1008
+ if (rval == -ENODATA &&
1009
+ status & SMIAPP_DATA_TRANSFER_IF_1_STATUS_EUSAGE)
1010
+ rval = 0;
1011
+
10341012 rval2 = smiapp_write(sensor, SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL, 0);
10351013 if (rval < 0)
10361014 return rval;
10371015 else
1038
- return rval2;
1016
+ return rval2 ?: p * SMIAPP_NVM_PAGE_SIZE;
10391017 }
10401018
10411019 /*
....@@ -1238,10 +1216,6 @@
12381216 sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
12391217 usleep_range(sleep, sleep);
12401218
1241
- mutex_lock(&sensor->mutex);
1242
-
1243
- sensor->active = true;
1244
-
12451219 /*
12461220 * Failures to respond to the address change command have been noticed.
12471221 * Those failures seem to be caused by the sensor requiring a longer
....@@ -1324,28 +1298,9 @@
13241298 goto out_cci_addr_fail;
13251299 }
13261300
1327
- /* Are we still initialising...? If not, proceed with control setup. */
1328
- if (sensor->pixel_array) {
1329
- rval = __v4l2_ctrl_handler_setup(
1330
- &sensor->pixel_array->ctrl_handler);
1331
- if (rval)
1332
- goto out_cci_addr_fail;
1333
-
1334
- rval = __v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
1335
- if (rval)
1336
- goto out_cci_addr_fail;
1337
-
1338
- rval = smiapp_update_mode(sensor);
1339
- if (rval < 0)
1340
- goto out_cci_addr_fail;
1341
- }
1342
-
1343
- mutex_unlock(&sensor->mutex);
1344
-
13451301 return 0;
13461302
13471303 out_cci_addr_fail:
1348
- mutex_unlock(&sensor->mutex);
13491304 gpiod_set_value(sensor->xshutdown, 0);
13501305 clk_disable_unprepare(sensor->ext_clk);
13511306
....@@ -1363,8 +1318,6 @@
13631318 struct smiapp_sensor *sensor =
13641319 container_of(ssd, struct smiapp_sensor, ssds[0]);
13651320
1366
- mutex_lock(&sensor->mutex);
1367
-
13681321 /*
13691322 * Currently power/clock to lens are enable/disabled separately
13701323 * but they are essentially the same signals. So if the sensor is
....@@ -1376,10 +1329,6 @@
13761329 smiapp_write(sensor,
13771330 SMIAPP_REG_U8_SOFTWARE_RESET,
13781331 SMIAPP_SOFTWARE_RESET);
1379
-
1380
- sensor->active = false;
1381
-
1382
- mutex_unlock(&sensor->mutex);
13831332
13841333 gpiod_set_value(sensor->xshutdown, 0);
13851334 clk_disable_unprepare(sensor->ext_clk);
....@@ -1397,6 +1346,7 @@
13971346 static int smiapp_start_streaming(struct smiapp_sensor *sensor)
13981347 {
13991348 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
1349
+ unsigned int binning_mode;
14001350 int rval;
14011351
14021352 mutex_lock(&sensor->mutex);
....@@ -1407,6 +1357,27 @@
14071357 if (rval)
14081358 goto out;
14091359
1360
+ /* Binning configuration */
1361
+ if (sensor->binning_horizontal == 1 &&
1362
+ sensor->binning_vertical == 1) {
1363
+ binning_mode = 0;
1364
+ } else {
1365
+ u8 binning_type =
1366
+ (sensor->binning_horizontal << 4)
1367
+ | sensor->binning_vertical;
1368
+
1369
+ rval = smiapp_write(
1370
+ sensor, SMIAPP_REG_U8_BINNING_TYPE, binning_type);
1371
+ if (rval < 0)
1372
+ goto out;
1373
+
1374
+ binning_mode = 1;
1375
+ }
1376
+ rval = smiapp_write(sensor, SMIAPP_REG_U8_BINNING_MODE, binning_mode);
1377
+ if (rval < 0)
1378
+ goto out;
1379
+
1380
+ /* Set up PLL */
14101381 rval = smiapp_pll_configure(sensor);
14111382 if (rval)
14121383 goto out;
....@@ -1443,7 +1414,7 @@
14431414 */
14441415
14451416 /* Digital crop */
1446
- if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
1417
+ if (SMIA_LIM(sensor, DIGITAL_CROP_CAPABILITY)
14471418 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
14481419 rval = smiapp_write(
14491420 sensor, SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET,
....@@ -1471,7 +1442,7 @@
14711442 }
14721443
14731444 /* Scaling */
1474
- if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
1445
+ if (SMIA_LIM(sensor, SCALING_CAPABILITY)
14751446 != SMIAPP_SCALING_CAPABILITY_NONE) {
14761447 rval = smiapp_write(sensor, SMIAPP_REG_U16_SCALING_MODE,
14771448 sensor->scaling_mode);
....@@ -1494,7 +1465,7 @@
14941465 if (rval < 0)
14951466 goto out;
14961467
1497
- if ((sensor->limits[SMIAPP_LIMIT_FLASH_MODE_CAPABILITY] &
1468
+ if ((SMIA_LIM(sensor, FLASH_MODE_CAPABILITY) &
14981469 (SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE |
14991470 SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE)) &&
15001471 sensor->hwcfg->strobe_setup != NULL &&
....@@ -1543,6 +1514,30 @@
15431514 * V4L2 subdev video operations
15441515 */
15451516
1517
+static int smiapp_pm_get_init(struct smiapp_sensor *sensor)
1518
+{
1519
+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
1520
+ int rval;
1521
+
1522
+ rval = pm_runtime_get_sync(&client->dev);
1523
+ if (rval < 0) {
1524
+ if (rval != -EBUSY && rval != -EAGAIN)
1525
+ pm_runtime_set_active(&client->dev);
1526
+ pm_runtime_put_noidle(&client->dev);
1527
+
1528
+ return rval;
1529
+ } else if (!rval) {
1530
+ rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->
1531
+ ctrl_handler);
1532
+ if (rval)
1533
+ return rval;
1534
+
1535
+ return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
1536
+ }
1537
+
1538
+ return 0;
1539
+}
1540
+
15461541 static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
15471542 {
15481543 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
....@@ -1552,22 +1547,23 @@
15521547 if (sensor->streaming == enable)
15531548 return 0;
15541549
1555
- if (enable) {
1556
- rval = pm_runtime_get_sync(&client->dev);
1557
- if (rval < 0) {
1558
- if (rval != -EBUSY && rval != -EAGAIN)
1559
- pm_runtime_set_active(&client->dev);
1560
- pm_runtime_put(&client->dev);
1561
- return rval;
1562
- }
1550
+ if (!enable) {
1551
+ smiapp_stop_streaming(sensor);
1552
+ sensor->streaming = false;
1553
+ pm_runtime_mark_last_busy(&client->dev);
1554
+ pm_runtime_put_autosuspend(&client->dev);
15631555
1564
- sensor->streaming = true;
1556
+ return 0;
1557
+ }
15651558
1566
- rval = smiapp_start_streaming(sensor);
1567
- if (rval < 0)
1568
- sensor->streaming = false;
1569
- } else {
1570
- rval = smiapp_stop_streaming(sensor);
1559
+ rval = smiapp_pm_get_init(sensor);
1560
+ if (rval)
1561
+ return rval;
1562
+
1563
+ sensor->streaming = true;
1564
+
1565
+ rval = smiapp_start_streaming(sensor);
1566
+ if (rval < 0) {
15711567 sensor->streaming = false;
15721568 pm_runtime_mark_last_busy(&client->dev);
15731569 pm_runtime_put_autosuspend(&client->dev);
....@@ -1717,8 +1713,7 @@
17171713 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
17181714 if (ssd == sensor->scaler) {
17191715 sensor->scale_m =
1720
- sensor->limits[
1721
- SMIAPP_LIMIT_SCALER_N_MIN];
1716
+ SMIA_LIM(sensor, SCALER_N_MIN);
17221717 sensor->scaling_mode =
17231718 SMIAPP_SCALING_MODE_NONE;
17241719 } else if (ssd == sensor->binner) {
....@@ -1726,7 +1721,7 @@
17261721 sensor->binning_vertical = 1;
17271722 }
17281723 }
1729
- /* Fall through */
1724
+ fallthrough;
17301725 case V4L2_SEL_TGT_COMPOSE:
17311726 *crops[SMIAPP_PAD_SRC] = *comp;
17321727 break;
....@@ -1830,12 +1825,12 @@
18301825
18311826 fmt->format.width =
18321827 clamp(fmt->format.width,
1833
- sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
1834
- sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);
1828
+ SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE),
1829
+ SMIA_LIM(sensor, MAX_X_OUTPUT_SIZE));
18351830 fmt->format.height =
18361831 clamp(fmt->format.height,
1837
- sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
1838
- sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);
1832
+ SMIA_LIM(sensor, MIN_Y_OUTPUT_SIZE),
1833
+ SMIA_LIM(sensor, MAX_Y_OUTPUT_SIZE));
18391834
18401835 smiapp_get_crop_compose(subdev, cfg, crops, NULL, fmt->which);
18411836
....@@ -1888,7 +1883,7 @@
18881883 val -= abs(w - ask_w);
18891884 val -= abs(h - ask_h);
18901885
1891
- if (w < sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])
1886
+ if (w < SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE))
18921887 val -= SCALING_GOODNESS_EXTREME;
18931888
18941889 dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n",
....@@ -1954,7 +1949,7 @@
19541949 struct i2c_client *client = v4l2_get_subdevdata(subdev);
19551950 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
19561951 u32 min, max, a, b, max_m;
1957
- u32 scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
1952
+ u32 scale_m = SMIA_LIM(sensor, SCALER_N_MIN);
19581953 int mode = SMIAPP_SCALING_MODE_HORIZONTAL;
19591954 u32 try[4];
19601955 u32 ntry = 0;
....@@ -1967,19 +1962,19 @@
19671962 crops[SMIAPP_PAD_SINK]->height);
19681963
19691964 a = crops[SMIAPP_PAD_SINK]->width
1970
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.width;
1965
+ * SMIA_LIM(sensor, SCALER_N_MIN) / sel->r.width;
19711966 b = crops[SMIAPP_PAD_SINK]->height
1972
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.height;
1967
+ * SMIA_LIM(sensor, SCALER_N_MIN) / sel->r.height;
19731968 max_m = crops[SMIAPP_PAD_SINK]->width
1974
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]
1975
- / sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE];
1969
+ * SMIA_LIM(sensor, SCALER_N_MIN)
1970
+ / SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE);
19761971
1977
- a = clamp(a, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],
1978
- sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);
1979
- b = clamp(b, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],
1980
- sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);
1981
- max_m = clamp(max_m, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],
1982
- sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);
1972
+ a = clamp(a, SMIA_LIM(sensor, SCALER_M_MIN),
1973
+ SMIA_LIM(sensor, SCALER_M_MAX));
1974
+ b = clamp(b, SMIA_LIM(sensor, SCALER_M_MIN),
1975
+ SMIA_LIM(sensor, SCALER_M_MAX));
1976
+ max_m = clamp(max_m, SMIA_LIM(sensor, SCALER_M_MIN),
1977
+ SMIA_LIM(sensor, SCALER_M_MAX));
19831978
19841979 dev_dbg(&client->dev, "scaling: a %d b %d max_m %d\n", a, b, max_m);
19851980
....@@ -2006,7 +2001,7 @@
20062001 subdev,
20072002 crops[SMIAPP_PAD_SINK]->width
20082003 / try[i]
2009
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
2004
+ * SMIA_LIM(sensor, SCALER_N_MIN),
20102005 sel->r.width,
20112006 crops[SMIAPP_PAD_SINK]->height,
20122007 sel->r.height,
....@@ -2020,18 +2015,18 @@
20202015 best = this;
20212016 }
20222017
2023
- if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
2018
+ if (SMIA_LIM(sensor, SCALING_CAPABILITY)
20242019 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
20252020 continue;
20262021
20272022 this = scaling_goodness(
20282023 subdev, crops[SMIAPP_PAD_SINK]->width
20292024 / try[i]
2030
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
2025
+ * SMIA_LIM(sensor, SCALER_N_MIN),
20312026 sel->r.width,
20322027 crops[SMIAPP_PAD_SINK]->height
20332028 / try[i]
2034
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
2029
+ * SMIA_LIM(sensor, SCALER_N_MIN),
20352030 sel->r.height,
20362031 sel->flags);
20372032
....@@ -2045,12 +2040,12 @@
20452040 sel->r.width =
20462041 (crops[SMIAPP_PAD_SINK]->width
20472042 / scale_m
2048
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]) & ~1;
2043
+ * SMIA_LIM(sensor, SCALER_N_MIN)) & ~1;
20492044 if (mode == SMIAPP_SCALING_MODE_BOTH)
20502045 sel->r.height =
20512046 (crops[SMIAPP_PAD_SINK]->height
20522047 / scale_m
2053
- * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN])
2048
+ * SMIA_LIM(sensor, SCALER_N_MIN))
20542049 & ~1;
20552050 else
20562051 sel->r.height = crops[SMIAPP_PAD_SINK]->height;
....@@ -2083,7 +2078,7 @@
20832078 smiapp_propagate(subdev, cfg, sel->which, V4L2_SEL_TGT_COMPOSE);
20842079
20852080 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
2086
- return smiapp_update_mode(sensor);
2081
+ return smiapp_pll_blanking_update(sensor);
20872082
20882083 return 0;
20892084 }
....@@ -2106,7 +2101,7 @@
21062101 return 0;
21072102 if (ssd == sensor->scaler
21082103 && sel->pad == SMIAPP_PAD_SINK
2109
- && sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
2104
+ && SMIA_LIM(sensor, DIGITAL_CROP_CAPABILITY)
21102105 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP)
21112106 return 0;
21122107 return -EINVAL;
....@@ -2122,10 +2117,10 @@
21222117 if (ssd == sensor->binner)
21232118 return 0;
21242119 if (ssd == sensor->scaler
2125
- && sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
2120
+ && SMIA_LIM(sensor, SCALING_CAPABILITY)
21262121 != SMIAPP_SCALING_CAPABILITY_NONE)
21272122 return 0;
2128
- /* Fall through */
2123
+ fallthrough;
21292124 default:
21302125 return -EINVAL;
21312126 }
....@@ -2187,8 +2182,8 @@
21872182 {
21882183 r->top = 0;
21892184 r->left = 0;
2190
- r->width = ssd->sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
2191
- r->height = ssd->sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
2185
+ r->width = SMIA_LIM(ssd->sensor, X_ADDR_MAX) + 1;
2186
+ r->height = SMIA_LIM(ssd->sensor, Y_ADDR_MAX) + 1;
21922187 }
21932188
21942189 static int __smiapp_get_selection(struct v4l2_subdev *subdev,
....@@ -2273,10 +2268,10 @@
22732268 sel->r.height = SMIAPP_ALIGN_DIM(sel->r.height, sel->flags);
22742269
22752270 sel->r.width = max_t(unsigned int,
2276
- sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
2271
+ SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE),
22772272 sel->r.width);
22782273 sel->r.height = max_t(unsigned int,
2279
- sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
2274
+ SMIA_LIM(sensor, MIN_Y_OUTPUT_SIZE),
22802275 sel->r.height);
22812276
22822277 switch (sel->target) {
....@@ -2322,42 +2317,30 @@
23222317 struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
23232318 struct i2c_client *client = v4l2_get_subdevdata(subdev);
23242319 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2325
- unsigned int nbytes;
2320
+ int rval;
23262321
23272322 if (!sensor->dev_init_done)
23282323 return -EBUSY;
23292324
2330
- if (!sensor->nvm_size) {
2331
- int rval;
2325
+ rval = smiapp_pm_get_init(sensor);
2326
+ if (rval < 0)
2327
+ return -ENODEV;
23322328
2333
- /* NVM not read yet - read it now */
2334
- sensor->nvm_size = sensor->hwcfg->nvm_size;
2335
-
2336
- rval = pm_runtime_get_sync(&client->dev);
2337
- if (rval < 0) {
2338
- if (rval != -EBUSY && rval != -EAGAIN)
2339
- pm_runtime_set_active(&client->dev);
2340
- pm_runtime_put_noidle(&client->dev);
2341
- return -ENODEV;
2342
- }
2343
-
2344
- if (smiapp_read_nvm(sensor, sensor->nvm)) {
2345
- pm_runtime_put(&client->dev);
2346
- dev_err(&client->dev, "nvm read failed\n");
2347
- return -ENODEV;
2348
- }
2349
-
2350
- pm_runtime_mark_last_busy(&client->dev);
2351
- pm_runtime_put_autosuspend(&client->dev);
2329
+ rval = smiapp_read_nvm(sensor, buf, PAGE_SIZE);
2330
+ if (rval < 0) {
2331
+ pm_runtime_put(&client->dev);
2332
+ dev_err(&client->dev, "nvm read failed\n");
2333
+ return -ENODEV;
23522334 }
2335
+
2336
+ pm_runtime_mark_last_busy(&client->dev);
2337
+ pm_runtime_put_autosuspend(&client->dev);
2338
+
23532339 /*
23542340 * NVM is still way below a PAGE_SIZE, so we can safely
23552341 * assume this for now.
23562342 */
2357
- nbytes = min_t(unsigned int, sensor->nvm_size, PAGE_SIZE);
2358
- memcpy(buf, sensor->nvm, nbytes);
2359
-
2360
- return nbytes;
2343
+ return rval;
23612344 }
23622345 static DEVICE_ATTR(nvm, S_IRUGO, smiapp_sysfs_nvm_read, NULL);
23632346
....@@ -2618,9 +2601,7 @@
26182601 ssd->npads = num_pads;
26192602 ssd->source_pad = num_pads - 1;
26202603
2621
- snprintf(ssd->sd.name,
2622
- sizeof(ssd->sd.name), "%s %s %d-%4.4x", sensor->minfo.name,
2623
- name, i2c_adapter_id(client->adapter), client->addr);
2604
+ v4l2_i2c_subdev_set_name(&ssd->sd, client, sensor->minfo.name, name);
26242605
26252606 smiapp_get_native_size(ssd, &ssd->sink_fmt);
26262607
....@@ -2762,7 +2743,7 @@
27622743 static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
27632744 {
27642745 struct smiapp_hwconfig *hwcfg;
2765
- struct v4l2_fwnode_endpoint *bus_cfg;
2746
+ struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
27662747 struct fwnode_handle *ep;
27672748 struct fwnode_handle *fwnode = dev_fwnode(dev);
27682749 u32 rotation;
....@@ -2776,27 +2757,33 @@
27762757 if (!ep)
27772758 return NULL;
27782759
2779
- bus_cfg = v4l2_fwnode_endpoint_alloc_parse(ep);
2780
- if (IS_ERR(bus_cfg))
2760
+ bus_cfg.bus_type = V4L2_MBUS_CSI2_DPHY;
2761
+ rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
2762
+ if (rval == -ENXIO) {
2763
+ bus_cfg = (struct v4l2_fwnode_endpoint)
2764
+ { .bus_type = V4L2_MBUS_CCP2 };
2765
+ rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
2766
+ }
2767
+ if (rval)
27812768 goto out_err;
27822769
27832770 hwcfg = devm_kzalloc(dev, sizeof(*hwcfg), GFP_KERNEL);
27842771 if (!hwcfg)
27852772 goto out_err;
27862773
2787
- switch (bus_cfg->bus_type) {
2788
- case V4L2_MBUS_CSI2:
2774
+ switch (bus_cfg.bus_type) {
2775
+ case V4L2_MBUS_CSI2_DPHY:
27892776 hwcfg->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2;
2790
- hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes;
2777
+ hwcfg->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
27912778 break;
27922779 case V4L2_MBUS_CCP2:
2793
- hwcfg->csi_signalling_mode = (bus_cfg->bus.mipi_csi1.strobe) ?
2780
+ hwcfg->csi_signalling_mode = (bus_cfg.bus.mipi_csi1.strobe) ?
27942781 SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE :
27952782 SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK;
27962783 hwcfg->lanes = 1;
27972784 break;
27982785 default:
2799
- dev_err(dev, "unsupported bus %u\n", bus_cfg->bus_type);
2786
+ dev_err(dev, "unsupported bus %u\n", bus_cfg.bus_type);
28002787 goto out_err;
28012788 }
28022789
....@@ -2808,7 +2795,7 @@
28082795 case 180:
28092796 hwcfg->module_board_orient =
28102797 SMIAPP_MODULE_BOARD_ORIENT_180;
2811
- /* Fall through */
2798
+ fallthrough;
28122799 case 0:
28132800 break;
28142801 default:
....@@ -2817,45 +2804,41 @@
28172804 }
28182805 }
28192806
2820
- /* NVM size is not mandatory */
2821
- fwnode_property_read_u32(fwnode, "nokia,nvm-size", &hwcfg->nvm_size);
2822
-
28232807 rval = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
28242808 &hwcfg->ext_clk);
28252809 if (rval)
28262810 dev_info(dev, "can't get clock-frequency\n");
28272811
2828
- dev_dbg(dev, "nvm %d, clk %d, mode %d\n",
2829
- hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode);
2812
+ dev_dbg(dev, "clk %d, mode %d\n", hwcfg->ext_clk,
2813
+ hwcfg->csi_signalling_mode);
28302814
2831
- if (!bus_cfg->nr_of_link_frequencies) {
2815
+ if (!bus_cfg.nr_of_link_frequencies) {
28322816 dev_warn(dev, "no link frequencies defined\n");
28332817 goto out_err;
28342818 }
28352819
28362820 hwcfg->op_sys_clock = devm_kcalloc(
2837
- dev, bus_cfg->nr_of_link_frequencies + 1 /* guardian */,
2821
+ dev, bus_cfg.nr_of_link_frequencies + 1 /* guardian */,
28382822 sizeof(*hwcfg->op_sys_clock), GFP_KERNEL);
28392823 if (!hwcfg->op_sys_clock)
28402824 goto out_err;
28412825
2842
- for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) {
2843
- hwcfg->op_sys_clock[i] = bus_cfg->link_frequencies[i];
2826
+ for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
2827
+ hwcfg->op_sys_clock[i] = bus_cfg.link_frequencies[i];
28442828 dev_dbg(dev, "freq %d: %lld\n", i, hwcfg->op_sys_clock[i]);
28452829 }
28462830
2847
- v4l2_fwnode_endpoint_free(bus_cfg);
2831
+ v4l2_fwnode_endpoint_free(&bus_cfg);
28482832 fwnode_handle_put(ep);
28492833 return hwcfg;
28502834
28512835 out_err:
2852
- v4l2_fwnode_endpoint_free(bus_cfg);
2836
+ v4l2_fwnode_endpoint_free(&bus_cfg);
28532837 fwnode_handle_put(ep);
28542838 return NULL;
28552839 }
28562840
2857
-static int smiapp_probe(struct i2c_client *client,
2858
- const struct i2c_device_id *devid)
2841
+static int smiapp_probe(struct i2c_client *client)
28592842 {
28602843 struct smiapp_sensor *sensor;
28612844 struct smiapp_hwconfig *hwcfg = smiapp_get_hwconfig(&client->dev);
....@@ -2870,7 +2853,6 @@
28702853 return -ENOMEM;
28712854
28722855 sensor->hwcfg = hwcfg;
2873
- mutex_init(&sensor->mutex);
28742856 sensor->src = &sensor->ssds[sensor->ssds_used];
28752857
28762858 v4l2_i2c_subdev_init(&sensor->src->sd, client, &smiapp_ops);
....@@ -2934,13 +2916,15 @@
29342916 if (rval < 0)
29352917 return rval;
29362918
2919
+ mutex_init(&sensor->mutex);
2920
+
29372921 rval = smiapp_identify_module(sensor);
29382922 if (rval) {
29392923 rval = -ENODEV;
29402924 goto out_power_off;
29412925 }
29422926
2943
- rval = smiapp_get_all_limits(sensor);
2927
+ rval = smiapp_read_all_smia_limits(sensor);
29442928 if (rval) {
29452929 rval = -ENODEV;
29462930 goto out_power_off;
....@@ -2976,7 +2960,7 @@
29762960 goto out_power_off;
29772961 }
29782962
2979
- if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) {
2963
+ if (SMIA_LIM(sensor, BINNING_CAPABILITY)) {
29802964 u32 val;
29812965
29822966 rval = smiapp_read(sensor,
....@@ -3011,17 +2995,10 @@
30112995 rval = -ENOENT;
30122996 goto out_power_off;
30132997 }
3014
- /* SMIA++ NVM initialization - it will be read from the sensor
3015
- * when it is first requested by userspace.
3016
- */
3017
- if (sensor->minfo.smiapp_version && sensor->hwcfg->nvm_size) {
3018
- sensor->nvm = devm_kzalloc(&client->dev,
3019
- sensor->hwcfg->nvm_size, GFP_KERNEL);
3020
- if (sensor->nvm == NULL) {
3021
- rval = -ENOMEM;
3022
- goto out_cleanup;
3023
- }
30242998
2999
+ if (sensor->minfo.smiapp_version &&
3000
+ SMIA_LIM(sensor, DATA_TRANSFER_IF_CAPABILITY) &
3001
+ SMIAPP_DATA_TRANSFER_IF_CAPABILITY_SUPPORTED) {
30253002 if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {
30263003 dev_err(&client->dev, "sysfs nvm entry failed\n");
30273004 rval = -EBUSY;
....@@ -3030,21 +3007,21 @@
30303007 }
30313008
30323009 /* We consider this as profile 0 sensor if any of these are zero. */
3033
- if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
3034
- !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
3035
- !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] ||
3036
- !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) {
3010
+ if (!SMIA_LIM(sensor, MIN_OP_SYS_CLK_DIV) ||
3011
+ !SMIA_LIM(sensor, MAX_OP_SYS_CLK_DIV) ||
3012
+ !SMIA_LIM(sensor, MIN_OP_PIX_CLK_DIV) ||
3013
+ !SMIA_LIM(sensor, MAX_OP_PIX_CLK_DIV)) {
30373014 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0;
3038
- } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
3015
+ } else if (SMIA_LIM(sensor, SCALING_CAPABILITY)
30393016 != SMIAPP_SCALING_CAPABILITY_NONE) {
3040
- if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
3017
+ if (SMIA_LIM(sensor, SCALING_CAPABILITY)
30413018 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
30423019 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1;
30433020 else
30443021 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2;
30453022 sensor->scaler = &sensor->ssds[sensor->ssds_used];
30463023 sensor->ssds_used++;
3047
- } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
3024
+ } else if (SMIA_LIM(sensor, DIGITAL_CROP_CAPABILITY)
30483025 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
30493026 sensor->scaler = &sensor->ssds[sensor->ssds_used];
30503027 sensor->ssds_used++;
....@@ -3054,20 +3031,20 @@
30543031 sensor->pixel_array = &sensor->ssds[sensor->ssds_used];
30553032 sensor->ssds_used++;
30563033
3057
- sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
3034
+ sensor->scale_m = SMIA_LIM(sensor, SCALER_N_MIN);
30583035
30593036 /* prepare PLL configuration input values */
30603037 sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
30613038 sensor->pll.csi2.lanes = sensor->hwcfg->lanes;
30623039 sensor->pll.ext_clk_freq_hz = sensor->hwcfg->ext_clk;
3063
- sensor->pll.scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
3040
+ sensor->pll.scale_n = SMIA_LIM(sensor, SCALER_N_MIN);
30643041 /* Profile 0 sensors have no separate OP clock branch. */
30653042 if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
30663043 sensor->pll.flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
30673044
3068
- smiapp_create_subdev(sensor, sensor->scaler, "scaler", 2);
3069
- smiapp_create_subdev(sensor, sensor->binner, "binner", 2);
3070
- smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array", 1);
3045
+ smiapp_create_subdev(sensor, sensor->scaler, " scaler", 2);
3046
+ smiapp_create_subdev(sensor, sensor->binner, " binner", 2);
3047
+ smiapp_create_subdev(sensor, sensor->pixel_array, " pixel_array", 1);
30713048
30723049 dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
30733050
....@@ -3094,7 +3071,7 @@
30943071 }
30953072
30963073 mutex_lock(&sensor->mutex);
3097
- rval = smiapp_update_mode(sensor);
3074
+ rval = smiapp_pll_blanking_update(sensor);
30983075 mutex_unlock(&sensor->mutex);
30993076 if (rval) {
31003077 dev_err(&client->dev, "update mode failed\n");
....@@ -3124,6 +3101,7 @@
31243101 return 0;
31253102
31263103 out_disable_runtime_pm:
3104
+ pm_runtime_put_noidle(&client->dev);
31273105 pm_runtime_disable(&client->dev);
31283106
31293107 out_media_entity_cleanup:
....@@ -3134,6 +3112,7 @@
31343112
31353113 out_power_off:
31363114 smiapp_power_off(&client->dev);
3115
+ mutex_destroy(&sensor->mutex);
31373116
31383117 return rval;
31393118 }
....@@ -3156,6 +3135,7 @@
31563135 media_entity_cleanup(&sensor->ssds[i].sd.entity);
31573136 }
31583137 smiapp_cleanup(sensor);
3138
+ mutex_destroy(&sensor->mutex);
31593139
31603140 return 0;
31613141 }
....@@ -3183,7 +3163,7 @@
31833163 .name = SMIAPP_NAME,
31843164 .pm = &smiapp_pm_ops,
31853165 },
3186
- .probe = smiapp_probe,
3166
+ .probe_new = smiapp_probe,
31873167 .remove = smiapp_remove,
31883168 .id_table = smiapp_id_table,
31893169 };