Re: [PATCH v2 33/34] staging: bcm2835-isp: Add support for BC2835 ISP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 19/05/2020 14:47, Naushir Patuck wrote:
> Hi Hans,
> 
> Thank you for the review and comments.  Just a follow up and
> overlapping Dave's comments:
> 
> On Mon, 18 May 2020 at 13:02, Hans Verkuil <hverkuil@xxxxxxxxx> wrote:
>>
>> On 04/05/2020 11:26, Laurent Pinchart wrote:
>>> From: Naushir Patuck <naush@xxxxxxxxxxxxxxx>
>>>
>>> Port the V4L2 compatible driver for the ISP unit found on Broadcom BCM2835
>>> chips.
>>>
>>> The driver interfaces though the VideoCore unit using the VCHIQ MMAL
>>> interface.
>>>
>>> ISP driver upported from from RaspberryPi BSP at revision:
>>> 6c3505be6c3e ("staging: vc04_services: isp: Make all references to bcm2835_isp_fmt const")
>>>
>>> Signed-off-by: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx>
>>> Signed-off-by: Naushir Patuck <naush@xxxxxxxxxxxxxxx>
>>> [Adapt to staging by moving all modifications that in the BSP are scattered
>>> in core components inside this directory]
>>> Signed-off-by: Jacopo Mondi <jacopo@xxxxxxxxxx>
>>> ---
>>>  .../v4l/pixfmt-meta-bcm2835-isp-stats.rst     |   41 +
>>>  drivers/staging/vc04_services/Kconfig         |    2 +
>>>  drivers/staging/vc04_services/Makefile        |    1 +
>>>  .../staging/vc04_services/bcm2835-isp/Kconfig |   14 +
>>>  .../vc04_services/bcm2835-isp/Makefile        |   10 +
>>>  .../bcm2835-isp/bcm2835-v4l2-isp.c            | 1632 +++++++++++++++++
>>>  .../bcm2835-isp/bcm2835_isp_ctrls.h           |   67 +
>>>  .../bcm2835-isp/bcm2835_isp_fmts.h            |  301 +++
>>>  .../include/uapi/linux/bcm2835-isp.h          |  333 ++++
>>>  .../staging/vc04_services/vchiq-mmal/Kconfig  |    3 +-
>>>  .../vc04_services/vchiq-mmal/mmal-encodings.h |    4 +
>>>  .../vchiq-mmal/mmal-parameters.h              |  153 +-
>>>  12 files changed, 2559 insertions(+), 2 deletions(-)
>>>  create mode 100644 drivers/staging/vc04_services/Documentation/userspace-api/media/v4l/pixfmt-meta-bcm2835-isp-stats.rst
>>>  create mode 100644 drivers/staging/vc04_services/bcm2835-isp/Kconfig
>>>  create mode 100644 drivers/staging/vc04_services/bcm2835-isp/Makefile
>>>  create mode 100644 drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
>>>  create mode 100644 drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h
>>>  create mode 100644 drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
>>>  create mode 100644 drivers/staging/vc04_services/include/uapi/linux/bcm2835-isp.h
>>>
>>
>> <snip>
>>
>>> diff --git a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
>>> new file mode 100644
>>> index 000000000000..a32faab4b8dc
>>> --- /dev/null
>>> +++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
>>> @@ -0,0 +1,1632 @@
>>

<snip>

>>
>>> +             break;
>>> +     }
>>> +
>>> +     /* We use the selection API instead of the old crop API. */
>>> +     v4l2_disable_ioctl(vfd, VIDIOC_CROPCAP);
>>> +     v4l2_disable_ioctl(vfd, VIDIOC_G_CROP);
>>> +     v4l2_disable_ioctl(vfd, VIDIOC_S_CROP);
>>
>> No need for this: the core handles this and will disable these ioctls
>> automatically.
> 
> Without these explicitally disabled, we fail v4l2-compliance on the
> video capture nodes with the following error:
> Format ioctls:
>     test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
>     test VIDIOC_G/S_PARM: OK (Not Supported)
>     test VIDIOC_G_FBUF: OK (Not Supported)
>     test VIDIOC_G_FMT: OK
>     test VIDIOC_TRY_FMT: OK
>     test VIDIOC_S_FMT: OK
>     test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
>     fail: v4l2-test-formats.cpp(1510): doioctl(node, VIDIOC_G_SELECTION, &sel)

I believe that's because G_SELECTION doesn't support the V4L2_SEL_TGT_CROP_DEFAULT
target. Once that is supported, this test should pass.

Regards,

	Hans

