diff options
Diffstat (limited to 'drivers/staging/vc04_services/bcm2835-camera')
12 files changed, 43 insertions, 3693 deletions
diff --git a/drivers/staging/vc04_services/bcm2835-camera/Kconfig b/drivers/staging/vc04_services/bcm2835-camera/Kconfig index c81baf2c111e..d0653d1ed3c7 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/Kconfig +++ b/drivers/staging/vc04_services/bcm2835-camera/Kconfig @@ -4,6 +4,7 @@ config VIDEO_BCM2835 depends on MEDIA_SUPPORT depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST) select BCM2835_VCHIQ + select BCM2835_VCHIQ_MMAL select VIDEOBUF2_VMALLOC select BTREE help diff --git a/drivers/staging/vc04_services/bcm2835-camera/Makefile b/drivers/staging/vc04_services/bcm2835-camera/Makefile index 472f21e1f2a1..3a76d6ade428 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/Makefile +++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile @@ -1,11 +1,11 @@ # SPDX-License-Identifier: GPL-2.0 bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \ bcm2835-camera.o \ - controls.o \ - mmal-vchiq.o + controls.o obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o ccflags-y += \ -I $(srctree)/$(src)/.. \ + -I $(srctree)/$(src)/../vchiq-mmal/ \ -D__VCCOREVER__=0x04000000 diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index 4f1adddb804f..df90c1f9d148 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -75,6 +75,12 @@ static const struct v4l2_fract tpf_max = {.numerator = 1, .denominator = FPS_MIN}, tpf_default = {.numerator = 1000, .denominator = 30000}; +/* Container for MMAL and VB2 buffers*/ +struct vb2_mmal_buffer { + struct vb2_v4l2_buffer vb; + struct mmal_buffer mmal; +}; + /* video formats */ static struct mmal_fmt formats[] = { { @@ -261,14 +267,15 @@ static int buffer_init(struct vb2_buffer *vb) { struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); - struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); + struct vb2_mmal_buffer *buf = + container_of(vb2, struct vb2_mmal_buffer, vb); v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n", __func__, dev, vb); - buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); - buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0); + buf->mmal.buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); + buf->mmal.buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0); - return mmal_vchi_buffer_init(dev->instance, buf); + return mmal_vchi_buffer_init(dev->instance, &buf->mmal); } static int buffer_prepare(struct vb2_buffer *vb) @@ -297,11 +304,13 @@ static void buffer_cleanup(struct vb2_buffer *vb) { struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); - struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); + struct vb2_mmal_buffer *buf = + container_of(vb2, struct vb2_mmal_buffer, vb); v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n", __func__, dev, vb); - mmal_vchi_buffer_cleanup(buf); + + mmal_vchi_buffer_cleanup(&buf->mmal); } static inline bool is_capturing(struct bm2835_mmal_dev *dev) @@ -313,14 +322,16 @@ static inline bool is_capturing(struct bm2835_mmal_dev *dev) static void buffer_cb(struct vchiq_mmal_instance *instance, struct vchiq_mmal_port *port, int status, - struct mmal_buffer *buf, - unsigned long length, u32 mmal_flags, s64 dts, s64 pts) + struct mmal_buffer *mmal_buf) { struct bm2835_mmal_dev *dev = port->cb_ctx; + struct vb2_mmal_buffer *buf = + container_of(mmal_buf, struct vb2_mmal_buffer, mmal); v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", - __func__, status, buf, length, mmal_flags, pts); + __func__, status, buf, mmal_buf->length, mmal_buf->mmal_flags, + mmal_buf->pts); if (status) { /* error in transfer */ @@ -331,7 +342,7 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, return; } - if (length == 0) { + if (mmal_buf->length == 0) { /* stream ended */ if (dev->capture.frame_count) { /* empty buffer whilst capturing - expected to be an @@ -347,7 +358,8 @@ 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)) + if (vchiq_mmal_submit_buffer(instance, port, + &buf->mmal)) v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "Failed to return EOS buffer"); } else { @@ -367,16 +379,16 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, return; } - if (dev->capture.vc_start_timestamp != -1 && pts) { + if (dev->capture.vc_start_timestamp != -1 && mmal_buf->pts) { ktime_t timestamp; - s64 runtime_us = pts - dev->capture.vc_start_timestamp; - + s64 runtime_us = mmal_buf->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, + dev->capture.vc_start_timestamp, mmal_buf->pts, ktime_to_ns(timestamp)); buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp); } else { @@ -385,13 +397,13 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, buf->vb.sequence = dev->capture.sequence++; buf->vb.field = V4L2_FIELD_NONE; - vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); - if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, mmal_buf->length); + if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME; vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); - if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && + if (mmal_buf->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"); @@ -472,14 +484,16 @@ static void buffer_queue(struct vb2_buffer *vb) { struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); - struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); + struct vb2_mmal_buffer *buf = + container_of(vb2, struct vb2_mmal_buffer, vb); int ret; v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p buf:%p, idx %u\n", __func__, dev, buf, vb2->vb2_buf.index); - ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf); + ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, + &buf->mmal); if (ret < 0) v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n", __func__); @@ -592,7 +606,7 @@ static void stop_streaming(struct vb2_queue *vq) dev->capture.frame_count = 0; /* ensure a format has actually been set */ - if (!dev->capture.port) { + if (!port) { v4l2_err(&dev->v4l2_dev, "no capture port - stream not started?\n"); return; @@ -612,11 +626,11 @@ static void stop_streaming(struct vb2_queue *vq) /* disable the connection from camera to encoder */ ret = vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port); - if (!ret && dev->capture.camera_port != dev->capture.port) { + if (!ret && dev->capture.camera_port != port) { v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "disabling port\n"); - ret = vchiq_mmal_port_disable(dev->instance, dev->capture.port); - } else if (dev->capture.camera_port != dev->capture.port) { + ret = vchiq_mmal_port_disable(dev->instance, port); + } else if (dev->capture.camera_port != port) { v4l2_err(&dev->v4l2_dev, "port_disable failed, error %d\n", ret); } @@ -1483,7 +1497,7 @@ static int get_num_cameras(struct vchiq_mmal_instance *instance, { int ret; struct vchiq_mmal_component *cam_info_component; - struct mmal_parameter_camera_info_t cam_info = {0}; + struct mmal_parameter_camera_info cam_info = {0}; u32 param_size = sizeof(cam_info); int i; @@ -1916,7 +1930,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev) q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; q->drv_priv = dev; - q->buf_struct_size = sizeof(struct mmal_buffer); + q->buf_struct_size = sizeof(struct vb2_mmal_buffer); q->ops = &bm2835_mmal_video_qops; q->mem_ops = &vb2_vmalloc_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h deleted file mode 100644 index ce88fac7c24b..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * 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') - -/** Special value signalling that time is not known */ -#define MMAL_TIME_UNKNOWN BIT_ULL(63) - -struct mmal_msg_context; - -/* mapping between v4l and mmal video modes */ -struct mmal_fmt { - u32 fourcc; /* v4l2 format id */ - int flags; /* v4l2 flags field */ - u32 mmal; - int depth; - u32 mmal_component; /* MMAL component index to be used to encode */ - u32 ybbp; /* depth of first Y plane for planar formats */ - bool remove_padding; /* Does the GPU have to remove padding, - * or can we do hide padding via bytesperline. - */ -}; - -/* buffer for one video frame */ -struct mmal_buffer { - /* v4l buffer data -- must be first */ - struct vb2_v4l2_buffer vb; - - /* list of buffers available */ - struct list_head list; - - void *buffer; /* buffer pointer */ - unsigned long buffer_size; /* size of allocated buffer */ - - struct mmal_msg_context *msg_context; -}; - -/* */ -struct mmal_colourfx { - s32 enable; - 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 deleted file mode 100644 index 2be9941a1f30..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h +++ /dev/null @@ -1,124 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * 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 - -#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4') -#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3') -#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V') -#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V') -#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V') -#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3') -#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2') -#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1') -#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1') -#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ') -#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ') -#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ') -#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O') -#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K') -#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G') - -#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G') -#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ') -#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ') -#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ') -#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ') -#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ') - -#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0') -#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0') -#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2') -#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2') -#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2') -#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V') -#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U') -#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y') -#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y') -#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2') -#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1') -#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B') -#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A') -#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R') -#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A') -#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2') -#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3') -#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4') -#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2') -#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3') -#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4') - -/** SAND Video (YUVUV128) format, native format understood by VideoCore. - * This format is *not* opaque - if requested you will receive full frames - * of YUV_UV video. - */ -#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D') - -/** VideoCore opaque image format, image handles are returned to - * the host but not the actual image data. - */ -#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') - -/** An EGL image handle - */ -#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') - -/* }@ */ - -/** \name Pre-defined audio encodings */ -/* @{ */ -#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U') -#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u') -#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S') -#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's') -#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F') -#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f') - -/* Pre-defined H264 encoding variants */ - -/** ISO 14496-10 Annex B byte stream format */ -#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0 -/** ISO 14496-15 AVC stream format */ -#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1') -/** Implicitly delineated NAL units without emulation prevention */ -#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ') - -/** \defgroup MmalColorSpace List of pre-defined video color spaces - * This defines a list of common color spaces. This list isn't exhaustive and - * is only provided as a convenience to avoid clients having to use FourCC - * codes directly. However components are allowed to define and use their own - * FourCC codes. - */ -/* @{ */ - -/** Unknown color space */ -#define MMAL_COLOR_SPACE_UNKNOWN 0 -/** ITU-R BT.601-5 [SDTV] */ -#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1') -/** ITU-R BT.709-3 [HDTV] */ -#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9') -/** JPEG JFIF */ -#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I') -/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ -#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C') -/** Society of Motion Picture and Television Engineers 240M (1999) */ -#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0') -/** ITU-R BT.470-2 System M */ -#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M') -/** ITU-R BT.470-2 System BG */ -#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G') -/** JPEG JFIF, but with 16..255 luma */ -#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6') -/* @} MmalColorSpace List */ - -#endif /* 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 deleted file mode 100644 index 342c9b670f7e..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * Authors: Vincent Sanders @ Collabora - * Dave Stevenson @ Broadcom - * (now dave.stevenson@raspberrypi.org) - * Simon Mellor @ Broadcom - * Luke Diamand @ Broadcom - */ - -#ifndef MMAL_MSG_COMMON_H -#define MMAL_MSG_COMMON_H - -enum mmal_msg_status { - MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */ - MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */ - MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */ - MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */ - MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */ - MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */ - MMAL_MSG_STATUS_ENXIO, /**< No such device or address */ - MMAL_MSG_STATUS_EIO, /**< I/O error */ - MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */ - MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */ - MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */ - MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */ - MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */ - MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */ - MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */ - MMAL_MSG_STATUS_EFAULT, /**< Bad address */ -}; - -struct mmal_rect { - s32 x; /**< x coordinate (from left) */ - s32 y; /**< y coordinate (from top) */ - s32 width; /**< width */ - s32 height; /**< height */ -}; - -struct mmal_rational { - s32 num; /**< Numerator */ - s32 den; /**< Denominator */ -}; - -#endif /* 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 deleted file mode 100644 index a118efd21d98..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * Authors: Vincent Sanders @ Collabora - * Dave Stevenson @ Broadcom - * (now dave.stevenson@raspberrypi.org) - * Simon Mellor @ Broadcom - * Luke Diamand @ Broadcom - */ - -#ifndef MMAL_MSG_FORMAT_H -#define MMAL_MSG_FORMAT_H - -#include "mmal-msg-common.h" - -/* MMAL_ES_FORMAT_T */ - -struct mmal_audio_format { - 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 */ -}; - -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 - * MmalColorSpace "pre-defined color spaces" for some examples. - */ - u32 color_space; -}; - -struct mmal_subpicture_format { - u32 x_offset; - u32 y_offset; -}; - -union mmal_es_specific_format { - struct mmal_audio_format audio; - struct mmal_video_format video; - struct mmal_subpicture_format subpicture; -}; - -/* 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 */ -}; - -/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */ -struct mmal_es_format { - 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 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 */ - 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 deleted file mode 100644 index 3fa3f2a578f0..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * 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 */ -}; - -/* 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. - * 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. - * 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) - * - * most elements are informational only, the pointer values for - * interogation messages are generally provided as additional - * structures within the message. When used to set values only the - * 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. - * This is set by the client. - */ - - u32 buffer_size; /* Actual maximum size of the buffers that - * will be sent to the port. This is set by - * the client. - */ - - u32 component; /* Component this port belongs to (Read Only) */ - - 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 deleted file mode 100644 index 43cc59316f90..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h +++ /dev/null @@ -1,406 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * 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 - * these are directly mapped onto the recived message data. - * - * BEWARE: They seem to *assume* pointers are u32 and that there is no - * structure padding! - * - * NOTE: this implementation uses kernel types to ensure sizes. Rather - * than assigning values to enums to force their size the - * 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 -#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal") - -/* max total message size is 512 bytes */ -#define MMAL_MSG_MAX_SIZE 512 -/* with six 32bit header elements max payload is therefore 488 bytes */ -#define MMAL_MSG_MAX_PAYLOAD 488 - -#include "mmal-msg-common.h" -#include "mmal-msg-format.h" -#include "mmal-msg-port.h" - -enum mmal_msg_type { - MMAL_MSG_TYPE_QUIT = 1, - 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_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_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_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_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_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_SET_REQUIREMENTS, /* Set buffer requirements*/ -}; - -struct mmal_msg_header { - u32 magic; - 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 padding; -}; - -/* Send from VC to host to report version */ -struct mmal_msg_version { - u32 flags; - u32 major; - u32 minor; - u32 minimum; -}; - -/* request to VC to create component */ -struct mmal_msg_component_create { - u32 client_component; /* component context */ - char name[128]; - u32 pid; /* For debug */ -}; - -/* reply from VC to component creation request */ -struct mmal_msg_component_create_reply { - u32 status; /* enum mmal_msg_status - how does this differ to - * the one in the header? - */ - u32 component_handle; /* VideoCore handle for component */ - u32 input_num; /* Number of input ports */ - u32 output_num; /* Number of output ports */ - u32 clock_num; /* Number of clock ports */ -}; - -/* request to VC to destroy a component */ -struct mmal_msg_component_destroy { - u32 component_handle; -}; - -struct mmal_msg_component_destroy_reply { - u32 status; /* The component destruction status */ -}; - -/* request and reply to VC to enable a component */ -struct mmal_msg_component_enable { - u32 component_handle; -}; - -struct mmal_msg_component_enable_reply { - u32 status; /* The component enable status */ -}; - -/* request and reply to VC to disable a component */ -struct mmal_msg_component_disable { - u32 component_handle; -}; - -struct mmal_msg_component_disable_reply { - u32 status; /* The component disable status */ -}; - -/* request to VC to get port information */ -struct mmal_msg_port_info_get { - u32 component_handle; /* component handle port is associated with */ - u32 port_type; /* enum mmal_msg_port_type */ - u32 index; /* port index to query */ -}; - -/* 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 */ - struct mmal_port port; - struct mmal_es_format format; /* elementary stream format */ - union mmal_es_specific_format es; /* es type specific data */ - u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */ -}; - -/* 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 */ - struct mmal_port port; - struct mmal_es_format format; - union mmal_es_specific_format es; - u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; -}; - -/* 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 */ - struct mmal_port port; - struct mmal_es_format format; - union mmal_es_specific_format es; - u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; -}; - -/* port action requests that take a mmal_port as a parameter */ -struct mmal_msg_port_action_port { - u32 component_handle; - u32 port_handle; - u32 action; /* enum mmal_msg_port_action_type */ - struct mmal_port port; -}; - -/* port action requests that take handles as a parameter */ -struct mmal_msg_port_action_handle { - u32 component_handle; - u32 port_handle; - 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 */ -}; - -/* MMAL buffer transfer */ - -/* 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 */ -#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0) -/* 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 */ -#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2) -/* 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) */ -#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3) -/* - * 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 - * (e.g. codec config data) - */ -#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5) -/* Signals an encrypted payload */ -#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6) -/* 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 - * capture - */ -#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8) -/* 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 */ -#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10) - -struct mmal_driver_buffer { - u32 magic; - u32 component_handle; - u32 port_handle; - u32 client_context; -}; - -/* buffer header */ -struct mmal_buffer_header { - u32 next; /* next header */ - u32 priv; /* framework private data */ - u32 cmd; - u32 data; - u32 alloc_size; - u32 length; - u32 offset; - u32 flags; - s64 pts; - s64 dts; - u32 type; - u32 user_data; -}; - -struct mmal_buffer_header_type_specific { - union { - struct { - u32 planes; - u32 offset[4]; - u32 pitch[4]; - u32 flags; - } video; - } u; -}; - -struct mmal_msg_buffer_from_host { - /* - *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. - */ - /* control data */ - struct mmal_driver_buffer drvbuf; - - /* referenced control data for passthrough buffer management */ - struct mmal_driver_buffer drvbuf_ref; - struct mmal_buffer_header buffer_header; /* buffer header itself */ - struct mmal_buffer_header_type_specific buffer_header_type_specific; - s32 is_zero_copy; - s32 has_reference; - - /* allows short data to be xfered in control message */ - u32 payload_in_message; - u8 short_data[MMAL_VC_SHORT_DATA]; -}; - -/* port parameter setting */ - -#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 */ - u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE]; -}; - -struct mmal_msg_port_parameter_set_reply { - u32 status; /* enum mmal_msg_status todo: how does this - * differ to the one in the header? - */ -}; - -/* 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 */ -}; - -struct mmal_msg_port_parameter_get_reply { - 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 port_type; - u32 port_num; - - u32 cmd; - u32 length; - u8 data[MMAL_WORKER_EVENT_SPACE]; - u32 delayed_buffer; -}; - -/* all mmal messages are serialised through this structure */ -struct mmal_msg { - /* header */ - struct mmal_msg_header h; - /* payload */ - union { - struct mmal_msg_version version; - - struct mmal_msg_component_create component_create; - struct mmal_msg_component_create_reply component_create_reply; - - struct mmal_msg_component_destroy component_destroy; - struct mmal_msg_component_destroy_reply component_destroy_reply; - - struct mmal_msg_component_enable component_enable; - struct mmal_msg_component_enable_reply component_enable_reply; - - struct mmal_msg_component_disable component_disable; - struct mmal_msg_component_disable_reply component_disable_reply; - - struct mmal_msg_port_info_get port_info_get; - struct mmal_msg_port_info_get_reply port_info_get_reply; - - struct mmal_msg_port_info_set port_info_set; - struct mmal_msg_port_info_set_reply port_info_set_reply; - - struct mmal_msg_port_action_port port_action_port; - struct mmal_msg_port_action_handle port_action_handle; - struct mmal_msg_port_action_reply port_action_reply; - - struct mmal_msg_buffer_from_host buffer_from_host; - - struct mmal_msg_port_parameter_set port_parameter_set; - struct mmal_msg_port_parameter_set_reply - port_parameter_set_reply; - struct mmal_msg_port_parameter_get - port_parameter_get; - struct mmal_msg_port_parameter_get_reply - port_parameter_get_reply; - - struct mmal_msg_event_to_host event_to_host; - - 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 deleted file mode 100644 index f4ac5a6149ea..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h +++ /dev/null @@ -1,755 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * Authors: Vincent Sanders @ Collabora - * Dave Stevenson @ Broadcom - * (now dave.stevenson@raspberrypi.org) - * Simon Mellor @ Broadcom - * Luke Diamand @ Broadcom - */ - -/* common parameters */ - -/** @name Parameter groups - * Parameters are divided into groups, and then allocated sequentially within - * a group using an enum. - * @{ - */ - -#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) -/** Camera-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) -/** Video-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) -/** Audio-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) -/** Clock-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) -/** Miracast-specific parameter ID group. */ -#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) - -/* Common parameters */ -enum mmal_parameter_common_type { - /**< 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_ZERO_COPY, - /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ - MMAL_PARAMETER_BUFFER_REQUIREMENTS, - /**< 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, - /**< 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 */ - /**< @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 */ - /**< @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 */ - /**< @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 */ - MMAL_PARAMETER_CAMERA_BURST_CAPTURE, - /** @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_CAMERA_MIN_ISO, - /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ - MMAL_PARAMETER_CAMERA_USE_CASE, - /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_CAPTURE_STATS_PASS, - /** @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, - /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_ENABLE_REGISTER_FILE, - /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, - /** @ref MMAL_PARAMETER_CONFIGFILE_T */ - MMAL_PARAMETER_CONFIGFILE_REGISTERS, - /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ - MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, - /**< @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 */ - /**< @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 { - s32 num; /**< Numerator */ - s32 den; /**< Denominator */ -}; - -enum mmal_parameter_camera_config_timestamp_mode { - MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */ - MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value - * for the frame timestamp - */ - MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp - * but subtract the - * timestamp of the first - * frame sent to give a - * zero based timestamp. - */ -}; - -struct mmal_parameter_fps_range { - /**< Low end of the permitted framerate range */ - struct mmal_parameter_rational fps_low; - /**< High end of the permitted framerate range */ - struct mmal_parameter_rational fps_high; -}; - -/* camera configuration parameter */ -struct mmal_parameter_camera_config { - /* Parameters for setting up the image pools */ - u32 max_stills_w; /* Max size of stills capture */ - u32 max_stills_h; - u32 stills_yuv422; /* Allow YUV422 stills capture */ - u32 one_shot_stills; /* Continuous or one shot stills captures. */ - - u32 max_preview_video_w; /* Max size of the preview or video - * capture frames - */ - u32 max_preview_video_h; - u32 num_preview_video_frames; - - /** Sets the height of the circular buffer for stills capture. */ - u32 stills_capture_circular_buffer_height; - - /** Allows preview/encode to resume as fast as possible after the stills - * input frame has been received, and then processes the still frame in - * the background whilst preview/encode has resumed. - * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE. - */ - u32 fast_preview_resume; - - /** Selects algorithm for timestamping frames if - * there is no clock component connected. - * enum mmal_parameter_camera_config_timestamp_mode - */ - s32 use_stc_timestamp; -}; - -enum mmal_parameter_exposuremode { - MMAL_PARAM_EXPOSUREMODE_OFF, - MMAL_PARAM_EXPOSUREMODE_AUTO, - MMAL_PARAM_EXPOSUREMODE_NIGHT, - MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, - MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, - MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, - MMAL_PARAM_EXPOSUREMODE_SPORTS, - MMAL_PARAM_EXPOSUREMODE_SNOW, - MMAL_PARAM_EXPOSUREMODE_BEACH, - MMAL_PARAM_EXPOSUREMODE_VERYLONG, - MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, - MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, - MMAL_PARAM_EXPOSUREMODE_FIREWORKS, -}; - -enum mmal_parameter_exposuremeteringmode { - MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE, - MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT, - MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT, - MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX, -}; - -enum mmal_parameter_awbmode { - MMAL_PARAM_AWBMODE_OFF, - MMAL_PARAM_AWBMODE_AUTO, - MMAL_PARAM_AWBMODE_SUNLIGHT, - MMAL_PARAM_AWBMODE_CLOUDY, - MMAL_PARAM_AWBMODE_SHADE, - MMAL_PARAM_AWBMODE_TUNGSTEN, - MMAL_PARAM_AWBMODE_FLUORESCENT, - MMAL_PARAM_AWBMODE_INCANDESCENT, - MMAL_PARAM_AWBMODE_FLASH, - MMAL_PARAM_AWBMODE_HORIZON, -}; - -enum mmal_parameter_imagefx { - MMAL_PARAM_IMAGEFX_NONE, - MMAL_PARAM_IMAGEFX_NEGATIVE, - MMAL_PARAM_IMAGEFX_SOLARIZE, - MMAL_PARAM_IMAGEFX_POSTERIZE, - MMAL_PARAM_IMAGEFX_WHITEBOARD, - MMAL_PARAM_IMAGEFX_BLACKBOARD, - MMAL_PARAM_IMAGEFX_SKETCH, - MMAL_PARAM_IMAGEFX_DENOISE, - MMAL_PARAM_IMAGEFX_EMBOSS, - MMAL_PARAM_IMAGEFX_OILPAINT, - MMAL_PARAM_IMAGEFX_HATCH, - MMAL_PARAM_IMAGEFX_GPEN, - MMAL_PARAM_IMAGEFX_PASTEL, - MMAL_PARAM_IMAGEFX_WATERCOLOUR, - MMAL_PARAM_IMAGEFX_FILM, - MMAL_PARAM_IMAGEFX_BLUR, - MMAL_PARAM_IMAGEFX_SATURATION, - MMAL_PARAM_IMAGEFX_COLOURSWAP, - MMAL_PARAM_IMAGEFX_WASHEDOUT, - MMAL_PARAM_IMAGEFX_POSTERISE, - MMAL_PARAM_IMAGEFX_COLOURPOINT, - MMAL_PARAM_IMAGEFX_COLOURBALANCE, - MMAL_PARAM_IMAGEFX_CARTOON, -}; - -enum MMAL_PARAM_FLICKERAVOID_T { - MMAL_PARAM_FLICKERAVOID_OFF, - MMAL_PARAM_FLICKERAVOID_AUTO, - MMAL_PARAM_FLICKERAVOID_50HZ, - MMAL_PARAM_FLICKERAVOID_60HZ, - MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF -}; - -struct mmal_parameter_awbgains { - struct mmal_parameter_rational r_gain; /**< Red gain */ - struct mmal_parameter_rational b_gain; /**< Blue gain */ -}; - -/** Manner of video rate control */ -enum mmal_parameter_rate_control_mode { - MMAL_VIDEO_RATECONTROL_DEFAULT, - MMAL_VIDEO_RATECONTROL_VARIABLE, - MMAL_VIDEO_RATECONTROL_CONSTANT, - MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, - MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES -}; - -enum mmal_video_profile { - MMAL_VIDEO_PROFILE_H263_BASELINE, - MMAL_VIDEO_PROFILE_H263_H320CODING, - MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, - MMAL_VIDEO_PROFILE_H263_ISWV2, - MMAL_VIDEO_PROFILE_H263_ISWV3, - MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, - MMAL_VIDEO_PROFILE_H263_INTERNET, - MMAL_VIDEO_PROFILE_H263_INTERLACE, - MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, - MMAL_VIDEO_PROFILE_MP4V_SIMPLE, - MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, - MMAL_VIDEO_PROFILE_MP4V_CORE, - MMAL_VIDEO_PROFILE_MP4V_MAIN, - MMAL_VIDEO_PROFILE_MP4V_NBIT, - MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, - MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, - MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, - MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, - MMAL_VIDEO_PROFILE_MP4V_HYBRID, - MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, - MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, - MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, - MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, - MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, - MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, - MMAL_VIDEO_PROFILE_H264_BASELINE, - MMAL_VIDEO_PROFILE_H264_MAIN, - MMAL_VIDEO_PROFILE_H264_EXTENDED, - MMAL_VIDEO_PROFILE_H264_HIGH, - MMAL_VIDEO_PROFILE_H264_HIGH10, - MMAL_VIDEO_PROFILE_H264_HIGH422, - MMAL_VIDEO_PROFILE_H264_HIGH444, - MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, - MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF -}; - -enum mmal_video_level { - MMAL_VIDEO_LEVEL_H263_10, - MMAL_VIDEO_LEVEL_H263_20, - MMAL_VIDEO_LEVEL_H263_30, - MMAL_VIDEO_LEVEL_H263_40, - MMAL_VIDEO_LEVEL_H263_45, - MMAL_VIDEO_LEVEL_H263_50, - MMAL_VIDEO_LEVEL_H263_60, - MMAL_VIDEO_LEVEL_H263_70, - MMAL_VIDEO_LEVEL_MP4V_0, - MMAL_VIDEO_LEVEL_MP4V_0b, - MMAL_VIDEO_LEVEL_MP4V_1, - MMAL_VIDEO_LEVEL_MP4V_2, - MMAL_VIDEO_LEVEL_MP4V_3, - MMAL_VIDEO_LEVEL_MP4V_4, - MMAL_VIDEO_LEVEL_MP4V_4a, - MMAL_VIDEO_LEVEL_MP4V_5, - MMAL_VIDEO_LEVEL_MP4V_6, - MMAL_VIDEO_LEVEL_H264_1, - MMAL_VIDEO_LEVEL_H264_1b, - MMAL_VIDEO_LEVEL_H264_11, - MMAL_VIDEO_LEVEL_H264_12, - MMAL_VIDEO_LEVEL_H264_13, - MMAL_VIDEO_LEVEL_H264_2, - MMAL_VIDEO_LEVEL_H264_21, - MMAL_VIDEO_LEVEL_H264_22, - MMAL_VIDEO_LEVEL_H264_3, - MMAL_VIDEO_LEVEL_H264_31, - MMAL_VIDEO_LEVEL_H264_32, - MMAL_VIDEO_LEVEL_H264_4, - MMAL_VIDEO_LEVEL_H264_41, - MMAL_VIDEO_LEVEL_H264_42, - MMAL_VIDEO_LEVEL_H264_5, - MMAL_VIDEO_LEVEL_H264_51, - MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF -}; - -struct mmal_parameter_video_profile { - enum mmal_video_profile profile; - enum mmal_video_level level; -}; - -/* video parameters */ - -enum mmal_parameter_video_type { - /** @ref MMAL_DISPLAYREGION_T */ - MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO, - - /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ - MMAL_PARAMETER_SUPPORTED_PROFILES, - - /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ - MMAL_PARAMETER_PROFILE, - - /** @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_INTRAPERIOD, - - /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */ - MMAL_PARAMETER_RATECONTROL, - - /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */ - MMAL_PARAMETER_NALUNITFORMAT, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_MINIMISE_FRAGMENTATION, - - /** @ref MMAL_PARAMETER_UINT32_T. - * Setting the value to zero resets to the default (one slice per - * frame). - */ - MMAL_PARAMETER_MB_ROWS_PER_SLICE, - - /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */ - MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, - - /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */ - MMAL_PARAMETER_VIDEO_EEDE_ENABLE, - - /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */ - MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, - - /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */ - MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, - /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */ - MMAL_PARAMETER_VIDEO_INTRA_REFRESH, - - /** @ref MMAL_PARAMETER_BOOLEAN_T. */ - MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, - - /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */ - MMAL_PARAMETER_VIDEO_BIT_RATE, - - /** @ref MMAL_PARAMETER_FRAME_RATE_T */ - MMAL_PARAMETER_VIDEO_FRAME_RATE, - - /** @ref MMAL_PARAMETER_UINT32_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, - - /** @ref MMAL_PARAMETER_UINT32_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, - - /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, - - MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */ - /** @ref MMAL_PARAMETER_UINT32_T. - * Changing this parameter from the default can reduce frame rate - * because image buffers need to be re-pitched. - */ - MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, - - /** @ref MMAL_PARAMETER_UINT32_T. - * Changing this parameter from the default can reduce frame rate - * because image buffers need to be re-pitched. - */ - MMAL_PARAMETER_VIDEO_ALIGN_VERT, - - /** @ref MMAL_PARAMETER_BOOLEAN_T. */ - MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, - - /** @ref MMAL_PARAMETER_UINT32_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, - - /**< @ref MMAL_PARAMETER_UINT32_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_QP_P, - - /**< @ref MMAL_PARAMETER_UINT32_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, - - /** @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, - - /** @ref MMAL_PARAMETER_UINT32_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, - - /* H264 specific parameters */ - - /** @ref MMAL_PARAMETER_BOOLEAN_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, - - /** @ref MMAL_PARAMETER_BOOLEAN_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, - - /** @ref MMAL_PARAMETER_BOOLEAN_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, - - /** @ref MMAL_PARAMETER_UINT32_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, - - /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */ - MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, - - /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */ - MMAL_PARAMETER_VIDEO_DRM_INIT_INFO, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, - - /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, - - /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */ - MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, - - /** @ref MMAL_PARAMETER_BYTES_T */ - MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, - - /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS, - - /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, - - /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER -}; - -/** Valid mirror modes */ -enum mmal_parameter_mirror { - MMAL_PARAM_MIRROR_NONE, - MMAL_PARAM_MIRROR_VERTICAL, - MMAL_PARAM_MIRROR_HORIZONTAL, - MMAL_PARAM_MIRROR_BOTH, -}; - -enum mmal_parameter_displaytransform { - MMAL_DISPLAY_ROT0 = 0, - MMAL_DISPLAY_MIRROR_ROT0 = 1, - MMAL_DISPLAY_MIRROR_ROT180 = 2, - MMAL_DISPLAY_ROT180 = 3, - MMAL_DISPLAY_MIRROR_ROT90 = 4, - MMAL_DISPLAY_ROT270 = 5, - MMAL_DISPLAY_ROT90 = 6, - MMAL_DISPLAY_MIRROR_ROT270 = 7, -}; - -enum mmal_parameter_displaymode { - MMAL_DISPLAY_MODE_FILL = 0, - MMAL_DISPLAY_MODE_LETTERBOX = 1, -}; - -enum mmal_parameter_displayset { - MMAL_DISPLAY_SET_NONE = 0, - MMAL_DISPLAY_SET_NUM = 1, - MMAL_DISPLAY_SET_FULLSCREEN = 2, - MMAL_DISPLAY_SET_TRANSFORM = 4, - MMAL_DISPLAY_SET_DEST_RECT = 8, - MMAL_DISPLAY_SET_SRC_RECT = 0x10, - MMAL_DISPLAY_SET_MODE = 0x20, - MMAL_DISPLAY_SET_PIXEL = 0x40, - MMAL_DISPLAY_SET_NOASPECT = 0x80, - MMAL_DISPLAY_SET_LAYER = 0x100, - MMAL_DISPLAY_SET_COPYPROTECT = 0x200, - MMAL_DISPLAY_SET_ALPHA = 0x400, -}; - -/* rectangle, used lots so it gets its own struct */ -struct vchiq_mmal_rect { - s32 x; - s32 y; - s32 width; - s32 height; -}; - -struct mmal_parameter_displayregion { - /** Bitfield that indicates which fields are set and should be - * used. All other fields will maintain their current value. - * \ref MMAL_DISPLAYSET_T defines the bits that can be - * combined. - */ - u32 set; - - /** Describes the display output device, with 0 typically - * being a directly connected LCD display. The actual values - * will depend on the hardware. Code using hard-wired numbers - * (e.g. 2) is certain to fail. - */ - - u32 display_num; - /** Indicates that we are using the full device screen area, - * rather than a window of the display. If zero, then - * dest_rect is used to specify a region of the display to - * use. - */ - - s32 fullscreen; - /** Indicates any rotation or flipping used to map frames onto - * the natural display orientation. - */ - u32 transform; /* enum mmal_parameter_displaytransform */ - - /** Where to display the frame within the screen, if - * fullscreen is zero. - */ - struct vchiq_mmal_rect dest_rect; - - /** Indicates which area of the frame to display. If all - * values are zero, the whole frame will be used. - */ - struct vchiq_mmal_rect src_rect; - - /** If set to non-zero, indicates that any display scaling - * should disregard the aspect ratio of the frame region being - * displayed. - */ - s32 noaspect; - - /** Indicates how the image should be scaled to fit the - * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates - * that the image should fill the screen by potentially - * cropping the frames. Setting \code mode \endcode to \code - * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the - * source region should be displayed and black bars added if - * necessary. - */ - u32 mode; /* enum mmal_parameter_displaymode */ - - /** If non-zero, defines the width of a source pixel relative - * to \code pixel_y \endcode. If zero, then pixels default to - * being square. - */ - u32 pixel_x; - - /** If non-zero, defines the height of a source pixel relative - * to \code pixel_x \endcode. If zero, then pixels default to - * being square. - */ - u32 pixel_y; - - /** Sets the relative depth of the images, with greater values - * being in front of smaller values. - */ - u32 layer; - - /** Set to non-zero to ensure copy protection is used on - * output. - */ - s32 copyprotect_required; - - /** Level of opacity of the layer, where zero is fully - * transparent and 255 is fully opaque. - */ - u32 alpha; -}; - -#define MMAL_MAX_IMAGEFX_PARAMETERS 5 - -struct mmal_parameter_imagefx_parameters { - enum mmal_parameter_imagefx effect; - u32 num_effect_params; - u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; -}; - -#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 -#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 -#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 - -struct mmal_parameter_camera_info_camera_t { - u32 port_id; - u32 max_width; - u32 max_height; - u32 lens_present; - u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; -}; - -enum mmal_parameter_camera_info_flash_type_t { - /* Make values explicit to ensure they match values in config ini */ - MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, - MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, - MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, - MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF -}; - -struct mmal_parameter_camera_info_flash_t { - enum mmal_parameter_camera_info_flash_type_t flash_type; -}; - -struct mmal_parameter_camera_info_t { - u32 num_cameras; - u32 num_flashes; - struct mmal_parameter_camera_info_camera_t - cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; - struct mmal_parameter_camera_info_flash_t - flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; -}; - -#endif diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c deleted file mode 100644 index de03b90021a8..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c +++ /dev/null @@ -1,1891 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * Authors: Vincent Sanders @ Collabora - * Dave Stevenson @ Broadcom - * (now dave.stevenson@raspberrypi.org) - * Simon Mellor @ Broadcom - * Luke Diamand @ Broadcom - * - * V4L2 driver MMAL vchiq interface code - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/mutex.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/completion.h> -#include <linux/vmalloc.h> -#include <media/videobuf2-vmalloc.h> - -#include "mmal-common.h" -#include "mmal-vchiq.h" -#include "mmal-msg.h" - -#define USE_VCHIQ_ARM -#include "interface/vchi/vchi.h" - -/* maximum number of components supported */ -#define VCHIQ_MMAL_MAX_COMPONENTS 4 - -/*#define FULL_MSG_DUMP 1*/ - -#ifdef DEBUG -static const char *const msg_type_names[] = { - "UNKNOWN", - "QUIT", - "SERVICE_CLOSED", - "GET_VERSION", - "COMPONENT_CREATE", - "COMPONENT_DESTROY", - "COMPONENT_ENABLE", - "COMPONENT_DISABLE", - "PORT_INFO_GET", - "PORT_INFO_SET", - "PORT_ACTION", - "BUFFER_FROM_HOST", - "BUFFER_TO_HOST", - "GET_STATS", - "PORT_PARAMETER_SET", - "PORT_PARAMETER_GET", - "EVENT_TO_HOST", - "GET_CORE_STATS_FOR_PORT", - "OPAQUE_ALLOCATOR", - "CONSUME_MEM", - "LMK", - "OPAQUE_ALLOCATOR_DESC", - "DRM_GET_LHS32", - "DRM_GET_TIME", - "BUFFER_FROM_HOST_ZEROLEN", - "PORT_FLUSH", - "HOST_LOG", -}; -#endif - -static const char *const port_action_type_names[] = { - "UNKNOWN", - "ENABLE", - "DISABLE", - "FLUSH", - "CONNECT", - "DISCONNECT", - "SET_REQUIREMENTS", -}; - -#if defined(DEBUG) -#if defined(FULL_MSG_DUMP) -#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \ - do { \ - pr_debug(TITLE" type:%s(%d) length:%d\n", \ - msg_type_names[(MSG)->h.type], \ - (MSG)->h.type, (MSG_LEN)); \ - print_hex_dump(KERN_DEBUG, "<<h: ", DUMP_PREFIX_OFFSET, \ - 16, 4, (MSG), \ - sizeof(struct mmal_msg_header), 1); \ - print_hex_dump(KERN_DEBUG, "<<p: ", DUMP_PREFIX_OFFSET, \ - 16, 4, \ - ((u8 *)(MSG)) + sizeof(struct mmal_msg_header),\ - (MSG_LEN) - sizeof(struct mmal_msg_header), 1); \ - } while (0) -#else -#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \ - { \ - pr_debug(TITLE" type:%s(%d) length:%d\n", \ - msg_type_names[(MSG)->h.type], \ - (MSG)->h.type, (MSG_LEN)); \ - } -#endif -#else -#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) -#endif - -struct vchiq_mmal_instance; - -/* normal message context */ -struct mmal_msg_context { - struct vchiq_mmal_instance *instance; - - /* Index in the context_map idr so that we can find the - * mmal_msg_context again when servicing the VCHI reply. - */ - int handle; - - union { - struct { - /* 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 */ - struct vchiq_mmal_port *port; - /* actual buffer used to store bulk reply */ - struct mmal_buffer *buffer; - /* amount of buffer used */ - unsigned long buffer_used; - /* MMAL buffer flags */ - u32 mmal_flags; - /* Presentation and Decode timestamps */ - s64 pts; - s64 dts; - - int status; /* context status */ - - } bulk; /* bulk data */ - - struct { - /* message handle to release */ - struct vchi_held_msg msg_handle; - /* pointer to received message */ - struct mmal_msg *msg; - /* received message length */ - u32 msg_len; - /* completion upon reply */ - struct completion cmplt; - } sync; /* synchronous response */ - } u; - -}; - -struct vchiq_mmal_instance { - struct vchi_service_handle *handle; - - /* ensure serialised access to service */ - struct mutex vchiq_mutex; - - /* vmalloc page to receive scratch bulk xfers into */ - void *bulk_scratch; - - struct idr context_map; - /* 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 * -get_msg_context(struct vchiq_mmal_instance *instance) -{ - struct mmal_msg_context *msg_context; - int handle; - - /* todo: should this be allocated from a pool to avoid kzalloc */ - msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL); - - if (!msg_context) - return ERR_PTR(-ENOMEM); - - /* Create an ID that will be passed along with our message so - * that when we service the VCHI reply, we can look up what - * message is being replied to. - */ - mutex_lock(&instance->context_map_lock); - handle = idr_alloc(&instance->context_map, msg_context, - 0, 0, GFP_KERNEL); - mutex_unlock(&instance->context_map_lock); - - if (handle < 0) { - kfree(msg_context); - return ERR_PTR(handle); - } - - msg_context->instance = instance; - msg_context->handle = handle; - - return msg_context; -} - -static struct mmal_msg_context * -lookup_msg_context(struct vchiq_mmal_instance *instance, int handle) -{ - return idr_find(&instance->context_map, handle); -} - -static void -release_msg_context(struct mmal_msg_context *msg_context) -{ - struct vchiq_mmal_instance *instance = msg_context->instance; - - mutex_lock(&instance->context_map_lock); - idr_remove(&instance->context_map, msg_context->handle); - mutex_unlock(&instance->context_map_lock); - kfree(msg_context); -} - -/* deals with receipt of event to host message */ -static void event_to_host_cb(struct vchiq_mmal_instance *instance, - struct mmal_msg *msg, u32 msg_len) -{ - pr_debug("unhandled event\n"); - pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n", - msg->u.event_to_host.client_component, - msg->u.event_to_host.port_type, - msg->u.event_to_host.port_num, - msg->u.event_to_host.cmd, msg->u.event_to_host.length); -} - -/* workqueue scheduled callback - * - * we do this because it is important we do not call any other vchiq - * sync calls from witin the message delivery thread - */ -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, - msg_context->u.bulk.buffer, - msg_context->u.bulk.buffer_used, - 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 */ -static int bulk_receive(struct vchiq_mmal_instance *instance, - struct mmal_msg *msg, - struct mmal_msg_context *msg_context) -{ - unsigned long rd_len; - - rd_len = msg->u.buffer_from_host.buffer_header.length; - - if (!msg_context->u.bulk.buffer) { - pr_err("bulk.buffer not configured - error in buffer_from_host\n"); - - /* todo: this is a serious error, we should never have - * committed a buffer_to_host operation to the mmal - * port without the buffer to back it up (underflow - * handling) and there is no obvious way to deal with - * this - how is the mmal servie going to react when - * we fail to do the xfer and reschedule a buffer when - * it arrives? perhaps a starved flag to indicate a - * waiting bulk receive? - */ - - return -EINVAL; - } - - /* ensure we do not overrun the available buffer */ - if (rd_len > msg_context->u.bulk.buffer->buffer_size) { - rd_len = msg_context->u.bulk.buffer->buffer_size; - pr_warn("short read as not enough receive buffer space\n"); - /* todo: is this the correct response, what happens to - * the rest of the message data? - */ - } - - /* store length */ - msg_context->u.bulk.buffer_used = rd_len; - 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_work(msg_context->instance->bulk_wq, - &msg_context->u.bulk.buffer_to_host_work); - - return 0; -} - -/* data in message, memcpy from packet into output buffer */ -static int inline_receive(struct vchiq_mmal_instance *instance, - struct mmal_msg *msg, - struct mmal_msg_context *msg_context) -{ - memcpy(msg_context->u.bulk.buffer->buffer, - msg->u.buffer_from_host.short_data, - msg->u.buffer_from_host.payload_in_message); - - msg_context->u.bulk.buffer_used = - msg->u.buffer_from_host.payload_in_message; - - return 0; -} - -/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */ -static int -buffer_from_host(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, struct mmal_buffer *buf) -{ - struct mmal_msg_context *msg_context; - struct mmal_msg m; - int ret; - - if (!port->enabled) - return -EINVAL; - - pr_debug("instance:%p buffer:%p\n", instance->handle, buf); - - /* get context */ - if (!buf->msg_context) { - pr_err("%s: msg_context not allocated, buf %p\n", __func__, - buf); - return -EINVAL; - } - msg_context = buf->msg_context; - - /* store bulk message context for when data arrives */ - msg_context->u.bulk.instance = instance; - msg_context->u.bulk.port = port; - msg_context->u.bulk.buffer = buf; - msg_context->u.bulk.buffer_used = 0; - - /* 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 */ - - m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST; - m.h.magic = MMAL_MAGIC; - m.h.context = msg_context->handle; - m.h.status = 0; - - /* drvbuf is our private data passed back */ - m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC; - m.u.buffer_from_host.drvbuf.component_handle = port->component->handle; - m.u.buffer_from_host.drvbuf.port_handle = port->handle; - m.u.buffer_from_host.drvbuf.client_context = msg_context->handle; - - /* buffer header */ - m.u.buffer_from_host.buffer_header.cmd = 0; - m.u.buffer_from_host.buffer_header.data = - (u32)(unsigned long)buf->buffer; - m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; - m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */ - m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */ - m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */ - m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; - m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; - - /* clear buffer type sepecific data */ - memset(&m.u.buffer_from_host.buffer_header_type_specific, 0, - sizeof(m.u.buffer_from_host.buffer_header_type_specific)); - - /* no payload in message */ - m.u.buffer_from_host.payload_in_message = 0; - - vchi_service_use(instance->handle); - - ret = vchi_queue_kernel_message(instance->handle, - &m, - sizeof(struct mmal_msg_header) + - sizeof(m.u.buffer_from_host)); - - vchi_service_release(instance->handle); - - return ret; -} - -/* deals with receipt of buffer to host message */ -static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, - struct mmal_msg *msg, u32 msg_len) -{ - struct mmal_msg_context *msg_context; - u32 handle; - - pr_debug("%s: instance:%p msg:%p msg_len:%d\n", - __func__, instance, msg, msg_len); - - if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { - handle = msg->u.buffer_from_host.drvbuf.client_context; - msg_context = lookup_msg_context(instance, handle); - - if (!msg_context) { - pr_err("drvbuf.client_context(%u) is invalid\n", - handle); - return; - } - } else { - pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n"); - 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); - - msg_context->u.bulk.status = msg->h.status; - - } else if (msg->u.buffer_from_host.buffer_header.length == 0) { - /* empty buffer */ - if (msg->u.buffer_from_host.buffer_header.flags & - MMAL_BUFFER_HEADER_FLAG_EOS) { - msg_context->u.bulk.status = - bulk_receive(instance, msg, msg_context); - if (msg_context->u.bulk.status == 0) - return; /* successful bulk submission, bulk - * completion will trigger callback - */ - } else { - /* do callback with empty buffer - not EOS though */ - msg_context->u.bulk.status = 0; - msg_context->u.bulk.buffer_used = 0; - } - } else if (msg->u.buffer_from_host.payload_in_message == 0) { - /* data is not in message, queue a bulk receive */ - msg_context->u.bulk.status = - bulk_receive(instance, msg, msg_context); - if (msg_context->u.bulk.status == 0) - return; /* successful bulk submission, bulk - * completion will trigger callback - */ - - /* failed to submit buffer, this will end badly */ - pr_err("error %d on bulk submission\n", - msg_context->u.bulk.status); - - } else if (msg->u.buffer_from_host.payload_in_message <= - MMAL_VC_SHORT_DATA) { - /* data payload within message */ - msg_context->u.bulk.status = inline_receive(instance, msg, - msg_context); - } else { - pr_err("message with invalid short payload\n"); - - /* signal error */ - msg_context->u.bulk.status = -EINVAL; - msg_context->u.bulk.buffer_used = - msg->u.buffer_from_host.payload_in_message; - } - - /* schedule the port callback */ - schedule_work(&msg_context->u.bulk.work); -} - -static void bulk_receive_cb(struct vchiq_mmal_instance *instance, - struct mmal_msg_context *msg_context) -{ - msg_context->u.bulk.status = 0; - - /* schedule the port callback */ - schedule_work(&msg_context->u.bulk.work); -} - -static void bulk_abort_cb(struct vchiq_mmal_instance *instance, - struct mmal_msg_context *msg_context) -{ - pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context); - - msg_context->u.bulk.status = -EINTR; - - schedule_work(&msg_context->u.bulk.work); -} - -/* incoming event service callback */ -static void service_callback(void *param, - const enum vchi_callback_reason reason, - void *bulk_ctx) -{ - struct vchiq_mmal_instance *instance = param; - int status; - u32 msg_len; - struct mmal_msg *msg; - struct vchi_held_msg msg_handle; - struct mmal_msg_context *msg_context; - - if (!instance) { - pr_err("Message callback passed NULL instance\n"); - return; - } - - switch (reason) { - case VCHI_CALLBACK_MSG_AVAILABLE: - status = vchi_msg_hold(instance->handle, (void **)&msg, - &msg_len, VCHI_FLAGS_NONE, &msg_handle); - if (status) { - pr_err("Unable to dequeue a message (%d)\n", status); - break; - } - - DBG_DUMP_MSG(msg, msg_len, "<<< reply message"); - - /* handling is different for buffer messages */ - switch (msg->h.type) { - case MMAL_MSG_TYPE_BUFFER_FROM_HOST: - vchi_held_msg_release(&msg_handle); - break; - - case MMAL_MSG_TYPE_EVENT_TO_HOST: - event_to_host_cb(instance, msg, msg_len); - vchi_held_msg_release(&msg_handle); - - break; - - case MMAL_MSG_TYPE_BUFFER_TO_HOST: - buffer_to_host_cb(instance, msg, msg_len); - vchi_held_msg_release(&msg_handle); - break; - - default: - /* messages dependent on header context to complete */ - if (!msg->h.context) { - pr_err("received message context was null!\n"); - vchi_held_msg_release(&msg_handle); - break; - } - - msg_context = lookup_msg_context(instance, - msg->h.context); - if (!msg_context) { - pr_err("received invalid message context %u!\n", - msg->h.context); - vchi_held_msg_release(&msg_handle); - break; - } - - /* fill in context values */ - msg_context->u.sync.msg_handle = msg_handle; - msg_context->u.sync.msg = msg; - msg_context->u.sync.msg_len = msg_len; - - /* todo: should this check (completion_done() - * == 1) for no one waiting? or do we need a - * flag to tell us the completion has been - * interrupted so we can free the message and - * its context. This probably also solves the - * message arriving after interruption todo - * below - */ - - /* complete message so caller knows it happened */ - complete(&msg_context->u.sync.cmplt); - break; - } - - break; - - case VCHI_CALLBACK_BULK_RECEIVED: - bulk_receive_cb(instance, bulk_ctx); - break; - - case VCHI_CALLBACK_BULK_RECEIVE_ABORTED: - bulk_abort_cb(instance, bulk_ctx); - break; - - case VCHI_CALLBACK_SERVICE_CLOSED: - /* TODO: consider if this requires action if received when - * driver is not explicitly closing the service - */ - break; - - default: - pr_err("Received unhandled message reason %d\n", reason); - break; - } -} - -static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance, - struct mmal_msg *msg, - unsigned int payload_len, - struct mmal_msg **msg_out, - struct vchi_held_msg *msg_handle_out) -{ - struct mmal_msg_context *msg_context; - int ret; - unsigned long timeout; - - /* payload size must not cause message to exceed max size */ - 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 - - sizeof(struct mmal_msg_header))); - return -EINVAL; - } - - msg_context = get_msg_context(instance); - if (IS_ERR(msg_context)) - return PTR_ERR(msg_context); - - init_completion(&msg_context->u.sync.cmplt); - - msg->h.magic = MMAL_MAGIC; - msg->h.context = msg_context->handle; - msg->h.status = 0; - - DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len), - ">>> sync message"); - - vchi_service_use(instance->handle); - - ret = vchi_queue_kernel_message(instance->handle, - msg, - sizeof(struct mmal_msg_header) + - payload_len); - - vchi_service_release(instance->handle); - - if (ret) { - pr_err("error %d queuing message\n", ret); - release_msg_context(msg_context); - return ret; - } - - timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt, - 3 * HZ); - if (timeout == 0) { - pr_err("timed out waiting for sync completion\n"); - ret = -ETIME; - /* todo: what happens if the message arrives after aborting */ - release_msg_context(msg_context); - return ret; - } - - *msg_out = msg_context->u.sync.msg; - *msg_handle_out = msg_context->u.sync.msg_handle; - release_msg_context(msg_context); - - return 0; -} - -static void dump_port_info(struct vchiq_mmal_port *port) -{ - pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled); - - pr_debug("buffer minimum num:%d size:%d align:%d\n", - port->minimum_buffer.num, - port->minimum_buffer.size, port->minimum_buffer.alignment); - - pr_debug("buffer recommended num:%d size:%d align:%d\n", - port->recommended_buffer.num, - port->recommended_buffer.size, - port->recommended_buffer.alignment); - - pr_debug("buffer current values num:%d size:%d align:%d\n", - port->current_buffer.num, - port->current_buffer.size, port->current_buffer.alignment); - - pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n", - port->format.type, - port->format.encoding, port->format.encoding_variant); - - pr_debug(" bitrate:%d flags:0x%x\n", - port->format.bitrate, port->format.flags); - - if (port->format.type == MMAL_ES_TYPE_VIDEO) { - pr_debug - ("es video format: width:%d height:%d colourspace:0x%x\n", - port->es.video.width, port->es.video.height, - port->es.video.color_space); - - pr_debug(" : crop xywh %d,%d,%d,%d\n", - port->es.video.crop.x, - port->es.video.crop.y, - port->es.video.crop.width, port->es.video.crop.height); - pr_debug(" : framerate %d/%d aspect %d/%d\n", - port->es.video.frame_rate.num, - port->es.video.frame_rate.den, - port->es.video.par.num, port->es.video.par.den); - } -} - -static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p) -{ - /* todo do readonly fields need setting at all? */ - p->type = port->type; - p->index = port->index; - p->index_all = 0; - p->is_enabled = port->enabled; - p->buffer_num_min = port->minimum_buffer.num; - p->buffer_size_min = port->minimum_buffer.size; - p->buffer_alignment_min = port->minimum_buffer.alignment; - p->buffer_num_recommended = port->recommended_buffer.num; - p->buffer_size_recommended = port->recommended_buffer.size; - - /* only three writable fields in a port */ - p->buffer_num = port->current_buffer.num; - p->buffer_size = port->current_buffer.size; - p->userdata = (u32)(unsigned long)port; -} - -static int port_info_set(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - pr_debug("setting port info port %p\n", port); - if (!port) - return -1; - dump_port_info(port); - - m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET; - - m.u.port_info_set.component_handle = port->component->handle; - m.u.port_info_set.port_type = port->type; - m.u.port_info_set.port_index = port->index; - - port_to_mmal_msg(port, &m.u.port_info_set.port); - - /* elementary stream format setup */ - m.u.port_info_set.format.type = port->format.type; - m.u.port_info_set.format.encoding = port->format.encoding; - m.u.port_info_set.format.encoding_variant = - port->format.encoding_variant; - m.u.port_info_set.format.bitrate = port->format.bitrate; - m.u.port_info_set.format.flags = port->format.flags; - - memcpy(&m.u.port_info_set.es, &port->es, - sizeof(union mmal_es_specific_format)); - - m.u.port_info_set.format.extradata_size = port->format.extradata_size; - memcpy(&m.u.port_info_set.extradata, port->format.extradata, - port->format.extradata_size); - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.port_info_set), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - /* return operation status */ - ret = -rmsg->u.port_info_get_reply.status; - - pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret, - port->component->handle, port->handle); - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* use port info get message to retrieve port information */ -static int port_info_get(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - /* port info time */ - m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET; - m.u.port_info_get.component_handle = port->component->handle; - m.u.port_info_get.port_type = port->type; - m.u.port_info_get.index = port->index; - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.port_info_get), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - /* return operation status */ - ret = -rmsg->u.port_info_get_reply.status; - if (ret != MMAL_MSG_STATUS_SUCCESS) - goto release_msg; - - if (rmsg->u.port_info_get_reply.port.is_enabled == 0) - port->enabled = 0; - else - port->enabled = 1; - - /* copy the values out of the message */ - port->handle = rmsg->u.port_info_get_reply.port_handle; - - /* port type and index cached to use on port info set because - * it does not use a port handle - */ - port->type = rmsg->u.port_info_get_reply.port_type; - port->index = rmsg->u.port_info_get_reply.port_index; - - port->minimum_buffer.num = - rmsg->u.port_info_get_reply.port.buffer_num_min; - port->minimum_buffer.size = - rmsg->u.port_info_get_reply.port.buffer_size_min; - port->minimum_buffer.alignment = - rmsg->u.port_info_get_reply.port.buffer_alignment_min; - - port->recommended_buffer.alignment = - rmsg->u.port_info_get_reply.port.buffer_alignment_min; - port->recommended_buffer.num = - rmsg->u.port_info_get_reply.port.buffer_num_recommended; - - port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num; - port->current_buffer.size = - rmsg->u.port_info_get_reply.port.buffer_size; - - /* stream format */ - port->format.type = rmsg->u.port_info_get_reply.format.type; - port->format.encoding = rmsg->u.port_info_get_reply.format.encoding; - port->format.encoding_variant = - rmsg->u.port_info_get_reply.format.encoding_variant; - port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate; - port->format.flags = rmsg->u.port_info_get_reply.format.flags; - - /* elementary stream format */ - memcpy(&port->es, - &rmsg->u.port_info_get_reply.es, - sizeof(union mmal_es_specific_format)); - port->format.es = &port->es; - - port->format.extradata_size = - rmsg->u.port_info_get_reply.format.extradata_size; - memcpy(port->format.extradata, - rmsg->u.port_info_get_reply.extradata, - port->format.extradata_size); - - pr_debug("received port info\n"); - dump_port_info(port); - -release_msg: - - pr_debug("%s:result:%d component:0x%x port:%d\n", - __func__, ret, port->component->handle, port->handle); - - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* create comonent on vc */ -static int create_component(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component, - const char *name) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - /* build component create message */ - m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE; - m.u.component_create.client_component = (u32)(unsigned long)component; - strncpy(m.u.component_create.name, name, - sizeof(m.u.component_create.name)); - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.component_create), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != m.h.type) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.component_create_reply.status; - if (ret != MMAL_MSG_STATUS_SUCCESS) - goto release_msg; - - /* a valid component response received */ - component->handle = rmsg->u.component_create_reply.component_handle; - component->inputs = rmsg->u.component_create_reply.input_num; - component->outputs = rmsg->u.component_create_reply.output_num; - component->clocks = rmsg->u.component_create_reply.clock_num; - - pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n", - component->handle, - component->inputs, component->outputs, component->clocks); - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* destroys a component on vc */ -static int destroy_component(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY; - m.u.component_destroy.component_handle = component->handle; - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.component_destroy), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != m.h.type) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.component_destroy_reply.status; - -release_msg: - - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* enable a component on vc */ -static int enable_component(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE; - m.u.component_enable.component_handle = component->handle; - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.component_enable), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != m.h.type) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.component_enable_reply.status; - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* disable a component on vc */ -static int disable_component(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE; - m.u.component_disable.component_handle = component->handle; - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.component_disable), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != m.h.type) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.component_disable_reply.status; - -release_msg: - - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* get version of mmal implementation */ -static int get_version(struct vchiq_mmal_instance *instance, - u32 *major_out, u32 *minor_out) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_GET_VERSION; - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.version), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != m.h.type) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - *major_out = rmsg->u.version.major; - *minor_out = rmsg->u.version.minor; - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* do a port action with a port as a parameter */ -static int port_action_port(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - enum mmal_msg_port_action_type action_type) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_PORT_ACTION; - m.u.port_action_port.component_handle = port->component->handle; - m.u.port_action_port.port_handle = port->handle; - m.u.port_action_port.action = action_type; - - port_to_mmal_msg(port, &m.u.port_action_port.port); - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.port_action_port), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.port_action_reply.status; - - pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n", - __func__, - ret, port->component->handle, port->handle, - port_action_type_names[action_type], action_type); - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* do a port action with handles as parameters */ -static int port_action_handle(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - enum mmal_msg_port_action_type action_type, - u32 connect_component_handle, - u32 connect_port_handle) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_PORT_ACTION; - - m.u.port_action_handle.component_handle = port->component->handle; - m.u.port_action_handle.port_handle = port->handle; - m.u.port_action_handle.action = action_type; - - m.u.port_action_handle.connect_component_handle = - connect_component_handle; - m.u.port_action_handle.connect_port_handle = connect_port_handle; - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(m.u.port_action_handle), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.port_action_reply.status; - - pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n", - __func__, - ret, port->component->handle, port->handle, - port_action_type_names[action_type], - action_type, connect_component_handle, connect_port_handle); - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -static int port_parameter_set(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - u32 parameter_id, void *value, u32 value_size) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET; - - m.u.port_parameter_set.component_handle = port->component->handle; - m.u.port_parameter_set.port_handle = port->handle; - m.u.port_parameter_set.id = parameter_id; - m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size; - memcpy(&m.u.port_parameter_set.value, value, value_size); - - ret = send_synchronous_mmal_msg(instance, &m, - (4 * sizeof(u32)) + value_size, - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) { - /* got an unexpected message type in reply */ - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.port_parameter_set_reply.status; - - pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", - __func__, - ret, port->component->handle, port->handle, parameter_id); - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -static int port_parameter_get(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - u32 parameter_id, void *value, u32 *value_size) -{ - int ret; - struct mmal_msg m; - struct mmal_msg *rmsg; - struct vchi_held_msg rmsg_handle; - - m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET; - - m.u.port_parameter_get.component_handle = port->component->handle; - m.u.port_parameter_get.port_handle = port->handle; - m.u.port_parameter_get.id = parameter_id; - m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size; - - ret = send_synchronous_mmal_msg(instance, &m, - sizeof(struct - mmal_msg_port_parameter_get), - &rmsg, &rmsg_handle); - if (ret) - return ret; - - if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) { - /* got an unexpected message type in reply */ - pr_err("Incorrect reply type %d\n", rmsg->h.type); - ret = -EINVAL; - goto release_msg; - } - - ret = -rmsg->u.port_parameter_get_reply.status; - /* port_parameter_get_reply.size includes the header, - * whilst *value_size doesn't. - */ - rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32)); - - if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) { - /* Copy only as much as we have space for - * but report true size of parameter - */ - memcpy(value, &rmsg->u.port_parameter_get_reply.value, - *value_size); - *value_size = rmsg->u.port_parameter_get_reply.size; - } 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); - -release_msg: - vchi_held_msg_release(&rmsg_handle); - - return ret; -} - -/* disables a port and drains buffers from it */ -static int port_disable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port) -{ - int ret; - struct list_head *q, *buf_head; - unsigned long flags = 0; - - if (!port->enabled) - return 0; - - port->enabled = 0; - - ret = port_action_port(instance, port, - MMAL_MSG_PORT_ACTION_TYPE_DISABLE); - if (ret == 0) { - /* - * Drain all queued buffers on port. This should only - * apply to buffers that have been queued before the port - * has been enabled. If the port has been enabled and buffers - * passed, then the buffers should have been removed from this - * list, and we should get the relevant callbacks via VCHIQ - * to release the buffers. - */ - spin_lock_irqsave(&port->slock, flags); - - list_for_each_safe(buf_head, q, &port->buffers) { - struct mmal_buffer *mmalbuf; - - mmalbuf = list_entry(buf_head, struct mmal_buffer, - list); - list_del(buf_head); - if (port->buffer_cb) - port->buffer_cb(instance, - port, 0, mmalbuf, 0, 0, - MMAL_TIME_UNKNOWN, - MMAL_TIME_UNKNOWN); - } - - spin_unlock_irqrestore(&port->slock, flags); - - ret = port_info_get(instance, port); - } - - return ret; -} - -/* enable a port */ -static int port_enable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port) -{ - unsigned int hdr_count; - struct list_head *q, *buf_head; - int ret; - - if (port->enabled) - return 0; - - ret = port_action_port(instance, port, - MMAL_MSG_PORT_ACTION_TYPE_ENABLE); - if (ret) - goto done; - - port->enabled = 1; - - if (port->buffer_cb) { - /* send buffer headers to videocore */ - hdr_count = 1; - list_for_each_safe(buf_head, q, &port->buffers) { - struct mmal_buffer *mmalbuf; - - mmalbuf = list_entry(buf_head, struct mmal_buffer, - list); - ret = buffer_from_host(instance, port, mmalbuf); - if (ret) - goto done; - - list_del(buf_head); - hdr_count++; - if (hdr_count > port->current_buffer.num) - break; - } - } - - ret = port_info_get(instance, port); - -done: - return ret; -} - -/* ------------------------------------------------------------------ - * Exported API - *------------------------------------------------------------------ - */ - -int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - ret = port_info_set(instance, port); - if (ret) - goto release_unlock; - - /* read what has actually been set */ - ret = port_info_get(instance, port); - -release_unlock: - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - u32 parameter, void *value, u32 value_size) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - ret = port_parameter_set(instance, port, parameter, value, value_size); - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - u32 parameter, void *value, u32 *value_size) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - ret = port_parameter_get(instance, port, parameter, value, value_size); - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -/* enable a port - * - * enables a port and queues buffers for satisfying callbacks if we - * provide a callback handler - */ -int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - vchiq_mmal_buffer_cb buffer_cb) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - /* already enabled - noop */ - if (port->enabled) { - ret = 0; - goto unlock; - } - - port->buffer_cb = buffer_cb; - - ret = port_enable(instance, port); - -unlock: - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - if (!port->enabled) { - mutex_unlock(&instance->vchiq_mutex); - return 0; - } - - ret = port_disable(instance, port); - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -/* ports will be connected in a tunneled manner so data buffers - * are not handled by client. - */ -int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *src, - struct vchiq_mmal_port *dst) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - /* disconnect ports if connected */ - if (src->connected) { - ret = port_disable(instance, src); - if (ret) { - pr_err("failed disabling src port(%d)\n", ret); - goto release_unlock; - } - - /* do not need to disable the destination port as they - * are connected and it is done automatically - */ - - ret = port_action_handle(instance, src, - MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, - src->connected->component->handle, - src->connected->handle); - if (ret < 0) { - pr_err("failed disconnecting src port\n"); - goto release_unlock; - } - src->connected->enabled = 0; - src->connected = NULL; - } - - if (!dst) { - /* do not make new connection */ - ret = 0; - pr_debug("not making new connection\n"); - goto release_unlock; - } - - /* copy src port format to dst */ - dst->format.encoding = src->format.encoding; - dst->es.video.width = src->es.video.width; - dst->es.video.height = src->es.video.height; - dst->es.video.crop.x = src->es.video.crop.x; - dst->es.video.crop.y = src->es.video.crop.y; - dst->es.video.crop.width = src->es.video.crop.width; - dst->es.video.crop.height = src->es.video.crop.height; - dst->es.video.frame_rate.num = src->es.video.frame_rate.num; - dst->es.video.frame_rate.den = src->es.video.frame_rate.den; - - /* set new format */ - ret = port_info_set(instance, dst); - if (ret) { - pr_debug("setting port info failed\n"); - goto release_unlock; - } - - /* read what has actually been set */ - ret = port_info_get(instance, dst); - if (ret) { - pr_debug("read back port info failed\n"); - goto release_unlock; - } - - /* connect two ports together */ - ret = port_action_handle(instance, src, - MMAL_MSG_PORT_ACTION_TYPE_CONNECT, - dst->component->handle, dst->handle); - if (ret < 0) { - pr_debug("connecting port %d:%d to %d:%d failed\n", - src->component->handle, src->handle, - dst->component->handle, dst->handle); - goto release_unlock; - } - src->connected = dst; - -release_unlock: - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - struct mmal_buffer *buffer) -{ - unsigned long flags = 0; - int ret; - - ret = buffer_from_host(instance, port, buffer); - if (ret == -EINVAL) { - /* Port is disabled. Queue for when it is enabled. */ - spin_lock_irqsave(&port->slock, flags); - list_add_tail(&buffer->list, &port->buffers); - spin_unlock_irqrestore(&port->slock, flags); - } - - return 0; -} - -int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, - struct mmal_buffer *buf) -{ - struct mmal_msg_context *msg_context = get_msg_context(instance); - - if (IS_ERR(msg_context)) - return (PTR_ERR(msg_context)); - - buf->msg_context = msg_context; - return 0; -} - -int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) -{ - struct mmal_msg_context *msg_context = buf->msg_context; - - if (msg_context) - release_msg_context(msg_context); - buf->msg_context = NULL; - - return 0; -} - -/* Initialise a mmal component and its ports - * - */ -int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance, - const char *name, - struct vchiq_mmal_component **component_out) -{ - int ret; - int idx; /* port index */ - struct vchiq_mmal_component *component; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) { - ret = -EINVAL; /* todo is this correct error? */ - goto unlock; - } - - component = &instance->component[instance->component_idx]; - - ret = create_component(instance, component, name); - if (ret < 0) { - pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", - __func__, ret); - goto unlock; - } - - /* ports info needs gathering */ - component->control.type = MMAL_PORT_TYPE_CONTROL; - component->control.index = 0; - component->control.component = component; - spin_lock_init(&component->control.slock); - INIT_LIST_HEAD(&component->control.buffers); - ret = port_info_get(instance, &component->control); - if (ret < 0) - goto release_component; - - for (idx = 0; idx < component->inputs; idx++) { - component->input[idx].type = MMAL_PORT_TYPE_INPUT; - component->input[idx].index = idx; - component->input[idx].component = component; - spin_lock_init(&component->input[idx].slock); - INIT_LIST_HEAD(&component->input[idx].buffers); - ret = port_info_get(instance, &component->input[idx]); - if (ret < 0) - goto release_component; - } - - for (idx = 0; idx < component->outputs; idx++) { - component->output[idx].type = MMAL_PORT_TYPE_OUTPUT; - component->output[idx].index = idx; - component->output[idx].component = component; - spin_lock_init(&component->output[idx].slock); - INIT_LIST_HEAD(&component->output[idx].buffers); - ret = port_info_get(instance, &component->output[idx]); - if (ret < 0) - goto release_component; - } - - for (idx = 0; idx < component->clocks; idx++) { - component->clock[idx].type = MMAL_PORT_TYPE_CLOCK; - component->clock[idx].index = idx; - component->clock[idx].component = component; - spin_lock_init(&component->clock[idx].slock); - INIT_LIST_HEAD(&component->clock[idx].buffers); - ret = port_info_get(instance, &component->clock[idx]); - if (ret < 0) - goto release_component; - } - - instance->component_idx++; - - *component_out = component; - - mutex_unlock(&instance->vchiq_mutex); - - return 0; - -release_component: - destroy_component(instance, component); -unlock: - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -/* - * cause a mmal component to be destroyed - */ -int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - if (component->enabled) - ret = disable_component(instance, component); - - ret = destroy_component(instance, component); - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -/* - * cause a mmal component to be enabled - */ -int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - if (component->enabled) { - mutex_unlock(&instance->vchiq_mutex); - return 0; - } - - ret = enable_component(instance, component); - if (ret == 0) - component->enabled = true; - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -/* - * cause a mmal component to be enabled - */ -int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - if (!component->enabled) { - mutex_unlock(&instance->vchiq_mutex); - return 0; - } - - ret = disable_component(instance, component); - if (ret == 0) - component->enabled = 0; - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -int vchiq_mmal_version(struct vchiq_mmal_instance *instance, - u32 *major_out, u32 *minor_out) -{ - int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - ret = get_version(instance, major_out, minor_out); - - mutex_unlock(&instance->vchiq_mutex); - - return ret; -} - -int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance) -{ - int status = 0; - - if (!instance) - return -EINVAL; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; - - vchi_service_use(instance->handle); - - status = vchi_service_close(instance->handle); - if (status != 0) - pr_err("mmal-vchiq: VCHIQ close failed\n"); - - mutex_unlock(&instance->vchiq_mutex); - - flush_workqueue(instance->bulk_wq); - destroy_workqueue(instance->bulk_wq); - - vfree(instance->bulk_scratch); - - idr_destroy(&instance->context_map); - - kfree(instance); - - return status; -} - -int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) -{ - int status; - struct vchiq_mmal_instance *instance; - static struct vchi_instance_handle *vchi_instance; - struct service_creation params = { - .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER), - .service_id = VC_MMAL_SERVER_NAME, - .callback = service_callback, - .callback_param = NULL, - }; - - /* compile time checks to ensure structure size as they are - * directly (de)serialised from memory. - */ - - /* ensure the header structure has packed to the correct size */ - BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24); - - /* ensure message structure does not exceed maximum length */ - BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE); - - /* mmal port struct is correct size */ - BUILD_BUG_ON(sizeof(struct mmal_port) != 64); - - /* create a vchi instance */ - status = vchi_initialise(&vchi_instance); - if (status) { - pr_err("Failed to initialise VCHI instance (status=%d)\n", - status); - return -EIO; - } - - status = vchi_connect(vchi_instance); - if (status) { - pr_err("Failed to connect VCHI instance (status=%d)\n", status); - return -EIO; - } - - instance = kzalloc(sizeof(*instance), GFP_KERNEL); - - if (!instance) - return -ENOMEM; - - mutex_init(&instance->vchiq_mutex); - - instance->bulk_scratch = vmalloc(PAGE_SIZE); - - 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", - status); - goto err_close_services; - } - - vchi_service_release(instance->handle); - - *out_instance = 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 deleted file mode 100644 index 47897e81ec58..000000000000 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h +++ /dev/null @@ -1,166 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Broadcom BM2835 V4L2 driver - * - * Copyright © 2013 Raspberry Pi (Trading) Ltd. - * - * Authors: Vincent Sanders @ Collabora - * Dave Stevenson @ Broadcom - * (now dave.stevenson@raspberrypi.org) - * Simon Mellor @ Broadcom - * Luke Diamand @ Broadcom - * - * MMAL interface to VCHIQ message passing - */ - -#ifndef MMAL_VCHIQ_H -#define MMAL_VCHIQ_H - -#include "mmal-msg-format.h" - -#define MAX_PORT_COUNT 4 - -/* Maximum size of the format extradata. */ -#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 - -struct vchiq_mmal_instance; - -enum vchiq_mmal_es_type { - MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ - MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */ - MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */ - MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */ - MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */ -}; - -struct vchiq_mmal_port_buffer { - unsigned int num; /* number of buffers */ - u32 size; /* size of buffers */ - u32 alignment; /* alignment of buffers */ -}; - -struct vchiq_mmal_port; - -typedef void (*vchiq_mmal_buffer_cb)( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - int status, struct mmal_buffer *buffer, - unsigned long length, u32 mmal_flags, s64 dts, s64 pts); - -struct vchiq_mmal_port { - 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 */ - - /* component port belongs to, allows simple deref */ - struct vchiq_mmal_component *component; - - struct vchiq_mmal_port *connected; /* port connected to */ - - /* buffer info */ - struct vchiq_mmal_port_buffer minimum_buffer; - struct vchiq_mmal_port_buffer recommended_buffer; - struct vchiq_mmal_port_buffer current_buffer; - - /* stream format */ - struct mmal_es_format_local format; - /* elementary stream format */ - union mmal_es_specific_format es; - - /* data buffers to fill */ - 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 */ - void *cb_ctx; -}; - -struct vchiq_mmal_component { - u32 enabled:1; - u32 handle; /* VideoCore handle for component */ - u32 inputs; /* Number of input ports */ - u32 outputs; /* Number of output ports */ - u32 clocks; /* Number of clock ports */ - struct vchiq_mmal_port control; /* control port */ - struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ - struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ - struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ -}; - -int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); -int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); - -/* Initialise a mmal component and its ports - * - */ -int vchiq_mmal_component_init( - struct vchiq_mmal_instance *instance, - const char *name, - struct vchiq_mmal_component **component_out); - -int vchiq_mmal_component_finalise( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component); - -int vchiq_mmal_component_enable( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component); - -int vchiq_mmal_component_disable( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component); - -/* enable a mmal port - * - * enables a port and if a buffer callback provided enque buffer - * headers as appropriate for the port. - */ -int vchiq_mmal_port_enable( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - vchiq_mmal_buffer_cb buffer_cb); - -/* disable a port - * - * disable a port will dequeue any pending buffers - */ -int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port); - -int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - u32 parameter, - void *value, - u32 value_size); - -int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - u32 parameter, - void *value, - u32 *value_size); - -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); - -int vchiq_mmal_version(struct vchiq_mmal_instance *instance, - u32 *major_out, - u32 *minor_out); - -int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - struct mmal_buffer *buf); - -int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, - struct mmal_buffer *buf); -int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf); -#endif /* MMAL_VCHIQ_H */ |