// SPDX-License-Identifier: GPL-2.0+ /* * vsp1_iif.c -- R-Car VSP1 IIF (ISP Interface) * * Copyright (C) 2025 Ideas On Board Oy * Copyright (C) 2025 Renesas Corporation */ #include "vsp1.h" #include "vsp1_dl.h" #include "vsp1_iif.h" #define IIF_MIN_WIDTH 128U #define IIF_MIN_HEIGHT 32U #define IIF_MAX_WIDTH 5120U #define IIF_MAX_HEIGHT 4096U /* ----------------------------------------------------------------------------- * Device Access */ static inline void vsp1_iif_write(struct vsp1_dl_body *dlb, u32 reg, u32 data) { vsp1_dl_body_write(dlb, reg, data); } /* ----------------------------------------------------------------------------- * V4L2 Subdevice Operations */ static const unsigned int iif_codes[] = { MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y16_1X16, MEDIA_BUS_FMT_METADATA_FIXED }; static const struct v4l2_subdev_pad_ops iif_pad_ops = { .enum_mbus_code = vsp1_subdev_enum_mbus_code, .enum_frame_size = vsp1_subdev_enum_frame_size, .get_fmt = vsp1_subdev_get_pad_format, .set_fmt = vsp1_subdev_set_pad_format, }; static const struct v4l2_subdev_ops iif_ops = { .pad = &iif_pad_ops, }; /* ----------------------------------------------------------------------------- * VSP1 Entity Operations */ static void iif_configure_stream(struct vsp1_entity *entity, struct v4l2_subdev_state *state, struct vsp1_pipeline *pipe, struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb) { vsp1_iif_write(dlb, VI6_IIF_CTRL, VI6_IIF_CTRL_CTRL); } static const struct vsp1_entity_operations iif_entity_ops = { .configure_stream = iif_configure_stream, }; /* ----------------------------------------------------------------------------- * Initialization and Cleanup */ struct vsp1_iif *vsp1_iif_create(struct vsp1_device *vsp1) { struct vsp1_iif *iif; int ret; iif = devm_kzalloc(vsp1->dev, sizeof(*iif), GFP_KERNEL); if (!iif) return ERR_PTR(-ENOMEM); iif->entity.ops = &iif_entity_ops; iif->entity.type = VSP1_ENTITY_IIF; iif->entity.codes = iif_codes; iif->entity.num_codes = ARRAY_SIZE(iif_codes); iif->entity.min_width = IIF_MIN_WIDTH; iif->entity.min_height = IIF_MIN_HEIGHT; iif->entity.max_width = IIF_MAX_WIDTH; iif->entity.max_height = IIF_MAX_HEIGHT; /* * The IIF is never exposed to userspace, but media entity registration * requires a function to be set. Use PROC_VIDEO_PIXEL_FORMATTER just to * avoid triggering a WARN_ON(), the value won't be seen anywhere. */ ret = vsp1_entity_init(vsp1, &iif->entity, "iif", 3, &iif_ops, MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER); if (ret < 0) return ERR_PTR(ret); return iif; }