diff options
Diffstat (limited to 'drivers/staging/vc04_services/bcm2835-camera')
12 files changed, 836 insertions, 673 deletions
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index 68f08dc18da9..ea54cc27e645 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ #include <linux/errno.h> @@ -79,7 +80,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_I420, .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 1, .remove_padding = 1, }, { @@ -88,7 +89,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_YUYV, .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 2, .remove_padding = 0, }, { @@ -97,7 +98,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_RGB24, .depth = 24, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 3, .remove_padding = 0, }, { @@ -106,7 +107,7 @@ static struct mmal_fmt formats[] = { .flags = V4L2_FMT_FLAG_COMPRESSED, .mmal = MMAL_ENCODING_JPEG, .depth = 8, - .mmal_component = MMAL_COMPONENT_IMAGE_ENCODE, + .mmal_component = COMP_IMAGE_ENCODE, .ybbp = 0, .remove_padding = 0, }, { @@ -115,7 +116,7 @@ static struct mmal_fmt formats[] = { .flags = V4L2_FMT_FLAG_COMPRESSED, .mmal = MMAL_ENCODING_H264, .depth = 8, - .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, + .mmal_component = COMP_VIDEO_ENCODE, .ybbp = 0, .remove_padding = 0, }, { @@ -124,7 +125,7 @@ static struct mmal_fmt formats[] = { .flags = V4L2_FMT_FLAG_COMPRESSED, .mmal = MMAL_ENCODING_MJPEG, .depth = 8, - .mmal_component = MMAL_COMPONENT_VIDEO_ENCODE, + .mmal_component = COMP_VIDEO_ENCODE, .ybbp = 0, .remove_padding = 0, }, { @@ -133,7 +134,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_YVYU, .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 2, .remove_padding = 0, }, { @@ -142,7 +143,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_VYUY, .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 2, .remove_padding = 0, }, { @@ -151,7 +152,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_UYVY, .depth = 16, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 2, .remove_padding = 0, }, { @@ -160,7 +161,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_NV12, .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 1, .remove_padding = 1, }, { @@ -169,7 +170,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_BGR24, .depth = 24, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 3, .remove_padding = 0, }, { @@ -178,7 +179,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_YV12, .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 1, .remove_padding = 1, }, { @@ -187,7 +188,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_NV21, .depth = 12, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 1, .remove_padding = 1, }, { @@ -196,7 +197,7 @@ static struct mmal_fmt formats[] = { .flags = 0, .mmal = MMAL_ENCODING_BGRA, .depth = 32, - .mmal_component = MMAL_COMPONENT_CAMERA, + .mmal_component = COMP_CAMERA, .ybbp = 4, .remove_padding = 0, }, @@ -235,6 +236,22 @@ static int queue_setup(struct vb2_queue *vq, return -EINVAL; } + /* Handle CREATE_BUFS situation - *nplanes != 0 */ + if (*nplanes) { + if (*nplanes != 1 || + sizes[0] < dev->capture.port->current_buffer.size) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: dev:%p Invalid buffer request from CREATE_BUFS, size %u < %u, nplanes %u != 1\n", + __func__, dev, sizes[0], + dev->capture.port->current_buffer.size, + *nplanes); + return -EINVAL; + } else { + return 0; + } + } + + /* Handle REQBUFS situation */ size = dev->capture.port->current_buffer.size; if (size == 0) { v4l2_err(&dev->v4l2_dev, @@ -312,7 +329,7 @@ static void buffer_cleanup(struct vb2_buffer *vb) static inline bool is_capturing(struct bm2835_mmal_dev *dev) { return dev->capture.camera_port == - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_CAPTURE]; + &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE]; } static void buffer_cb(struct vchiq_mmal_instance *instance, @@ -327,25 +344,24 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", __func__, status, buf, length, mmal_flags, pts); - if (status != 0) { + if (status) { /* error in transfer */ if (buf) { /* there was a buffer with the error so return it */ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); } return; - } else if (length == 0) { + } + + if (length == 0) { /* stream ended */ - if (buf) { - /* this should only ever happen if the port is - * disabled and there are buffers still queued + if (dev->capture.frame_count) { + /* empty buffer whilst capturing - expected to be an + * EOS, so grab another frame */ - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); - pr_debug("Empty buffer"); - } else if (dev->capture.frame_count) { - /* grab another frame */ if (is_capturing(dev)) { - pr_debug("Grab another frame"); + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Grab another frame"); vchiq_mmal_port_parameter_set( instance, dev->capture.camera_port, @@ -353,48 +369,60 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, &dev->capture.frame_count, sizeof(dev->capture.frame_count)); } + if (vchiq_mmal_submit_buffer(instance, port, buf)) + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Failed to return EOS buffer"); } else { - /* signal frame completion */ + /* stopping streaming. + * return buffer, and signal frame completion + */ + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); complete(&dev->capture.frame_cmplt); } + return; + } + + if (!dev->capture.frame_count) { + /* signal frame completion */ + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + complete(&dev->capture.frame_cmplt); + return; + } + + if (dev->capture.vc_start_timestamp != -1 && pts) { + ktime_t timestamp; + s64 runtime_us = pts - + dev->capture.vc_start_timestamp; + timestamp = ktime_add_us(dev->capture.kernel_start_ts, + runtime_us); + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Convert start time %llu and %llu with offset %llu to %llu\n", + ktime_to_ns(dev->capture.kernel_start_ts), + dev->capture.vc_start_timestamp, pts, + ktime_to_ns(timestamp)); + buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp); } else { - if (dev->capture.frame_count) { - if (dev->capture.vc_start_timestamp != -1 && - pts != 0) { - ktime_t timestamp; - s64 runtime_us = pts - - dev->capture.vc_start_timestamp; - timestamp = ktime_add_us(dev->capture.kernel_start_ts, - runtime_us); - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "Convert start time %llu and %llu with offset %llu to %llu\n", - ktime_to_ns(dev->capture.kernel_start_ts), - dev->capture.vc_start_timestamp, pts, - ktime_to_ns(timestamp)); - buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp); - } else { - buf->vb.vb2_buf.timestamp = ktime_get_ns(); - } + buf->vb.vb2_buf.timestamp = ktime_get_ns(); + } + buf->vb.sequence = dev->capture.sequence++; + buf->vb.field = V4L2_FIELD_NONE; - vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); + if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) + buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME; - if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && - is_capturing(dev)) { - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "Grab another frame as buffer has EOS"); - vchiq_mmal_port_parameter_set( - instance, - dev->capture.camera_port, - MMAL_PARAMETER_CAPTURE, - &dev->capture.frame_count, - sizeof(dev->capture.frame_count)); - } - } else { - /* signal frame completion */ - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); - complete(&dev->capture.frame_cmplt); - } + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + + if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && + is_capturing(dev)) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Grab another frame as buffer has EOS"); + vchiq_mmal_port_parameter_set( + instance, + dev->capture.camera_port, + MMAL_PARAMETER_CAPTURE, + &dev->capture.frame_count, + sizeof(dev->capture.frame_count)); } } @@ -405,7 +433,7 @@ static int enable_camera(struct bm2835_mmal_dev *dev) if (!dev->camera_use_count) { ret = vchiq_mmal_port_parameter_set( dev->instance, - &dev->component[MMAL_COMPONENT_CAMERA]->control, + &dev->component[COMP_CAMERA]->control, MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num, sizeof(dev->camera_num)); if (ret < 0) { @@ -416,7 +444,7 @@ static int enable_camera(struct bm2835_mmal_dev *dev) ret = vchiq_mmal_component_enable( dev->instance, - dev->component[MMAL_COMPONENT_CAMERA]); + dev->component[COMP_CAMERA]); if (ret < 0) { v4l2_err(&dev->v4l2_dev, "Failed enabling camera, ret %d\n", ret); @@ -448,7 +476,7 @@ static int disable_camera(struct bm2835_mmal_dev *dev) ret = vchiq_mmal_component_disable( dev->instance, - dev->component[MMAL_COMPONENT_CAMERA]); + dev->component[COMP_CAMERA]); if (ret < 0) { v4l2_err(&dev->v4l2_dev, "Failed disabling camera, ret %d\n", ret); @@ -456,7 +484,7 @@ static int disable_camera(struct bm2835_mmal_dev *dev) } vchiq_mmal_port_parameter_set( dev->instance, - &dev->component[MMAL_COMPONENT_CAMERA]->control, + &dev->component[COMP_CAMERA]->control, MMAL_PARAMETER_CAMERA_NUM, &i, sizeof(i)); } @@ -505,10 +533,13 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* enable frame capture */ dev->capture.frame_count = 1; + /* reset sequence number */ + dev->capture.sequence = 0; + /* if the preview is not already running, wait for a few frames for AGC * to settle down. */ - if (!dev->component[MMAL_COMPONENT_PREVIEW]->enabled) + if (!dev->component[COMP_PREVIEW]->enabled) msleep(300); /* enable the connection from camera to encoder (if applicable) */ @@ -536,10 +567,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Flag to indicate just to rely on kernel timestamps */ dev->capture.vc_start_timestamp = -1; - } else + } else { v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "Start time %lld size %d\n", dev->capture.vc_start_timestamp, parameter_size); + } dev->capture.kernel_start_ts = ktime_get(); @@ -549,8 +581,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) vchiq_mmal_port_enable(dev->instance, dev->capture.port, buffer_cb); if (ret) { v4l2_err(&dev->v4l2_dev, - "Failed to enable capture port - error %d. Disabling camera port again\n", - ret); + "Failed to enable capture port - error %d. Disabling camera port again\n", + ret); vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port); @@ -576,6 +608,7 @@ static void stop_streaming(struct vb2_queue *vq) int ret; unsigned long timeout; struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq); + struct vchiq_mmal_port *port = dev->capture.port; v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n", __func__, dev); @@ -599,12 +632,6 @@ static void stop_streaming(struct vb2_queue *vq) &dev->capture.frame_count, sizeof(dev->capture.frame_count)); - /* wait for last frame to complete */ - timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt, HZ); - if (timeout == 0) - v4l2_err(&dev->v4l2_dev, - "timed out waiting for frame completion\n"); - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "disabling connection\n"); @@ -619,6 +646,21 @@ static void stop_streaming(struct vb2_queue *vq) ret); } + /* wait for all buffers to be returned */ + while (atomic_read(&port->buffers_with_vpu)) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: Waiting for buffers to be returned - %d outstanding\n", + __func__, atomic_read(&port->buffers_with_vpu)); + timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt, + HZ); + if (timeout == 0) { + v4l2_err(&dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", + __func__, + atomic_read(&port->buffers_with_vpu)); + break; + } + } + if (disable_camera(dev) < 0) v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n"); } @@ -730,9 +772,9 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, vidioc_try_fmt_vid_overlay(file, priv, f); dev->overlay = f->fmt.win; - if (dev->component[MMAL_COMPONENT_PREVIEW]->enabled) { + if (dev->component[COMP_PREVIEW]->enabled) { set_overlay_params(dev, - &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]); + &dev->component[COMP_PREVIEW]->input[0]); } return 0; @@ -745,12 +787,12 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on) struct vchiq_mmal_port *src; struct vchiq_mmal_port *dst; - if ((on && dev->component[MMAL_COMPONENT_PREVIEW]->enabled) || - (!on && !dev->component[MMAL_COMPONENT_PREVIEW]->enabled)) + if ((on && dev->component[COMP_PREVIEW]->enabled) || + (!on && !dev->component[COMP_PREVIEW]->enabled)) return 0; /* already in requested state */ src = - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_PREVIEW]; + &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW]; if (!on) { /* disconnect preview ports and disable component */ @@ -762,39 +804,39 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on) if (ret >= 0) ret = vchiq_mmal_component_disable( dev->instance, - dev->component[MMAL_COMPONENT_PREVIEW]); + dev->component[COMP_PREVIEW]); disable_camera(dev); return ret; } /* set preview port format and connect it to output */ - dst = &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]; + dst = &dev->component[COMP_PREVIEW]->input[0]; ret = vchiq_mmal_port_set_format(dev->instance, src); if (ret < 0) - goto error; + return ret; ret = set_overlay_params(dev, dst); if (ret < 0) - goto error; + return ret; if (enable_camera(dev) < 0) - goto error; + return -EINVAL; ret = vchiq_mmal_component_enable( dev->instance, - dev->component[MMAL_COMPONENT_PREVIEW]); + dev->component[COMP_PREVIEW]); if (ret < 0) - goto error; + return ret; v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "connecting %p to %p\n", src, dst); ret = vchiq_mmal_port_connect_tunnel(dev->instance, src, dst); - if (!ret) - ret = vchiq_mmal_port_enable(dev->instance, src, NULL); -error: - return ret; + if (ret) + return ret; + + return vchiq_mmal_port_enable(dev->instance, src, NULL); } static int vidioc_g_fbuf(struct file *file, void *fh, @@ -805,7 +847,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, */ struct bm2835_mmal_dev *dev = video_drvdata(file); struct vchiq_mmal_port *preview_port = - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_PREVIEW]; + &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW]; a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_GLOBAL_ALPHA; @@ -826,7 +868,7 @@ static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp) { /* only a single camera input */ - if (inp->index != 0) + if (inp->index) return -EINVAL; inp->type = V4L2_INPUT_TYPE_CAMERA; @@ -842,7 +884,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { - if (i != 0) + if (i) return -EINVAL; return 0; @@ -864,10 +906,6 @@ static int vidioc_querycap(struct file *file, void *priv, snprintf((char *)cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev->v4l2_dev.name); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | - V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; } @@ -939,14 +977,27 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 1, 0); f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; if (!mfmt->remove_padding) { - int align_mask = ((32 * mfmt->depth) >> 3) - 1; - /* GPU isn't removing padding, so stride is aligned to 32 */ - f->fmt.pix.bytesperline = - (f->fmt.pix.bytesperline + align_mask) & ~align_mask; + if (mfmt->depth == 24) { + /* + * 24bpp is a pain as we can't use simple masking. + * Min stride is width aligned to 16, times 24bpp. + */ + f->fmt.pix.bytesperline = + ((f->fmt.pix.width + 15) & ~15) * 3; + } else { + /* + * GPU isn't removing padding, so stride is aligned to + * 32 + */ + int align_mask = ((32 * mfmt->depth) >> 3) - 1; + + f->fmt.pix.bytesperline = + (f->fmt.pix.bytesperline + align_mask) & + ~align_mask; + } v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "Not removing padding, so bytes/line = %d, " - "(align_mask %d)\n", - f->fmt.pix.bytesperline, align_mask); + "Not removing padding, so bytes/line = %d\n", + f->fmt.pix.bytesperline); } /* Image buffer has to be padded to allow for alignment, even though @@ -1007,27 +1058,28 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev, } /* format dependent port setup */ switch (mfmt->mmal_component) { - case MMAL_COMPONENT_CAMERA: + case COMP_CAMERA: /* Make a further decision on port based on resolution */ if (f->fmt.pix.width <= max_video_width && f->fmt.pix.height <= max_video_height) - camera_port = port = - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_VIDEO]; + camera_port = + &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]; else - camera_port = port = - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_CAPTURE]; + camera_port = + &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE]; + port = camera_port; break; - case MMAL_COMPONENT_IMAGE_ENCODE: - encode_component = dev->component[MMAL_COMPONENT_IMAGE_ENCODE]; - port = &dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->output[0]; + case COMP_IMAGE_ENCODE: + encode_component = dev->component[COMP_IMAGE_ENCODE]; + port = &dev->component[COMP_IMAGE_ENCODE]->output[0]; camera_port = - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_CAPTURE]; + &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE]; break; - case MMAL_COMPONENT_VIDEO_ENCODE: - encode_component = dev->component[MMAL_COMPONENT_VIDEO_ENCODE]; - port = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + case COMP_VIDEO_ENCODE: + encode_component = dev->component[COMP_VIDEO_ENCODE]; + port = &dev->component[COMP_VIDEO_ENCODE]->output[0]; camera_port = - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_VIDEO]; + &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]; break; default: break; @@ -1067,13 +1119,13 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev, ret = vchiq_mmal_port_set_format(dev->instance, camera_port); - if (!ret && - camera_port == - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_VIDEO]) { + if (!ret + && camera_port == + &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]) { bool overlay_enabled = - !!dev->component[MMAL_COMPONENT_PREVIEW]->enabled; + !!dev->component[COMP_PREVIEW]->enabled; struct vchiq_mmal_port *preview_port = - &dev->component[MMAL_COMPONENT_CAMERA]->output[MMAL_CAMERA_PORT_PREVIEW]; + &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW]; /* Preview and encode ports need to match on resolution */ if (overlay_enabled) { /* Need to disable the overlay before we can update @@ -1104,7 +1156,7 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev, ret = vchiq_mmal_port_connect_tunnel( dev->instance, preview_port, - &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]); + &dev->component[COMP_PREVIEW]->input[0]); if (!ret) ret = vchiq_mmal_port_enable(dev->instance, preview_port, @@ -1158,11 +1210,11 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev, port->format.encoding_variant = 0; /* Set any encoding specific parameters */ switch (mfmt->mmal_component) { - case MMAL_COMPONENT_VIDEO_ENCODE: + case COMP_VIDEO_ENCODE: port->format.bitrate = dev->capture.encode_bitrate; break; - case MMAL_COMPONENT_IMAGE_ENCODE: + case COMP_IMAGE_ENCODE: /* Could set EXIF parameters here */ break; default: @@ -1206,9 +1258,8 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev, port->current_buffer.size); port->current_buffer.size = (f->fmt.pix.sizeimage < - (100 << 10)) - ? (100 << 10) - : f->fmt.pix.sizeimage; + (100 << 10)) ? + (100 << 10) : f->fmt.pix.sizeimage; } v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, @@ -1281,7 +1332,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, } ret = mmal_setup_components(dev, f); - if (ret != 0) { + if (ret) { v4l2_err(&dev->v4l2_dev, "%s: failed to setup mmal components: %d\n", __func__, ret); @@ -1292,7 +1343,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, } static int vidioc_enum_framesizes(struct file *file, void *fh, - struct v4l2_frmsizeenum *fsize) + struct v4l2_frmsizeenum *fsize) { struct bm2835_mmal_dev *dev = video_drvdata(file); static const struct v4l2_frmsize_stepwise sizes = { @@ -1446,6 +1497,8 @@ static const struct video_device vdev_template = { .fops = &camera0_fops, .ioctl_ops = &camera0_ioctl_ops, .release = video_device_release_empty, + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | + V4L2_CAP_STREAMING | V4L2_CAP_READWRITE, }; /* Returns the number of cameras, and also the max resolution supported @@ -1531,14 +1584,14 @@ static int mmal_init(struct bm2835_mmal_dev *dev) /* get the camera component ready */ ret = vchiq_mmal_component_init(dev->instance, "ril.camera", - &dev->component[MMAL_COMPONENT_CAMERA]); + &dev->component[COMP_CAMERA]); if (ret < 0) goto unreg_mmal; - camera = dev->component[MMAL_COMPONENT_CAMERA]; - if (camera->outputs < MMAL_CAMERA_PORT_COUNT) { + camera = dev->component[COMP_CAMERA]; + if (camera->outputs < CAM_PORT_COUNT) { v4l2_err(&dev->v4l2_dev, "%s: too few camera outputs %d needed %d\n", - __func__, camera->outputs, MMAL_CAMERA_PORT_COUNT); + __func__, camera->outputs, CAM_PORT_COUNT); ret = -EINVAL; goto unreg_camera; } @@ -1560,7 +1613,7 @@ static int mmal_init(struct bm2835_mmal_dev *dev) dev->rgb_bgr_swapped = true; param_size = sizeof(supported_encodings); ret = vchiq_mmal_port_parameter_get(dev->instance, - &camera->output[MMAL_CAMERA_PORT_CAPTURE], + &camera->output[CAM_PORT_CAPTURE], MMAL_PARAMETER_SUPPORTED_ENCODINGS, &supported_encodings, ¶m_size); @@ -1581,7 +1634,7 @@ static int mmal_init(struct bm2835_mmal_dev *dev) } } } - format = &camera->output[MMAL_CAMERA_PORT_PREVIEW].format; + format = &camera->output[CAM_PORT_PREVIEW].format; format->encoding = MMAL_ENCODING_OPAQUE; format->encoding_variant = MMAL_ENCODING_I420; @@ -1595,7 +1648,7 @@ static int mmal_init(struct bm2835_mmal_dev *dev) format->es->video.frame_rate.num = 0; /* Rely on fps_range */ format->es->video.frame_rate.den = 1; - format = &camera->output[MMAL_CAMERA_PORT_VIDEO].format; + format = &camera->output[CAM_PORT_VIDEO].format; format->encoding = MMAL_ENCODING_OPAQUE; format->encoding_variant = MMAL_ENCODING_I420; @@ -1609,7 +1662,7 @@ static int mmal_init(struct bm2835_mmal_dev *dev) format->es->video.frame_rate.num = 0; /* Rely on fps_range */ format->es->video.frame_rate.den = 1; - format = &camera->output[MMAL_CAMERA_PORT_CAPTURE].format; + format = &camera->output[CAM_PORT_CAPTURE].format; format->encoding = MMAL_ENCODING_OPAQUE; @@ -1633,49 +1686,49 @@ static int mmal_init(struct bm2835_mmal_dev *dev) /* get the preview component ready */ ret = vchiq_mmal_component_init( dev->instance, "ril.video_render", - &dev->component[MMAL_COMPONENT_PREVIEW]); + &dev->component[COMP_PREVIEW]); if (ret < 0) goto unreg_camera; - if (dev->component[MMAL_COMPONENT_PREVIEW]->inputs < 1) { + if (dev->component[COMP_PREVIEW]->inputs < 1) { ret = -EINVAL; v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n", - __func__, dev->component[MMAL_COMPONENT_PREVIEW]->inputs, 1); + __func__, dev->component[COMP_PREVIEW]->inputs, 1); goto unreg_preview; } /* get the image encoder component ready */ ret = vchiq_mmal_component_init( dev->instance, "ril.image_encode", - &dev->component[MMAL_COMPONENT_IMAGE_ENCODE]); + &dev->component[COMP_IMAGE_ENCODE]); if (ret < 0) goto unreg_preview; - if (dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->inputs < 1) { + if (dev->component[COMP_IMAGE_ENCODE]->inputs < 1) { ret = -EINVAL; v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n", - __func__, dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->inputs, + __func__, dev->component[COMP_IMAGE_ENCODE]->inputs, 1); goto unreg_image_encoder; } /* get the video encoder component ready */ ret = vchiq_mmal_component_init(dev->instance, "ril.video_encode", - &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]); + &dev->component[COMP_VIDEO_ENCODE]); if (ret < 0) goto unreg_image_encoder; - if (dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->inputs < 1) { + if (dev->component[COMP_VIDEO_ENCODE]->inputs < 1) { ret = -EINVAL; v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n", - __func__, dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->inputs, + __func__, dev->component[COMP_VIDEO_ENCODE]->inputs, 1); goto unreg_vid_encoder; } { struct vchiq_mmal_port *encoder_port = - &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + &dev->component[COMP_VIDEO_ENCODE]->output[0]; encoder_port->format.encoding = MMAL_ENCODING_H264; ret = vchiq_mmal_port_set_format(dev->instance, encoder_port); @@ -1686,12 +1739,12 @@ static int mmal_init(struct bm2835_mmal_dev *dev) vchiq_mmal_port_parameter_set( dev->instance, - &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->control, + &dev->component[COMP_VIDEO_ENCODE]->control, MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, &enable, sizeof(enable)); vchiq_mmal_port_parameter_set(dev->instance, - &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->control, + &dev->component[COMP_VIDEO_ENCODE]->control, MMAL_PARAMETER_MINIMISE_FRAGMENTATION, &enable, sizeof(enable)); @@ -1709,23 +1762,23 @@ unreg_vid_encoder: pr_err("Cleanup: Destroy video encoder\n"); vchiq_mmal_component_finalise( dev->instance, - dev->component[MMAL_COMPONENT_VIDEO_ENCODE]); + dev->component[COMP_VIDEO_ENCODE]); unreg_image_encoder: pr_err("Cleanup: Destroy image encoder\n"); vchiq_mmal_component_finalise( dev->instance, - dev->component[MMAL_COMPONENT_IMAGE_ENCODE]); + dev->component[COMP_IMAGE_ENCODE]); unreg_preview: pr_err("Cleanup: Destroy video render\n"); vchiq_mmal_component_finalise(dev->instance, - dev->component[MMAL_COMPONENT_PREVIEW]); + dev->component[COMP_PREVIEW]); unreg_camera: pr_err("Cleanup: Destroy camera\n"); vchiq_mmal_component_finalise(dev->instance, - dev->component[MMAL_COMPONENT_CAMERA]); + dev->component[COMP_CAMERA]); unreg_mmal: vchiq_mmal_finalise(dev->instance); @@ -1781,19 +1834,19 @@ static void bcm2835_cleanup_instance(struct bm2835_mmal_dev *dev) dev->capture.encode_component); } vchiq_mmal_component_disable(dev->instance, - dev->component[MMAL_COMPONENT_CAMERA]); + dev->component[COMP_CAMERA]); vchiq_mmal_component_finalise(dev->instance, - dev->component[MMAL_COMPONENT_VIDEO_ENCODE]); + dev->component[COMP_VIDEO_ENCODE]); vchiq_mmal_component_finalise(dev->instance, - dev->component[MMAL_COMPONENT_IMAGE_ENCODE]); + dev->component[COMP_IMAGE_ENCODE]); vchiq_mmal_component_finalise(dev->instance, - dev->component[MMAL_COMPONENT_PREVIEW]); + dev->component[COMP_PREVIEW]); vchiq_mmal_component_finalise(dev->instance, - dev->component[MMAL_COMPONENT_CAMERA]); + dev->component[COMP_CAMERA]); v4l2_ctrl_handler_free(&dev->ctrl_handler); diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h index 2b5679eb5b4a..b5fce38de038 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom * * core driver device */ @@ -15,18 +16,18 @@ #define V4L2_CTRL_COUNT 29 /* number of v4l controls */ enum { - MMAL_COMPONENT_CAMERA = 0, - MMAL_COMPONENT_PREVIEW, - MMAL_COMPONENT_IMAGE_ENCODE, - MMAL_COMPONENT_VIDEO_ENCODE, - MMAL_COMPONENT_COUNT + COMP_CAMERA = 0, + COMP_PREVIEW, + COMP_IMAGE_ENCODE, + COMP_VIDEO_ENCODE, + COMP_COUNT }; enum { - MMAL_CAMERA_PORT_PREVIEW = 0, - MMAL_CAMERA_PORT_VIDEO, - MMAL_CAMERA_PORT_CAPTURE, - MMAL_CAMERA_PORT_COUNT + CAM_PORT_PREVIEW = 0, + CAM_PORT_VIDEO, + CAM_PORT_CAPTURE, + CAM_PORT_COUNT }; #define PREVIEW_LAYER 2 @@ -60,7 +61,7 @@ struct bm2835_mmal_dev { /* allocated mmal instance and components */ struct vchiq_mmal_instance *instance; - struct vchiq_mmal_component *component[MMAL_COMPONENT_COUNT]; + struct vchiq_mmal_component *component[COMP_COUNT]; int camera_use_count; struct v4l2_window overlay; @@ -90,6 +91,8 @@ struct bm2835_mmal_dev { s64 vc_start_timestamp; /* Kernel start timestamp for streaming */ ktime_t kernel_start_ts; + /* Sequence number of last buffer */ + u32 sequence; struct vchiq_mmal_port *port; /* port being used for capture */ /* camera port being used for capture */ @@ -127,6 +130,7 @@ int set_framerate_params(struct bm2835_mmal_dev *dev); (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, \ diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c index dade79738a29..89786c264867 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ #include <linux/errno.h> @@ -52,21 +53,9 @@ static const s64 ev_bias_qmenu[] = { static const s64 iso_qmenu[] = { 0, 100000, 200000, 400000, 800000, }; -static const uint32_t iso_values[] = { - 0, 100, 200, 400, 800, -}; -static const s64 mains_freq_qmenu[] = { - V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, - V4L2_CID_POWER_LINE_FREQUENCY_50HZ, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, - V4L2_CID_POWER_LINE_FREQUENCY_AUTO -}; - -/* Supported video encode modes */ -static const s64 bitrate_mode_qmenu[] = { - (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, +static const u32 iso_values[] = { + 0, 100, 200, 400, 800, }; enum bm2835_mmal_ctrl_type { @@ -89,10 +78,10 @@ struct bm2835_mmal_v4l2_ctrl { /* control minimum value or * mask for MMAL_CONTROL_TYPE_STD_MENU */ - s32 min; - s32 max; /* maximum value of control */ - s32 def; /* default value of control */ - s32 step; /* step size of the control */ + s64 min; + s64 max; /* maximum value of control */ + s64 def; /* default value of control */ + u64 step; /* step size of the control */ const s64 *imenu; /* integer menu array */ u32 mmal_id; /* mmal parameter id */ bm2835_mmal_v4l2_ctrl_cb *setter; @@ -175,7 +164,7 @@ static int ctrl_set_rational(struct bm2835_mmal_dev *dev, struct mmal_parameter_rational rational_value; struct vchiq_mmal_port *control; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; rational_value.num = ctrl->val; rational_value.den = 100; @@ -193,7 +182,7 @@ static int ctrl_set_value(struct bm2835_mmal_dev *dev, u32 u32_value; struct vchiq_mmal_port *control; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; u32_value = ctrl->val; @@ -218,7 +207,7 @@ static int ctrl_set_iso(struct bm2835_mmal_dev *dev, dev->manual_iso_enabled = (ctrl->val == V4L2_ISO_SENSITIVITY_MANUAL); - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; if (dev->manual_iso_enabled) u32_value = dev->iso; @@ -237,7 +226,7 @@ static int ctrl_set_value_ev(struct bm2835_mmal_dev *dev, s32 s32_value; struct vchiq_mmal_port *control; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; s32_value = (ctrl->val - 12) * 2; /* Convert from index to 1/6ths */ @@ -254,7 +243,7 @@ static int ctrl_set_rotate(struct bm2835_mmal_dev *dev, u32 u32_value; struct vchiq_mmal_component *camera; - camera = dev->component[MMAL_COMPONENT_CAMERA]; + camera = dev->component[COMP_CAMERA]; u32_value = ((ctrl->val % 360) / 90) * 90; @@ -288,7 +277,7 @@ static int ctrl_set_flip(struct bm2835_mmal_dev *dev, else dev->vflip = ctrl->val; - camera = dev->component[MMAL_COMPONENT_CAMERA]; + camera = dev->component[COMP_CAMERA]; if (dev->hflip && dev->vflip) u32_value = MMAL_PARAM_MIRROR_BOTH; @@ -325,7 +314,7 @@ static int ctrl_set_exposure(struct bm2835_mmal_dev *dev, struct vchiq_mmal_port *control; int ret = 0; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; if (mmal_ctrl->mmal_id == MMAL_PARAMETER_SHUTTER_SPEED) { /* V4L2 is in 100usec increments. @@ -400,13 +389,14 @@ static int ctrl_set_metering_mode(struct bm2835_mmal_dev *dev, struct vchiq_mmal_port *control; u32 u32_value = dev->metering_mode; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; return vchiq_mmal_port_parameter_set(dev->instance, control, mmal_ctrl->mmal_id, &u32_value, sizeof(u32_value)); - } else + } else { return 0; + } } static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev, @@ -416,7 +406,7 @@ static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev, u32 u32_value; struct vchiq_mmal_port *control; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; switch (ctrl->val) { case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED: @@ -445,7 +435,7 @@ static int ctrl_set_awb_mode(struct bm2835_mmal_dev *dev, u32 u32_value; struct vchiq_mmal_port *control; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; switch (ctrl->val) { case V4L2_WHITE_BALANCE_MANUAL: @@ -501,7 +491,7 @@ static int ctrl_set_awb_gains(struct bm2835_mmal_dev *dev, struct vchiq_mmal_port *control; struct mmal_parameter_awbgains gains; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; if (ctrl->id == V4L2_CID_RED_BALANCE) dev->red_gain = ctrl->val; @@ -549,7 +539,7 @@ static int ctrl_set_image_effect(struct bm2835_mmal_dev *dev, v4l2_to_mmal_effects_values[i].v; } - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; ret = vchiq_mmal_port_parameter_set( dev->instance, control, @@ -579,13 +569,13 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev *dev, struct v4l2_ctrl *ctrl, const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) { - int ret = -EINVAL; + int ret; struct vchiq_mmal_port *control; - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; - dev->colourfx.enable = (ctrl->val & 0xff00) >> 8; - dev->colourfx.enable = ctrl->val & 0xff; + dev->colourfx.u = (ctrl->val & 0xff00) >> 8; + dev->colourfx.v = ctrl->val & 0xff; ret = vchiq_mmal_port_parameter_set(dev->instance, control, MMAL_PARAMETER_COLOUR_EFFECT, @@ -603,15 +593,28 @@ static int ctrl_set_bitrate(struct bm2835_mmal_dev *dev, struct v4l2_ctrl *ctrl, const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) { + int ret; struct vchiq_mmal_port *encoder_out; dev->capture.encode_bitrate = ctrl->val; - encoder_out = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0]; - return vchiq_mmal_port_parameter_set(dev->instance, encoder_out, - mmal_ctrl->mmal_id, &ctrl->val, - sizeof(ctrl->val)); + ret = vchiq_mmal_port_parameter_set(dev->instance, encoder_out, + mmal_ctrl->mmal_id, &ctrl->val, + sizeof(ctrl->val)); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n", + __func__, mmal_ctrl, ctrl->id, ctrl->val, ret, + (ret == 0 ? 0 : -EINVAL)); + + /* + * Older firmware versions (pre July 2019) have a bug in handling + * MMAL_PARAMETER_VIDEO_BIT_RATE that result in the call + * returning -MMAL_MSG_STATUS_EINVAL. So ignore errors from this call. + */ + return 0; } static int ctrl_set_bitrate_mode(struct bm2835_mmal_dev *dev, @@ -621,7 +624,7 @@ static int ctrl_set_bitrate_mode(struct bm2835_mmal_dev *dev, u32 bitrate_mode; struct vchiq_mmal_port *encoder_out; - encoder_out = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0]; dev->capture.encode_bitrate_mode = ctrl->val; switch (ctrl->val) { @@ -648,7 +651,7 @@ static int ctrl_set_image_encode_output(struct bm2835_mmal_dev *dev, u32 u32_value; struct vchiq_mmal_port *jpeg_out; - jpeg_out = &dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->output[0]; + jpeg_out = &dev->component[COMP_IMAGE_ENCODE]->output[0]; u32_value = ctrl->val; @@ -664,7 +667,7 @@ static int ctrl_set_video_encode_param_output(struct bm2835_mmal_dev *dev, u32 u32_value; struct vchiq_mmal_port *vid_enc_ctl; - vid_enc_ctl = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0]; + vid_enc_ctl = &dev->component[COMP_VIDEO_ENCODE]->output[0]; u32_value = ctrl->val; @@ -777,7 +780,7 @@ static int ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev *dev, } ret = vchiq_mmal_port_parameter_set(dev->instance, - &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0], + &dev->component[COMP_VIDEO_ENCODE]->output[0], mmal_ctrl->mmal_id, ¶m, sizeof(param)); } @@ -795,7 +798,7 @@ static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev, v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev, "scene mode selected %d, was %d\n", ctrl->val, dev->scene_mode); - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; + control = &dev->component[COMP_CAMERA]->control; if (ctrl->val == dev->scene_mode) return 0; @@ -956,8 +959,8 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { }, { V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU, - 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL, - MMAL_PARAMETER_ISO, + 0, V4L2_ISO_SENSITIVITY_AUTO, V4L2_ISO_SENSITIVITY_AUTO, 1, + NULL, MMAL_PARAMETER_ISO, ctrl_set_iso, false }, @@ -968,22 +971,13 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { ctrl_set_value, false }, -/* { - * 0, MMAL_CONTROL_TYPE_CLUSTER, 3, 1, 0, NULL, 0, NULL - * }, - */ { V4L2_CID_EXPOSURE_AUTO, MMAL_CONTROL_TYPE_STD_MENU, - ~0x03, 3, V4L2_EXPOSURE_AUTO, 0, NULL, - MMAL_PARAMETER_EXPOSURE_MODE, + ~0x03, V4L2_EXPOSURE_APERTURE_PRIORITY, V4L2_EXPOSURE_AUTO, 0, + NULL, MMAL_PARAMETER_EXPOSURE_MODE, ctrl_set_exposure, false }, -/* todo this needs mixing in with set exposure - * { - * V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, - * }, - */ { V4L2_CID_EXPOSURE_ABSOLUTE, MMAL_CONTROL_TYPE_STD, /* Units of 100usecs */ @@ -1011,7 +1005,8 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { { V4L2_CID_EXPOSURE_METERING, MMAL_CONTROL_TYPE_STD_MENU, - ~0x7, 2, V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL, + ~0x7, V4L2_EXPOSURE_METERING_SPOT, + V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL, MMAL_PARAMETER_EXP_METERING_MODE, ctrl_set_metering_mode, false @@ -1019,7 +1014,8 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { { V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, MMAL_CONTROL_TYPE_STD_MENU, - ~0x3ff, 9, V4L2_WHITE_BALANCE_AUTO, 0, NULL, + ~0x3ff, V4L2_WHITE_BALANCE_SHADE, V4L2_WHITE_BALANCE_AUTO, 0, + NULL, MMAL_PARAMETER_AWB_MODE, ctrl_set_awb_mode, false @@ -1040,7 +1036,7 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { }, { V4L2_CID_COLORFX, MMAL_CONTROL_TYPE_STD_MENU, - 0, 15, V4L2_COLORFX_NONE, 0, NULL, + 0, V4L2_COLORFX_SET_CBCR, V4L2_COLORFX_NONE, 0, NULL, MMAL_PARAMETER_IMAGE_EFFECT, ctrl_set_image_effect, false @@ -1075,8 +1071,8 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { }, { V4L2_CID_MPEG_VIDEO_BITRATE_MODE, MMAL_CONTROL_TYPE_STD_MENU, - 0, ARRAY_SIZE(bitrate_mode_qmenu) - 1, - 0, 0, bitrate_mode_qmenu, + 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, + 0, 0, NULL, MMAL_PARAMETER_RATECONTROL, ctrl_set_bitrate_mode, false @@ -1098,8 +1094,8 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { }, { V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU, - 0, ARRAY_SIZE(mains_freq_qmenu) - 1, - 1, 1, mains_freq_qmenu, + 0, V4L2_CID_POWER_LINE_FREQUENCY_AUTO, + 1, 1, NULL, MMAL_PARAMETER_FLICKER_AVOID, ctrl_set_flicker_avoidance, false @@ -1110,15 +1106,15 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { 0, 1, NULL, MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, ctrl_set_video_encode_param_output, - true /* Errors ignored as requires latest firmware to work */ + false }, { V4L2_CID_MPEG_VIDEO_H264_PROFILE, MMAL_CONTROL_TYPE_STD_MENU, - ~((1<<V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | - (1<<V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | - (1<<V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | - (1<<V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), + ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1, NULL, MMAL_PARAMETER_PROFILE, @@ -1127,18 +1123,18 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { }, { V4L2_CID_MPEG_VIDEO_H264_LEVEL, MMAL_CONTROL_TYPE_STD_MENU, - ~((1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1B) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | - (1<<V4L2_MPEG_VIDEO_H264_LEVEL_4_0)), + ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0)), V4L2_MPEG_VIDEO_H264_LEVEL_4_0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0, 1, NULL, MMAL_PARAMETER_PROFILE, @@ -1147,7 +1143,7 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { }, { V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, - -1, /* Min is computed at runtime */ + -1, /* Min (mask) is computed at runtime */ V4L2_SCENE_MODE_TEXT, V4L2_SCENE_MODE_NONE, 1, NULL, MMAL_PARAMETER_PROFILE, @@ -1213,18 +1209,15 @@ int set_framerate_params(struct bm2835_mmal_dev *dev) fps_range.fps_high.den); ret = vchiq_mmal_port_parameter_set(dev->instance, - &dev->component[MMAL_COMPONENT_CAMERA]-> - output[MMAL_CAMERA_PORT_PREVIEW], + &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW], MMAL_PARAMETER_FPS_RANGE, &fps_range, sizeof(fps_range)); ret += vchiq_mmal_port_parameter_set(dev->instance, - &dev->component[MMAL_COMPONENT_CAMERA]-> - output[MMAL_CAMERA_PORT_VIDEO], + &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO], MMAL_PARAMETER_FPS_RANGE, &fps_range, sizeof(fps_range)); ret += vchiq_mmal_port_parameter_set(dev->instance, - &dev->component[MMAL_COMPONENT_CAMERA]-> - output[MMAL_CAMERA_PORT_CAPTURE], + &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE], MMAL_PARAMETER_FPS_RANGE, &fps_range, sizeof(fps_range)); if (ret) @@ -1247,14 +1240,17 @@ int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev, switch (ctrl->type) { case MMAL_CONTROL_TYPE_STD: - dev->ctrls[c] = v4l2_ctrl_new_std(hdl, - &bm2835_mmal_ctrl_ops, ctrl->id, - ctrl->min, ctrl->max, ctrl->step, ctrl->def); + dev->ctrls[c] = + v4l2_ctrl_new_std(hdl, + &bm2835_mmal_ctrl_ops, + ctrl->id, ctrl->min, + ctrl->max, ctrl->step, + ctrl->def); break; case MMAL_CONTROL_TYPE_STD_MENU: { - int mask = ctrl->min; + u64 mask = ctrl->min; if (ctrl->id == V4L2_CID_SCENE_MODE) { /* Special handling to work out the mask @@ -1264,25 +1260,29 @@ int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev, */ int i; - mask = 1 << V4L2_SCENE_MODE_NONE; + mask = BIT(V4L2_SCENE_MODE_NONE); for (i = 0; i < ARRAY_SIZE(scene_configs); i++) { - mask |= 1 << scene_configs[i].v4l2_scene; + mask |= BIT(scene_configs[i].v4l2_scene); } mask = ~mask; } - dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl, - &bm2835_mmal_ctrl_ops, ctrl->id, - ctrl->max, mask, ctrl->def); + dev->ctrls[c] = + v4l2_ctrl_new_std_menu(hdl, + &bm2835_mmal_ctrl_ops, + ctrl->id, ctrl->max, + mask, ctrl->def); break; } case MMAL_CONTROL_TYPE_INT_MENU: - dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl, - &bm2835_mmal_ctrl_ops, ctrl->id, - ctrl->max, ctrl->def, ctrl->imenu); + dev->ctrls[c] = + v4l2_ctrl_new_int_menu(hdl, + &bm2835_mmal_ctrl_ops, + ctrl->id, ctrl->max, + ctrl->def, ctrl->imenu); break; case MMAL_CONTROL_TYPE_CLUSTER: diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h index a20bf274a4fd..6f56c517d850 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h @@ -4,14 +4,17 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom * * MMAL structures * */ +#ifndef MMAL_COMMON_H +#define MMAL_COMMON_H #define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) #define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') @@ -55,3 +58,4 @@ struct mmal_colourfx { u32 u; u32 v; }; +#endif diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h index 129203597f91..2be9941a1f30 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ #ifndef MMAL_ENCODINGS_H #define MMAL_ENCODINGS_H diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h index ec8455639d49..342c9b670f7e 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ #ifndef MMAL_MSG_COMMON_H diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h index c9d6fbe25fe4..a118efd21d98 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ #ifndef MMAL_MSG_FORMAT_H @@ -18,22 +19,23 @@ /* MMAL_ES_FORMAT_T */ struct mmal_audio_format { - u32 channels; /**< Number of audio channels */ - u32 sample_rate; /**< Sample rate */ + u32 channels; /* Number of audio channels */ + u32 sample_rate; /* Sample rate */ - u32 bits_per_sample; /**< Bits per sample */ - u32 block_align; /**< Size of a block of data */ + u32 bits_per_sample; /* Bits per sample */ + u32 block_align; /* Size of a block of data */ }; struct mmal_video_format { - u32 width; /**< Width of frame in pixels */ - u32 height; /**< Height of frame in rows of pixels */ - struct mmal_rect crop; /**< Visible region of the frame */ - struct mmal_rational frame_rate; /**< Frame rate */ - struct mmal_rational par; /**< Pixel aspect ratio */ - - /* FourCC specifying the color space of the video stream. See the - * \ref MmalColorSpace "pre-defined color spaces" for some examples. + u32 width; /* Width of frame in pixels */ + u32 height; /* Height of frame in rows of pixels */ + struct mmal_rect crop; /* Visible region of the frame */ + struct mmal_rational frame_rate; /* Frame rate */ + struct mmal_rational par; /* Pixel aspect ratio */ + + /* + * FourCC specifying the color space of the video stream. See the + * MmalColorSpace "pre-defined color spaces" for some examples. */ u32 color_space; }; @@ -49,48 +51,56 @@ union mmal_es_specific_format { struct mmal_subpicture_format subpicture; }; -/** Definition of an elementary stream format (MMAL_ES_FORMAT_T) */ +/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */ struct mmal_es_format_local { - u32 type; /* enum mmal_es_type */ - - u32 encoding; /* FourCC specifying encoding of the elementary stream.*/ - u32 encoding_variant; /* FourCC specifying the specific - * encoding variant of the elementary - * stream. - */ - - union mmal_es_specific_format *es; /* Type specific - * information for the - * elementary stream - */ - - u32 bitrate; /**< Bitrate in bits per second */ - u32 flags; /**< Flags describing properties of the elementary stream. */ - - u32 extradata_size; /**< Size of the codec specific data */ - u8 *extradata; /**< Codec specific data */ + u32 type; /* enum mmal_es_type */ + + u32 encoding; /* FourCC specifying encoding of the elementary + * stream. + */ + u32 encoding_variant; /* FourCC specifying the specific + * encoding variant of the elementary + * stream. + */ + + union mmal_es_specific_format *es; /* Type specific + * information for the + * elementary stream + */ + + u32 bitrate; /* Bitrate in bits per second */ + u32 flags; /* Flags describing properties of the elementary + * stream. + */ + + u32 extradata_size; /* Size of the codec specific data */ + u8 *extradata; /* Codec specific data */ }; -/** Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */ +/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */ struct mmal_es_format { - u32 type; /* enum mmal_es_type */ + u32 type; /* enum mmal_es_type */ - u32 encoding; /* FourCC specifying encoding of the elementary stream.*/ - u32 encoding_variant; /* FourCC specifying the specific - * encoding variant of the elementary - * stream. - */ + u32 encoding; /* FourCC specifying encoding of the elementary + * stream. + */ + u32 encoding_variant; /* FourCC specifying the specific + * encoding variant of the elementary + * stream. + */ - u32 es; /* Type specific + u32 es; /* Type specific * information for the * elementary stream */ - u32 bitrate; /**< Bitrate in bits per second */ - u32 flags; /**< Flags describing properties of the elementary stream. */ + u32 bitrate; /* Bitrate in bits per second */ + u32 flags; /* Flags describing properties of the elementary + * stream. + */ - u32 extradata_size; /**< Size of the codec specific data */ - u32 extradata; /**< Codec specific data */ + u32 extradata_size; /* Size of the codec specific data */ + u32 extradata; /* Codec specific data */ }; #endif /* MMAL_MSG_FORMAT_H */ diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h index 3b3ed79cadd9..3fa3f2a578f0 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h @@ -4,36 +4,40 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ /* MMAL_PORT_TYPE_T */ enum mmal_port_type { - MMAL_PORT_TYPE_UNKNOWN = 0, /**< Unknown port type */ - MMAL_PORT_TYPE_CONTROL, /**< Control port */ - MMAL_PORT_TYPE_INPUT, /**< Input port */ - MMAL_PORT_TYPE_OUTPUT, /**< Output port */ - MMAL_PORT_TYPE_CLOCK, /**< Clock port */ + MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */ + MMAL_PORT_TYPE_CONTROL, /* Control port */ + MMAL_PORT_TYPE_INPUT, /* Input port */ + MMAL_PORT_TYPE_OUTPUT, /* Output port */ + MMAL_PORT_TYPE_CLOCK, /* Clock port */ }; -/** The port is pass-through and doesn't need buffer headers allocated */ +/* The port is pass-through and doesn't need buffer headers allocated */ #define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01 -/** The port wants to allocate the buffer payloads. +/* + *The port wants to allocate the buffer payloads. * This signals a preference that payload allocation should be done * on this port for efficiency reasons. */ #define MMAL_PORT_CAPABILITY_ALLOCATION 0x02 -/** The port supports format change events. +/* + * The port supports format change events. * This applies to input ports and is used to let the client know * whether the port supports being reconfigured via a format * change event (i.e. without having to disable the port). */ #define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04 -/* mmal port structure (MMAL_PORT_T) +/* + * mmal port structure (MMAL_PORT_T) * * most elements are informational only, the pointer values for * interogation messages are generally provided as additional @@ -41,50 +45,50 @@ enum mmal_port_type { * buffer_num, buffer_size and userdata parameters are writable. */ struct mmal_port { - u32 priv; /* Private member used by the framework */ - u32 name; /* Port name. Used for debugging purposes (RO) */ - - u32 type; /* Type of the port (RO) enum mmal_port_type */ - u16 index; /* Index of the port in its type list (RO) */ - u16 index_all; /* Index of the port in the list of all ports (RO) */ - - u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */ - u32 format; /* Format of the elementary stream */ - - u32 buffer_num_min; /* Minimum number of buffers the port - * requires (RO). This is set by the - * component. - */ - - u32 buffer_size_min; /* Minimum size of buffers the port - * requires (RO). This is set by the - * component. - */ - - u32 buffer_alignment_min; /* Minimum alignment requirement for - * the buffers (RO). A value of - * zero means no special alignment - * requirements. This is set by the - * component. - */ - - u32 buffer_num_recommended; /* Number of buffers the port - * recommends for optimal - * performance (RO). A value of - * zero means no special - * recommendation. This is set - * by the component. - */ - - u32 buffer_size_recommended; /* Size of buffers the port - * recommends for optimal - * performance (RO). A value of - * zero means no special - * recommendation. This is set - * by the component. - */ - - u32 buffer_num; /* Actual number of buffers the port will use. + u32 priv; /* Private member used by the framework */ + u32 name; /* Port name. Used for debugging purposes (RO) */ + + u32 type; /* Type of the port (RO) enum mmal_port_type */ + u16 index; /* Index of the port in its type list (RO) */ + u16 index_all; /* Index of the port in the list of all ports (RO) */ + + u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */ + u32 format; /* Format of the elementary stream */ + + u32 buffer_num_min; /* Minimum number of buffers the port + * requires (RO). This is set by the + * component. + */ + + u32 buffer_size_min; /* Minimum size of buffers the port + * requires (RO). This is set by the + * component. + */ + + u32 buffer_alignment_min;/* Minimum alignment requirement for + * the buffers (RO). A value of + * zero means no special alignment + * requirements. This is set by the + * component. + */ + + u32 buffer_num_recommended; /* Number of buffers the port + * recommends for optimal + * performance (RO). A value of + * zero means no special + * recommendation. This is set + * by the component. + */ + + u32 buffer_size_recommended; /* Size of buffers the port + * recommends for optimal + * performance (RO). A value of + * zero means no special + * recommendation. This is set + * by the component. + */ + + u32 buffer_num; /* Actual number of buffers the port will use. * This is set by the client. */ @@ -93,14 +97,13 @@ struct mmal_port { * the client. */ - u32 component; /* Component this port belongs to (Read Only) */ - - u32 userdata; /* Field reserved for use by the client */ + u32 component; /* Component this port belongs to (Read Only) */ - u32 capabilities; /* Flags describing the capabilities of a - * port (RO). Bitwise combination of \ref - * portcapabilities "Port capabilities" - * values. - */ + u32 userdata; /* Field reserved for use by the client */ + u32 capabilities; /* Flags describing the capabilities of a + * port (RO). Bitwise combination of \ref + * portcapabilities "Port capabilities" + * values. + */ }; diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h index d1c57edbe2b8..43cc59316f90 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h @@ -4,13 +4,15 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ -/* all the data structures which serialise the MMAL protocol. note +/* + * all the data structures which serialise the MMAL protocol. note * these are directly mapped onto the recived message data. * * BEWARE: They seem to *assume* pointers are u32 and that there is no @@ -21,6 +23,8 @@ * implementation uses fixed size types and not the enums (though the * comments have the actual enum type */ +#ifndef MMAL_MSG_H +#define MMAL_MSG_H #define VC_MMAL_VER 15 #define VC_MMAL_MIN_VER 10 @@ -40,51 +44,51 @@ enum mmal_msg_type { MMAL_MSG_TYPE_SERVICE_CLOSED, MMAL_MSG_TYPE_GET_VERSION, MMAL_MSG_TYPE_COMPONENT_CREATE, - MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */ + MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */ MMAL_MSG_TYPE_COMPONENT_ENABLE, MMAL_MSG_TYPE_COMPONENT_DISABLE, MMAL_MSG_TYPE_PORT_INFO_GET, MMAL_MSG_TYPE_PORT_INFO_SET, - MMAL_MSG_TYPE_PORT_ACTION, /* 10 */ + MMAL_MSG_TYPE_PORT_ACTION, /* 10 */ MMAL_MSG_TYPE_BUFFER_FROM_HOST, MMAL_MSG_TYPE_BUFFER_TO_HOST, MMAL_MSG_TYPE_GET_STATS, MMAL_MSG_TYPE_PORT_PARAMETER_SET, - MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */ + MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */ MMAL_MSG_TYPE_EVENT_TO_HOST, MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT, MMAL_MSG_TYPE_OPAQUE_ALLOCATOR, MMAL_MSG_TYPE_CONSUME_MEM, - MMAL_MSG_TYPE_LMK, /* 20 */ + MMAL_MSG_TYPE_LMK, /* 20 */ MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC, MMAL_MSG_TYPE_DRM_GET_LHS32, MMAL_MSG_TYPE_DRM_GET_TIME, MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN, - MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */ + MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */ MMAL_MSG_TYPE_HOST_LOG, MMAL_MSG_TYPE_MSG_LAST }; /* port action request messages differ depending on the action type */ enum mmal_msg_port_action_type { - MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */ - MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */ - MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */ - MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */ - MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */ - MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */ + MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */ + MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */ + MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */ + MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */ + MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */ + MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */ MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/ }; struct mmal_msg_header { u32 magic; - u32 type; /** enum mmal_msg_type */ + u32 type; /* enum mmal_msg_type */ /* Opaque handle to the control service */ u32 control_service; - u32 context; /** a u32 per message context */ - u32 status; /** The status of the vchiq operation */ + u32 context; /* a u32 per message context */ + u32 status; /* The status of the vchiq operation */ u32 padding; }; @@ -98,9 +102,9 @@ struct mmal_msg_version { /* request to VC to create component */ struct mmal_msg_component_create { - u32 client_component; /* component context */ + u32 client_component; /* component context */ char name[128]; - u32 pid; /* For debug */ + u32 pid; /* For debug */ }; /* reply from VC to component creation request */ @@ -120,7 +124,7 @@ struct mmal_msg_component_destroy { }; struct mmal_msg_component_destroy_reply { - u32 status; /** The component destruction status */ + u32 status; /* The component destruction status */ }; /* request and reply to VC to enable a component */ @@ -129,7 +133,7 @@ struct mmal_msg_component_enable { }; struct mmal_msg_component_enable_reply { - u32 status; /** The component enable status */ + u32 status; /* The component enable status */ }; /* request and reply to VC to disable a component */ @@ -138,7 +142,7 @@ struct mmal_msg_component_disable { }; struct mmal_msg_component_disable_reply { - u32 status; /** The component disable status */ + u32 status; /* The component disable status */ }; /* request to VC to get port information */ @@ -150,12 +154,12 @@ struct mmal_msg_port_info_get { /* reply from VC to get port info request */ struct mmal_msg_port_info_get_reply { - u32 status; /** enum mmal_msg_status */ - u32 component_handle; /* component handle port is associated with */ - u32 port_type; /* enum mmal_msg_port_type */ - u32 port_index; /* port indexed in query */ - s32 found; /* unused */ - u32 port_handle; /**< Handle to use for this port */ + u32 status; /* enum mmal_msg_status */ + u32 component_handle; /* component handle port is associated with */ + u32 port_type; /* enum mmal_msg_port_type */ + u32 port_index; /* port indexed in query */ + s32 found; /* unused */ + u32 port_handle; /* Handle to use for this port */ struct mmal_port port; struct mmal_es_format format; /* elementary stream format */ union mmal_es_specific_format es; /* es type specific data */ @@ -165,8 +169,8 @@ struct mmal_msg_port_info_get_reply { /* request to VC to set port information */ struct mmal_msg_port_info_set { u32 component_handle; - u32 port_type; /* enum mmal_msg_port_type */ - u32 port_index; /* port indexed in query */ + u32 port_type; /* enum mmal_msg_port_type */ + u32 port_index; /* port indexed in query */ struct mmal_port port; struct mmal_es_format format; union mmal_es_specific_format es; @@ -176,11 +180,11 @@ struct mmal_msg_port_info_set { /* reply from VC to port info set request */ struct mmal_msg_port_info_set_reply { u32 status; - u32 component_handle; /* component handle port is associated with */ - u32 port_type; /* enum mmal_msg_port_type */ - u32 index; /* port indexed in query */ - s32 found; /* unused */ - u32 port_handle; /**< Handle to use for this port */ + u32 component_handle; /* component handle port is associated with */ + u32 port_type; /* enum mmal_msg_port_type */ + u32 index; /* port indexed in query */ + s32 found; /* unused */ + u32 port_handle; /* Handle to use for this port */ struct mmal_port port; struct mmal_es_format format; union mmal_es_specific_format es; @@ -191,7 +195,7 @@ struct mmal_msg_port_info_set_reply { struct mmal_msg_port_action_port { u32 component_handle; u32 port_handle; - u32 action; /* enum mmal_msg_port_action_type */ + u32 action; /* enum mmal_msg_port_action_type */ struct mmal_port port; }; @@ -199,50 +203,54 @@ struct mmal_msg_port_action_port { struct mmal_msg_port_action_handle { u32 component_handle; u32 port_handle; - u32 action; /* enum mmal_msg_port_action_type */ + u32 action; /* enum mmal_msg_port_action_type */ u32 connect_component_handle; u32 connect_port_handle; }; struct mmal_msg_port_action_reply { - u32 status; /** The port action operation status */ + u32 status; /* The port action operation status */ }; /* MMAL buffer transfer */ -/** Size of space reserved in a buffer message for short messages. */ +/* Size of space reserved in a buffer message for short messages. */ #define MMAL_VC_SHORT_DATA 128 -/** Signals that the current payload is the end of the stream of data */ +/* Signals that the current payload is the end of the stream of data */ #define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0) -/** Signals that the start of the current payload starts a frame */ +/* Signals that the start of the current payload starts a frame */ #define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1) -/** Signals that the end of the current payload ends a frame */ +/* Signals that the end of the current payload ends a frame */ #define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2) -/** Signals that the current payload contains only complete frames (>1) */ +/* Signals that the current payload contains only complete frames (>1) */ #define MMAL_BUFFER_HEADER_FLAG_FRAME \ - (MMAL_BUFFER_HEADER_FLAG_FRAME_START|MMAL_BUFFER_HEADER_FLAG_FRAME_END) -/** Signals that the current payload is a keyframe (i.e. self decodable) */ + (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \ + MMAL_BUFFER_HEADER_FLAG_FRAME_END) +/* Signals that the current payload is a keyframe (i.e. self decodable) */ #define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3) -/** Signals a discontinuity in the stream of data (e.g. after a seek). +/* + * Signals a discontinuity in the stream of data (e.g. after a seek). * Can be used for instance by a decoder to reset its state */ #define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4) -/** Signals a buffer containing some kind of config data for the component +/* + * Signals a buffer containing some kind of config data for the component * (e.g. codec config data) */ #define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5) -/** Signals an encrypted payload */ +/* Signals an encrypted payload */ #define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6) -/** Signals a buffer containing side information */ +/* Signals a buffer containing side information */ #define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7) -/** Signals a buffer which is the snapshot/postview image from a stills +/* + * Signals a buffer which is the snapshot/postview image from a stills * capture */ #define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8) -/** Signals a buffer which contains data known to be corrupted */ +/* Signals a buffer which contains data known to be corrupted */ #define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9) -/** Signals that a buffer failed to be transmitted */ +/* Signals that a buffer failed to be transmitted */ #define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10) struct mmal_driver_buffer { @@ -254,8 +262,8 @@ struct mmal_driver_buffer { /* buffer header */ struct mmal_buffer_header { - u32 next; /* next header */ - u32 priv; /* framework private data */ + u32 next; /* next header */ + u32 priv; /* framework private data */ u32 cmd; u32 data; u32 alloc_size; @@ -280,7 +288,8 @@ struct mmal_buffer_header_type_specific { }; struct mmal_msg_buffer_from_host { - /* The front 32 bytes of the buffer header are copied + /* + *The front 32 bytes of the buffer header are copied * back to us in the reply to allow for context. This * area is used to store two mmal_driver_buffer structures to * allow for multiple concurrent service users. @@ -295,7 +304,7 @@ struct mmal_msg_buffer_from_host { s32 is_zero_copy; s32 has_reference; - /** allows short data to be xfered in control message */ + /* allows short data to be xfered in control message */ u32 payload_in_message; u8 short_data[MMAL_VC_SHORT_DATA]; }; @@ -305,11 +314,11 @@ struct mmal_msg_buffer_from_host { #define MMAL_WORKER_PORT_PARAMETER_SPACE 96 struct mmal_msg_port_parameter_set { - u32 component_handle; /* component */ - u32 port_handle; /* port */ - u32 id; /* Parameter ID */ - u32 size; /* Parameter size */ - uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; + u32 component_handle; /* component */ + u32 port_handle; /* port */ + u32 id; /* Parameter ID */ + u32 size; /* Parameter size */ + u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE]; }; struct mmal_msg_port_parameter_set_reply { @@ -321,24 +330,24 @@ struct mmal_msg_port_parameter_set_reply { /* port parameter getting */ struct mmal_msg_port_parameter_get { - u32 component_handle; /* component */ - u32 port_handle; /* port */ - u32 id; /* Parameter ID */ - u32 size; /* Parameter size */ + u32 component_handle; /* component */ + u32 port_handle; /* port */ + u32 id; /* Parameter ID */ + u32 size; /* Parameter size */ }; struct mmal_msg_port_parameter_get_reply { - u32 status; /* Status of mmal_port_parameter_get call */ - u32 id; /* Parameter ID */ - u32 size; /* Parameter size */ - uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; + u32 status; /* Status of mmal_port_parameter_get call */ + u32 id; /* Parameter ID */ + u32 size; /* Parameter size */ + u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE]; }; /* event messages */ #define MMAL_WORKER_EVENT_SPACE 256 struct mmal_msg_event_to_host { - u32 client_component; /* component context */ + u32 client_component; /* component context */ u32 port_type; u32 port_num; @@ -394,3 +403,4 @@ struct mmal_msg { u8 payload[MMAL_MSG_MAX_PAYLOAD]; } u; }; +#endif diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h index 184024dfb8b7..80a99128f5f3 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom */ /* common parameters */ @@ -18,152 +19,208 @@ * @{ */ -#ifndef __MMAL_PARAMETERS_H -#define __MMAL_PARAMETERS_H +#ifndef MMAL_PARAMETERS_H +#define MMAL_PARAMETERS_H /** Common parameter ID group, used with many types of component. */ -#define MMAL_PARAMETER_GROUP_COMMON (0<<16) +#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) /** Camera-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_CAMERA (1<<16) +#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) /** Video-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_VIDEO (2<<16) +#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) /** Audio-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_AUDIO (3<<16) +#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) /** Clock-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_CLOCK (4<<16) +#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) /** Miracast-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_MIRACAST (5<<16) +#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) /* Common parameters */ enum mmal_parameter_common_type { - MMAL_PARAMETER_UNUSED /**< Never a valid parameter ID */ - = MMAL_PARAMETER_GROUP_COMMON, - MMAL_PARAMETER_SUPPORTED_ENCODINGS, /**< MMAL_PARAMETER_ENCODING_T */ - MMAL_PARAMETER_URI, /**< MMAL_PARAMETER_URI_T */ - - /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ + /**< Never a valid parameter ID */ + MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON, + + /**< MMAL_PARAMETER_ENCODING_T */ + MMAL_PARAMETER_SUPPORTED_ENCODINGS, + /**< MMAL_PARAMETER_URI_T */ + MMAL_PARAMETER_URI, + /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ MMAL_PARAMETER_CHANGE_EVENT_REQUEST, - - /** MMAL_PARAMETER_BOOLEAN_T */ + /** MMAL_PARAMETER_BOOLEAN_T */ MMAL_PARAMETER_ZERO_COPY, - - /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ + /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ MMAL_PARAMETER_BUFFER_REQUIREMENTS, - - MMAL_PARAMETER_STATISTICS, /**< MMAL_PARAMETER_STATISTICS_T */ - MMAL_PARAMETER_CORE_STATISTICS, /**< MMAL_PARAMETER_CORE_STATISTICS_T */ - MMAL_PARAMETER_MEM_USAGE, /**< MMAL_PARAMETER_MEM_USAGE_T */ - MMAL_PARAMETER_BUFFER_FLAG_FILTER, /**< MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_SEEK, /**< MMAL_PARAMETER_SEEK_T */ - MMAL_PARAMETER_POWERMON_ENABLE, /**< MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_LOGGING, /**< MMAL_PARAMETER_LOGGING_T */ - MMAL_PARAMETER_SYSTEM_TIME, /**< MMAL_PARAMETER_UINT64_T */ - MMAL_PARAMETER_NO_IMAGE_PADDING /**< MMAL_PARAMETER_BOOLEAN_T */ + /**< MMAL_PARAMETER_STATISTICS_T */ + MMAL_PARAMETER_STATISTICS, + /**< MMAL_PARAMETER_CORE_STATISTICS_T */ + MMAL_PARAMETER_CORE_STATISTICS, + /**< MMAL_PARAMETER_MEM_USAGE_T */ + MMAL_PARAMETER_MEM_USAGE, + /**< MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_BUFFER_FLAG_FILTER, + /**< MMAL_PARAMETER_SEEK_T */ + MMAL_PARAMETER_SEEK, + /**< MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_POWERMON_ENABLE, + /**< MMAL_PARAMETER_LOGGING_T */ + MMAL_PARAMETER_LOGGING, + /**< MMAL_PARAMETER_UINT64_T */ + MMAL_PARAMETER_SYSTEM_TIME, + /**< MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_NO_IMAGE_PADDING, }; /* camera parameters */ enum mmal_parameter_camera_type { /* 0 */ - /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ - MMAL_PARAMETER_THUMBNAIL_CONFIGURATION - = MMAL_PARAMETER_GROUP_CAMERA, - MMAL_PARAMETER_CAPTURE_QUALITY, /**< Unused? */ - MMAL_PARAMETER_ROTATION, /**< @ref MMAL_PARAMETER_INT32_T */ - MMAL_PARAMETER_EXIF_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_EXIF, /**< @ref MMAL_PARAMETER_EXIF_T */ - MMAL_PARAMETER_AWB_MODE, /**< @ref MMAL_PARAM_AWBMODE_T */ - MMAL_PARAMETER_IMAGE_EFFECT, /**< @ref MMAL_PARAMETER_IMAGEFX_T */ - MMAL_PARAMETER_COLOUR_EFFECT, /**< @ref MMAL_PARAMETER_COLOURFX_T */ - MMAL_PARAMETER_FLICKER_AVOID, /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ - MMAL_PARAMETER_FLASH, /**< @ref MMAL_PARAMETER_FLASH_T */ - MMAL_PARAMETER_REDEYE, /**< @ref MMAL_PARAMETER_REDEYE_T */ - MMAL_PARAMETER_FOCUS, /**< @ref MMAL_PARAMETER_FOCUS_T */ - MMAL_PARAMETER_FOCAL_LENGTHS, /**< Unused? */ - MMAL_PARAMETER_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ - MMAL_PARAMETER_ZOOM, /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ - MMAL_PARAMETER_MIRROR, /**< @ref MMAL_PARAMETER_MIRROR_T */ + /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ + MMAL_PARAMETER_THUMBNAIL_CONFIGURATION = + MMAL_PARAMETER_GROUP_CAMERA, + /**< Unused? */ + MMAL_PARAMETER_CAPTURE_QUALITY, + /**< @ref MMAL_PARAMETER_INT32_T */ + MMAL_PARAMETER_ROTATION, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_EXIF_DISABLE, + /**< @ref MMAL_PARAMETER_EXIF_T */ + MMAL_PARAMETER_EXIF, + /**< @ref MMAL_PARAM_AWBMODE_T */ + MMAL_PARAMETER_AWB_MODE, + /**< @ref MMAL_PARAMETER_IMAGEFX_T */ + MMAL_PARAMETER_IMAGE_EFFECT, + /**< @ref MMAL_PARAMETER_COLOURFX_T */ + MMAL_PARAMETER_COLOUR_EFFECT, + /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ + MMAL_PARAMETER_FLICKER_AVOID, + /**< @ref MMAL_PARAMETER_FLASH_T */ + MMAL_PARAMETER_FLASH, + /**< @ref MMAL_PARAMETER_REDEYE_T */ + MMAL_PARAMETER_REDEYE, + /**< @ref MMAL_PARAMETER_FOCUS_T */ + MMAL_PARAMETER_FOCUS, + /**< Unused? */ + MMAL_PARAMETER_FOCAL_LENGTHS, + /**< @ref MMAL_PARAMETER_INT32_T */ + MMAL_PARAMETER_EXPOSURE_COMP, + /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ + MMAL_PARAMETER_ZOOM, + /**< @ref MMAL_PARAMETER_MIRROR_T */ + MMAL_PARAMETER_MIRROR, /* 0x10 */ - MMAL_PARAMETER_CAMERA_NUM, /**< @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_EXPOSURE_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ - MMAL_PARAMETER_EXP_METERING_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ - MMAL_PARAMETER_FOCUS_STATUS, /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ - MMAL_PARAMETER_CAMERA_CONFIG, /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ - MMAL_PARAMETER_CAPTURE_STATUS, /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ - MMAL_PARAMETER_FACE_TRACK, /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ - MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_JPEG_Q_FACTOR, /**< @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_FRAME_RATE, /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ - MMAL_PARAMETER_USE_STC, /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ - MMAL_PARAMETER_CAMERA_INFO, /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ - MMAL_PARAMETER_VIDEO_STABILISATION, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_FACE_TRACK_RESULTS, /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ - MMAL_PARAMETER_ENABLE_RAW_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + /**< @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAMERA_NUM, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAPTURE, + /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ + MMAL_PARAMETER_EXPOSURE_MODE, + /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ + MMAL_PARAMETER_EXP_METERING_MODE, + /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ + MMAL_PARAMETER_FOCUS_STATUS, + /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ + MMAL_PARAMETER_CAMERA_CONFIG, + /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ + MMAL_PARAMETER_CAPTURE_STATUS, + /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ + MMAL_PARAMETER_FACE_TRACK, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, + /**< @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_JPEG_Q_FACTOR, + /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ + MMAL_PARAMETER_FRAME_RATE, + /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ + MMAL_PARAMETER_USE_STC, + /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ + MMAL_PARAMETER_CAMERA_INFO, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_STABILISATION, + /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ + MMAL_PARAMETER_FACE_TRACK_RESULTS, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ENABLE_RAW_CAPTURE, /* 0x20 */ - MMAL_PARAMETER_DPF_FILE, /**< @ref MMAL_PARAMETER_URI_T */ - MMAL_PARAMETER_ENABLE_DPF_FILE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_DPF_FAIL_IS_FATAL, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_CAPTURE_MODE, /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ - MMAL_PARAMETER_FOCUS_REGIONS, /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ - MMAL_PARAMETER_INPUT_CROP, /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ - MMAL_PARAMETER_SENSOR_INFORMATION, /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ - MMAL_PARAMETER_FLASH_SELECT, /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ - MMAL_PARAMETER_FIELD_OF_VIEW, /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ - MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, /**< @ref MMAL_PARAMETER_DRC_T */ - MMAL_PARAMETER_ALGORITHM_CONTROL, /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ - MMAL_PARAMETER_SHARPNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ - MMAL_PARAMETER_CONTRAST, /**< @ref MMAL_PARAMETER_RATIONAL_T */ - MMAL_PARAMETER_BRIGHTNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ - MMAL_PARAMETER_SATURATION, /**< @ref MMAL_PARAMETER_RATIONAL_T */ + /**< @ref MMAL_PARAMETER_URI_T */ + MMAL_PARAMETER_DPF_FILE, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ENABLE_DPF_FILE, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_DPF_FAIL_IS_FATAL, + /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ + MMAL_PARAMETER_CAPTURE_MODE, + /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ + MMAL_PARAMETER_FOCUS_REGIONS, + /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ + MMAL_PARAMETER_INPUT_CROP, + /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ + MMAL_PARAMETER_SENSOR_INFORMATION, + /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ + MMAL_PARAMETER_FLASH_SELECT, + /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ + MMAL_PARAMETER_FIELD_OF_VIEW, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, + /**< @ref MMAL_PARAMETER_DRC_T */ + MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, + /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ + MMAL_PARAMETER_ALGORITHM_CONTROL, + /**< @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_SHARPNESS, + /**< @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_CONTRAST, + /**< @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_BRIGHTNESS, + /**< @ref MMAL_PARAMETER_RATIONAL_T */ + MMAL_PARAMETER_SATURATION, /* 0x30 */ - MMAL_PARAMETER_ISO, /**< @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_ANTISHAKE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - - /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ + /**< @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_ISO, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ANTISHAKE, + /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ + /** @ref MMAL_PARAMETER_BOOLEAN_T */ MMAL_PARAMETER_CAMERA_BURST_CAPTURE, - - /** @ref MMAL_PARAMETER_UINT32_T */ + /** @ref MMAL_PARAMETER_UINT32_T */ MMAL_PARAMETER_CAMERA_MIN_ISO, - - /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ + /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ MMAL_PARAMETER_CAMERA_USE_CASE, - - /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ MMAL_PARAMETER_CAPTURE_STATS_PASS, - - /** @ref MMAL_PARAMETER_UINT32_T */ + /** @ref MMAL_PARAMETER_UINT32_T */ MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ + /** @ref MMAL_PARAMETER_BOOLEAN_T */ MMAL_PARAMETER_ENABLE_REGISTER_FILE, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ + /** @ref MMAL_PARAMETER_BOOLEAN_T */ MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, - - /** @ref MMAL_PARAMETER_CONFIGFILE_T */ + /** @ref MMAL_PARAMETER_CONFIGFILE_T */ MMAL_PARAMETER_CONFIGFILE_REGISTERS, - - /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ + /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, - MMAL_PARAMETER_JPEG_ATTACH_LOG, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_ZERO_SHUTTER_LAG, /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ - MMAL_PARAMETER_FPS_RANGE, /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ - MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_JPEG_ATTACH_LOG, + /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ + MMAL_PARAMETER_ZERO_SHUTTER_LAG, + /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ + MMAL_PARAMETER_FPS_RANGE, + /**< @ref MMAL_PARAMETER_INT32_T */ + MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, /* 0x40 */ - MMAL_PARAMETER_SW_SHARPEN_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_FLASH_REQUIRED, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_SW_SATURATION_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_SHUTTER_SPEED, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_CUSTOM_AWB_GAINS, /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_SW_SHARPEN_DISABLE, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_FLASH_REQUIRED, + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_SW_SATURATION_DISABLE, + /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_SHUTTER_SPEED, + /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ + MMAL_PARAMETER_CUSTOM_AWB_GAINS, }; struct mmal_parameter_rational { @@ -410,7 +467,8 @@ enum mmal_parameter_video_type { MMAL_PARAMETER_MINIMISE_FRAGMENTATION, /** @ref MMAL_PARAMETER_UINT32_T. - * Setting the value to zero resets to the default (one slice per frame). + * Setting the value to zero resets to the default (one slice per + * frame). */ MMAL_PARAMETER_MB_ROWS_PER_SLICE, diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c index 16af735af5c3..1c180ead4a20 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom * * V4L2 driver MMAL vchiq interface code */ @@ -117,8 +118,10 @@ struct mmal_msg_context { union { struct { - /* work struct for defered callback - must come first */ + /* work struct for buffer_cb callback */ struct work_struct work; + /* work struct for deferred callback */ + struct work_struct buffer_to_host_work; /* mmal instance */ struct vchiq_mmal_instance *instance; /* mmal port */ @@ -161,11 +164,15 @@ struct vchiq_mmal_instance { void *bulk_scratch; struct idr context_map; - spinlock_t context_map_lock; + /* protect accesses to context_map */ + struct mutex context_map_lock; /* component to use next */ int component_idx; struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS]; + + /* ordered workqueue to process all bulk operations */ + struct workqueue_struct *bulk_wq; }; static struct mmal_msg_context * @@ -184,10 +191,10 @@ get_msg_context(struct vchiq_mmal_instance *instance) * that when we service the VCHI reply, we can look up what * message is being replied to. */ - spin_lock(&instance->context_map_lock); + mutex_lock(&instance->context_map_lock); handle = idr_alloc(&instance->context_map, msg_context, 0, 0, GFP_KERNEL); - spin_unlock(&instance->context_map_lock); + mutex_unlock(&instance->context_map_lock); if (handle < 0) { kfree(msg_context); @@ -211,9 +218,9 @@ release_msg_context(struct mmal_msg_context *msg_context) { struct vchiq_mmal_instance *instance = msg_context->instance; - spin_lock(&instance->context_map_lock); + mutex_lock(&instance->context_map_lock); idr_remove(&instance->context_map, msg_context->handle); - spin_unlock(&instance->context_map_lock); + mutex_unlock(&instance->context_map_lock); kfree(msg_context); } @@ -239,6 +246,8 @@ static void buffer_work_cb(struct work_struct *work) struct mmal_msg_context *msg_context = container_of(work, struct mmal_msg_context, u.bulk.work); + atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); + msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, msg_context->u.bulk.port, msg_context->u.bulk.status, @@ -247,7 +256,44 @@ static void buffer_work_cb(struct work_struct *work) msg_context->u.bulk.mmal_flags, msg_context->u.bulk.dts, msg_context->u.bulk.pts); +} + +/* workqueue scheduled callback to handle receiving buffers + * + * VCHI will allow up to 4 bulk receives to be scheduled before blocking. + * If we block in the service_callback context then we can't process the + * VCHI_CALLBACK_BULK_RECEIVED message that would otherwise allow the blocked + * vchi_bulk_queue_receive() call to complete. + */ +static void buffer_to_host_work_cb(struct work_struct *work) +{ + struct mmal_msg_context *msg_context = + container_of(work, struct mmal_msg_context, + u.bulk.buffer_to_host_work); + struct vchiq_mmal_instance *instance = msg_context->instance; + unsigned long len = msg_context->u.bulk.buffer_used; + int ret; + if (!len) + /* Dummy receive to ensure the buffers remain in order */ + len = 8; + /* queue the bulk submission */ + vchi_service_use(instance->handle); + ret = vchi_bulk_queue_receive(instance->handle, + msg_context->u.bulk.buffer->buffer, + /* Actual receive needs to be a multiple + * of 4 bytes + */ + (len + 3) & ~3, + VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | + VCHI_FLAGS_BLOCK_UNTIL_QUEUED, + msg_context); + + vchi_service_release(instance->handle); + + if (ret != 0) + pr_err("%s: ctx: %p, vchi_bulk_queue_receive failed %d\n", + __func__, msg_context, ret); } /* enqueue a bulk receive for a given message context */ @@ -256,7 +302,6 @@ static int bulk_receive(struct vchiq_mmal_instance *instance, struct mmal_msg_context *msg_context) { unsigned long rd_len; - int ret; rd_len = msg->u.buffer_from_host.buffer_header.length; @@ -287,50 +332,13 @@ static int bulk_receive(struct vchiq_mmal_instance *instance, /* store length */ msg_context->u.bulk.buffer_used = rd_len; - msg_context->u.bulk.mmal_flags = - msg->u.buffer_from_host.buffer_header.flags; msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; - /* queue the bulk submission */ - vchi_service_use(instance->handle); - ret = vchi_bulk_queue_receive(instance->handle, - msg_context->u.bulk.buffer->buffer, - /* Actual receive needs to be a multiple - * of 4 bytes - */ - (rd_len + 3) & ~3, - VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | - VCHI_FLAGS_BLOCK_UNTIL_QUEUED, - msg_context); - - vchi_service_release(instance->handle); - - return ret; -} - -/* enque a dummy bulk receive for a given message context */ -static int dummy_bulk_receive(struct vchiq_mmal_instance *instance, - struct mmal_msg_context *msg_context) -{ - int ret; - - /* zero length indicates this was a dummy transfer */ - msg_context->u.bulk.buffer_used = 0; - - /* queue the bulk submission */ - vchi_service_use(instance->handle); - - ret = vchi_bulk_queue_receive(instance->handle, - instance->bulk_scratch, - 8, - VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | - VCHI_FLAGS_BLOCK_UNTIL_QUEUED, - msg_context); + queue_work(msg_context->instance->bulk_wq, + &msg_context->u.bulk.buffer_to_host_work); - vchi_service_release(instance->handle); - - return ret; + return 0; } /* data in message, memcpy from packet into output buffer */ @@ -378,6 +386,10 @@ buffer_from_host(struct vchiq_mmal_instance *instance, /* initialise work structure ready to schedule callback */ INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb); + INIT_WORK(&msg_context->u.bulk.buffer_to_host_work, + buffer_to_host_work_cb); + + atomic_inc(&port->buffers_with_vpu); /* prep the buffer from host message */ memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */ @@ -447,6 +459,9 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, return; } + msg_context->u.bulk.mmal_flags = + msg->u.buffer_from_host.buffer_header.flags; + if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { /* message reception had an error */ pr_warn("error %d in reply\n", msg->h.status); @@ -458,7 +473,7 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, if (msg->u.buffer_from_host.buffer_header.flags & MMAL_BUFFER_HEADER_FLAG_EOS) { msg_context->u.bulk.status = - dummy_bulk_receive(instance, msg_context); + bulk_receive(instance, msg, msg_context); if (msg_context->u.bulk.status == 0) return; /* successful bulk submission, bulk * completion will trigger callback @@ -635,7 +650,7 @@ static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance, if (payload_len > (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) { pr_err("payload length %d exceeds max:%d\n", payload_len, - (int)(MMAL_MSG_MAX_SIZE - + (int)(MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))); return -EINVAL; } @@ -838,9 +853,9 @@ static int port_info_get(struct vchiq_mmal_instance *instance, goto release_msg; if (rmsg->u.port_info_get_reply.port.is_enabled == 0) - port->enabled = false; + port->enabled = 0; else - port->enabled = true; + port->enabled = 1; /* copy the values out of the message */ port->handle = rmsg->u.port_info_get_reply.port_handle; @@ -1252,9 +1267,10 @@ static int port_parameter_get(struct vchiq_mmal_instance *instance, memcpy(value, &rmsg->u.port_parameter_get_reply.value, *value_size); *value_size = rmsg->u.port_parameter_get_reply.size; - } else + } else { memcpy(value, &rmsg->u.port_parameter_get_reply.value, rmsg->u.port_parameter_get_reply.size); + } pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, ret, port->component->handle, port->handle, parameter_id); @@ -1276,7 +1292,7 @@ static int port_disable(struct vchiq_mmal_instance *instance, if (!port->enabled) return 0; - port->enabled = false; + port->enabled = 0; ret = port_action_port(instance, port, MMAL_MSG_PORT_ACTION_TYPE_DISABLE); @@ -1323,22 +1339,12 @@ static int port_enable(struct vchiq_mmal_instance *instance, if (port->enabled) return 0; - /* ensure there are enough buffers queued to cover the buffer headers */ - if (port->buffer_cb) { - hdr_count = 0; - list_for_each(buf_head, &port->buffers) { - hdr_count++; - } - if (hdr_count < port->current_buffer.num) - return -ENOSPC; - } - ret = port_action_port(instance, port, MMAL_MSG_PORT_ACTION_TYPE_ENABLE); if (ret) goto done; - port->enabled = true; + port->enabled = 1; if (port->buffer_cb) { /* send buffer headers to videocore */ @@ -1505,7 +1511,7 @@ int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, pr_err("failed disconnecting src port\n"); goto release_unlock; } - src->connected->enabled = false; + src->connected->enabled = 0; src->connected = NULL; } @@ -1752,7 +1758,7 @@ int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, ret = disable_component(instance, component); if (ret == 0) - component->enabled = false; + component->enabled = 0; mutex_unlock(&instance->vchiq_mutex); @@ -1792,6 +1798,9 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance) mutex_unlock(&instance->vchiq_mutex); + flush_workqueue(instance->bulk_wq); + destroy_workqueue(instance->bulk_wq); + vfree(instance->bulk_scratch); idr_destroy(&instance->context_map); @@ -1849,11 +1858,16 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) instance->bulk_scratch = vmalloc(PAGE_SIZE); - spin_lock_init(&instance->context_map_lock); + mutex_init(&instance->context_map_lock); idr_init_base(&instance->context_map, 1); params.callback_param = instance; + instance->bulk_wq = alloc_ordered_workqueue("mmal-vchiq", + WQ_MEM_RECLAIM); + if (!instance->bulk_wq) + goto err_free; + status = vchi_service_open(vchi_instance, ¶ms, &instance->handle); if (status) { pr_err("Failed to open VCHI service connection (status=%d)\n", @@ -1868,8 +1882,9 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) return 0; err_close_services: - vchi_service_close(instance->handle); + destroy_workqueue(instance->bulk_wq); +err_free: vfree(instance->bulk_scratch); kfree(instance); return -ENODEV; diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h index 22b839ecd5f0..f738e7f99e96 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h @@ -4,10 +4,11 @@ * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> - * Dave Stevenson <dsteve@broadcom.com> - * Simon Mellor <simellor@broadcom.com> - * Luke Diamand <luked@broadcom.com> + * Authors: Vincent Sanders @ Collabora + * Dave Stevenson @ Broadcom + * (now dave.stevenson@raspberrypi.org) + * Simon Mellor @ Broadcom + * Luke Diamand @ Broadcom * * MMAL interface to VCHIQ message passing */ @@ -47,7 +48,7 @@ typedef void (*vchiq_mmal_buffer_cb)( unsigned long length, u32 mmal_flags, s64 dts, s64 pts); struct vchiq_mmal_port { - bool enabled; + u32 enabled:1; u32 handle; u32 type; /* port type, cached to use on port info set */ u32 index; /* port index, cached to use on port info set */ @@ -71,6 +72,9 @@ struct vchiq_mmal_port { struct list_head buffers; /* lock to serialise adding and removing buffers from list */ spinlock_t slock; + + /* Count of buffers the VPU has yet to return */ + atomic_t buffers_with_vpu; /* callback on buffer completion */ vchiq_mmal_buffer_cb buffer_cb; /* callback context */ @@ -78,7 +82,7 @@ struct vchiq_mmal_port { }; struct vchiq_mmal_component { - bool enabled; + u32 enabled:1; u32 handle; /* VideoCore handle for component */ u32 inputs; /* Number of input ports */ u32 outputs; /* Number of output ports */ @@ -127,7 +131,7 @@ int vchiq_mmal_port_enable( * disable a port will dequeue any pending buffers */ int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port); + struct vchiq_mmal_port *port); int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, struct vchiq_mmal_port *port, @@ -145,8 +149,8 @@ int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, struct vchiq_mmal_port *port); int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *src, - struct vchiq_mmal_port *dst); + struct vchiq_mmal_port *src, + struct vchiq_mmal_port *dst); int vchiq_mmal_version(struct vchiq_mmal_instance *instance, u32 *major_out, |