>     fail: v4l2-test-formats.cpp(1550): testLegacyCrop(node)
>     test Cropping: FAIL
>     test Composing: OK (Not Supported)
>     test Scaling: OK (Not Supported)
> 
>>
>>> +
>>> +     ret = bcm2835_isp_get_supported_fmts(node);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     /* Initialise the the video node. */
>>> +     vfd->vfl_type   = VFL_TYPE_VIDEO;
>>> +     vfd->fops       = &bcm2835_isp_fops,
>>> +     vfd->ioctl_ops  = &bcm2835_isp_node_ioctl_ops,
>>> +     vfd->minor      = -1,
>>> +     vfd->release    = video_device_release_empty,
>>> +     vfd->queue      = &node->queue;
>>> +     vfd->lock       = &node->lock;
>>> +     vfd->v4l2_dev   = &dev->v4l2_dev;
>>> +     vfd->vfl_dir    = node->vfl_dir;
>>> +
>>> +     node->q_data.fmt = get_default_format(node);
>>> +     node->q_data.width = DEFAULT_DIM;
>>> +     node->q_data.height = DEFAULT_DIM;
>>> +     node->q_data.bytesperline =
>>> +             get_bytesperline(DEFAULT_DIM, node->q_data.fmt);
>>> +     node->q_data.sizeimage = node_is_stats(node) ?
>>> +                              get_port_data(node)->recommended_buffer.size :
>>> +                              get_sizeimage(node->q_data.bytesperline,
>>> +                                            node->q_data.width,
>>> +                                            node->q_data.height,
>>> +                                            node->q_data.fmt);
>>> +
>>> +     queue->io_modes = VB2_MMAP | VB2_DMABUF;
>>> +     queue->drv_priv = node;
>>> +     queue->ops = &bcm2835_isp_node_queue_ops;
>>> +     queue->mem_ops = &vb2_dma_contig_memops;
>>> +     queue->buf_struct_size = sizeof(struct bcm2835_isp_buffer);
>>> +     queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
>>> +     queue->dev = dev->dev;
>>> +     queue->lock = &node->queue_lock;
>>> +
>>> +     ret = vb2_queue_init(queue);
>>> +     if (ret < 0) {
>>> +             v4l2_info(&dev->v4l2_dev, "vb2_queue_init failed\n");
>>> +             return ret;
>>> +     }
>>> +     node->queue_init = true;
>>> +
>>> +     /* Define the device names */
>>> +     snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME,
>>> +              node->name, node->id);
>>> +
>>> +     ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr + index);
>>> +     if (ret) {
>>> +             v4l2_err(&dev->v4l2_dev,
>>> +                      "Failed to register video %s[%d] device node\n",
>>> +                      node->name, node->id);
>>> +             return ret;
>>> +     }
>>
>> Move registering the video device to the end of this function.
>> Otherwise the output video device would be created (and available for
>> userspace) before the controls are added.
>>
> 
> Ack
> 
>>> +
>>> +     node->registered = true;
>>> +     video_set_drvdata(vfd, node);
>>> +
>>> +     /* Set some controls and defaults, but only on the VIDEO_OUTPUT node. */
>>> +     if (node_is_output(node)) {
>>> +             unsigned int i;
>>> +
>>> +             /* Use this ctrl template to assign all out ISP custom ctrls. */
>>> +             struct v4l2_ctrl_config ctrl_template = {
>>> +                     .ops            = &bcm2835_isp_ctrl_ops,
>>> +                     .type           = V4L2_CTRL_TYPE_U8,
>>> +                     .def            = 0,
>>> +                     .min            = 0x00,
>>> +                     .max            = 0xff,
>>> +                     .step           = 1,
>>> +             };
>>> +
>>> +             v4l2_ctrl_handler_init(&dev->ctrl_handler, 4);
>>> +
>>> +             dev->r_gain = 1000;
>>> +             dev->b_gain = 1000;
>>> +
>>> +             v4l2_ctrl_new_std(&dev->ctrl_handler,  &bcm2835_isp_ctrl_ops,
>>> +                               V4L2_CID_RED_BALANCE, 1, 0xffff, 1,
>>> +                               dev->r_gain);
>>> +
>>> +             v4l2_ctrl_new_std(&dev->ctrl_handler, &bcm2835_isp_ctrl_ops,
>>> +                               V4L2_CID_BLUE_BALANCE, 1, 0xffff, 1,
>>> +                               dev->b_gain);
>>> +
>>> +             v4l2_ctrl_new_std(&dev->ctrl_handler, &bcm2835_isp_ctrl_ops,
>>> +                               V4L2_CID_DIGITAL_GAIN, 1, 0xffff, 1, 1000);
>>> +
>>> +             for (i = 0; i < ARRAY_SIZE(custom_ctrls); i++) {
>>> +                     ctrl_template.name = custom_ctrls[i].name;
>>> +                     ctrl_template.id = custom_ctrls[i].id;
>>> +                     ctrl_template.dims[0] = custom_ctrls[i].size;
>>> +                     ctrl_template.flags = custom_ctrls[i].flags;
>>> +                     v4l2_ctrl_new_custom(&dev->ctrl_handler,
>>> +                                          &ctrl_template, NULL);
>>> +             }
>>> +
>>> +             node->vfd.ctrl_handler = &dev->ctrl_handler;
>>
>> Missing error check.
> 
> Ack
> 
>>
>>> +     }
>>> +
>>> +     v4l2_info(&dev->v4l2_dev,
>>> +               "Device node %s[%d] registered as /dev/video%d\n",
>>> +               node->name, node->id, vfd->num);
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +/* Unregister one of the /dev/video<N> nodes associated with the ISP. */
>>> +static void unregister_node(struct bcm2835_isp_node *node)
>>> +{
>>> +     struct bcm2835_isp_dev *dev = node_get_dev(node);
>>> +
>>> +     v4l2_info(&dev->v4l2_dev,
>>> +               "Unregistering node %s[%d] device node /dev/video%d\n",
>>> +               node->name, node->id, node->vfd.num);
>>> +
>>> +     if (node->queue_init)
>>> +             vb2_queue_release(&node->queue);
>>> +
>>> +     if (node->registered) {
>>> +             video_unregister_device(&node->vfd);
>>> +             if (node_is_output(node))
>>> +                     v4l2_ctrl_handler_free(&dev->ctrl_handler);
>>> +     }
>>> +
>>> +     /*
>>> +      * node->supported_fmts.list is free'd automatically
>>> +      * as a managed resource.
>>> +      */
>>> +     node->supported_fmts.list = NULL;
>>> +     node->supported_fmts.num_entries = 0;
>>> +     node->vfd.ctrl_handler = NULL;
>>> +     node->registered = false;
>>> +     node->queue_init = false;
>>> +}
>>> +
>>> +static void media_controller_unregister(struct bcm2835_isp_dev *dev)
>>> +{
>>> +     unsigned int i;
>>> +
>>> +     v4l2_info(&dev->v4l2_dev, "Unregister from media controller\n");
>>> +
>>> +     if (dev->media_device_registered) {
>>> +             media_device_unregister(&dev->mdev);
>>> +             media_device_cleanup(&dev->mdev);
>>> +             dev->media_device_registered = false;
>>> +     }
>>> +
>>> +     kfree(dev->entity.name);
>>> +     dev->entity.name = NULL;
>>> +
>>> +     if (dev->media_entity_registered) {
>>> +             media_device_unregister_entity(&dev->entity);
>>> +             dev->media_entity_registered = false;
>>> +     }
>>> +
>>> +     for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
>>> +             struct bcm2835_isp_node *node = &dev->node[i];
>>> +
>>> +             if (node->media_node_registered) {
>>> +                     media_remove_intf_links(node->intf_link->intf);
>>> +                     media_entity_remove_links(&dev->node[i].vfd.entity);
>>> +                     media_devnode_remove(node->intf_devnode);
>>> +                     media_device_unregister_entity(&node->vfd.entity);
>>> +                     kfree(node->vfd.entity.name);
>>> +             }
>>> +             node->media_node_registered = false;
>>> +     }
>>> +
>>> +     dev->v4l2_dev.mdev = NULL;
>>> +}
>>> +
>>> +static int media_controller_register_node(struct bcm2835_isp_dev *dev, int num)
>>> +{
>>> +     struct bcm2835_isp_node *node = &dev->node[num];
>>> +     struct media_entity *entity = &node->vfd.entity;
>>> +     int output = node_is_output(node);
>>> +     char *name;
>>> +     int ret;
>>> +
>>> +     v4l2_info(&dev->v4l2_dev,
>>> +               "Register %s node %d with media controller\n",
>>> +               output ? "output" : "capture", num);
>>> +     entity->obj_type = MEDIA_ENTITY_TYPE_VIDEO_DEVICE;
>>> +     entity->function = MEDIA_ENT_F_IO_V4L;
>>> +     entity->info.dev.major = VIDEO_MAJOR;
>>> +     entity->info.dev.minor = node->vfd.minor;
>>> +     name = kmalloc(BCM2835_ISP_ENTITY_NAME_LEN, GFP_KERNEL);
>>> +     if (!name) {
>>> +             ret = -ENOMEM;
>>> +             goto error_no_mem;
>>> +     }
>>> +     snprintf(name, BCM2835_ISP_ENTITY_NAME_LEN, "%s0-%s%d",
>>> +              BCM2835_ISP_NAME, output ? "output" : "capture", num);
>>> +     entity->name = name;
>>> +     node->pad.flags = output ? MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
>>> +     ret = media_entity_pads_init(entity, 1, &node->pad);
>>> +     if (ret)
>>> +             goto error_pads_init;
>>> +     ret = media_device_register_entity(&dev->mdev, entity);
>>> +     if (ret)
>>> +             goto error_register_entity;
>>> +
>>> +     node->intf_devnode = media_devnode_create(&dev->mdev,
>>> +                                               MEDIA_INTF_T_V4L_VIDEO, 0,
>>> +                                               VIDEO_MAJOR, node->vfd.minor);
>>> +     if (!node->intf_devnode) {
>>> +             ret = -ENOMEM;
>>> +             goto error_devnode_create;
>>> +     }
>>> +
>>> +     node->intf_link = media_create_intf_link(entity,
>>> +                                              &node->intf_devnode->intf,
>>> +                                              MEDIA_LNK_FL_IMMUTABLE |
>>> +                                              MEDIA_LNK_FL_ENABLED);
>>> +     if (!node->intf_link) {
>>> +             ret = -ENOMEM;
>>> +             goto error_create_intf_link;
>>> +     }
>>> +
>>> +     if (output)
>>> +             ret = media_create_pad_link(entity, 0, &dev->entity, num,
>>> +                                         MEDIA_LNK_FL_IMMUTABLE |
>>> +                                                 MEDIA_LNK_FL_ENABLED);
>>> +     else
>>> +             ret = media_create_pad_link(&dev->entity, num, entity, 0,
>>> +                                         MEDIA_LNK_FL_IMMUTABLE |
>>> +                                         MEDIA_LNK_FL_ENABLED);
>>> +     if (ret)
>>> +             goto error_create_pad_link;
>>> +
>>> +     dev->node[num].media_node_registered = true;
>>> +     return 0;
>>> +
>>> +error_create_pad_link:
>>> +     media_remove_intf_links(&node->intf_devnode->intf);
>>> +error_create_intf_link:
>>> +     media_devnode_remove(node->intf_devnode);
>>> +error_devnode_create:
>>> +     media_device_unregister_entity(&node->vfd.entity);
>>> +error_register_entity:
>>> +error_pads_init:
>>> +     kfree(entity->name);
>>> +     entity->name = NULL;
>>> +error_no_mem:
>>> +     if (ret)
>>> +             v4l2_info(&dev->v4l2_dev, "Error registering node\n");
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +static int media_controller_register(struct bcm2835_isp_dev *dev)
>>> +{
>>> +     char *name;
>>> +     unsigned int i;
>>> +     int ret;
>>> +
>>> +     v4l2_dbg(2, debug, &dev->v4l2_dev, "Registering with media controller\n");
>>> +     dev->mdev.dev = dev->dev;
>>> +     strscpy(dev->mdev.model, "bcm2835-isp",
>>> +             sizeof(dev->mdev.model));
>>> +     strscpy(dev->mdev.bus_info, "platform:bcm2835-isp",
>>> +             sizeof(dev->mdev.bus_info));
>>> +     media_device_init(&dev->mdev);
>>> +     dev->v4l2_dev.mdev = &dev->mdev;
>>> +
>>> +     v4l2_dbg(2, debug, &dev->v4l2_dev, "Register entity for nodes\n");
>>> +
>>> +     name = kmalloc(BCM2835_ISP_ENTITY_NAME_LEN, GFP_KERNEL);
>>> +     if (!name) {
>>> +             ret = -ENOMEM;
>>> +             goto done;
>>> +     }
>>> +     snprintf(name, BCM2835_ISP_ENTITY_NAME_LEN, "bcm2835_isp0");
>>> +     dev->entity.name = name;
>>> +     dev->entity.obj_type = MEDIA_ENTITY_TYPE_BASE;
>>> +     dev->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
>>> +
>>> +     for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
>>> +             dev->pad[i].flags = node_is_output(&dev->node[i]) ?
>>> +                                     MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
>>> +     }
>>> +
>>> +     ret = media_entity_pads_init(&dev->entity, BCM2835_ISP_NUM_NODES,
>>> +                                  dev->pad);
>>> +     if (ret)
>>> +             goto done;
>>> +
>>> +     ret = media_device_register_entity(&dev->mdev, &dev->entity);
>>> +     if (ret)
>>> +             goto done;
>>> +
>>> +     dev->media_entity_registered = true;
>>> +     for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
>>> +             ret = media_controller_register_node(dev, i);
>>> +             if (ret)
>>> +                     goto done;
>>> +     }
>>> +
>>> +     ret = media_device_register(&dev->mdev);
>>> +     if (!ret)
>>> +             dev->media_device_registered = true;
>>> +done:
>>> +     return ret;
>>> +}
>>> +
>>> +static int bcm2835_isp_remove(struct platform_device *pdev)
>>> +{
>>> +     struct bcm2835_isp_dev *dev = platform_get_drvdata(pdev);
>>> +     unsigned int i;
>>> +
>>> +     media_controller_unregister(dev);
>>> +
>>> +     for (i = 0; i < BCM2835_ISP_NUM_NODES; i++)
>>> +             unregister_node(&dev->node[i]);
>>> +
>>> +     v4l2_device_unregister(&dev->v4l2_dev);
>>> +
>>> +     if (dev->component)
>>> +             vchiq_mmal_component_finalise(dev->mmal_instance,
>>> +                                           dev->component);
>>> +
>>> +     vchiq_mmal_finalise(dev->mmal_instance);
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int bcm2835_isp_probe(struct platform_device *pdev)
>>> +{
>>> +     struct bcm2835_isp_dev *dev;
>>> +     unsigned int i;
>>> +     int ret;
>>> +
>>> +     dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
>>> +     if (!dev)
>>> +             return -ENOMEM;
>>> +
>>> +     dev->dev = &pdev->dev;
>>> +
>>> +     ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     ret = vchiq_mmal_init(&dev->mmal_instance);
>>> +     if (ret) {
>>> +             v4l2_device_unregister(&dev->v4l2_dev);
>>> +             return ret;
>>> +     }
>>> +
>>> +     ret = vchiq_mmal_component_init(dev->mmal_instance, "ril.isp",
>>> +                                     &dev->component);
>>> +     if (ret) {
>>> +             v4l2_err(&dev->v4l2_dev,
>>> +                      "%s: failed to create ril.isp component\n", __func__);
>>> +             goto error;
>>> +     }
>>> +
>>> +     if ((dev->component->inputs != BCM2835_ISP_NUM_OUTPUTS) ||
>>> +         (dev->component->outputs != BCM2835_ISP_NUM_CAPTURES +
>>> +                                     BCM2835_ISP_NUM_METADATA)) {
>>> +             v4l2_err(&dev->v4l2_dev,
>>> +                      "%s: ril.isp returned %d i/p (%d expected), %d o/p (%d expected) ports\n",
>>> +                       __func__, dev->component->inputs,
>>> +                       BCM2835_ISP_NUM_OUTPUTS,
>>> +                       dev->component->outputs,
>>> +                       BCM2835_ISP_NUM_CAPTURES + BCM2835_ISP_NUM_METADATA);
>>> +             goto error;
>>> +     }
>>> +
>>> +     atomic_set(&dev->num_streaming, 0);
>>> +
>>> +     for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
>>> +             struct bcm2835_isp_node *node = &dev->node[i];
>>> +
>>> +             ret = register_node(dev, node, i);
>>> +             if (ret)
>>> +                     goto error;
>>> +     }
>>> +
>>> +     ret = media_controller_register(dev);
>>> +     if (ret)
>>> +             goto error;
>>> +
>>> +     platform_set_drvdata(pdev, dev);
>>> +     v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", BCM2835_ISP_NAME);
>>> +     return 0;
>>> +
>>> +error:
>>> +     bcm2835_isp_remove(pdev);
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +static struct platform_driver bcm2835_isp_pdrv = {
>>> +     .probe = bcm2835_isp_probe,
>>> +     .remove = bcm2835_isp_remove,
>>> +     .driver = {
>>> +                     .name = BCM2835_ISP_NAME,
>>> +               },
>>> +};
>>> +
>>> +module_platform_driver(bcm2835_isp_pdrv);
>>> +
>>> +MODULE_DESCRIPTION("BCM2835 ISP driver");
>>> +MODULE_AUTHOR("Naushir Patuck <naush@xxxxxxxxxxxxxxx>");
>>> +MODULE_LICENSE("GPL");
>>> +MODULE_VERSION("1.0");
>>> +MODULE_ALIAS("platform:bcm2835-isp");
>>> diff --git a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h
>>> new file mode 100644
>>> index 000000000000..cfbb1063aad1
>>> --- /dev/null
>>> +++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h
>>> @@ -0,0 +1,67 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/*
>>> + * Broadcom BCM2835 ISP driver
>>> + *
>>> + * Copyright © 2019-2020 Raspberry Pi (Trading) Ltd.
>>> + *
>>> + * Author: Naushir Patuck (naush@xxxxxxxxxxxxxxx)
>>> + *
>>> + */
>>> +
>>> +#ifndef BCM2835_ISP_CTRLS
>>> +#define BCM2835_ISP_CTRLS
>>> +
>>> +#include <linux/bcm2835-isp.h>
>>> +
>>> +struct bcm2835_isp_custom_ctrl {
>>> +     const char *name;
>>> +     u32 id;
>>> +     u32 size;
>>> +     u32 flags;
>>> +};
>>> +
>>> +static const struct bcm2835_isp_custom_ctrl custom_ctrls[] = {
>>> +     {
>>> +             .name   = "Colour Correction Matrix",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_CC_MATRIX,
>>> +             .size   = sizeof(struct bcm2835_isp_custom_ccm),
>>> +             .flags  = 0
>>> +     }, {
>>> +             .name   = "Lens Shading",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_LENS_SHADING,
>>> +             .size   = sizeof(struct bcm2835_isp_lens_shading),
>>> +             .flags  = V4L2_CTRL_FLAG_EXECUTE_ON_WRITE
>>> +     }, {
>>> +             .name   = "Black Level",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL,
>>> +             .size   = sizeof(struct bcm2835_isp_black_level),
>>> +             .flags  = 0
>>> +     }, {
>>> +             .name   = "Green Equalisation",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_GEQ,
>>> +             .size   = sizeof(struct bcm2835_isp_geq),
>>> +             .flags  = 0
>>> +     }, {
>>> +             .name   = "Gamma",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_GAMMA,
>>> +             .size   = sizeof(struct bcm2835_isp_gamma),
>>> +             .flags  = 0
>>> +     }, {
>>> +             .name   = "Sharpen",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_SHARPEN,
>>> +             .size   = sizeof(struct bcm2835_isp_sharpen),
>>> +             .flags  = 0
>>> +     }, {
>>> +             .name   = "Denoise",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_DENOISE,
>>> +             .size   = sizeof(struct bcm2835_isp_denoise),
>>> +             .flags  = 0
>>> +     }, {
>>> +             .name   = "Defective Pixel Correction",
>>> +             .id     = V4L2_CID_USER_BCM2835_ISP_DPC,
>>> +             .size   = sizeof(struct bcm2835_isp_dpc),
>>> +             .flags  = 0
>>> +     }
>>> +};
>>> +
>>> +#endif
>>> diff --git a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
>>> new file mode 100644
>>> index 000000000000..af3bde152bb2
>>> --- /dev/null
>>> +++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h
>>> @@ -0,0 +1,301 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/*
>>> + * Broadcom BCM2835 ISP driver
>>> + *
>>> + * Copyright © 2019-2020 Raspberry Pi (Trading) Ltd.
>>> + *
>>> + * Author: Naushir Patuck (naush@xxxxxxxxxxxxxxx)
>>> + *
>>> + */
>>> +
>>> +#ifndef BCM2835_ISP_FMTS
>>> +#define BCM2835_ISP_FMTS
>>> +
>>> +#include <linux/videodev2.h>
>>> +#include "vchiq-mmal/mmal-encodings.h"
>>> +
>>> +struct bcm2835_isp_fmt {
>>> +     u32 fourcc;
>>> +     int depth;
>>> +     int bytesperline_align;
>>> +     u32 flags;
>>> +     u32 mmal_fmt;
>>> +     int size_multiplier_x2;
>>> +     enum v4l2_colorspace colorspace;
>>> +     unsigned int step_size;
>>> +};
>>> +
>>> +struct bcm2835_isp_fmt_list {
>>> +     struct bcm2835_isp_fmt const **list;
>>> +     unsigned int num_entries;
>>> +};
>>> +
>>> +static const struct bcm2835_isp_fmt supported_formats[] = {
>>> +     {
>>> +             /* YUV formats */
>>> +             .fourcc             = V4L2_PIX_FMT_YUV420,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_I420,
>>> +             .size_multiplier_x2 = 3,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_YVU420,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_YV12,
>>> +             .size_multiplier_x2 = 3,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_NV12,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_NV12,
>>> +             .size_multiplier_x2 = 3,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_NV21,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_NV21,
>>> +             .size_multiplier_x2 = 3,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_YUYV,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_YUYV,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_UYVY,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_UYVY,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_YVYU,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_YVYU,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_VYUY,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_VYUY,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SMPTE170M,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             /* RGB formats */
>>> +             .fourcc             = V4L2_PIX_FMT_RGB24,
>>> +             .depth              = 24,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_RGB24,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SRGB,
>>> +             .step_size          = 1,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_RGB565,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_RGB16,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SRGB,
>>> +             .step_size          = 1,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_BGR24,
>>> +             .depth              = 24,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BGR24,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SRGB,
>>> +             .step_size          = 1,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_ABGR32,
>>> +             .depth              = 32,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BGRA,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_SRGB,
>>> +             .step_size          = 1,
>>> +     }, {
>>> +             /* Bayer formats */
>>> +             /* 8 bit */
>>> +             .fourcc             = V4L2_PIX_FMT_SRGGB8,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SRGGB8,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SBGGR8,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SBGGR8,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGRBG8,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGRBG8,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGBRG8,
>>> +             .depth              = 8,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGBRG8,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             /* 10 bit */
>>> +             .fourcc             = V4L2_PIX_FMT_SRGGB10P,
>>> +             .depth              = 10,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SRGGB10P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SBGGR10P,
>>> +             .depth              = 10,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SBGGR10P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGRBG10P,
>>> +             .depth              = 10,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGRBG10P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGBRG10P,
>>> +             .depth              = 10,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGBRG10P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             /* 12 bit */
>>> +             .fourcc             = V4L2_PIX_FMT_SRGGB12P,
>>> +             .depth              = 12,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SRGGB12P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SBGGR12P,
>>> +             .depth              = 12,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SBGGR12P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGRBG12P,
>>> +             .depth              = 12,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGRBG12P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGBRG12P,
>>> +             .depth              = 12,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGBRG12P,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             /* 16 bit */
>>> +             .fourcc             = V4L2_PIX_FMT_SRGGB16,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SRGGB16,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SBGGR16,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SBGGR16,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGRBG16,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGRBG16,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             .fourcc             = V4L2_PIX_FMT_SGBRG16,
>>> +             .depth              = 16,
>>> +             .bytesperline_align = 32,
>>> +             .flags              = 0,
>>> +             .mmal_fmt           = MMAL_ENCODING_BAYER_SGBRG16,
>>> +             .size_multiplier_x2 = 2,
>>> +             .colorspace         = V4L2_COLORSPACE_RAW,
>>> +             .step_size          = 2,
>>> +     }, {
>>> +             /* ISP statistics format */
>>> +             .fourcc             = V4L2_META_FMT_BCM2835_ISP_STATS,
>>> +             .mmal_fmt           = MMAL_ENCODING_BRCM_STATS,
>>> +             /* The rest are not valid fields for stats. */
>>> +     }
>>> +};
>>> +
>>> +#endif
>>> diff --git a/drivers/staging/vc04_services/include/uapi/linux/bcm2835-isp.h b/drivers/staging/vc04_services/include/uapi/linux/bcm2835-isp.h
>>> new file mode 100644
>>> index 000000000000..edc452fa8318
>>> --- /dev/null
>>> +++ b/drivers/staging/vc04_services/include/uapi/linux/bcm2835-isp.h
>>> @@ -0,0 +1,333 @@
>>> +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
>>> +/*
>>> + * bcm2835-isp.h
>>> + *
>>> + * BCM2835 ISP driver - user space header file.
>>> + *
>>> + * Copyright © 2019-2020 Raspberry Pi (Trading) Ltd.
>>> + *
>>> + * Author: Naushir Patuck (naush@xxxxxxxxxxxxxxx)
>>> + *
>>> + */
>>> +
>>> +#ifndef __BCM2835_ISP_H_
>>> +#define __BCM2835_ISP_H_
>>> +
>>> +#include <linux/v4l2-controls.h>
>>> +
>>> +/* TODO: move the control IDs definitions to v4l2-controls.h */
>>> +#define V4L2_CID_USER_BCM2835_ISP_BASE         (V4L2_CID_USER_BASE + 0x10c0)
>>
>> As the TODO says: move this to v4l2-controls.h. Currently the 0x10c0 offset
>> clashes with V4L2_CID_USER_ATMEL_ISC_BASE, so that certainly should be fixed.
>>
> 
> Unfortunately, there seems to be a mixup here.  Laurent, we have
> accidentally mailed a WIP revision of this patch.  The final version
> does have V4L2_CID_USER_BCM2835_ISP_BASE with a unique id in
> v4l2-controls.h.  I will talk with Laurent separately to get the
> correct revison included in the next patch-set.
> 
>>> +
>>> +/* TODO: move the formats definitions to videodev2.h */
>>> +/* 12  Y/CbCr 4:2:0 128 pixel wide column */
>>> +#define V4L2_PIX_FMT_NV12_COL128 v4l2_fourcc('N', 'C', '1', '2')
>>> +/* Y/CbCr 4:2:0 10bpc, 3x10 packed as 4 bytes in a 128 bytes / 96 pixel wide column */
>>> +#define V4L2_PIX_FMT_NV12_10_COL128 v4l2_fourcc('N', 'C', '3', '0')
>>> +/* Sensor Ancillary metadata */
>>> +#define V4L2_META_FMT_SENSOR_DATA v4l2_fourcc('S', 'E', 'N', 'S')
>>> +/* BCM2835 ISP image statistics output */
>>> +#define V4L2_META_FMT_BCM2835_ISP_STATS v4l2_fourcc('B', 'S', 'T', 'A')
>>> +
> 
> Similarly, these have also been moved to the right header files.
> 
>>> +#define V4L2_CID_USER_BCM2835_ISP_CC_MATRIX  \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0001)
>>> +#define V4L2_CID_USER_BCM2835_ISP_LENS_SHADING       \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0002)
>>> +#define V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL        \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0003)
>>> +#define V4L2_CID_USER_BCM2835_ISP_GEQ                \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0004)
>>> +#define V4L2_CID_USER_BCM2835_ISP_GAMMA              \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0005)
>>> +#define V4L2_CID_USER_BCM2835_ISP_DENOISE    \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0006)
>>> +#define V4L2_CID_USER_BCM2835_ISP_SHARPEN    \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0007)
>>> +#define V4L2_CID_USER_BCM2835_ISP_DPC                \
>>> +                             (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0008)
>>
>> There is no documentation for these controls. Specifically, it doesn't
>> tell you which struct should be used.
> 
> As above, the documentaiton is available in the newer patch.
> 
>>
>>> +
>>> +/*
>>> + * All structs below are directly mapped onto the equivalent structs in
>>> + * drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
>>> + * for convenience.
>>> + */
>>> +
>>> +/**
>>> + * struct bcm2835_isp_rational - Rational value type.
>>> + *
>>> + * @num:     Numerator.
>>> + * @den:     Denominator.
>>> + */
>>> +struct bcm2835_isp_rational {
>>> +     __s32 num;
>>> +     __s32 den;
>>
>> Wouldn't it make more sense if den is a __u32?
> 
> Ack
> 
>>
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_ccm - Colour correction matrix.
>>> + *
>>> + * @ccm:     3x3 correction matrix coefficients.
>>> + * @offsets: 1x3 correction offsets.
>>> + */
>>> +struct bcm2835_isp_ccm {
>>> +     struct bcm2835_isp_rational ccm[3][3];
>>> +     __s32 offsets[3];
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_custom_ccm - Custom CCM applied with the
>>> + *                              V4L2_CID_USER_BCM2835_ISP_CC_MATRIX ctrl.
>>> + *
>>> + * @enabled: Enable custom CCM.
>>> + * @ccm:     Custom CCM coefficients and offsets.
>>> + */
>>> +struct bcm2835_isp_custom_ccm {
>>> +     __u32 enabled;
>>> +     struct bcm2835_isp_ccm ccm;
>>> +};
>>> +
>>> +/**
>>> + * enum bcm2835_isp_gain_format - format of the gains in the lens shading
>>> + *                             tables used with the
>>> + *                             V4L2_CID_USER_BCM2835_ISP_LENS_SHADING ctrl.
>>> + *
>>> + * @GAIN_FORMAT_U0P8_1:              Gains are u0.8 format, starting at 1.0
>>> + * @GAIN_FORMAT_U1P7_0:              Gains are u1.7 format, starting at 0.0
>>> + * @GAIN_FORMAT_U1P7_1:              Gains are u1.7 format, starting at 1.0
>>> + * @GAIN_FORMAT_U2P6_0:              Gains are u2.6 format, starting at 0.0
>>> + * @GAIN_FORMAT_U2P6_1:              Gains are u2.6 format, starting at 1.0
>>> + * @GAIN_FORMAT_U3P5_0:              Gains are u3.5 format, starting at 0.0
>>> + * @GAIN_FORMAT_U3P5_1:              Gains are u3.5 format, starting at 1.0
>>> + * @GAIN_FORMAT_U4P10:               Gains are u4.10 format, starting at 0.0
>>> + */
>>> +enum bcm2835_isp_gain_format {
>>> +     GAIN_FORMAT_U0P8_1 = 0,
>>> +     GAIN_FORMAT_U1P7_0 = 1,
>>> +     GAIN_FORMAT_U1P7_1 = 2,
>>> +     GAIN_FORMAT_U2P6_0 = 3,
>>> +     GAIN_FORMAT_U2P6_1 = 4,
>>> +     GAIN_FORMAT_U3P5_0 = 5,
>>> +     GAIN_FORMAT_U3P5_1 = 6,
>>> +     GAIN_FORMAT_U4P10  = 7,
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_lens_shading - Lens shading tables supplied with the
>>> + *                                V4L2_CID_USER_BCM2835_ISP_LENS_SHADING
>>> + *                                ctrl.
>>> + *
>>> + * @enabled:         Enable lens shading.
>>> + * @grid_cell_size:  Size of grid cells in samples (16, 32, 64, 128 or 256).
>>> + * @grid_width:              Width of lens shading tables in grid cells.
>>> + * @grid_stride:     Row to row distance (in grid cells) between grid cells
>>> + *                   in the same horizontal location.
>>> + * @grid_height:     Height of lens shading tables in grid cells.
>>> + * @mem_handle_table:        Memory handle to the tables.
>>
>> What sort of handle is this? I.e. where does it come from?
> 
> I believe there was a separte discusion about this.  This is a vcsm
> handle that is used to store the table coefficients in memory that is
> accessible from Videocore.  There is work in progress to update this
> to use dmabuf handles.
> 
>>
>>> + * @ref_transform:   Reference transform - unsupported, please pass zero.
>>> + * @corner_sampled:  Whether the gains are sampled at the corner points
>>> + *                   of the grid cells or in the cell centres.
>>> + * @gain_format:     Format of the gains (see enum &bcm2835_isp_gain_format).
>>> + */
>>> +struct bcm2835_isp_lens_shading {
>>> +     __u32 enabled;
>>> +     __u32 grid_cell_size;
>>> +     __u32 grid_width;
>>> +     __u32 grid_stride;
>>> +     __u32 grid_height;
>>> +     __u32 mem_handle_table;
>>> +     __u32 ref_transform;
>>> +     __u32 corner_sampled;
>>> +     __u32 gain_format;
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_black_level - Sensor black level set with the
>>> + *                               V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL ctrl.
>>> + *
>>> + * @enabled:         Enable black level.
>>> + * @black_level_r:   Black level for red channel.
>>> + * @black_level_g:   Black level for green channels.
>>> + * @black_level_b:   Black level for blue channel.
>>> + */
>>> +struct bcm2835_isp_black_level {
>>> +     __u32 enabled;
>>> +     __u16 black_level_r;
>>> +     __u16 black_level_g;
>>> +     __u16 black_level_b;
>>> +     __u8 pad_[2]; /* Unused */
>>
>> I prefer 'padding' over 'pad_'.
> 
> Ack
> 
>>
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_geq - Green equalisation parameters set with the
>>> + *                       V4L2_CID_USER_BCM2835_ISP_GEQ ctrl.
>>> + *
>>> + * @enabled: Enable green equalisation.
>>> + * @offset:  Fixed offset of the green equalisation threshold.
>>> + * @slope:   Slope of the green equalisation threshold.
>>> + */
>>> +struct bcm2835_isp_geq {
>>> +     __u32 enabled;
>>> +     __u32 offset;
>>> +     struct bcm2835_isp_rational slope;
>>> +};
>>> +
>>> +#define BCM2835_NUM_GAMMA_PTS 33
>>> +
>>> +/**
>>> + * struct bcm2835_isp_gamma - Gamma parameters set with the
>>> + *                         V4L2_CID_USER_BCM2835_ISP_GAMMA ctrl.
>>> + *
>>> + * @enabled: Enable gamma adjustment.
>>> + * @X:               X values of the points defining the gamma curve.
>>> + *           Values should be scaled to 16 bits.
>>> + * @Y:               Y values of the points defining the gamma curve.
>>> + *           Values should be scaled to 16 bits.
>>
>> I assume 0 == black and 0xffff == white (or max luminance)?
>>
>> And so typically x[0] == y[0] == 0 and x[32] == y[32] == 0xffff?
>>
> 
> Typically yes, but it is not strictily true.  We could have parameters
> that clip the signal above min (0) and below max (0xffff).
> 
>>> + */
>>> +struct bcm2835_isp_gamma {
>>> +     __u32 enabled;
>>> +     __u16 x[BCM2835_NUM_GAMMA_PTS];
>>> +     __u16 y[BCM2835_NUM_GAMMA_PTS];
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_denoise - Denoise parameters set with the
>>> + *                           V4L2_CID_USER_BCM2835_ISP_DENOISE ctrl.
>>> + *
>>> + * @enabled: Enable denoise.
>>> + * @constant:        Fixed offset of the noise threshold.
>>> + * @slope:   Slope of the noise threshold.
>>> + * @strength:        Denoise strength between 0.0 (off) and 1.0 (maximum).
>>> + */
>>> +struct bcm2835_isp_denoise {
>>> +     __u32 enabled;
>>> +     __u32 constant;
>>> +     struct bcm2835_isp_rational slope;
>>> +     struct bcm2835_isp_rational strength;
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_sharpen - Sharpen parameters set with the
>>> + *                           V4L2_CID_USER_BCM2835_ISP_SHARPEN ctrl.
>>> + *
>>> + * @enabled: Enable sharpening.
>>> + * @threshold:       Threshold at which to start sharpening pixels.
>>> + * @strength:        Strength with which pixel sharpening increases.
>>> + * @limit:   Limit to the amount of sharpening applied.
>>> + */
>>> +struct bcm2835_isp_sharpen {
>>> +     __u32 enabled;
>>> +     struct bcm2835_isp_rational threshold;
>>> +     struct bcm2835_isp_rational strength;
>>> +     struct bcm2835_isp_rational limit;
>>> +};
>>> +
>>> +/**
>>> + * enum bcm2835_isp_dpc_mode - defective pixel correction (DPC) strength.
>>> + *
>>> + * @DPC_MODE_OFF:            No DPC.
>>> + * @DPC_MODE_NORMAL:         Normal DPC.
>>> + * @DPC_MODE_STRONG:         Strong DPC.
>>> + */
>>> +enum bcm2835_isp_dpc_mode {
>>> +     DPC_MODE_OFF = 0,
>>> +     DPC_MODE_NORMAL = 1,
>>> +     DPC_MODE_STRONG = 2,
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_dpc - Defective pixel correction (DPC) parameters set
>>> + *                       with the V4L2_CID_USER_BCM2835_ISP_DPC ctrl.
>>> + *
>>> + * @enabled: Enable DPC.
>>> + * @strength:        DPC strength (see enum &bcm2835_isp_dpc_mode).
>>
>> Isn't DPC_MODE_OFF equal to just setting 'enabled' to false? If so,
>> wouldn't the 'strength' field be sufficient?
> 
> This is a bit of a quirk of the hardware pipeline.  DPC_MODE_OFF still
> keeps the block enabled, but running (mostly) as a passthrough.  The
> enabled field physically switches off the block.
> 
>>
>>> + */
>>> +struct bcm2835_isp_dpc {
>>> +     __u32 enabled;
>>> +     __u32 strength;
>>> +};
>>> +
>>> +/*
>>> + * ISP statistics structures.
>>> + *
>>> + * The bcm2835_isp_stats structure is generated at the output of the
>>> + * statistics node.  Note that this does not directly map onto the statistics
>>> + * output of the ISP HW.  Instead, the MMAL firmware code maps the HW statistics
>>> + * to the bcm2835_isp_stats structure.
>>> + */
>>> +#define DEFAULT_AWB_REGIONS_X 16
>>> +#define DEFAULT_AWB_REGIONS_Y 12
>>> +
>>> +#define NUM_HISTOGRAMS 2
>>> +#define NUM_HISTOGRAM_BINS 128
>>> +#define AWB_REGIONS (DEFAULT_AWB_REGIONS_X * DEFAULT_AWB_REGIONS_Y)
>>> +#define FLOATING_REGIONS 16
>>> +#define AGC_REGIONS 16
>>> +#define FOCUS_REGIONS 12
>>> +
>>> +/**
>>> + * struct bcm2835_isp_stats_hist - Histogram statistics
>>> + *
>>> + * @r_hist:  Red channel histogram.
>>> + * @g_hist:  Combined green channel histogram.
>>> + * @b_hist:  Blue channel histogram.
>>> + */
>>> +struct bcm2835_isp_stats_hist {
>>> +     __u32 r_hist[NUM_HISTOGRAM_BINS];
>>> +     __u32 g_hist[NUM_HISTOGRAM_BINS];
>>> +     __u32 b_hist[NUM_HISTOGRAM_BINS];
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_stats_region - Region sums.
>>> + *
>>> + * @counted: The number of 2x2 bayer tiles accumulated.
>>> + * @notcounted:      The number of 2x2 bayer tiles not accumulated.
>>> + * @r_sum:   Total sum of counted pixels in the red channel for a region.
>>> + * @g_sum:   Total sum of counted pixels in the green channel for a region.
>>> + * @b_sum:   Total sum of counted pixels in the blue channel for a region.
>>> + */
>>> +struct bcm2835_isp_stats_region {
>>> +     __u32 counted;
>>> +     __u32 notcounted;
>>> +     __u64 r_sum;
>>> +     __u64 g_sum;
>>> +     __u64 b_sum;
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_stats_focus - Focus statistics.
>>> + *
>>> + * @contrast_val:    Focus measure - accumulated output of the focus filter.
>>> + *                   In the first dimension, index [0] counts pixels below a
>>> + *                   preset threshold, and index [1] counts pixels above the
>>> + *                   threshold.  In the second dimension, index [0] uses the
>>> + *                   first predefined filter, and index [1] uses the second
>>> + *                   predefined filter.
>>> + * @contrast_val_num:        The number of counted pixels in the above accumulation.
>>> + */
>>> +struct bcm2835_isp_stats_focus {
>>> +     __u64 contrast_val[2][2];
>>> +     __u32 contrast_val_num[2][2];
>>> +};
>>> +
>>> +/**
>>> + * struct bcm2835_isp_stats - ISP statistics.
>>> + *
>>> + * @version:         Version of the bcm2835_isp_stats structure.
>>> + * @size:            Size of the bcm2835_isp_stats structure.
>>> + * @hist:            Histogram statistics for the entire image.
>>> + * @awb_stats:               Statistics for the regions defined for AWB calculations.
>>> + * @floating_stats:  Statistics for arbitrarily placed (floating) regions.
>>> + * @agc_stats:               Statistics for the regions defined for AGC calculations.
>>> + * @focus_stats:     Focus filter statistics for the focus regions.
>>> + */
>>> +struct bcm2835_isp_stats {
>>> +     __u32 version;
>>> +     __u32 size;
>>> +     struct bcm2835_isp_stats_hist hist[NUM_HISTOGRAMS];
>>> +     struct bcm2835_isp_stats_region awb_stats[AWB_REGIONS];
>>> +     struct bcm2835_isp_stats_region floating_stats[FLOATING_REGIONS];
>>> +     struct bcm2835_isp_stats_region agc_stats[AGC_REGIONS];
>>> +     struct bcm2835_isp_stats_focus focus_stats[FOCUS_REGIONS];
>>> +};
>>> +
>>> +#endif /* __BCM2835_ISP_H_ */
>>> diff --git a/drivers/staging/vc04_services/vchiq-mmal/Kconfig b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
>>> index 106f71e709df..072f3c755a68 100644
>>> --- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig
>>> +++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
>>> @@ -5,4 +5,5 @@ config BCM2835_VCHIQ_MMAL
>>>       help
>>>         Enables the MMAL API over VCHIQ interface as used for the
>>>         majority of the multimedia services on VideoCore.
>>> -       Defaults to Y when the Broadcomd BCM2835 camera host is selected.
>>> +       Defaults to Y when the Broadcomd BCM2835 camera host or ISP are
>>> +       selected.
>>> diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
>>> index 44ba91aa6d47..8d904fcce388 100644
>>> --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
>>> +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
>>> @@ -100,6 +100,10 @@
>>>   */
>>>  #define MMAL_ENCODING_EGL_IMAGE        MMAL_FOURCC('E', 'G', 'L', 'I')
>>>
>>> +/** ISP image statistics format
>>> + */
>>> +#define MMAL_ENCODING_BRCM_STATS       MMAL_FOURCC('S', 'T', 'A', 'T')
>>> +
>>>  /* }@ */
>>>
>>>  /** \name Pre-defined audio encodings */
>>> diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
>>> index 1793103b18fd..b3552af5cf8f 100644
>>> --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
>>> +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
>>> @@ -221,6 +221,62 @@ enum mmal_parameter_camera_type {
>>>       MMAL_PARAMETER_SHUTTER_SPEED,
>>>               /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */
>>>       MMAL_PARAMETER_CUSTOM_AWB_GAINS,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CAMERA_SETTINGS_T */
>>> +     MMAL_PARAMETER_CAMERA_SETTINGS,
>>> +             /**< Takes a @ref MMAL_PARAMETER_PRIVACY_INDICATOR_T */
>>> +     MMAL_PARAMETER_PRIVACY_INDICATOR,
>>> +             /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */
>>> +     MMAL_PARAMETER_VIDEO_DENOISE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */
>>> +     MMAL_PARAMETER_STILLS_DENOISE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CAMERA_ANNOTATE_T */
>>> +     MMAL_PARAMETER_ANNOTATE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_STEREOSCOPIC_MODE_T */
>>> +     MMAL_PARAMETER_STEREOSCOPIC_MODE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CAMERA_INTERFACE_T */
>>> +     MMAL_PARAMETER_CAMERA_INTERFACE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CAMERA_CLOCKING_MODE_T */
>>> +     MMAL_PARAMETER_CAMERA_CLOCKING_MODE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CAMERA_RX_CONFIG_T */
>>> +     MMAL_PARAMETER_CAMERA_RX_CONFIG,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CAMERA_RX_TIMING_T */
>>> +     MMAL_PARAMETER_CAMERA_RX_TIMING,
>>> +             /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
>>> +     MMAL_PARAMETER_DPF_CONFIG,
>>> +
>>> +     /* 0x50 */
>>> +             /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
>>> +     MMAL_PARAMETER_JPEG_RESTART_INTERVAL,
>>> +             /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
>>> +     MMAL_PARAMETER_CAMERA_ISP_BLOCK_OVERRIDE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_LENS_SHADING_T */
>>> +     MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
>>> +     MMAL_PARAMETER_BLACK_LEVEL,
>>> +             /**< Takes a @ref MMAL_PARAMETER_RESIZE_T */
>>> +     MMAL_PARAMETER_RESIZE_PARAMS,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CROP_T */
>>> +     MMAL_PARAMETER_CROP,
>>> +             /**< Takes a @ref MMAL_PARAMETER_INT32_T */
>>> +     MMAL_PARAMETER_OUTPUT_SHIFT,
>>> +             /**< Takes a @ref MMAL_PARAMETER_INT32_T */
>>> +     MMAL_PARAMETER_CCM_SHIFT,
>>> +             /**< Takes a @ref MMAL_PARAMETER_CUSTOM_CCM_T */
>>> +     MMAL_PARAMETER_CUSTOM_CCM,
>>> +             /**< Takes a @ref MMAL_PARAMETER_RATIONAL_T */
>>> +     MMAL_PARAMETER_ANALOG_GAIN,
>>> +             /**< Takes a @ref MMAL_PARAMETER_RATIONAL_T */
>>> +     MMAL_PARAMETER_DIGITAL_GAIN,
>>> +             /**< Takes a @ref MMAL_PARAMETER_DENOISE_T */
>>> +     MMAL_PARAMETER_DENOISE,
>>> +             /**< Takes a @ref MMAL_PARAMETER_SHARPEN_T */
>>> +     MMAL_PARAMETER_SHARPEN,
>>> +             /**< Takes a @ref MMAL_PARAMETER_GEQ_T */
>>> +     MMAL_PARAMETER_GEQ,
>>> +             /**< Tales a @ref MMAP_PARAMETER_DPC_T */
>>> +     MMAL_PARAMETER_DPC,
>>> +             /**< Tales a @ref MMAP_PARAMETER_GAMMA_T */
>>> +     MMAL_PARAMETER_GAMMA,
>>>  };
>>>
>>>  struct mmal_parameter_rational {
>>> @@ -779,7 +835,102 @@ struct mmal_parameter_camera_info {
>>>       struct mmal_parameter_camera_info_camera
>>>               cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS];
>>>       struct mmal_parameter_camera_info_flash
>>> -                             flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES];
>>> +             flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES];
>>> +};
>>> +
>>> +struct mmal_parameter_ccm {
>>> +     struct mmal_parameter_rational ccm[3][3];
>>> +     s32 offsets[3];
>>> +};
>>> +
>>> +struct mmal_parameter_custom_ccm {
>>> +     u32 enabled; /**< Enable the custom CCM. */
>>> +     struct mmal_parameter_ccm ccm; /**< CCM to be used. */
>>> +};
>>> +
>>> +struct mmal_parameter_lens_shading {
>>> +     u32 enabled;
>>> +     u32 grid_cell_size;
>>> +     u32 grid_width;
>>> +     u32 grid_stride;
>>> +     u32 grid_height;
>>> +     u32 mem_handle_table;
>>> +     u32 ref_transform;
>>> +};
>>> +
>>> +enum mmal_parameter_ls_gain_format_type {
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U0P8_1 = 0,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U1P7_0 = 1,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U1P7_1 = 2,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U2P6_0 = 3,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U2P6_1 = 4,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U3P5_0 = 5,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U3P5_1 = 6,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_U4P10  = 7,
>>> +     MMAL_PARAMETER_LS_GAIN_FORMAT_TYPE_DUMMY  = 0x7FFFFFFF
>>> +};
>>> +
>>> +struct mmal_parameter_lens_shading_v2 {
>>> +     u32 enabled;
>>> +     u32 grid_cell_size;
>>> +     u32 grid_width;
>>> +     u32 grid_stride;
>>> +     u32 grid_height;
>>> +     u32 mem_handle_table;
>>> +     u32 ref_transform;
>>> +     u32 corner_sampled;
>>> +     enum mmal_parameter_ls_gain_format_type gain_format;
>>> +};
>>> +
>>> +struct mmal_parameter_black_level {
>>> +     u32 enabled;
>>> +     u16 black_level_r;
>>> +     u16 black_level_g;
>>> +     u16 black_level_b;
>>> +     u8 pad_[2]; /* Unused */
>>> +};
>>> +
>>> +struct mmal_parameter_geq {
>>> +     u32 enabled;
>>> +     u32 offset;
>>> +     struct mmal_parameter_rational slope;
>>> +};
>>> +
>>> +#define MMAL_NUM_GAMMA_PTS 33
>>> +struct mmal_parameter_gamma {
>>> +     u32 enabled;
>>> +     u16 x[MMAL_NUM_GAMMA_PTS];
>>> +     u16 y[MMAL_NUM_GAMMA_PTS];
>>> +};
>>> +
>>> +struct mmal_parameter_denoise {
>>> +     u32 enabled;
>>> +     u32 constant;
>>> +     struct mmal_parameter_rational slope;
>>> +     struct mmal_parameter_rational strength;
>>> +};
>>> +
>>> +struct mmal_parameter_sharpen {
>>> +     u32 enabled;
>>> +     struct mmal_parameter_rational threshold;
>>> +     struct mmal_parameter_rational strength;
>>> +     struct mmal_parameter_rational limit;
>>> +};
>>> +
>>> +enum mmal_dpc_mode {
>>> +     MMAL_DPC_MODE_OFF = 0,
>>> +     MMAL_DPC_MODE_NORMAL = 1,
>>> +     MMAL_DPC_MODE_STRONG = 2,
>>> +     MMAL_DPC_MODE_MAX = 0x7FFFFFFF,
>>> +};
>>> +
>>> +struct mmal_parameter_dpc {
>>> +     u32 enabled;
>>> +     u32 strength;
>>> +};
>>> +
>>> +struct mmal_parameter_crop {
>>> +     struct vchiq_mmal_rect rect;
>>>  };
>>>
>>>  #endif
>>>
>>
>> Regards,
>>
>>         Hans
> 
> Regards,
> Naush
> 





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux