On 18/10/2023 14:53, Shengjiu Wang wrote: > On Mon, Oct 16, 2023 at 10:01 PM Hans Verkuil <hverkuil@xxxxxxxxx> wrote: >> >> On 13/10/2023 10:31, Shengjiu Wang wrote: >>> 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 <shengjiu.wang@xxxxxxx> >>> --- >>> 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. >> >>> + >>> +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. >> >>> +}; >>> + >>> +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