Skip to content

Commit 6722e13

Browse files
6by9pelwell
authored andcommitted
media: i2c: imx415: Make HBLANK controllable and in consistent units
The control of HMAX documented in the datasheet is consistent with being in terms of a scaled INCK, being always 72MHz or 74.25MHz. It is NOT link frequency dependent, but the minimum value for HMAX is dictated by the link frequency. If PIXEL_RATE is defined as being 12 times the 72 or 74.25MHz, and all values are scaled down again when writing HMAX, then the numbers all work out regardless of INCK or link frequency. Retain an hmax_min (set to the same value as the previous fixed hmax register value) to set as the default value to avoid changing the behaviour for existing users. Signed-off-by: Dave Stevenson <[email protected]>
1 parent 4e8d73c commit 6722e13

File tree

1 file changed

+38
-48
lines changed

1 file changed

+38
-48
lines changed

drivers/media/i2c/imx415.c

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#define IMX415_PIXEL_ARRAY_VBLANK 58
2828
#define IMX415_EXPOSURE_OFFSET 8
2929

30+
#define IMX415_PIXEL_RATE_74_25MHZ 891000000
31+
#define IMX415_PIXEL_RATE_72MHZ 864000000
32+
3033
#define IMX415_NUM_CLK_PARAM_REGS 11
3134

