Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: ar0521: Adjust exposure and blankings limits

Adjust the control limits for V4L2_CID_VBLANK, V4L2_CID_HBLANK and
V4L2_CID_EXPOSURE when a new format is applied to the sensor.

Update the exposure control limits when a new blanking value is
applied and change the controls initialization to use valid values for the
default format.

The exposure control default value is changed to report the default
value of register 0x3012.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Jacopo Mondi and committed by
Mauro Carvalho Chehab
64114626 f9746da3

+68 -16
+68 -16
drivers/media/i2c/ar0521.c
··· 40 40 41 41 #define AR0521_WIDTH_BLANKING_MIN 572u 42 42 #define AR0521_HEIGHT_BLANKING_MIN 38u /* must be even */ 43 - #define AR0521_TOTAL_WIDTH_MIN 2968u 43 + #define AR0521_TOTAL_HEIGHT_MAX 65535u /* max_frame_length_lines */ 44 + #define AR0521_TOTAL_WIDTH_MAX 65532u /* max_line_length_pck */ 44 45 45 46 #define AR0521_ANA_GAIN_MIN 0x00 46 47 #define AR0521_ANA_GAIN_MAX 0x3f ··· 126 125 struct v4l2_mbus_framefmt fmt; 127 126 struct ar0521_ctrls ctrls; 128 127 unsigned int lane_count; 129 - u16 total_width; 130 - u16 total_height; 131 128 struct { 132 129 u16 pre; 133 130 u16 mult; ··· 482 483 struct v4l2_subdev_format *format) 483 484 { 484 485 struct ar0521_dev *sensor = to_ar0521_dev(sd); 486 + int max_vblank, max_hblank, exposure_max; 487 + int ret; 485 488 486 489 ar0521_adj_fmt(&format->format); 487 490 ··· 494 493 495 494 fmt = v4l2_subdev_get_try_format(sd, sd_state, 0 /* pad */); 496 495 *fmt = format->format; 497 - } else { 498 - sensor->fmt = format->format; 499 - ar0521_calc_mode(sensor); 496 + 497 + mutex_unlock(&sensor->lock); 498 + 499 + return 0; 500 500 } 501 501 502 + sensor->fmt = format->format; 503 + ar0521_calc_mode(sensor); 504 + 505 + /* 506 + * Update the exposure and blankings limits. Blankings are also reset 507 + * to the minimum. 508 + */ 509 + max_hblank = AR0521_TOTAL_WIDTH_MAX - sensor->fmt.width; 510 + ret = __v4l2_ctrl_modify_range(sensor->ctrls.hblank, 511 + sensor->ctrls.hblank->minimum, 512 + max_hblank, sensor->ctrls.hblank->step, 513 + sensor->ctrls.hblank->minimum); 514 + if (ret) 515 + goto unlock; 516 + 517 + ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.hblank, 518 + sensor->ctrls.hblank->minimum); 519 + if (ret) 520 + goto unlock; 521 + 522 + max_vblank = AR0521_TOTAL_HEIGHT_MAX - sensor->fmt.height; 523 + ret = __v4l2_ctrl_modify_range(sensor->ctrls.vblank, 524 + sensor->ctrls.vblank->minimum, 525 + max_vblank, sensor->ctrls.vblank->step, 526 + sensor->ctrls.vblank->minimum); 527 + if (ret) 528 + goto unlock; 529 + 530 + ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, 531 + sensor->ctrls.vblank->minimum); 532 + if (ret) 533 + goto unlock; 534 + 535 + exposure_max = sensor->fmt.height + AR0521_HEIGHT_BLANKING_MIN - 4; 536 + ret = __v4l2_ctrl_modify_range(sensor->ctrls.exposure, 537 + sensor->ctrls.exposure->minimum, 538 + exposure_max, 539 + sensor->ctrls.exposure->step, 540 + sensor->ctrls.exposure->default_value); 541 + unlock: 502 542 mutex_unlock(&sensor->lock); 503 - return 0; 543 + 544 + return ret; 504 545 } 505 546 506 547 static int ar0521_s_ctrl(struct v4l2_ctrl *ctrl) 507 548 { 508 549 struct v4l2_subdev *sd = ctrl_to_sd(ctrl); 509 550 struct ar0521_dev *sensor = to_ar0521_dev(sd); 551 + int exp_max; 510 552 int ret; 511 553 512 554 /* v4l2_ctrl_lock() locks our own mutex */ 513 555 514 556 switch (ctrl->id) { 515 - case V4L2_CID_HBLANK: 516 557 case V4L2_CID_VBLANK: 517 - sensor->total_width = sensor->fmt.width + 518 - sensor->ctrls.hblank->val; 519 - sensor->total_height = sensor->fmt.width + 520 - sensor->ctrls.vblank->val; 558 + exp_max = sensor->fmt.height + ctrl->val - 4; 559 + __v4l2_ctrl_modify_range(sensor->ctrls.exposure, 560 + sensor->ctrls.exposure->minimum, 561 + exp_max, sensor->ctrls.exposure->step, 562 + sensor->ctrls.exposure->default_value); 521 563 break; 522 564 } 523 565 ··· 618 574 const struct v4l2_ctrl_ops *ops = &ar0521_ctrl_ops; 619 575 struct ar0521_ctrls *ctrls = &sensor->ctrls; 620 576 struct v4l2_ctrl_handler *hdl = &ctrls->handler; 577 + int max_vblank, max_hblank, exposure_max; 621 578 struct v4l2_ctrl *link_freq; 622 579 int ret; 623 580 ··· 640 595 -512, 511, 1, 0); 641 596 v4l2_ctrl_cluster(3, &ctrls->gain); 642 597 598 + /* Initialize blanking limits using the default 2592x1944 format. */ 599 + max_hblank = AR0521_TOTAL_WIDTH_MAX - AR0521_WIDTH_MAX; 643 600 ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, 644 - AR0521_WIDTH_BLANKING_MIN, 4094, 1, 601 + AR0521_WIDTH_BLANKING_MIN, 602 + max_hblank, 1, 645 603 AR0521_WIDTH_BLANKING_MIN); 604 + 605 + max_vblank = AR0521_TOTAL_HEIGHT_MAX - AR0521_HEIGHT_MAX; 646 606 ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, 647 - AR0521_HEIGHT_BLANKING_MIN, 4094, 2, 607 + AR0521_HEIGHT_BLANKING_MIN, 608 + max_vblank, 2, 648 609 AR0521_HEIGHT_BLANKING_MIN); 649 610 v4l2_ctrl_cluster(2, &ctrls->hblank); 650 611 ··· 660 609 AR0521_PIXEL_CLOCK_MAX, 1, 661 610 AR0521_PIXEL_CLOCK_RATE); 662 611 663 - /* Manual exposure time */ 612 + /* Manual exposure time: max exposure time = visible + blank - 4 */ 613 + exposure_max = AR0521_HEIGHT_MAX + AR0521_HEIGHT_BLANKING_MIN - 4; 664 614 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, 665 - 65535, 1, 360); 615 + exposure_max, 1, 0x70); 666 616 667 617 link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ, 668 618 ARRAY_SIZE(ar0521_link_frequencies) - 1,