From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 13 May 2024 10:30:14 +0000
Subject: [PATCH] modify sin led gpio
---
kernel/drivers/staging/media/imx/imx-media-vdic.c | 165 ++++++++++++++++++++----------------------------------
1 files changed, 61 insertions(+), 104 deletions(-)
diff --git a/kernel/drivers/staging/media/imx/imx-media-vdic.c b/kernel/drivers/staging/media/imx/imx-media-vdic.c
index 482250d..879329f 100644
--- a/kernel/drivers/staging/media/imx/imx-media-vdic.c
+++ b/kernel/drivers/staging/media/imx/imx-media-vdic.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* V4L2 Deinterlacer Subdev for Freescale i.MX5/6 SOC
*
* Copyright (c) 2017 Mentor Graphics Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
*/
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
@@ -60,8 +49,8 @@
/*
* Min/Max supported width and heights.
*/
-#define MIN_W 176
-#define MIN_H 144
+#define MIN_W 32
+#define MIN_H 32
#define MAX_W_VDIC 968
#define MAX_H_VDIC 2048
#define W_ALIGN 4 /* multiple of 16 pixels */
@@ -69,12 +58,11 @@
#define S_ALIGN 1 /* multiple of 2 */
struct vdic_priv {
- struct device *dev;
- struct ipu_soc *ipu;
- struct imx_media_dev *md;
+ struct device *ipu_dev;
+ struct ipu_soc *ipu;
+
struct v4l2_subdev sd;
struct media_pad pad[VDIC_NUM_PADS];
- int ipu_id;
/* lock to protect all members below */
struct mutex lock;
@@ -149,8 +137,6 @@
struct ipuv3_channel *ch;
struct ipu_vdi *vdi;
- priv->ipu = priv->md->ipu[priv->ipu_id];
-
vdi = ipu_vdi_get(priv->ipu);
if (IS_ERR(vdi)) {
v4l2_err(&priv->sd, "failed to get VDIC\n");
@@ -219,26 +205,24 @@
switch (priv->fieldtype) {
case V4L2_FIELD_SEQ_TB:
- prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0);
- curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + fs;
- next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
- break;
case V4L2_FIELD_SEQ_BT:
prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0) + fs;
curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + fs;
break;
+ case V4L2_FIELD_INTERLACED_TB:
case V4L2_FIELD_INTERLACED_BT:
+ case V4L2_FIELD_INTERLACED:
prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0) + is;
curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is;
break;
default:
- /* assume V4L2_FIELD_INTERLACED_TB */
- prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0);
- curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is;
- next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
- break;
+ /*
+ * can't get here, priv->fieldtype can only be one of
+ * the above. This is to quiet smatch errors.
+ */
+ return;
}
ipu_cpmem_set_buffer(priv->vdi_in_ch_p, 0, prev_phys);
@@ -263,10 +247,10 @@
memset(&image, 0, sizeof(image));
image.pix = vdev->fmt.fmt.pix;
+ image.rect = vdev->compose;
/* one field to VDIC channels */
image.pix.height /= 2;
- image.rect.width = image.pix.width;
- image.rect.height = image.pix.height;
+ image.rect.height /= 2;
image.phys0 = phys0;
image.phys1 = phys1;
@@ -517,7 +501,8 @@
if (priv->stream_count != !enable)
goto update_count;
- dev_dbg(priv->dev, "stream %s\n", enable ? "ON" : "OFF");
+ dev_dbg(priv->ipu_dev, "%s: stream %s\n", sd->name,
+ enable ? "ON" : "OFF");
if (enable)
ret = vdic_start(priv);
@@ -563,7 +548,8 @@
if (code->pad >= VDIC_NUM_PADS)
return -EINVAL;
- return imx_media_enum_ipu_format(&code->code, code->index, CS_SEL_YUV);
+ return imx_media_enum_ipu_formats(&code->code, code->index,
+ PIXFMT_SEL_YUV);
}
static int vdic_get_fmt(struct v4l2_subdev *sd,
@@ -598,12 +584,13 @@
{
struct v4l2_mbus_framefmt *infmt;
- *cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_YUV);
+ *cc = imx_media_find_ipu_format(sdformat->format.code,
+ PIXFMT_SEL_YUV);
if (!*cc) {
u32 code;
- imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
- *cc = imx_media_find_ipu_format(code, CS_SEL_YUV);
+ imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV);
+ *cc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV);
sdformat->format.code = (*cc)->codes[0];
}
@@ -623,14 +610,13 @@
&sdformat->format.height,
MIN_H, MAX_H_VDIC, H_ALIGN, S_ALIGN);
- imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
- true);
-
/* input must be interlaced! Choose SEQ_TB if not */
if (!V4L2_FIELD_HAS_BOTH(sdformat->format.field))
sdformat->format.field = V4L2_FIELD_SEQ_TB;
break;
}
+
+ imx_media_try_colorimetry(&sdformat->format, true);
}
static int vdic_set_fmt(struct v4l2_subdev *sd,
@@ -692,8 +678,8 @@
struct v4l2_subdev *remote_sd;
int ret = 0;
- dev_dbg(priv->dev, "link setup %s -> %s", remote->entity->name,
- local->entity->name);
+ dev_dbg(priv->ipu_dev, "%s: link setup %s -> %s",
+ sd->name, remote->entity->name, local->entity->name);
mutex_lock(&priv->lock);
@@ -752,7 +738,7 @@
remote_sd = media_entity_to_v4l2_subdev(remote->entity);
/* direct pad must connect to a CSI */
- if (!(remote_sd->grp_id & IMX_MEDIA_GRP_ID_CSI) ||
+ if (!(remote_sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) ||
remote->index != CSI_SRC_PAD_DIRECT) {
ret = -EINVAL;
goto out;
@@ -826,7 +812,10 @@
switch (fi->pad) {
case VDIC_SINK_PAD_DIRECT:
case VDIC_SINK_PAD_IDMAC:
- /* No limits on input frame interval */
+ /* No limits on valid input frame intervals */
+ if (fi->interval.numerator == 0 ||
+ fi->interval.denominator == 0)
+ fi->interval = priv->frame_interval[fi->pad];
/* Reset output interval */
*output_fi = fi->interval;
if (priv->csi_direct)
@@ -854,25 +843,16 @@
return ret;
}
-/*
- * retrieve our pads parsed from the OF graph by the media device
- */
static int vdic_registered(struct v4l2_subdev *sd)
{
struct vdic_priv *priv = v4l2_get_subdevdata(sd);
int i, ret;
u32 code;
- /* get media device */
- priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
-
for (i = 0; i < VDIC_NUM_PADS; i++) {
- priv->pad[i].flags = (i == VDIC_SRC_PAD_DIRECT) ?
- MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
-
code = 0;
if (i != VDIC_SINK_PAD_IDMAC)
- imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
+ imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV);
/* set a default mbus format */
ret = imx_media_init_mbus_fmt(&priv->format_mbus[i],
@@ -890,15 +870,7 @@
priv->active_input_pad = VDIC_SINK_PAD_DIRECT;
- ret = vdic_init_controls(priv);
- if (ret)
- return ret;
-
- ret = media_entity_pads_init(&sd->entity, VDIC_NUM_PADS, priv->pad);
- if (ret)
- v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
-
- return ret;
+ return vdic_init_controls(priv);
}
static void vdic_unregistered(struct v4l2_subdev *sd)
@@ -937,77 +909,62 @@
.unregistered = vdic_unregistered,
};
-static int imx_vdic_probe(struct platform_device *pdev)
+struct v4l2_subdev *imx_media_vdic_register(struct v4l2_device *v4l2_dev,
+ struct device *ipu_dev,
+ struct ipu_soc *ipu,
+ u32 grp_id)
{
- struct imx_media_internal_sd_platformdata *pdata;
struct vdic_priv *priv;
- int ret;
+ int i, ret;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(ipu_dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
- platform_set_drvdata(pdev, &priv->sd);
- priv->dev = &pdev->dev;
-
- pdata = priv->dev->platform_data;
- priv->ipu_id = pdata->ipu_id;
+ priv->ipu_dev = ipu_dev;
+ priv->ipu = ipu;
v4l2_subdev_init(&priv->sd, &vdic_subdev_ops);
v4l2_set_subdevdata(&priv->sd, priv);
priv->sd.internal_ops = &vdic_internal_ops;
priv->sd.entity.ops = &vdic_entity_ops;
priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
- priv->sd.dev = &pdev->dev;
- priv->sd.owner = THIS_MODULE;
+ priv->sd.owner = ipu_dev->driver->owner;
priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
- /* get our group id */
- priv->sd.grp_id = pdata->grp_id;
- strncpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name));
+ priv->sd.grp_id = grp_id;
+ imx_media_grp_id_to_sd_name(priv->sd.name, sizeof(priv->sd.name),
+ priv->sd.grp_id, ipu_get_num(ipu));
mutex_init(&priv->lock);
- ret = v4l2_async_register_subdev(&priv->sd);
+ for (i = 0; i < VDIC_NUM_PADS; i++)
+ priv->pad[i].flags = (i == VDIC_SRC_PAD_DIRECT) ?
+ MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
+
+ ret = media_entity_pads_init(&priv->sd.entity, VDIC_NUM_PADS,
+ priv->pad);
if (ret)
goto free;
- return 0;
+ ret = v4l2_device_register_subdev(v4l2_dev, &priv->sd);
+ if (ret)
+ goto free;
+
+ return &priv->sd;
free:
mutex_destroy(&priv->lock);
- return ret;
+ return ERR_PTR(ret);
}
-static int imx_vdic_remove(struct platform_device *pdev)
+int imx_media_vdic_unregister(struct v4l2_subdev *sd)
{
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
struct vdic_priv *priv = v4l2_get_subdevdata(sd);
v4l2_info(sd, "Removing\n");
- v4l2_async_unregister_subdev(sd);
+ v4l2_device_unregister_subdev(sd);
mutex_destroy(&priv->lock);
media_entity_cleanup(&sd->entity);
return 0;
}
-
-static const struct platform_device_id imx_vdic_ids[] = {
- { .name = "imx-ipuv3-vdic" },
- { },
-};
-MODULE_DEVICE_TABLE(platform, imx_vdic_ids);
-
-static struct platform_driver imx_vdic_driver = {
- .probe = imx_vdic_probe,
- .remove = imx_vdic_remove,
- .id_table = imx_vdic_ids,
- .driver = {
- .name = "imx-ipuv3-vdic",
- },
-};
-module_platform_driver(imx_vdic_driver);
-
-MODULE_DESCRIPTION("i.MX VDIC subdev driver");
-MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-ipuv3-vdic");
--
Gitblit v1.6.2