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: atomisp: Implement link_setup() op for ISP subdev MC entity

The atomisp driver's Android heritage makes it weird in that
even though it uses MC + subdev-s it is designed to primarily
be controlled through its /dev/video# node.

It implements s_input() on /dev/video# to select which sensor to use,
while ignoring link_setup() calls to enable a link to another sensor.

Add support for selecting the active sensor the MC way by adding
link_setup() support.

The implementation is a bit convoluted due to the atomisp driver's
heritage.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Hans de Goede and committed by
Mauro Carvalho Chehab
71b3ed53 185883b2

+52
+52
drivers/staging/media/atomisp/pci/atomisp_subdev.c
··· 31 31 #include "atomisp_compat.h" 32 32 #include "atomisp_fops.h" 33 33 #include "atomisp_internal.h" 34 + #include "atomisp_ioctl.h" 34 35 35 36 const struct atomisp_in_fmt_conv atomisp_in_fmt_conv[] = { 36 37 { MEDIA_BUS_FMT_SBGGR8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, IA_CSS_BAYER_ORDER_BGGR }, ··· 635 634 } 636 635 637 636 /* media operations */ 637 + static int atomisp_link_setup(struct media_entity *entity, 638 + const struct media_pad *local, 639 + const struct media_pad *remote, u32 flags) 640 + { 641 + struct v4l2_subdev *sd = container_of(entity, struct v4l2_subdev, 642 + entity); 643 + struct atomisp_sub_device *asd = v4l2_get_subdevdata(sd); 644 + struct atomisp_device *isp = asd->isp; 645 + int i, csi_idx, ret; 646 + 647 + /* ISP's source is immutable */ 648 + if (local != &asd->pads[ATOMISP_SUBDEV_PAD_SINK]) { 649 + v4l2_err(sd, "Error pad %d does not support changing flags\n", 650 + local->index); 651 + return -EINVAL; 652 + } 653 + 654 + for (csi_idx = 0; csi_idx < ATOMISP_CAMERA_NR_PORTS; csi_idx++) { 655 + if (&isp->csi2_port[csi_idx].pads[CSI2_PAD_SOURCE] == remote) 656 + break; 657 + } 658 + 659 + if (csi_idx == ATOMISP_CAMERA_NR_PORTS) { 660 + v4l2_err(sd, "Error cannot find CSI receiver for remote pad\n"); 661 + return -EINVAL; 662 + } 663 + 664 + /* Ignore disables, input_curr should only be updated on enables */ 665 + if (!(flags & MEDIA_LNK_FL_ENABLED)) 666 + return 0; 667 + 668 + for (i = 0; i < isp->input_cnt; i++) { 669 + if (isp->inputs[i].camera == isp->sensor_subdevs[csi_idx]) 670 + break; 671 + } 672 + 673 + if (i == isp->input_cnt) { 674 + v4l2_err(sd, "Error no sensor for CSI receiver %d\n", csi_idx); 675 + return -EINVAL; 676 + } 677 + 678 + mutex_lock(&isp->mutex); 679 + ret = atomisp_pipe_check(&asd->video_out, true); 680 + if (ret == 0) 681 + asd->input_curr = i; 682 + mutex_unlock(&isp->mutex); 683 + 684 + return ret; 685 + } 686 + 638 687 static const struct media_entity_operations isp_subdev_media_ops = { 639 688 .link_validate = v4l2_subdev_link_validate, 689 + .link_setup = atomisp_link_setup, 640 690 /* .set_power = v4l2_subdev_set_power, */ 641 691 }; 642 692