// SPDX-License-Identifier: GPL-2.0-or-later /* * vimc-common.c Virtual Media Controller Driver * * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
*/
#include <linux/init.h> #include <linux/module.h>
#include <media/v4l2-ctrls.h>
#include"vimc-common.h"
/* * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code * in the scaler)
*/ staticconststruct vimc_pix_map vimc_pix_map_list[] = { /* TODO: add all missing formats */
for (i = 0; i < ent->num_pads; i++) if (ent->pads[i].flags & MEDIA_PAD_FL_SINK) returnfalse; returntrue;
}
conststruct vimc_pix_map *vimc_pix_map_by_index(unsignedint i)
{ if (i >= ARRAY_SIZE(vimc_pix_map_list)) return NULL;
return &vimc_pix_map_list[i];
}
u32 vimc_mbus_code_by_index(unsignedint index)
{ unsignedint i, j;
for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { for (j = 0; j < ARRAY_SIZE(vimc_pix_map_list[i].code); j++) { if (!vimc_pix_map_list[i].code[j]) break;
if (!index) return vimc_pix_map_list[i].code[j];
index--;
}
} return 0;
}
conststruct vimc_pix_map *vimc_pix_map_by_code(u32 code)
{ unsignedint i, j;
for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { for (j = 0; j < ARRAY_SIZE(vimc_pix_map_list[i].code); j++) { if (vimc_pix_map_list[i].code[j] == code) return &vimc_pix_map_list[i];
}
} return NULL;
}
for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { if (vimc_pix_map_list[i].pixelformat == pixelformat) return &vimc_pix_map_list[i];
} return NULL;
}
/* The width, height and pixelformat must match. */ if (source_fmt.width != sink_fmt.width ||
source_fmt.height != sink_fmt.height ||
source_fmt.pixelformat != sink_fmt.pixelformat) return -EPIPE;
/* * The field order must match, or the sink field order must be NONE * to support interlaced hardware connected to bridges that support * progressive formats only.
*/ if (source_fmt.field != sink_fmt.field &&
sink_fmt.field != V4L2_FIELD_NONE) return -EPIPE;
/* * If colorspace is DEFAULT, then assume all the colorimetry is also * DEFAULT, return 0 to skip comparing the other colorimetry parameters
*/ if (source_fmt.colorspace == V4L2_COLORSPACE_DEFAULT ||
sink_fmt.colorspace == V4L2_COLORSPACE_DEFAULT) return 0;
/* Colorspace must match. */ if (source_fmt.colorspace != sink_fmt.colorspace) return -EPIPE;
/* Colorimetry must match if they are not set to DEFAULT */ if (source_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
sink_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
source_fmt.ycbcr_enc != sink_fmt.ycbcr_enc) return -EPIPE;
/* Expose this subdev to user space */
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; if (sd->ctrl_handler)
sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
/* Initialize the media entity */
ret = media_entity_pads_init(&sd->entity, num_pads, pads); if (ret) return ret;
/* * Finalize the subdev initialization if it supports active states. Use * the control handler lock as the state lock if available.
*/ if (int_ops && int_ops->init_state) { if (sd->ctrl_handler)
sd->state_lock = sd->ctrl_handler->lock;
ret = v4l2_subdev_init_finalize(sd); if (ret) {
dev_err(v4l2_dev->dev, "%s: subdev initialization failed (err=%d)\n",
name, ret); goto err_clean_m_ent;
}
}
/* Register the subdev with the v4l2 and the media framework */
ret = v4l2_device_register_subdev(v4l2_dev, sd); if (ret) {
dev_err(v4l2_dev->dev, "%s: subdev register failed (err=%d)\n",
name, ret); goto err_clean_sd;
}
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.