123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718 |
- From 22fef46503bd929ef663255285c9aa7c6a4dd93f Mon Sep 17 00:00:00 2001
- From: 6by9 <6by9@users.noreply.github.com>
- Date: Fri, 8 Apr 2016 18:15:43 +0100
- Subject: [PATCH] V4L2 driver updates (#1393)
- * BCM2835-V4L2: Correct ISO control and add V4L2_CID_ISO_SENSITIVITY_AUTO
- https://github.com/raspberrypi/linux/issues/1251
- V4L2_CID_ISO_SENSITIVITY was not advertising ISO*1000 as it should.
- V4L2_CID_ISO_SENSITIVITY_AUTO was not implemented, so was taking
- V4L2_CID_ISO_SENSITIVITY as 0 for auto mode.
- Still accepts 0 for auto, but also abides by the new parameter.
- Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
- * BCM2835-V4L2: Add a video_nr parameter.
- Adds a kernel parameter "video_nr" to specify the preferred
- /dev/videoX device node.
- https://www.raspberrypi.org/forums/viewtopic.php?f=38&t=136120&p=905545
- Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
- * BCM2835-V4L2: Add support for multiple cameras
- Ask GPU on load how many cameras have been detected, and
- enumerate that number of devices.
- Only applicable on the Compute Module as no other device
- exposes multiple CSI2 interfaces.
- Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
- * BCM2835-V4L2: Add control of the overlay location and alpha.
- Actually do something useful in vidioc_s_fmt_vid_overlay and
- vidioc_try_fmt_vid_overlay, rather than effectively having
- read-only fields.
- Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
- * BCM2835-V4L2: V4L2-Compliance failure fix
- VIDIOC_TRY_FMT was failing due to bytesperline not
- being set correctly by default.
- Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
- * BCM2835-V4L2: Make all module parameters static
- Clean up to correct variable scope
- Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
- ---
- drivers/media/platform/bcm2835/bcm2835-camera.c | 372 +++++++++++++++--------
- drivers/media/platform/bcm2835/bcm2835-camera.h | 19 +-
- drivers/media/platform/bcm2835/controls.c | 31 +-
- drivers/media/platform/bcm2835/mmal-parameters.h | 33 ++
- 4 files changed, 320 insertions(+), 135 deletions(-)
- --- a/drivers/media/platform/bcm2835/bcm2835-camera.c
- +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
- @@ -45,6 +45,8 @@
- #define MAX_VIDEO_MODE_WIDTH 1280
- #define MAX_VIDEO_MODE_HEIGHT 720
-
- +#define MAX_BCM2835_CAMERAS 2
- +
- MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture");
- MODULE_AUTHOR("Vincent Sanders");
- MODULE_LICENSE("GPL");
- @@ -54,8 +56,13 @@ int bcm2835_v4l2_debug;
- module_param_named(debug, bcm2835_v4l2_debug, int, 0644);
- MODULE_PARM_DESC(bcm2835_v4l2_debug, "Debug level 0-2");
-
- -int max_video_width = MAX_VIDEO_MODE_WIDTH;
- -int max_video_height = MAX_VIDEO_MODE_HEIGHT;
- +#define UNSET (-1)
- +static int video_nr[] = {[0 ... (MAX_BCM2835_CAMERAS - 1)] = UNSET };
- +module_param_array(video_nr, int, NULL, 0644);
- +MODULE_PARM_DESC(video_nr, "videoX start numbers, -1 is autodetect");
- +
- +static int max_video_width = MAX_VIDEO_MODE_WIDTH;
- +static int max_video_height = MAX_VIDEO_MODE_HEIGHT;
- module_param(max_video_width, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- MODULE_PARM_DESC(max_video_width, "Threshold for video mode");
- module_param(max_video_height, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- @@ -70,11 +77,12 @@ MODULE_PARM_DESC(max_video_height, "Thre
- * our function table list (actually switch to an alternate set, but same
- * result).
- */
- -int gst_v4l2src_is_broken = 0;
- +static int gst_v4l2src_is_broken;
- module_param(gst_v4l2src_is_broken, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- MODULE_PARM_DESC(gst_v4l2src_is_broken, "If non-zero, enable workaround for Gstreamer");
-
- -static struct bm2835_mmal_dev *gdev; /* global device data */
- +/* global device data array */
- +static struct bm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS];
-
- #define FPS_MIN 1
- #define FPS_MAX 90
- @@ -413,6 +421,17 @@ static int enable_camera(struct bm2835_m
- {
- int ret;
- if (!dev->camera_use_count) {
- + ret = vchiq_mmal_port_parameter_set(
- + dev->instance,
- + &dev->component[MMAL_COMPONENT_CAMERA]->control,
- + MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
- + sizeof(dev->camera_num));
- + if (ret < 0) {
- + v4l2_err(&dev->v4l2_dev,
- + "Failed setting camera num, ret %d\n", ret);
- + return -EINVAL;
- + }
- +
- ret = vchiq_mmal_component_enable(
- dev->instance,
- dev->component[MMAL_COMPONENT_CAMERA]);
- @@ -647,6 +666,30 @@ static struct vb2_ops bm2835_mmal_video_
- IOCTL operations
- ------------------------------------------------------------------*/
-
- +static int set_overlay_params(struct bm2835_mmal_dev *dev,
- + struct vchiq_mmal_port *port)
- +{
- + int ret;
- + struct mmal_parameter_displayregion prev_config = {
- + .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_ALPHA |
- + MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN,
- + .layer = PREVIEW_LAYER,
- + .alpha = dev->overlay.global_alpha,
- + .fullscreen = 0,
- + .dest_rect = {
- + .x = dev->overlay.w.left,
- + .y = dev->overlay.w.top,
- + .width = dev->overlay.w.width,
- + .height = dev->overlay.w.height,
- + },
- + };
- + ret = vchiq_mmal_port_parameter_set(dev->instance, port,
- + MMAL_PARAMETER_DISPLAYREGION,
- + &prev_config, sizeof(prev_config));
- +
- + return ret;
- +}
- +
- /* overlay ioctl */
- static int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
- @@ -678,10 +721,31 @@ static int vidioc_g_fmt_vid_overlay(stru
- static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
- {
- - /* Only support one format so get the current one. */
- - vidioc_g_fmt_vid_overlay(file, priv, f);
- + struct bm2835_mmal_dev *dev = video_drvdata(file);
-
- - /* todo: allow the size and/or offset to be changed. */
- + f->fmt.win.field = V4L2_FIELD_NONE;
- + f->fmt.win.chromakey = 0;
- + f->fmt.win.clips = NULL;
- + f->fmt.win.clipcount = 0;
- + f->fmt.win.bitmap = NULL;
- +
- + v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, MAX_WIDTH, 1,
- + &f->fmt.win.w.height, MIN_HEIGHT, MAX_HEIGHT,
- + 1, 0);
- + v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, MAX_WIDTH, 1,
- + &f->fmt.win.w.top, MIN_HEIGHT, MAX_HEIGHT,
- + 1, 0);
- +
- + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- + "Overlay: Now w/h %dx%d l/t %dx%d\n",
- + f->fmt.win.w.width, f->fmt.win.w.height,
- + f->fmt.win.w.left, f->fmt.win.w.top);
- +
- + v4l2_dump_win_format(1,
- + bcm2835_v4l2_debug,
- + &dev->v4l2_dev,
- + &f->fmt.win,
- + __func__);
- return 0;
- }
-
- @@ -693,8 +757,11 @@ static int vidioc_s_fmt_vid_overlay(stru
- vidioc_try_fmt_vid_overlay(file, priv, f);
-
- dev->overlay = f->fmt.win;
- + if (dev->component[MMAL_COMPONENT_PREVIEW]->enabled) {
- + set_overlay_params(dev,
- + &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]);
- + }
-
- - /* todo: program the preview port parameters */
- return 0;
- }
-
- @@ -704,20 +771,6 @@ static int vidioc_overlay(struct file *f
- struct bm2835_mmal_dev *dev = video_drvdata(file);
- struct vchiq_mmal_port *src;
- struct vchiq_mmal_port *dst;
- - struct mmal_parameter_displayregion prev_config = {
- - .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_ALPHA |
- - MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN,
- - .layer = PREVIEW_LAYER,
- - .alpha = 255,
- - .fullscreen = 0,
- - .dest_rect = {
- - .x = dev->overlay.w.left,
- - .y = dev->overlay.w.top,
- - .width = dev->overlay.w.width,
- - .height = dev->overlay.w.height,
- - },
- - };
- -
- if ((on && dev->component[MMAL_COMPONENT_PREVIEW]->enabled) ||
- (!on && !dev->component[MMAL_COMPONENT_PREVIEW]->enabled))
- return 0; /* already in requested state */
- @@ -749,9 +802,7 @@ static int vidioc_overlay(struct file *f
- if (ret < 0)
- goto error;
-
- - ret = vchiq_mmal_port_parameter_set(dev->instance, dst,
- - MMAL_PARAMETER_DISPLAYREGION,
- - &prev_config, sizeof(prev_config));
- + ret = set_overlay_params(dev, dst);
- if (ret < 0)
- goto error;
-
- @@ -782,6 +833,9 @@ static int vidioc_g_fbuf(struct file *fi
- struct vchiq_mmal_port *preview_port =
- &dev->component[MMAL_COMPONENT_CAMERA]->
- output[MMAL_CAMERA_PORT_PREVIEW];
- +
- + a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY |
- + V4L2_FBUF_CAP_GLOBAL_ALPHA;
- a->flags = V4L2_FBUF_FLAG_OVERLAY;
- a->fmt.width = preview_port->es.video.width;
- a->fmt.height = preview_port->es.video.height;
- @@ -1445,6 +1499,34 @@ static struct video_device vdev_template
- .release = video_device_release_empty,
- };
-
- +static int get_num_cameras(struct vchiq_mmal_instance *instance)
- +{
- + int ret;
- + struct vchiq_mmal_component *cam_info_component;
- + struct mmal_parameter_camera_info_t cam_info = {0};
- + int param_size = sizeof(cam_info);
- +
- + /* create a camera_info component */
- + ret = vchiq_mmal_component_init(instance, "camera_info",
- + &cam_info_component);
- + if (ret < 0)
- + /* Unusual failure - let's guess one camera. */
- + return 1;
- +
- + if (vchiq_mmal_port_parameter_get(instance,
- + &cam_info_component->control,
- + MMAL_PARAMETER_CAMERA_INFO,
- + &cam_info,
- + ¶m_size)) {
- + pr_info("Failed to get camera info\n");
- + }
- +
- + vchiq_mmal_component_finalise(instance,
- + cam_info_component);
- +
- + return cam_info.num_cameras;
- +}
- +
- static int set_camera_parameters(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *camera)
- {
- @@ -1685,7 +1767,9 @@ static int __init bm2835_mmal_init_devic
- /* video device needs to be able to access instance data */
- video_set_drvdata(vfd, dev);
-
- - ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
- + ret = video_register_device(vfd,
- + VFL_TYPE_GRABBER,
- + video_nr[dev->camera_num]);
- if (ret < 0)
- return ret;
-
- @@ -1696,10 +1780,52 @@ static int __init bm2835_mmal_init_devic
- return 0;
- }
-
- +void bcm2835_cleanup_instance(struct bm2835_mmal_dev *dev)
- +{
- + if (!dev)
- + return;
- +
- + v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
- + video_device_node_name(&dev->vdev));
- +
- + video_unregister_device(&dev->vdev);
- +
- + if (dev->capture.encode_component) {
- + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- + "mmal_exit - disconnect tunnel\n");
- + vchiq_mmal_port_connect_tunnel(dev->instance,
- + dev->capture.camera_port, NULL);
- + vchiq_mmal_component_disable(dev->instance,
- + dev->capture.encode_component);
- + }
- + vchiq_mmal_component_disable(dev->instance,
- + dev->component[MMAL_COMPONENT_CAMERA]);
- +
- + vchiq_mmal_component_finalise(dev->instance,
- + dev->
- + component[MMAL_COMPONENT_VIDEO_ENCODE]);
- +
- + vchiq_mmal_component_finalise(dev->instance,
- + dev->
- + component[MMAL_COMPONENT_IMAGE_ENCODE]);
- +
- + vchiq_mmal_component_finalise(dev->instance,
- + dev->component[MMAL_COMPONENT_PREVIEW]);
- +
- + vchiq_mmal_component_finalise(dev->instance,
- + dev->component[MMAL_COMPONENT_CAMERA]);
- +
- + v4l2_ctrl_handler_free(&dev->ctrl_handler);
- +
- + v4l2_device_unregister(&dev->v4l2_dev);
- +
- + kfree(dev);
- +}
- +
- static struct v4l2_format default_v4l2_format = {
- .fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG,
- .fmt.pix.width = 1024,
- - .fmt.pix.bytesperline = 1024,
- + .fmt.pix.bytesperline = 0,
- .fmt.pix.height = 768,
- .fmt.pix.sizeimage = 1024*768,
- };
- @@ -1709,76 +1835,93 @@ static int __init bm2835_mmal_init(void)
- int ret;
- struct bm2835_mmal_dev *dev;
- struct vb2_queue *q;
- + int camera;
- + unsigned int num_cameras;
- + struct vchiq_mmal_instance *instance;
-
- - dev = kzalloc(sizeof(*gdev), GFP_KERNEL);
- - if (!dev)
- - return -ENOMEM;
- -
- - /* setup device defaults */
- - dev->overlay.w.left = 150;
- - dev->overlay.w.top = 50;
- - dev->overlay.w.width = 1024;
- - dev->overlay.w.height = 768;
- - dev->overlay.clipcount = 0;
- - dev->overlay.field = V4L2_FIELD_NONE;
- -
- - dev->capture.fmt = &formats[3]; /* JPEG */
- -
- - /* v4l device registration */
- - snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
- - "%s", BM2835_MMAL_MODULE_NAME);
- - ret = v4l2_device_register(NULL, &dev->v4l2_dev);
- - if (ret)
- - goto free_dev;
- -
- - /* setup v4l controls */
- - ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler);
- - if (ret < 0)
- - goto unreg_dev;
- - dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler;
- -
- - /* mmal init */
- - ret = mmal_init(dev);
- + ret = vchiq_mmal_init(&instance);
- if (ret < 0)
- - goto unreg_dev;
- + return ret;
-
- - /* initialize queue */
- - q = &dev->capture.vb_vidq;
- - memset(q, 0, sizeof(*q));
- - q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- - q->drv_priv = dev;
- - q->buf_struct_size = sizeof(struct mmal_buffer);
- - q->ops = &bm2835_mmal_video_qops;
- - q->mem_ops = &vb2_vmalloc_memops;
- - q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- - ret = vb2_queue_init(q);
- - if (ret < 0)
- - goto unreg_dev;
- + num_cameras = get_num_cameras(instance);
- + if (num_cameras > MAX_BCM2835_CAMERAS)
- + num_cameras = MAX_BCM2835_CAMERAS;
- +
- + for (camera = 0; camera < num_cameras; camera++) {
- + dev = kzalloc(sizeof(struct bm2835_mmal_dev), GFP_KERNEL);
- + if (!dev)
- + return -ENOMEM;
- +
- + dev->camera_num = camera;
- +
- + /* setup device defaults */
- + dev->overlay.w.left = 150;
- + dev->overlay.w.top = 50;
- + dev->overlay.w.width = 1024;
- + dev->overlay.w.height = 768;
- + dev->overlay.clipcount = 0;
- + dev->overlay.field = V4L2_FIELD_NONE;
- + dev->overlay.global_alpha = 255;
- +
- + dev->capture.fmt = &formats[3]; /* JPEG */
- +
- + /* v4l device registration */
- + snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
- + "%s", BM2835_MMAL_MODULE_NAME);
- + ret = v4l2_device_register(NULL, &dev->v4l2_dev);
- + if (ret)
- + goto free_dev;
-
- - /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */
- - mutex_init(&dev->mutex);
- + /* setup v4l controls */
- + ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler);
- + if (ret < 0)
- + goto unreg_dev;
- + dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler;
- +
- + /* mmal init */
- + dev->instance = instance;
- + ret = mmal_init(dev);
- + if (ret < 0)
- + goto unreg_dev;
- +
- + /* initialize queue */
- + q = &dev->capture.vb_vidq;
- + memset(q, 0, sizeof(*q));
- + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- + q->drv_priv = dev;
- + q->buf_struct_size = sizeof(struct mmal_buffer);
- + q->ops = &bm2835_mmal_video_qops;
- + q->mem_ops = &vb2_vmalloc_memops;
- + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- + ret = vb2_queue_init(q);
- + if (ret < 0)
- + goto unreg_dev;
- +
- + /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */
- + mutex_init(&dev->mutex);
- +
- + /* initialise video devices */
- + ret = bm2835_mmal_init_device(dev, &dev->vdev);
- + if (ret < 0)
- + goto unreg_dev;
- +
- + /* Really want to call vidioc_s_fmt_vid_cap with the default
- + * format, but currently the APIs don't join up.
- + */
- + ret = mmal_setup_components(dev, &default_v4l2_format);
- + if (ret < 0) {
- + v4l2_err(&dev->v4l2_dev,
- + "%s: could not setup components\n", __func__);
- + goto unreg_dev;
- + }
-
- - /* initialise video devices */
- - ret = bm2835_mmal_init_device(dev, &dev->vdev);
- - if (ret < 0)
- - goto unreg_dev;
- + v4l2_info(&dev->v4l2_dev,
- + "Broadcom 2835 MMAL video capture ver %s loaded.\n",
- + BM2835_MMAL_VERSION);
-
- - /* Really want to call vidioc_s_fmt_vid_cap with the default
- - * format, but currently the APIs don't join up.
- - */
- - ret = mmal_setup_components(dev, &default_v4l2_format);
- - if (ret < 0) {
- - v4l2_err(&dev->v4l2_dev,
- - "%s: could not setup components\n", __func__);
- - goto unreg_dev;
- + gdev[camera] = dev;
- }
- -
- - v4l2_info(&dev->v4l2_dev,
- - "Broadcom 2835 MMAL video capture ver %s loaded.\n",
- - BM2835_MMAL_VERSION);
- -
- - gdev = dev;
- return 0;
-
- unreg_dev:
- @@ -1788,8 +1931,11 @@ unreg_dev:
- free_dev:
- kfree(dev);
-
- - v4l2_err(&dev->v4l2_dev,
- - "%s: error %d while loading driver\n",
- + for ( ; camera > 0; camera--) {
- + bcm2835_cleanup_instance(gdev[camera]);
- + gdev[camera] = NULL;
- + }
- + pr_info("%s: error %d while loading driver\n",
- BM2835_MMAL_MODULE_NAME, ret);
-
- return ret;
- @@ -1797,46 +1943,14 @@ free_dev:
-
- static void __exit bm2835_mmal_exit(void)
- {
- - if (!gdev)
- - return;
- -
- - v4l2_info(&gdev->v4l2_dev, "unregistering %s\n",
- - video_device_node_name(&gdev->vdev));
- + int camera;
- + struct vchiq_mmal_instance *instance = gdev[0]->instance;
-
- - video_unregister_device(&gdev->vdev);
- -
- - if (gdev->capture.encode_component) {
- - v4l2_dbg(1, bcm2835_v4l2_debug, &gdev->v4l2_dev,
- - "mmal_exit - disconnect tunnel\n");
- - vchiq_mmal_port_connect_tunnel(gdev->instance,
- - gdev->capture.camera_port, NULL);
- - vchiq_mmal_component_disable(gdev->instance,
- - gdev->capture.encode_component);
- + for (camera = 0; camera < MAX_BCM2835_CAMERAS; camera++) {
- + bcm2835_cleanup_instance(gdev[camera]);
- + gdev[camera] = NULL;
- }
- - vchiq_mmal_component_disable(gdev->instance,
- - gdev->component[MMAL_COMPONENT_CAMERA]);
- -
- - vchiq_mmal_component_finalise(gdev->instance,
- - gdev->
- - component[MMAL_COMPONENT_VIDEO_ENCODE]);
- -
- - vchiq_mmal_component_finalise(gdev->instance,
- - gdev->
- - component[MMAL_COMPONENT_IMAGE_ENCODE]);
- -
- - vchiq_mmal_component_finalise(gdev->instance,
- - gdev->component[MMAL_COMPONENT_PREVIEW]);
- -
- - vchiq_mmal_component_finalise(gdev->instance,
- - gdev->component[MMAL_COMPONENT_CAMERA]);
- -
- - vchiq_mmal_finalise(gdev->instance);
- -
- - v4l2_ctrl_handler_free(&gdev->ctrl_handler);
- -
- - v4l2_device_unregister(&gdev->v4l2_dev);
- -
- - kfree(gdev);
- + vchiq_mmal_finalise(instance);
- }
-
- module_init(bm2835_mmal_init);
- --- a/drivers/media/platform/bcm2835/bcm2835-camera.h
- +++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
- @@ -15,7 +15,7 @@
- * core driver device
- */
-
- -#define V4L2_CTRL_COUNT 28 /* number of v4l controls */
- +#define V4L2_CTRL_COUNT 29 /* number of v4l controls */
-
- enum {
- MMAL_COMPONENT_CAMERA = 0,
- @@ -58,6 +58,8 @@ struct bm2835_mmal_dev {
- enum mmal_parameter_exposuremeteringmode metering_mode;
- unsigned int manual_shutter_speed;
- bool exp_auto_priority;
- + bool manual_iso_enabled;
- + uint32_t iso;
-
- /* allocated mmal instance and components */
- struct vchiq_mmal_instance *instance;
- @@ -104,6 +106,8 @@ struct bm2835_mmal_dev {
-
- } capture;
-
- + unsigned int camera_num;
- +
- };
-
- int bm2835_mmal_init_controls(
- @@ -124,3 +128,16 @@ int set_framerate_params(struct bm2835_m
- (pix_fmt)->pixelformat, (pix_fmt)->bytesperline, \
- (pix_fmt)->sizeimage, (pix_fmt)->colorspace, (pix_fmt)->priv); \
- }
- +#define v4l2_dump_win_format(level, debug, dev, win_fmt, desc) \
- +{ \
- + v4l2_dbg(level, debug, dev, \
- +"%s: w %u h %u l %u t %u field %u chromakey %06X clip %p " \
- +"clipcount %u bitmap %p\n", \
- + desc == NULL ? "" : desc, \
- + (win_fmt)->w.width, (win_fmt)->w.height, \
- + (win_fmt)->w.left, (win_fmt)->w.top, \
- + (win_fmt)->field, \
- + (win_fmt)->chromakey, \
- + (win_fmt)->clips, (win_fmt)->clipcount, \
- + (win_fmt)->bitmap); \
- +}
- --- a/drivers/media/platform/bcm2835/controls.c
- +++ b/drivers/media/platform/bcm2835/controls.c
- @@ -49,10 +49,13 @@ static const s64 ev_bias_qmenu[] = {
- 4000
- };
-
- -/* Supported ISO values
- +/* Supported ISO values (*1000)
- * ISOO = auto ISO
- */
- static const s64 iso_qmenu[] = {
- + 0, 100000, 200000, 400000, 800000,
- +};
- +static const uint32_t iso_values[] = {
- 0, 100, 200, 400, 800,
- };
-
- @@ -201,7 +204,7 @@ static int ctrl_set_value(struct bm2835_
- &u32_value, sizeof(u32_value));
- }
-
- -static int ctrl_set_value_menu(struct bm2835_mmal_dev *dev,
- +static int ctrl_set_iso(struct bm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
- {
- @@ -211,12 +214,23 @@ static int ctrl_set_value_menu(struct bm
- if (ctrl->val > mmal_ctrl->max || ctrl->val < mmal_ctrl->min)
- return 1;
-
- + if (ctrl->id == V4L2_CID_ISO_SENSITIVITY)
- + dev->iso = iso_values[ctrl->val];
- + else if (ctrl->id == V4L2_CID_ISO_SENSITIVITY_AUTO)
- + dev->manual_iso_enabled =
- + (ctrl->val == V4L2_ISO_SENSITIVITY_MANUAL ?
- + true :
- + false);
- +
- control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
-
- - u32_value = mmal_ctrl->imenu[ctrl->val];
- + if (dev->manual_iso_enabled)
- + u32_value = dev->iso;
- + else
- + u32_value = 0;
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- - mmal_ctrl->mmal_id,
- + MMAL_PARAMETER_ISO,
- &u32_value, sizeof(u32_value));
- }
-
- @@ -956,7 +970,14 @@ static const struct bm2835_mmal_v4l2_ctr
- V4L2_CID_ISO_SENSITIVITY, MMAL_CONTROL_TYPE_INT_MENU,
- 0, ARRAY_SIZE(iso_qmenu) - 1, 0, 1, iso_qmenu,
- MMAL_PARAMETER_ISO,
- - &ctrl_set_value_menu,
- + &ctrl_set_iso,
- + false
- + },
- + {
- + V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU,
- + 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL,
- + MMAL_PARAMETER_ISO,
- + &ctrl_set_iso,
- false
- },
- {
- --- a/drivers/media/platform/bcm2835/mmal-parameters.h
- +++ b/drivers/media/platform/bcm2835/mmal-parameters.h
- @@ -654,3 +654,36 @@ struct mmal_parameter_imagefx_parameters
- u32 num_effect_params;
- u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS];
- };
- +
- +#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4
- +#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2
- +#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16
- +
- +struct mmal_parameter_camera_info_camera_t {
- + u32 port_id;
- + u32 max_width;
- + u32 max_height;
- + u32 lens_present;
- + u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN];
- +};
- +
- +enum mmal_parameter_camera_info_flash_type_t {
- + /* Make values explicit to ensure they match values in config ini */
- + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0,
- + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1,
- + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2,
- + MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF
- +};
- +
- +struct mmal_parameter_camera_info_flash_t {
- + enum mmal_parameter_camera_info_flash_type_t flash_type;
- +};
- +
- +struct mmal_parameter_camera_info_t {
- + u32 num_cameras;
- + u32 num_flashes;
- + struct mmal_parameter_camera_info_camera_t
- + cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS];
- + struct mmal_parameter_camera_info_flash_t
- + flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES];
- +};
|