aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch7518
1 files changed, 7518 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch b/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch
new file mode 100644
index 0000000000..278d57b1bd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch
@@ -0,0 +1,7518 @@
+From 85961f2d8f646488acb86f996c78a1f9ad57cb0a Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Mon, 24 Sep 2018 16:30:37 +0100
+Subject: [PATCH] staging: vc04_services: Split vchiq-mmal into a
+ module
+
+In preparation for adding a video codec V4L2 module which also
+wants to use vchiq-mmal functions, split it out into an
+independent module.
+The minimum number of changes have been made to achieve this
+(eg straight moves where possible) so existing checkpatch
+errors will still be present.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ drivers/staging/vc04_services/Kconfig | 1 +
+ drivers/staging/vc04_services/Makefile | 1 +
+ .../vc04_services/bcm2835-camera/Kconfig | 2 +-
+ .../vc04_services/bcm2835-camera/Makefile | 5 +++--
+ .../staging/vc04_services/vchiq-mmal/Kconfig | 7 ++++++
+ .../staging/vc04_services/vchiq-mmal/Makefile | 8 +++++++
+ .../mmal-common.h | 0
+ .../mmal-encodings.h | 0
+ .../mmal-msg-common.h | 0
+ .../mmal-msg-format.h | 0
+ .../mmal-msg-port.h | 0
+ .../{bcm2835-camera => vchiq-mmal}/mmal-msg.h | 0
+ .../mmal-parameters.h | 0
+ .../mmal-vchiq.c | 22 +++++++++++++++++++
+ .../mmal-vchiq.h | 0
+ 15 files changed, 43 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Kconfig
+ create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Makefile
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-common.h (100%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-encodings.h (100%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-common.h (100%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-format.h (100%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-port.h (100%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg.h (100%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-parameters.h (100%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.c (98%)
+ rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.h (100%)
+
+--- a/drivers/staging/vc04_services/Kconfig
++++ b/drivers/staging/vc04_services/Kconfig
+@@ -22,6 +22,7 @@ config BCM2835_VCHIQ
+ source "drivers/staging/vc04_services/bcm2835-audio/Kconfig"
+
+ source "drivers/staging/vc04_services/bcm2835-camera/Kconfig"
++source "drivers/staging/vc04_services/vchiq-mmal/Kconfig"
+
+ endif
+
+--- a/drivers/staging/vc04_services/Makefile
++++ b/drivers/staging/vc04_services/Makefile
+@@ -12,6 +12,7 @@ vchiq-objs := \
+
+ obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/
+ obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/
++obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/
+
+ ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000
+
+--- a/drivers/staging/vc04_services/bcm2835-camera/Kconfig
++++ b/drivers/staging/vc04_services/bcm2835-camera/Kconfig
+@@ -3,7 +3,7 @@ config VIDEO_BCM2835
+ tristate "BCM2835 Camera"
+ 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
+--- a/drivers/staging/vc04_services/bcm2835-camera/Makefile
++++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile
+@@ -1,11 +1,12 @@
+ # 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)/.. \
++ -Idrivers/staging/vc04_services \
++ -Idrivers/staging/vc04_services/vchiq-mmal \
+ -D__VCCOREVER__=0x04000000
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
+@@ -0,0 +1,7 @@
++config BCM2835_VCHIQ_MMAL
++ tristate "BCM2835 MMAL VCHIQ service"
++ depends on (ARCH_BCM2835 || COMPILE_TEST)
++ select BCM2835_VCHIQ
++ help
++ Enables the MMAL API over VCHIQ as used for the
++ majority of the multimedia services on VideoCore.
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/Makefile
+@@ -0,0 +1,8 @@
++# SPDX-License-Identifier: GPL-2.0
++bcm2835-mmal-vchiq-objs := mmal-vchiq.o
++
++obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += bcm2835-mmal-vchiq.o
++
++ccflags-y += \
++ -Idrivers/staging/vc04_services \
++ -D__VCCOREVER__=0x04000000
+--- 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 {
+- VCHI_SERVICE_HANDLE_T 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 VCHI_CALLBACK_REASON_T 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 VCHI_INSTANCE_T 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, &params, &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;
+-}
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+@@ -0,0 +1,1913 @@
++// 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/module.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"
++
++MODULE_DESCRIPTION("BCM2835 MMAL VCHIQ interface");
++MODULE_AUTHOR("Dave Stevenson, <dave.stevenson@raspberrypi.org>");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("0.0.1");
++
++/* 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 {
++ VCHI_SERVICE_HANDLE_T 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 VCHI_CALLBACK_REASON_T 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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_port_set_format);
++
++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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
++
++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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_get);
++
++/* 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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_port_enable);
++
++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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_port_disable);
++
++/* 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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_port_connect_tunnel);
++
++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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_submit_buffer);
++
++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;
++}
++EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init);
++
++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;
++}
++EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
++
++/* 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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_component_init);
++
++/*
++ * 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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_component_finalise);
++
++/*
++ * 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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_component_enable);
++
++/*
++ * 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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_component_disable);
++
++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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_version);
++
++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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_finalise);
++
++int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
++{
++ int status;
++ struct vchiq_mmal_instance *instance;
++ static VCHI_INSTANCE_T 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, &params, &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;
++}
++EXPORT_SYMBOL_GPL(vchiq_mmal_init);
+--- 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
+--- 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 */
+--- 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 */
+--- 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 */
+--- 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.
+- */
+-};
+--- 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
+--- 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
+--- 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 */
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
+@@ -0,0 +1,60 @@
++/* 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
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
+@@ -0,0 +1,124 @@
++/* 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 */
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h
+@@ -0,0 +1,48 @@
++/* 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 */
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h
+@@ -0,0 +1,106 @@
++/* 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 */
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h
+@@ -0,0 +1,109 @@
++/* 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.
++ */
++};
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h
+@@ -0,0 +1,406 @@
++/* 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
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
+@@ -0,0 +1,755 @@
++/* 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
+--- /dev/null
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
+@@ -0,0 +1,166 @@
++/* 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 */