3235
#define IMX415_REG_8BIT(n) ((1 << 16) | (n))
@@ -59,6 +62,8 @@
5962
#define IMX415_VMAX IMX415_REG_24BIT(0x3024)
6063
#define IMX415_VMAX_MAX 0xfffff
6164
#define IMX415_HMAX IMX415_REG_16BIT(0x3028)
65+
#define IMX415_HMAX_MAX 0xffff
66+
#define IMX415_HMAX_MULTIPLIER 12
6267
#define IMX415_SHR0 IMX415_REG_24BIT(0x3050)
6368
#define IMX415_GAIN_PCG_0 IMX415_REG_16BIT(0x3090)
6469
#define IMX415_AGAIN_MIN 0
@@ -459,7 +464,6 @@ static const struct imx415_clk_params imx415_clk_params[] = {
459464

460465
/* all-pixel 2-lane 720 Mbps 15.74 Hz mode */
461466
static const struct imx415_reg imx415_mode_2_720[] = {
462-
{ IMX415_HMAX, 0x07F0 },
463467
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
464468
{ IMX415_TCLKPOST, 0x006F },
465469
{ IMX415_TCLKPREPARE, 0x002F },
@@ -474,7 +478,6 @@ static const struct imx415_reg imx415_mode_2_720[] = {
474478

475479
/* all-pixel 2-lane 1440 Mbps 30.01 Hz mode */
476480
static const struct imx415_reg imx415_mode_2_1440[] = {
477-
{ IMX415_HMAX, 0x042A },
478481
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
479482
{ IMX415_TCLKPOST, 0x009F },
480483
{ IMX415_TCLKPREPARE, 0x0057 },
@@ -489,7 +492,6 @@ static const struct imx415_reg imx415_mode_2_1440[] = {
489492

490493
/* all-pixel 4-lane 891 Mbps 30 Hz mode */
491494
static const struct imx415_reg imx415_mode_4_891[] = {
492-
{ IMX415_HMAX, 0x044C },
493495
{ IMX415_LANEMODE, IMX415_LANEMODE_4 },
494496
{ IMX415_TCLKPOST, 0x007F },
495497
{ IMX415_TCLKPREPARE, 0x0037 },
@@ -507,39 +509,10 @@ struct imx415_mode_reg_list {
507509
const struct imx415_reg *regs;
508510
};
509511

510-
/*
511-
* Mode : number of lanes, lane rate and frame rate dependent settings
512-
*
513-
* pixel_rate and hmax_pix are needed to calculate hblank for the v4l2 ctrl
514-
* interface. These values can not be found in the data sheet and should be
515-
* treated as virtual values. Use following table when adding new modes.
516-
*
517-
* lane_rate lanes fps hmax_pix pixel_rate
518-
*
519-
* 594 2 10.000 4400 99000000
520-
* 891 2 15.000 4400 148500000
521-
* 720 2 15.748 4064 144000000
522-
* 1782 2 30.000 4400 297000000
523-
* 2079 2 30.000 4400 297000000
524-
* 1440 2 30.019 4510 304615385
525-
*
526-
* 594 4 20.000 5500 247500000
527-
* 594 4 25.000 4400 247500000
528-
* 720 4 25.000 4400 247500000
529-
* 720 4 30.019 4510 304615385
530-
* 891 4 30.000 4400 297000000
531-
* 1440 4 30.019 4510 304615385
532-
* 1440 4 60.038 4510 609230769
533-
* 1485 4 60.000 4400 594000000
534-
* 1782 4 60.000 4400 594000000
535-
* 2079 4 60.000 4400 594000000
536-
* 2376 4 90.164 4392 891000000
537-
*/
538512
struct imx415_mode {
539513
u64 lane_rate;
540514
u32 lanes;
541-
u32 hmax_pix;
542-
u64 pixel_rate;
515+
u32 hmax_min;
543516
struct imx415_mode_reg_list reg_list;
544517
};
545518

@@ -548,8 +521,7 @@ static const struct imx415_mode supported_modes[] = {
548521
{
549522
.lane_rate = 720000000,
550523
.lanes = 2,
551-
.hmax_pix = 4064,
552-
.pixel_rate = 144000000,
524+
.hmax_min = 2032,
553525
.reg_list = {
554526
.num_of_regs = ARRAY_SIZE(imx415_mode_2_720),
555527
.regs = imx415_mode_2_720,
@@ -558,8 +530,7 @@ static const struct imx415_mode supported_modes[] = {
558530
{
559531
.lane_rate = 1440000000,
560532
.lanes = 2,
561-
.hmax_pix = 4510,
562-
.pixel_rate = 304615385,
533+
.hmax_min = 1066,
563534
.reg_list = {
564535
.num_of_regs = ARRAY_SIZE(imx415_mode_2_1440),
565536
.regs = imx415_mode_2_1440,
@@ -568,8 +539,7 @@ static const struct imx415_mode supported_modes[] = {
568539
{
569540
.lane_rate = 891000000,
570541
.lanes = 4,
571-
.hmax_pix = 4400,
572-
.pixel_rate = 297000000,
542+
.hmax_min = 1100,
573543
.reg_list = {
574544
.num_of_regs = ARRAY_SIZE(imx415_mode_4_891),
575545
.regs = imx415_mode_4_891,
@@ -601,6 +571,7 @@ static const char *const imx415_test_pattern_menu[] = {
601571
struct imx415 {
602572
struct device *dev;
603573
struct clk *clk;
574+
unsigned long pixel_rate;
604575
struct regulator_bulk_data supplies[ARRAY_SIZE(imx415_supply_names)];
605576
struct gpio_desc *reset;
606577
struct regmap *regmap;
@@ -614,6 +585,7 @@ struct imx415 {
614585

615586
struct v4l2_ctrl_handler ctrls;
616587
struct v4l2_ctrl *vblank;
588+
struct v4l2_ctrl *hblank;
617589
struct v4l2_ctrl *hflip;
618590
struct v4l2_ctrl *vflip;
619591
struct v4l2_ctrl *exposure;
@@ -845,6 +817,11 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl)
845817
case V4L2_CID_TEST_PATTERN:
846818
return imx415_set_testpattern(sensor, ctrl->val);
847819

820+
case V4L2_CID_HBLANK:
821+
return imx415_write(sensor, IMX415_HMAX,
822+
(format->width + ctrl->val) /
823+
IMX415_HMAX_MULTIPLIER);
824+
848825
default:
849826
return -EINVAL;
850827
}
@@ -858,12 +835,11 @@ static int imx415_ctrls_init(struct imx415 *sensor)
858835
{
859836
struct v4l2_fwnode_device_properties props;
860837
struct v4l2_ctrl *ctrl;
861-
u64 pixel_rate = supported_modes[sensor->cur_mode].pixel_rate;
862838
u64 lane_rate = supported_modes[sensor->cur_mode].lane_rate;
863839
u32 exposure_max = IMX415_PIXEL_ARRAY_HEIGHT +
864840
IMX415_PIXEL_ARRAY_VBLANK -
865841
IMX415_EXPOSURE_OFFSET;
866-
u32 hblank;
842+
u32 hblank_min, hblank_max;
867843
unsigned int i;
868844
int ret;
869845

@@ -900,21 +876,24 @@ static int imx415_ctrls_init(struct imx415 *sensor)
900876
IMX415_AGAIN_MAX, IMX415_AGAIN_STEP,
901877
IMX415_AGAIN_MIN);
902878

903-
hblank = supported_modes[sensor->cur_mode].hmax_pix -
904-
IMX415_PIXEL_ARRAY_WIDTH;
879+
hblank_min = (supported_modes[sensor->cur_mode].hmax_min *
880+
IMX415_HMAX_MULTIPLIER) - IMX415_PIXEL_ARRAY_WIDTH;
881+
hblank_max = (IMX415_HMAX_MAX * IMX415_HMAX_MULTIPLIER) -
882+
IMX415_PIXEL_ARRAY_WIDTH;
905883
ctrl = v4l2_ctrl_new_std(&sensor->ctrls, &imx415_ctrl_ops,
906-
V4L2_CID_HBLANK, hblank, hblank, 1, hblank);
907-
if (ctrl)
908-
ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
884+
V4L2_CID_HBLANK, hblank_min,
885+
hblank_max, IMX415_HMAX_MULTIPLIER,
886+
hblank_min);
909887

910888
sensor->vblank = v4l2_ctrl_new_std(&sensor->ctrls, &imx415_ctrl_ops,
911889
V4L2_CID_VBLANK,
912890
IMX415_PIXEL_ARRAY_VBLANK,
913891
IMX415_VMAX_MAX - IMX415_PIXEL_ARRAY_HEIGHT,
914892
1, IMX415_PIXEL_ARRAY_VBLANK);
915893

916-
v4l2_ctrl_new_std(&sensor->ctrls, NULL, V4L2_CID_PIXEL_RATE, pixel_rate,
917-
pixel_rate, 1, pixel_rate);
894+
v4l2_ctrl_new_std(&sensor->ctrls, NULL, V4L2_CID_PIXEL_RATE,
895+
sensor->pixel_rate, sensor->pixel_rate, 1,
896+
sensor->pixel_rate);
918897

919898
sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls, &imx415_ctrl_ops,
920899
V4L2_CID_HFLIP, 0, 1, 1, 0);
@@ -1410,6 +1389,17 @@ static int imx415_parse_hw_config(struct imx415 *sensor)
14101389
"no valid sensor mode defined\n");
14111390
goto done_endpoint_free;
14121391
}
1392+
switch (inck) {
1393+
case 27000000:
1394+
case 37125000:
1395+
case 74250000:
1396+
sensor->pixel_rate = IMX415_PIXEL_RATE_74_25MHZ;
1397+
break;
1398+
case 24000000:
1399+
case 72000000:
1400+
sensor->pixel_rate = IMX415_PIXEL_RATE_72MHZ;
1401+
break;
1402+
}
14131403

14141404
lane_rate = supported_modes[sensor->cur_mode].lane_rate;
14151405
for (i = 0; i < ARRAY_SIZE(imx415_clk_params); ++i) {

0 commit comments

Comments
 (0)