// SPDX-License-Identifier: GPL-2.0 /* * V4L2 Capture ISI subdev driver for i.MX8QXP/QM platform * * ISI is a Image Sensor Interface of i.MX8QXP/QM platform, which * used to process image from camera sensor to memory or DC * * Copyright (c) 2019 NXP Semiconductor
*/
if (code->pad == MXC_ISI_PIPE_PAD_SOURCE) { conststruct v4l2_mbus_framefmt *format;
format = mxc_isi_pipe_get_pad_format(pipe, state,
MXC_ISI_PIPE_PAD_SINK);
info = mxc_isi_bus_format_by_code(format->code,
MXC_ISI_PIPE_PAD_SINK);
if (info->encoding == MXC_ISI_ENC_RAW) { /* * For RAW formats, the sink and source media bus codes * must match.
*/ if (code->index) return -EINVAL;
code->code = info->output;
} else { /* * For RGB or YUV formats, the ISI supports format * conversion. Either of the two output formats can be * used regardless of the input.
*/ if (code->index > 1) return -EINVAL;
code->code = output_codes[code->index];
}
return0;
}
index = code->index;
for (i = 0; i < ARRAY_SIZE(mxc_isi_bus_formats); ++i) {
info = &mxc_isi_bus_formats[i];
if (!(info->pads & BIT(MXC_ISI_PIPE_PAD_SINK))) continue;
if (index == 0) {
code->code = info->mbus_code; return0;
}
if (vb2_is_busy(&pipe->video.vb2_q)) return -EBUSY;
if (fmt->pad == MXC_ISI_PIPE_PAD_SINK) { unsignedint max_width;
info = mxc_isi_bus_format_by_code(mf->code,
MXC_ISI_PIPE_PAD_SINK); if (!info)
info = mxc_isi_bus_format_by_code(MXC_ISI_DEF_MBUS_CODE_SINK,
MXC_ISI_PIPE_PAD_SINK);
/* * Limit the max line length if there's no adjacent pipe to * chain with.
*/
max_width = pipe->id == pipe->isi->pdata->num_channels - 1
? MXC_ISI_MAX_WIDTH_UNCHAINED
: MXC_ISI_MAX_WIDTH_CHAINED;
/* Propagate the format to the source pad. */
rect = mxc_isi_pipe_get_pad_compose(pipe, state,
MXC_ISI_PIPE_PAD_SINK);
rect->width = mf->width;
rect->height = mf->height;
format = mxc_isi_pipe_get_pad_format(pipe, state,
MXC_ISI_PIPE_PAD_SOURCE);
format->code = info->output;
format->width = mf->width;
format->height = mf->height;
} else { /* * For RGB or YUV formats, the ISI supports RGB <-> YUV format * conversion. For RAW formats, the sink and source media bus * codes must match.
*/
format = mxc_isi_pipe_get_pad_format(pipe, state,
MXC_ISI_PIPE_PAD_SINK);
info = mxc_isi_bus_format_by_code(format->code,
MXC_ISI_PIPE_PAD_SINK);
if (info->encoding != MXC_ISI_ENC_RAW) { if (mf->code != MEDIA_BUS_FMT_YUV8_1X24 &&
mf->code != MEDIA_BUS_FMT_RGB888_1X24)
mf->code = info->output;
info = mxc_isi_bus_format_by_code(mf->code,
MXC_ISI_PIPE_PAD_SOURCE);
}
mf->code = info->output;
/* * The width and height on the source can't be changed, they * must match the crop rectangle size.
*/
rect = mxc_isi_pipe_get_pad_crop(pipe, state,
MXC_ISI_PIPE_PAD_SOURCE);
switch (sel->target) { case V4L2_SEL_TGT_COMPOSE_BOUNDS: if (sel->pad != MXC_ISI_PIPE_PAD_SINK) /* No compose rectangle on source pad. */ return -EINVAL;
/* The sink compose is bound by the sink format. */
format = mxc_isi_pipe_get_pad_format(pipe, state,
MXC_ISI_PIPE_PAD_SINK);
sel->r.left = 0;
sel->r.top = 0;
sel->r.width = format->width;
sel->r.height = format->height; break;
case V4L2_SEL_TGT_CROP_BOUNDS: if (sel->pad != MXC_ISI_PIPE_PAD_SOURCE) /* No crop rectangle on sink pad. */ return -EINVAL;
/* The source crop is bound by the sink compose. */
rect = mxc_isi_pipe_get_pad_compose(pipe, state,
MXC_ISI_PIPE_PAD_SINK);
sel->r = *rect; break;
case V4L2_SEL_TGT_CROP: if (sel->pad != MXC_ISI_PIPE_PAD_SOURCE) /* No crop rectangle on sink pad. */ return -EINVAL;
rect = mxc_isi_pipe_get_pad_crop(pipe, state, sel->pad);
sel->r = *rect; break;
case V4L2_SEL_TGT_COMPOSE: if (sel->pad != MXC_ISI_PIPE_PAD_SINK) /* No compose rectangle on source pad. */ return -EINVAL;
rect = mxc_isi_pipe_get_pad_compose(pipe, state, sel->pad);
sel->r = *rect; break;
switch (sel->target) { case V4L2_SEL_TGT_CROP: if (sel->pad != MXC_ISI_PIPE_PAD_SOURCE) /* The pipeline support cropping on the source only. */ return -EINVAL;
/* The source crop is bound by the sink compose. */
rect = mxc_isi_pipe_get_pad_compose(pipe, state,
MXC_ISI_PIPE_PAD_SINK);
sel->r.left = clamp_t(s32, sel->r.left, 0, rect->width - 1);
sel->r.top = clamp_t(s32, sel->r.top, 0, rect->height - 1);
sel->r.width = clamp(sel->r.width, MXC_ISI_MIN_WIDTH,
rect->width - sel->r.left);
sel->r.height = clamp(sel->r.height, MXC_ISI_MIN_HEIGHT,
rect->height - sel->r.top);
rect = mxc_isi_pipe_get_pad_crop(pipe, state,
MXC_ISI_PIPE_PAD_SOURCE);
*rect = sel->r;
/* Propagate the crop rectangle to the source pad. */
format = mxc_isi_pipe_get_pad_format(pipe, state,
MXC_ISI_PIPE_PAD_SOURCE);
format->width = sel->r.width;
format->height = sel->r.height; break;
case V4L2_SEL_TGT_COMPOSE: if (sel->pad != MXC_ISI_PIPE_PAD_SINK) /* Composing is supported on the sink only. */ return -EINVAL;
/* The sink crop is bound by the sink format downscaling only). */
format = mxc_isi_pipe_get_pad_format(pipe, state,
MXC_ISI_PIPE_PAD_SINK);
ret = mxc_isi_channel_acquire(pipe, irq_handler, bypass); if (ret) return ret;
/* Chain the channel if needed for wide resolutions. */ if (sink_fmt->width > MXC_ISI_MAX_WIDTH_UNCHAINED) {
ret = mxc_isi_channel_chain(pipe, bypass); if (ret)
mxc_isi_channel_release(pipe);
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.16Bemerkung:
(vorverarbeitet am 2026-06-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.