Skip to content

Commit 843f37f

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 4d5fea8 commit 843f37f

File tree

1 file changed

+39
-48
lines changed

1 file changed

+39
-48
lines changed

drivers/media/i2c/imx415.c

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

31+
#define IMX415_PIXEL_RATE_74_25MHZ 891000000
32+
#define IMX415_PIXEL_RATE_72MHZ 864000000
33+
3134
#define IMX415_NUM_CLK_PARAM_REGS 11
3235

3336
#define IMX415_MODE CCI_REG8(0x3000)
@@ -54,6 +57,8 @@
5457
#define IMX415_VMAX CCI_REG24_LE(0x3024)
5558
#define IMX415_VMAX_MAX 0xfffff
5659
#define IMX415_HMAX CCI_REG16_LE(0x3028)
60+
#define IMX415_HMAX_MAX 0xffff
61+
#define IMX415_HMAX_MULTIPLIER 12
5762
#define IMX415_SHR0 CCI_REG24_LE(0x3050)
5863
#define IMX415_GAIN_PCG_0 CCI_REG16_LE(0x3090)
5964
#define IMX415_AGAIN_MIN 0
@@ -449,7 +454,6 @@ static const struct imx415_clk_params imx415_clk_params[] = {
449454

450455
/* all-pixel 2-lane 720 Mbps 15.74 Hz mode */
451456
static const struct cci_reg_sequence imx415_mode_2_720[] = {
452-
{ IMX415_HMAX, 0x07F0 },
453457
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
454458
{ IMX415_TCLKPOST, 0x006F },
455459
{ IMX415_TCLKPREPARE, 0x002F },
@@ -464,7 +468,6 @@ static const struct cci_reg_sequence imx415_mode_2_720[] = {
464468

465469
/* all-pixel 2-lane 1440 Mbps 30.01 Hz mode */
466470
static const struct cci_reg_sequence imx415_mode_2_1440[] = {
467-
{ IMX415_HMAX, 0x042A },
468471
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
469472
{ IMX415_TCLKPOST, 0x009F },
470473
{ IMX415_TCLKPREPARE, 0x0057 },
@@ -479,7 +482,6 @@ static const struct cci_reg_sequence imx415_mode_2_1440[] = {
479482

480483
/* all-pixel 4-lane 891 Mbps 30 Hz mode */
481484
static const struct cci_reg_sequence imx415_mode_4_891[] = {
482-
{ IMX415_HMAX, 0x044C },
483485
{ IMX415_LANEMODE, IMX415_LANEMODE_4 },
484486
{ IMX415_TCLKPOST, 0x007F },
485487
{ IMX415_TCLKPREPARE, 0x0037 },
@@ -497,39 +499,10 @@ struct imx415_mode_reg_list {
497499
const struct cci_reg_sequence *regs;
498500
};
499501

500-
/*
501-
* Mode : number of lanes, lane rate and frame rate dependent settings
502-
*
503-
* pixel_rate and hmax_pix are needed to calculate hblank for the v4l2 ctrl
504-
* interface. These values can not be found in the data sheet and should be
505-
* treated as virtual values. Use following table when adding new modes.
506-
*
507-
* lane_rate lanes fps hmax_pix pixel_rate
508-
*
509-
* 594 2 10.000 4400 99000000
510-
* 891 2 15.000 4400 148500000
511-
* 720 2 15.748 4064 144000000
512-
* 1782 2 30.000 4400 297000000
513-
* 2079 2 30.000 4400 297000000
514-
* 1440 2 30.019 4510 304615385
515-
*
516-
* 594 4 20.000 5500 247500000
517-
* 594 4 25.000 4400 247500000
518-
* 720 4 25.000 4400 247500000
519-
* 720 4 30.019 4510 304615385
520-
* 891 4 30.000 4400 297000000
521-
* 1440 4 30.019 4510 304615385
522-
* 1440 4 60.038 4510 609230769
523-
* 1485 4 60.000 4400 594000000
524-
* 1782 4 60.000 4400 594000000
525-
* 2079 4 60.000 4400 594000000
526-
* 2376 4 90.164 4392 891000000
527-
*/
528502
struct imx415_mode {
529503
u64 lane_rate;
530504
u32 lanes;
531-
u32 hmax_pix;
532-
u64 pixel_rate;
505+
u32 hmax_min;
533506
struct imx415_mode_reg_list reg_list;
534507
};
535508

@@ -538,8 +511,7 @@ static const struct imx415_mode supported_modes[] = {
538511
{
539512
.lane_rate = 720000000,
540513
.lanes = 2,
541-
.hmax_pix = 4064,
542-
.pixel_rate = 144000000,
514+
.hmax_min = 2032,
543515
.reg_list = {
544516
.num_of_regs = ARRAY_SIZE(imx415_mode_2_720),
545517
.regs = imx415_mode_2_720,
@@ -548,8 +520,7 @@ static const struct imx415_mode supported_modes[] = {
548520
{
549521
.lane_rate = 1440000000,
550522
.lanes = 2,
551-
.hmax_pix = 4510,
552-
.pixel_rate = 304615385,
523+
.hmax_min = 1066,
553524
.reg_list = {
554525
.num_of_regs = ARRAY_SIZE(imx415_mode_2_1440),
555526
.regs = imx415_mode_2_1440,
@@ -558,8 +529,7 @@ static const struct imx415_mode supported_modes[] = {
558529
{
559530
.lane_rate = 891000000,
560531
.lanes = 4,
561-
.hmax_pix = 4400,
562-
.pixel_rate = 297000000,
532+
.hmax_min = 1100,
563533
.reg_list = {
564534
.num_of_regs = ARRAY_SIZE(imx415_mode_4_891),
565535
.regs = imx415_mode_4_891,
@@ -586,6 +556,7 @@ static const char *const imx415_test_pattern_menu[] = {
586556
struct imx415 {
587557
struct device *dev;
588558
struct clk *clk;
559+
unsigned long pixel_rate;
589560
struct regulator_bulk_data supplies[ARRAY_SIZE(imx415_supply_names)];
590561
struct gpio_desc *reset;
591562
struct regmap *regmap;
@@ -597,6 +568,7 @@ struct imx415 {
597568

598569
struct v4l2_ctrl_handler ctrls;
599570
struct v4l2_ctrl *vblank;
571+
struct v4l2_ctrl *hblank;
600572
struct v4l2_ctrl *hflip;
601573
struct v4l2_ctrl *vflip;
602574
struct v4l2_ctrl *exposure;
@@ -786,6 +758,12 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl)
786758
ret = imx415_set_testpattern(sensor, ctrl->val);
787759
break;
788760

761+
case V4L2_CID_HBLANK:
762+
return cci_write(sensor->regmap, IMX415_HMAX,
763+
(format->width + ctrl->val) /
764+
IMX415_HMAX_MULTIPLIER,
765+
NULL);
766+
789767
default:
790768
ret = -EINVAL;
791769
break;
@@ -804,12 +782,11 @@ static int imx415_ctrls_init(struct imx415 *sensor)
804782
{
805783
struct v4l2_fwnode_device_properties props;
806784
struct v4l2_ctrl *ctrl;
807-
u64 pixel_rate = supported_modes[sensor->cur_mode].pixel_rate;
808785
u64 lane_rate = supported_modes[sensor->cur_mode].lane_rate;
809786
u32 exposure_max = IMX415_PIXEL_ARRAY_HEIGHT +
810787
IMX415_PIXEL_ARRAY_VBLANK -
811788
IMX415_EXPOSURE_OFFSET;
812-
u32 hblank;
789+
u32 hblank_min, hblank_max;
813790
unsigned int i;
814791
int ret;
815792

@@ -846,21 +823,24 @@ static int imx415_ctrls_init(struct imx415 *sensor)
846823
IMX415_AGAIN_MAX, IMX415_AGAIN_STEP,
847824
IMX415_AGAIN_MIN);
848825

849-
hblank = supported_modes[sensor->cur_mode].hmax_pix -
850-
IMX415_PIXEL_ARRAY_WIDTH;
826+
hblank_min = (supported_modes[sensor->cur_mode].hmax_min *
827+
IMX415_HMAX_MULTIPLIER) - IMX415_PIXEL_ARRAY_WIDTH;
828+
hblank_max = (IMX415_HMAX_MAX * IMX415_HMAX_MULTIPLIER) -
829+
IMX415_PIXEL_ARRAY_WIDTH;
851830
ctrl = v4l2_ctrl_new_std(&sensor->ctrls, &imx415_ctrl_ops,
852-
V4L2_CID_HBLANK, hblank, hblank, 1, hblank);
853-
if (ctrl)
854-
ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
831+
V4L2_CID_HBLANK, hblank_min,
832+
hblank_max, IMX415_HMAX_MULTIPLIER,
833+
hblank_min);
855834

856835
sensor->vblank = v4l2_ctrl_new_std(&sensor->ctrls, &imx415_ctrl_ops,
857836
V4L2_CID_VBLANK,
858837
IMX415_PIXEL_ARRAY_VBLANK,
859838
IMX415_VMAX_MAX - IMX415_PIXEL_ARRAY_HEIGHT,
860839
1, IMX415_PIXEL_ARRAY_VBLANK);
861840

862-
v4l2_ctrl_new_std(&sensor->ctrls, NULL, V4L2_CID_PIXEL_RATE, pixel_rate,
863-
pixel_rate, 1, pixel_rate);
841+
v4l2_ctrl_new_std(&sensor->ctrls, NULL, V4L2_CID_PIXEL_RATE,
842+
sensor->pixel_rate, sensor->pixel_rate, 1,
843+
sensor->pixel_rate);
864844

865845
sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls, &imx415_ctrl_ops,
866846
V4L2_CID_HFLIP, 0, 1, 1, 0);
@@ -1333,6 +1313,17 @@ static int imx415_parse_hw_config(struct imx415 *sensor)
13331313
"no valid sensor mode defined\n");
13341314
goto done_endpoint_free;
13351315
}
1316+
switch (inck) {
1317+
case 27000000:
1318+
case 37125000:
1319+
case 74250000:
1320+
sensor->pixel_rate = IMX415_PIXEL_RATE_74_25MHZ;
1321+
break;
1322+
case 24000000:
1323+
case 72000000:
1324+
sensor->pixel_rate = IMX415_PIXEL_RATE_72MHZ;
1325+
break;
1326+
}
13361327

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

0 commit comments

Comments
 (0)