aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0233-V4L2-driver-updates-1393.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0233-V4L2-driver-updates-1393.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0233-V4L2-driver-updates-1393.patch718
1 files changed, 0 insertions, 718 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0233-V4L2-driver-updates-1393.patch b/target/linux/brcm2708/patches-4.4/0233-V4L2-driver-updates-1393.patch
deleted file mode 100644
index 580489205a..0000000000
--- a/target/linux/brcm2708/patches-4.4/0233-V4L2-driver-updates-1393.patch
+++ /dev/null
@@ -1,718 +0,0 @@
-From 21e3542368e5df2eecb87f32187cb7a64c55fd04 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,
-+ &param_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];
-+};