Thread (37 messages) 37 messages, 4 authors, 2023-10-19

Re: [RFC PATCH v6 10/11] media: imx-asrc: Add memory to memory driver

From: Hans Verkuil <hidden>
Date: 2023-10-18 12:58:02
Also in: alsa-devel, linux-media, lkml

On 18/10/2023 14:53, Shengjiu Wang wrote:
On Mon, Oct 16, 2023 at 10:01 PM Hans Verkuil [off-list ref] wrote:
quoted
On 13/10/2023 10:31, Shengjiu Wang wrote:
quoted
Implement the ASRC memory to memory function using
the v4l2 framework, user can use this function with
v4l2 ioctl interface.

User send the output and capture buffer to driver and
driver store the converted data to the capture buffer.

This feature can be shared by ASRC and EASRC drivers

Signed-off-by: Shengjiu Wang <redacted>
---
 drivers/media/platform/nxp/Kconfig    |   12 +
 drivers/media/platform/nxp/Makefile   |    1 +
 drivers/media/platform/nxp/imx-asrc.c | 1248 +++++++++++++++++++++++++
 3 files changed, 1261 insertions(+)
 create mode 100644 drivers/media/platform/nxp/imx-asrc.c
diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig
index 40e3436669e2..8234644ee341 100644
--- a/drivers/media/platform/nxp/Kconfig
+++ b/drivers/media/platform/nxp/Kconfig
@@ -67,3 +67,15 @@ config VIDEO_MX2_EMMAPRP

 source "drivers/media/platform/nxp/dw100/Kconfig"
 source "drivers/media/platform/nxp/imx-jpeg/Kconfig"
+
+config VIDEO_IMX_ASRC
+     tristate "NXP i.MX ASRC M2M support"
+     depends on V4L_MEM2MEM_DRIVERS
+     depends on MEDIA_SUPPORT
+     select VIDEOBUF2_DMA_CONTIG
+     select V4L2_MEM2MEM_DEV
+     help
+         Say Y if you want to add ASRC M2M support for NXP CPUs.
+         It is a complement for ASRC M2P and ASRC P2M features.
+         This option is only useful for out-of-tree drivers since
+         in-tree drivers select it automatically.
diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/nxp/Makefile
index 4d90eb713652..1325675e34f5 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
 obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
 obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
+obj-$(CONFIG_VIDEO_IMX_ASRC) += imx-asrc.o
diff --git a/drivers/media/platform/nxp/imx-asrc.c b/drivers/media/platform/nxp/imx-asrc.c
new file mode 100644
index 000000000000..373ca2b5ec90
--- /dev/null
+++ b/drivers/media/platform/nxp/imx-asrc.c
@@ -0,0 +1,1248 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+// Copyright (C) 2019-2023 NXP
+//
+// Freescale ASRC Memory to Memory (M2M) driver
+
+#include <linux/dma/imx-dma.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/fsl_asrc_common.h>
+
+#define V4L_CAP OUT
+#define V4L_OUT IN
+
+#define ASRC_xPUT_DMA_CALLBACK(dir) \
+     (((dir) == V4L_OUT) ? asrc_input_dma_callback \
+     : asrc_output_dma_callback)
+
+#define DIR_STR(dir) (dir) == V4L_OUT ? "out" : "cap"
+
+#define ASRC_M2M_BUFFER_SIZE (512 * 1024)
+#define ASRC_M2M_PERIOD_SIZE (48 * 1024)
+#define ASRC_M2M_SG_NUM (20)
Where do all these values come from? How do they relate?
Some comments would be welcome.

Esp. ASRC_M2M_SG_NUM is a bit odd.
quoted
+
+struct asrc_fmt {
+     u32     fourcc;
+     snd_pcm_format_t     format;
Do you need this field? If not, then you can drop the whole
struct and just use u32 fourcc in the formats[] array.
quoted
+};
+
+struct asrc_pair_m2m {
+     struct fsl_asrc_pair *pair;
+     struct asrc_m2m *m2m;
+     struct v4l2_fh fh;
+     struct v4l2_ctrl_handler ctrl_handler;
+     int channels[2];
+     struct v4l2_ctrl_fixed_point src_rate;
+     struct v4l2_ctrl_fixed_point dst_rate;
+
+};
+
+struct asrc_m2m {
+     struct fsl_asrc_m2m_pdata pdata;
+     struct v4l2_device v4l2_dev;
+     struct v4l2_m2m_dev *m2m_dev;
+     struct video_device *dec_vdev;
+     struct mutex mlock; /* v4l2 ioctls serialization */
+     struct platform_device *pdev;
+};
+
+static struct asrc_fmt formats[] = {
+     {
+             .fourcc = V4L2_AUDIO_FMT_S8,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_S16_LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_U16_LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_S24_LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_S24_3LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_U24_LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_U24_3LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_S32_LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_U32_LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_S20_3LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_U20_3LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_FLOAT_LE,
+     },
+     {
+             .fourcc = V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE,
+     },
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static snd_pcm_format_t convert_fourcc(u32 fourcc) {
+
+     return (__force snd_pcm_format_t)v4l2_fourcc_to_audfmt(fourcc);
Is this cast something that should be done in the v4l2_fourcc_to_audfmt
define instead?
need to avoid include asound.h in videodev2.h,  so add this cast in driver.
It's a #define, so just including videodev2.h won't require asound.h.

Regards,

	Hans
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help