Add an ISP parameter buffer parser for CAMSS offline ISP drivers. camss_isp_params_apply() wraps the upstream v4l2-isp buffer validation and adds a dispatch layer: after validation each block is forwarded to a driver-supplied handler indexed by block type.
Signed-off-by: Loic Poulain <[email protected]> --- drivers/media/platform/qcom/camss/Makefile | 3 +- .../media/platform/qcom/camss/camss-isp-params.c | 67 ++++++++++++++++++++++ .../media/platform/qcom/camss/camss-isp-params.h | 62 ++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index f3acb1b54b6c1455d72e2d947c860f0c337648de..fba6f34b8d9f70ea258f7ae1a293a8d58d866498 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -32,7 +32,8 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom-camss.o qcom-camss-isp-objs := camss-isp-bufq.o \ camss-isp-sched.o \ - camss-isp-pipeline.o + camss-isp-pipeline.o \ + camss-isp-params.o obj-$(CONFIG_VIDEO_QCOM_CAMSS_ISP) += qcom-camss-isp.o diff --git a/drivers/media/platform/qcom/camss/camss-isp-params.c b/drivers/media/platform/qcom/camss/camss-isp-params.c new file mode 100644 index 0000000000000000000000000000000000000000..66dc717bb3a2a26707d206e537691deb4d58f04d --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-params.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-isp-params.c + * + * CAMSS ISP parameter buffer parser. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <media/videobuf2-core.h> +#include <media/v4l2-isp.h> + +#include "camss-isp-params.h" + +int camss_isp_params_apply(struct device *dev, + struct vb2_buffer *vb, + const struct v4l2_isp_params_block_type_info *type_info, + const camss_isp_params_handler_fn *handlers, + unsigned int num_handlers, + void *priv) +{ + const struct v4l2_isp_params_buffer *buf; + unsigned int remaining; + unsigned int offset = 0; + int ret; + + ret = v4l2_isp_params_validate_buffer_size(dev, vb, + v4l2_isp_params_buffer_size(CAMSS_PARAMS_MAX_PAYLOAD)); + if (ret) + return ret; + + buf = vb2_plane_vaddr(vb, 0); + + ret = v4l2_isp_params_validate_buffer(dev, vb, buf, type_info, num_handlers); + if (ret) + return ret; + + dev_dbg(dev, "params: version=%u data_size=%u\n", buf->version, buf->data_size); + + remaining = buf->data_size; + + while (remaining >= sizeof(struct v4l2_isp_params_block_header)) { + const union camss_isp_params_block *block = + (const union camss_isp_params_block *)&buf->data[offset]; + u16 type = block->header.type; + u32 bsize = block->header.size; + + if (type < num_handlers && handlers[type]) + handlers[type](priv, block); + else + dev_dbg(dev, "params: no handler for block type %u\n", type); + + offset += bsize; + remaining -= bsize; + } + + dev_dbg(dev, "params: buffer parsed successfully\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(camss_isp_params_apply); + +MODULE_DESCRIPTION("CAMSS ISP parameter buffer parser"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/qcom/camss/camss-isp-params.h b/drivers/media/platform/qcom/camss/camss-isp-params.h new file mode 100644 index 0000000000000000000000000000000000000000..4cedfbc745f81655569ff8bdd8e389b35f2c67a7 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-params.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * camss-isp-params.h + * + * CAMSS ISP parameter buffer parser. + * + * Wraps the upstream v4l2_isp_params_validate_buffer() validation and adds + * a dispatch layer: after validation each block is forwarded to a + * driver-supplied handler. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef CAMSS_ISP_PARAMS_H +#define CAMSS_ISP_PARAMS_H + +#include <linux/types.h> +#include <media/v4l2-isp.h> +#include <uapi/linux/camss-config.h> + +#define CAMSS_ISP_PARAMS_FMT_INIT \ + { .fourcc = V4L2_META_FMT_QCOM_ISP_PARAMS, .depth = 8, .align = 0, .num_planes = 1 } + +#define CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY (1U << V4L2_ISP_PARAMS_FL_DRIVER_FLAGS(0)) + +struct device; +struct vb2_buffer; +struct camss_isp_fmt; + +union camss_isp_params_block { + struct v4l2_isp_params_block_header header; + struct camss_params_wb_gain wb_gain; + struct camss_params_chroma_enhan chroma_enhan; + struct camss_params_color_correct color_correct; +}; + +typedef void (*camss_isp_params_handler_fn)(void *priv, const union camss_isp_params_block *block); + +/** + * camss_isp_params_apply - validate and dispatch a params buffer + * + * @dev: device for error logging + * @vb: the vb2 buffer (used for size validation) + * @type_info: per-block-type validation info, indexed by block type + * @handlers: per-block-type handlers, indexed by block type + * @num_handlers: number of entries in @type_info and @handlers + * @priv: opaque pointer forwarded to each handler + * + * Calls v4l2_isp_params_validate_buffer_size(), then + * v4l2_isp_params_validate_buffer(), then walks the validated block stream + * dispatching each block to its handler. + * + * Returns 0 on success, negative errno on validation failure. + */ +int camss_isp_params_apply(struct device *dev, + struct vb2_buffer *vb, + const struct v4l2_isp_params_block_type_info *type_info, + const camss_isp_params_handler_fn *handlers, + unsigned int num_handlers, + void *priv); + +#endif /* CAMSS_ISP_PARAMS_H */ -- 2.34.1

