From patchwork Thu Dec 12 07:45:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shengjiu Wang X-Patchwork-Id: 849763 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 94EE0E7717F for ; Thu, 12 Dec 2024 07:47:23 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [45.14.194.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 3E995417; Thu, 12 Dec 2024 08:47:11 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EBC96F8060E; Thu, 12 Dec 2024 08:46:21 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 1399EF8060B; Thu, 12 Dec 2024 08:46:21 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B03BCF802BE; Thu, 12 Dec 2024 08:45:59 +0100 (CET) Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20629.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::629]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 08F79F8012B for ; Thu, 12 Dec 2024 08:45:56 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 08F79F8012B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=nxp.com header.i=@nxp.com header.a=rsa-sha256 header.s=selector1 header.b=h8W35r6z ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=WOe6EeuY/R+P0m+iyJcWBQ5gA4wbI+P0VUzT6MfewWzfzIv7r8wxAkI6FXWxLTICyVA737LNQkXRUSFGttm6qk+peU4r4XJJaqXfWIZgKAcvJfFoKjbPEKsPMumkMtLLDpFp5xkH7rS83ojckIyRrLgX3XUYfPMpMZpRz3SUcyg4tzeoRTLG2zHxgjJM5zhiay8PtQ2rltFJxiZPu2CuTaF5mAsawHoUSfLNanMbmCNNL0VKTR/QPwexTfgdDG2VI7lV3XqXnsgWVwgTVIXETfRsyJdoeKLl0DJ0wJk/0jsEJ482J8yFfote2I49UiWT17T67YKxcnwm5PetB5gVSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=8f6ttwYZXSGqEAL54j0qzoFjSj4HqsYoO6Te5HL+rSE=; b=Y6v0kBk+39vI7Q/S1f9ZUwvZt+qQsSYoraYhvZD9Y3We/U3uiCCoHwJEfTJgFPdplxjlWKUf4+UGTcGFb2Pu+Emb0YJxbs/itCgXg+X5pbSxkh0O7dPojWYW+k0z/mFodl5fXfhU0C0oNH9/WMXdq4Rf6axjgnhwwFpMevxBOX4vCQ7Vl6rX0b47Pd92uwWnwQ+ajhLhEl5C1uQx15s5Gxv3XWsyWJTsUTnnJuQt1JlBzbDdecw04jplZuVJBHPeR03+IgkAPTZrIujLPxGR0mBlxq2ukn6+HgKvgFbHWsLnf9Z+8sbTwwo7aIpvhx9TxTtNhiZCp2WFm+B+UvAR2g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8f6ttwYZXSGqEAL54j0qzoFjSj4HqsYoO6Te5HL+rSE=; b=h8W35r6zIV49KcFJo//offxUtrtWPJDCRAZz7UgmZgiT6e7osiFg64Ldr16GyGnihwid+JjxLMzTgwjMLt8sFcXEbZZb8Tjf2x9qwfcN9UFeg1ukCy7ibFjFkBNfOmOFoUYG99mHETzL0Hosfqzh2qQUgoNDjVIJ2j653V+1SML3qixq7Srbz5IGgJEVIXm60Fk+adCnj+16e1AVIJI4nyfOYUkb/SA0SQf7+OAm/7WsjiVxOvMGA9yioshGZr49IMTWeKdHW6wscGr2gC/oqvoFZR9snezV/htfTYiHkQjzU8xI4GPq7LIXjaYrxcNhFz2FF8w7V32B5vPldtFMIQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from VI1PR04MB7055.eurprd04.prod.outlook.com (2603:10a6:800:123::21) by DBAPR04MB7256.eurprd04.prod.outlook.com (2603:10a6:10:1a3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8251.16; Thu, 12 Dec 2024 07:45:54 +0000 Received: from VI1PR04MB7055.eurprd04.prod.outlook.com ([fe80::d6ab:1538:d868:bf8]) by VI1PR04MB7055.eurprd04.prod.outlook.com ([fe80::d6ab:1538:d868:bf8%7]) with mapi id 15.20.8251.008; Thu, 12 Dec 2024 07:45:54 +0000 From: Shengjiu Wang To: vkoul@kernel.org, perex@perex.cz, tiwai@suse.com, alsa-devel@alsa-project.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, shengjiu.wang@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com, nicoleotsuka@gmail.com, lgirdwood@gmail.com, broonie@kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v7 2/6] ASoC: fsl_asrc: define functions for memory to memory usage Date: Thu, 12 Dec 2024 15:45:05 +0800 Message-Id: <20241212074509.3445859-3-shengjiu.wang@nxp.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20241212074509.3445859-1-shengjiu.wang@nxp.com> References: <20241212074509.3445859-1-shengjiu.wang@nxp.com> X-ClientProxiedBy: SI2PR02CA0053.apcprd02.prod.outlook.com (2603:1096:4:196::16) To VI1PR04MB7055.eurprd04.prod.outlook.com (2603:10a6:800:123::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR04MB7055:EE_|DBAPR04MB7256:EE_ X-MS-Office365-Filtering-Correlation-Id: d34a5090-631e-40f5-2d1d-08dd1a8101d5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|52116014|366016|7416014|921020|38350700014; X-Microsoft-Antispam-Message-Info: uGfGP5zVn8vXa5ZhN92JJKZFEo6T3iH73oYt2D2yiVWTywDdA7c1hXp0uPwrCnM9eM0klY1OgACeJFNgV5gmO9pH/mO7HUzgUto2bcB+Wt7U8LlWhl2saqyGxleFjC26FXNBjSmyvYCt/6ZhVzbAr9PSp9IyoRF8yHPWO7eEy+rVCd7EKAINlHuOoZtm4YC+juhChdHOd83Ai6i2eZmwLkL0Wy6H5VBYoVVu3JOBtqyWfEJwj7tgS1wFoVKhJtCiSS74ehq+I6k7pyB5HYB6G3jANgOKM/Q9ulQdjEJzfQ/0zzfPIcn+QsC1TgKiWBzWTcnBZiXhuHFrgs1iv0ZDfybMl3ImnqPNLtSCqXsgZo6ATFD+Y2usF1oeC1BSa4xCLUcPDT0927yf2yYYcfMrkBPd5Vhc03fW0tTEeqNaehXk8iV++ikFAo2oN0vzGPJ8toHx390cO3AqREBXqRXlDTgJhAONO9p92S1Od5izAxRO/8/RAc1BTZRIRF7QWcBYt4Vc+hzMtAWfCo+/Tbsr1xF7BbT22/xQF+SWM+bVFlbjRvYLoC+6oxI/qxAQvx6VyJrP/lVyWFAtg8vCH8Ku/L3MTVBou5rJtqfHXgHJ0DrXEcIKKVfT2mknxDAdSQi3cFVPosgWDVR0e9r6nM72T54wXAyodOiuHa99p6WlOcWYDZmGyx4VHKs8dnkaSAjgFseSY1CbQqlxQInYB4UyHDj0I2TFvdyDHf89dP2UPz7m9RYA08fN+pdBFeOyMU041nOuAbj3FvidljiSGfdSLvgiLQU9cXxgbvG3/KHd5UHtW5OUnt1ud5hv+C0GzDLUGV52VQkIRe7Kdr0njbktbnZejc8mVQbbd3G56JfsggbRQI+8vJPOEmtrNrbww8cNFYYUrJiyqLzMaBnge599PfjeBdsKxWltKeZ5ir5sF+ciCKZ/ngi+D5+l6GCXrXDmYt+gbSavBZKddKEaQJvyW+4fFBelXNmdCrNAJi7xiXMfZdIZgbLvsV5HWlfiK4tB2FY/a0rFsrYv45JsyyZLOrc/bpC7gxlDhsXIQOyj8vM+YJWJXU8T52gH1HMmID6sLJIW8BNFpsg0FY+fSQAesHRrsG7pldWDyi8sO1i0MQvb+FXJlnmJKY7s0bVXEyd7YHFXC30BLBMEmp9N97pu6PVZ3OYJA/BhrQrSXwI/D8iCvAGZRwYUieBgDF1e9HTXZ3V1CxcZenDengG5fvsfCMHNuJ2emwUJej42HIDv4fKsIhdteGn3CnSKUQjE5GV2U5T31Cp0UbmuK3Smy5uXdzrnXE846bfN6er83/l8bx8sH30x8QW6KR6XBaTLilP99hypBHpNhdxjCmUNKtMB7JJWyEoYMqe98N+00Iy3n0hMAGWPDrTjPU6kjyimH9+zFtdH3sA2Pq//CtXza/ZlPQYh48fB9z3ynF7VBKDsm7A= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR04MB7055.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(52116014)(366016)(7416014)(921020)(38350700014); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 6qGodaWUjsusl7CEQIoxZ3p2lsvuj0wMEwM1BdpcIEuKcFFZrbD+mxEgjQ4j8Itv6RWw//4PRN8Xwiea0Qp+8afBTYk1/NM7oNeR/kT7B+/JcWdGmclWDiti71aiJtkBw77jviCc8ogEulq5YFZAdbnzkLrA5FnID2UmMi55jazdr5TY3JKDOOE6vR+/a4uffBXnT7rMRNeDB71T173hygmg1S6bGVEAC118LnOGXXjx0ARvr1Ewa7khGvYT7L4dC8rBv7+tqUVyUw2SE+mWJrgMi9KTDkPMfYolsoL1XSYudy3eEccK7Z5C9yAnHujbDDrxAfMvLm/ovxjC+Jdw21a/Zo711UNrZtm01nKZ432I39adZL3mLeFfTac3aBf9CLLJLrl2KIj0Cej7UiCI/TOSsy/gCkBhUS/D27LNhWHIHKWUFFtWLxMh+rFYw97fjPY+DN40yhzceIYWIS/lr626BnJRTeHQ24TflO0zM34KDNLZBDk4f3B+xVIM/abIU1JnikJDi9zz4Aue2ii2zVdY0vRbJBos8B8pXbB3C8q/6NBLOOpKdUPSdVVCs7LHL2466BwIlx5oVws3uqexu8s5r5WduSaanFn1GpzCJe4E4fl1Adb/W+1F4AJ+bazDWGIN7PYxJqxA/TEgS430bTQMB3KecYf8oIFSjpDSuahpacpVMk9ds8lJiA2BL9qPhRq6oYWJ0u6xUxe6Q2aVU7Xjk2lp9GEru0g5NbQtZU5i3QEWhNUSOTkEG+M9dUq90ieEPFYSqKlakA0dUjgH9E2Q+u0S5O9p1VaTltVbKxSusNsCjNV9R+lvwxhmzeGrZFt1l/hiyMCAqKYmMWSifmWrobS+MV1ry63BUXuiiTghM9oadvq02+FoRgmP71n5Mm7Tn/XJM8j3NwAkZ1DoyObrxKWXo/VFUoYT9yBdxpskddhoW3uaFrKuJOeFqKNSI4r9XS2I/V5jUW830UoM5KmGtspK6semrwwydHrXN70pbE8HKChQIfxumQRDBgwFRyk5wL9krmJ9mL9K07Se/SXlzZcOXCW/XG3CuQY3SbzCWVXv29nOTCrjnuQ8che42DvYLL7dSy1na6dJr3+kohYWSG5OUX4bEL7taJ539hoZO738kAx/LgzQppLmlBkSs/PNyp2VOpePt6MRE1+qmS5EdY//X1hVY+OGVW30VOS+u4smieLeNny9+THVjJvW3y7ay2la87pX4ysDdXywVjQLGi26EL6yfST66cXoe0Y3wdNWqJP9ARPjXh2nRrOFiHetAqmVhJNtbPdatb+tLVoPxu/WWncKt4TolKT85UZt8kxIluvk16m+Mx7rxvqZmEykvBm9o5BgY+4drF48neOP45C+NR+zjd49ysfX0fZZyziAsE01clNGQnelZ8DaaS9j0XDA16rJAU2ae3dBpU4R18dHxyfQeyUwAkV82ydSwwcYBYIB5qIx2x3sasIVwOjsQAXKv6XlZrw0rqYu5jXObFHZjvDyer4YNdHcGaCIrkVsq3Yulbpcbz+mWKmmGld7b7pK6hWx+CgDCIgAM3WTun6nF7MZ/Wte8RDkyy3nC925NDePj/a6dVGuu8oE X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: d34a5090-631e-40f5-2d1d-08dd1a8101d5 X-MS-Exchange-CrossTenant-AuthSource: VI1PR04MB7055.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Dec 2024 07:45:54.4273 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ViiCvpiKjcwLblSwMauSi/fbYWMLwRhu9uaU7k6AUBVNjWkv9EftZ+Uf/ElUmxY6dC0a4PDhuWlFWUmkmFRlqA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAPR04MB7256 Message-ID-Hash: S5IO53BU6ZXYXGLA37AE2NBEELUG2CLK X-Message-ID-Hash: S5IO53BU6ZXYXGLA37AE2NBEELUG2CLK X-MailFrom: shengjiu.wang@nxp.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: ASRC can be used on memory to memory case, define several functions for m2m usage. m2m_prepare: prepare for the start step m2m_start: the start step m2m_unprepare: unprepare for stop step, optional m2m_stop: stop step m2m_check_format: check format is supported or not m2m_calc_out_len: calculate output length according to input length m2m_get_maxburst: burst size for dma m2m_pair_suspend: suspend function of pair, optional. m2m_pair_resume: resume function of pair get_output_fifo_size: get remaining data size in FIFO Signed-off-by: Shengjiu Wang Acked-by: Jaroslav Kysela --- sound/soc/fsl/fsl_asrc.c | 142 ++++++++++++++++++++++++++++++++ sound/soc/fsl/fsl_asrc.h | 2 + sound/soc/fsl/fsl_asrc_common.h | 61 ++++++++++++++ 3 files changed, 205 insertions(+) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index bd5c46d763c0..471753276209 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -1063,6 +1063,139 @@ static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index) return REG_ASRDx(dir, index); } +/* Get sample numbers in FIFO */ +static unsigned int fsl_asrc_get_output_fifo_size(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc *asrc = pair->asrc; + enum asrc_pair_index index = pair->index; + u32 val; + + regmap_read(asrc->regmap, REG_ASRFST(index), &val); + + val &= ASRFSTi_OUTPUT_FIFO_MASK; + + return val >> ASRFSTi_OUTPUT_FIFO_SHIFT; +} + +static int fsl_asrc_m2m_prepare(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc_pair_priv *pair_priv = pair->private; + struct fsl_asrc *asrc = pair->asrc; + struct device *dev = &asrc->pdev->dev; + struct asrc_config config; + int ret; + + /* fill config */ + config.pair = pair->index; + config.channel_num = pair->channels; + config.input_sample_rate = pair->rate[IN]; + config.output_sample_rate = pair->rate[OUT]; + config.input_format = pair->sample_format[IN]; + config.output_format = pair->sample_format[OUT]; + config.inclk = INCLK_NONE; + config.outclk = OUTCLK_ASRCK1_CLK; + + pair_priv->config = &config; + ret = fsl_asrc_config_pair(pair, true); + if (ret) { + dev_err(dev, "failed to config pair: %d\n", ret); + return ret; + } + + pair->first_convert = 1; + + return 0; +} + +static int fsl_asrc_m2m_start(struct fsl_asrc_pair *pair) +{ + if (pair->first_convert) { + fsl_asrc_start_pair(pair); + pair->first_convert = 0; + } + /* + * Clear DMA request during the stall state of ASRC: + * During STALL state, the remaining in input fifo would never be + * smaller than the input threshold while the output fifo would not + * be bigger than output one. Thus the DMA request would be cleared. + */ + fsl_asrc_set_watermarks(pair, ASRC_FIFO_THRESHOLD_MIN, + ASRC_FIFO_THRESHOLD_MAX); + + /* Update the real input threshold to raise DMA request */ + fsl_asrc_set_watermarks(pair, ASRC_M2M_INPUTFIFO_WML, + ASRC_M2M_OUTPUTFIFO_WML); + + return 0; +} + +static int fsl_asrc_m2m_stop(struct fsl_asrc_pair *pair) +{ + if (!pair->first_convert) { + fsl_asrc_stop_pair(pair); + pair->first_convert = 1; + } + + return 0; +} + +/* calculate capture data length according to output data length and sample rate */ +static int fsl_asrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int input_buffer_length) +{ + unsigned int in_width, out_width; + unsigned int channels = pair->channels; + unsigned int in_samples, out_samples; + unsigned int out_length; + + in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8; + out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8; + + in_samples = input_buffer_length / in_width / channels; + out_samples = pair->rate[OUT] * in_samples / pair->rate[IN]; + out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * channels; + + return out_length; +} + +static int fsl_asrc_m2m_get_maxburst(u8 dir, struct fsl_asrc_pair *pair) +{ + struct fsl_asrc *asrc = pair->asrc; + struct fsl_asrc_priv *asrc_priv = asrc->private; + int wml = (dir == IN) ? ASRC_M2M_INPUTFIFO_WML : ASRC_M2M_OUTPUTFIFO_WML; + + if (!asrc_priv->soc->use_edma) + return wml * pair->channels; + else + return 1; +} + +static int fsl_asrc_m2m_get_cap(struct fsl_asrc_m2m_cap *cap) +{ + cap->fmt_in = FSL_ASRC_FORMATS; + cap->fmt_out = FSL_ASRC_FORMATS | SNDRV_PCM_FMTBIT_S8; + + cap->rate_in = supported_asrc_rate; + cap->rate_in_count = ARRAY_SIZE(supported_asrc_rate); + cap->rate_out = supported_asrc_rate; + cap->rate_out_count = ARRAY_SIZE(supported_asrc_rate); + cap->chan_min = 1; + cap->chan_max = 10; + + return 0; +} + +static int fsl_asrc_m2m_pair_resume(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc *asrc = pair->asrc; + int i; + + for (i = 0; i < pair->channels * 4; i++) + regmap_write(asrc->regmap, REG_ASRDI(pair->index), 0); + + pair->first_convert = 1; + return 0; +} + static int fsl_asrc_runtime_resume(struct device *dev); static int fsl_asrc_runtime_suspend(struct device *dev); @@ -1147,6 +1280,15 @@ static int fsl_asrc_probe(struct platform_device *pdev) asrc->get_fifo_addr = fsl_asrc_get_fifo_addr; asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv); + asrc->m2m_prepare = fsl_asrc_m2m_prepare; + asrc->m2m_start = fsl_asrc_m2m_start; + asrc->m2m_stop = fsl_asrc_m2m_stop; + asrc->get_output_fifo_size = fsl_asrc_get_output_fifo_size; + asrc->m2m_calc_out_len = fsl_asrc_m2m_calc_out_len; + asrc->m2m_get_maxburst = fsl_asrc_m2m_get_maxburst; + asrc->m2m_pair_resume = fsl_asrc_m2m_pair_resume; + asrc->m2m_get_cap = fsl_asrc_m2m_get_cap; + if (of_device_is_compatible(np, "fsl,imx35-asrc")) { asrc_priv->clk_map[IN] = input_clk_map_imx35; asrc_priv->clk_map[OUT] = output_clk_map_imx35; diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 86d2422ad606..1c492eb237f5 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -12,6 +12,8 @@ #include "fsl_asrc_common.h" +#define ASRC_M2M_INPUTFIFO_WML 0x4 +#define ASRC_M2M_OUTPUTFIFO_WML 0x2 #define ASRC_DMA_BUFFER_NUM 2 #define ASRC_INPUTFIFO_THRESHOLD 32 #define ASRC_OUTPUTFIFO_THRESHOLD 32 diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h index 7e1c13ca37f1..3bdd6ea07c09 100644 --- a/sound/soc/fsl/fsl_asrc_common.h +++ b/sound/soc/fsl/fsl_asrc_common.h @@ -21,6 +21,26 @@ enum asrc_pair_index { #define PAIR_CTX_NUM 0x4 +/** + * struct fsl_asrc_m2m_cap - capability data + * @fmt_in: input sample format + * @fmt_out: output sample format + * @chan_min: minimum channel number + * @chan_max: maximum channel number + * @rate_in: minimum rate + * @rate_out: maximum rete + */ +struct fsl_asrc_m2m_cap { + u64 fmt_in; + u64 fmt_out; + int chan_min; + int chan_max; + const unsigned int *rate_in; + int rate_in_count; + const unsigned int *rate_out; + int rate_out_count; +}; + /** * fsl_asrc_pair: ASRC Pair common data * @@ -34,6 +54,13 @@ enum asrc_pair_index { * @pos: hardware pointer position * @req_dma_chan: flag to release dev_to_dev chan * @private: pair private area + * @complete: dma task complete + * @sample_format: format of m2m + * @rate: rate of m2m + * @buf_len: buffer length of m2m + * @dma_buffer: buffer pointers + * @first_convert: start of conversion + * @ratio_mod: ratio modification */ struct fsl_asrc_pair { struct fsl_asrc *asrc; @@ -49,6 +76,15 @@ struct fsl_asrc_pair { bool req_dma_chan; void *private; + + /* used for m2m */ + struct completion complete[2]; + snd_pcm_format_t sample_format[2]; + unsigned int rate[2]; + unsigned int buf_len[2]; + struct snd_dma_buffer dma_buffer[2]; + unsigned int first_convert; + unsigned int ratio_mod; }; /** @@ -72,6 +108,17 @@ struct fsl_asrc_pair { * @request_pair: function pointer * @release_pair: function pointer * @get_fifo_addr: function pointer + * @m2m_get_cap: function pointer + * @m2m_prepare: function pointer + * @m2m_start: function pointer + * @m2m_unprepare: function pointer + * @m2m_stop: function pointer + * @m2m_calc_out_len: function pointer + * @m2m_get_maxburst: function pointer + * @m2m_pair_suspend: function pointer + * @m2m_pair_resume: function pointer + * @m2m_set_ratio_mod: function pointer + * @get_output_fifo_size: function pointer * @pair_priv_size: size of pair private struct. * @private: private data structure */ @@ -97,6 +144,20 @@ struct fsl_asrc { int (*request_pair)(int channels, struct fsl_asrc_pair *pair); void (*release_pair)(struct fsl_asrc_pair *pair); int (*get_fifo_addr)(u8 dir, enum asrc_pair_index index); + int (*m2m_get_cap)(struct fsl_asrc_m2m_cap *cap); + + int (*m2m_prepare)(struct fsl_asrc_pair *pair); + int (*m2m_start)(struct fsl_asrc_pair *pair); + int (*m2m_unprepare)(struct fsl_asrc_pair *pair); + int (*m2m_stop)(struct fsl_asrc_pair *pair); + + int (*m2m_calc_out_len)(struct fsl_asrc_pair *pair, int input_buffer_length); + int (*m2m_get_maxburst)(u8 dir, struct fsl_asrc_pair *pair); + int (*m2m_pair_suspend)(struct fsl_asrc_pair *pair); + int (*m2m_pair_resume)(struct fsl_asrc_pair *pair); + int (*m2m_set_ratio_mod)(struct fsl_asrc_pair *pair, int val); + + unsigned int (*get_output_fifo_size)(struct fsl_asrc_pair *pair); size_t pair_priv_size; void *private; From patchwork Thu Dec 12 07:45:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shengjiu Wang X-Patchwork-Id: 849762 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A98FEE7717F for ; Thu, 12 Dec 2024 07:48:06 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [45.14.194.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B980E415; Thu, 12 Dec 2024 08:47:49 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B1E47F80679; Thu, 12 Dec 2024 08:46:32 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 83ECBF80675; Thu, 12 Dec 2024 08:46:32 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8B7F2F805B3; Thu, 12 Dec 2024 08:46:13 +0100 (CET) Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on20604.outbound.protection.outlook.com [IPv6:2a01:111:f403:2612::604]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id F05DDF8012B for ; Thu, 12 Dec 2024 08:46:07 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F05DDF8012B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=nxp.com header.i=@nxp.com header.a=rsa-sha256 header.s=selector1 header.b=Ubuaup24 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=MiSudVjCptqLROzRhhYGHxzLIuUOTDn8gndX2UTag5bVPHiFcHaWuzf+UCDOOWuXcqUeP2trJ1IhiGoGeYOZDb2oAOlVTO0BWmvxnFlew4BDpdNawC2h54z9MOIHS5XOpo0Ewv/zleqhM2AJWA7vGpbD3scrRsYAU22ghPeqYzwHXFSS0FftrU6ZuWq5GxuSY5+4AII8HvbwMFg7nq9PGcZhfkwhrJK1pTt3Qy10/Ih20/Tv+6tjcnPYDGFGaag/yWjLNzZa6lKBatznHYlE1wU6gKajVcoTD+vHh3SHzmloek1q6GsqosnhzupHR3tKTAg00hRDLySs7gqbAy4F6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Y8WklpCyPzkisRefnf7uXkQvNqdT5cPLUt75hxgw9Do=; b=FPn3LRueCvqaw8lafXMnY2PBq/p6AFtR6mQ/oEVhLG0p9Lz8/ugt2z48WRV9Xo4D/+ItiwH53pNncCKlJB2m1kzLA9yba1LDQXZhRPhjG/rvlmtgIWonPkxgYU6lO0dncXaJ+wmvEZL3JkeWmX9jcqb0oJLQNCr7Z0Km9Z8rvBgcXxe/mOZPJLjnB/1ZSN7cl7XvFgGaVcXqkIpfHzewnqlee7QhNEG50Aj76iNKDVf77CGcK8d0tZoy8ci7uy0ElQohhh8DPXn0Sv+Q+cCFkyFq057/xSvE4z4L8m5YrRej9QhUXFQvKCr5iu539n0F7+ssHpZqrrenZEOiNOHyUA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Y8WklpCyPzkisRefnf7uXkQvNqdT5cPLUt75hxgw9Do=; b=Ubuaup24/FKepsWVwLF8UPBnyDgVmjO4V3UEunDAl6aK4SoYD8Goe4/enjM11+lETw0jnPsmj3gb8Bi9kmh8gbp6CV/FLcJlXgu6LLrKlOHWBLZnCBhxljK5yc2zL+/JiiovIzXD8/OqAVl3vidMKI839Ex6jTXAnMDxHhMl4CToOgUOzrausiIXeKGl/ofyG6/cjA9ulQBdmv4oEP6GLR8SFr2x6bLTVoM2c+4hTv1rhRfPgdtHJ70RNVhFRqAgYjnEBWlJhkobAVbIcxMPMR6uMpcpKj0GvUWuJEoWwOViq4hpZR37YFJdAGZ61iZtEdo8unE+T5oIXki7COwBmQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from VI1PR04MB7055.eurprd04.prod.outlook.com (2603:10a6:800:123::21) by DBAPR04MB7256.eurprd04.prod.outlook.com (2603:10a6:10:1a3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8251.16; Thu, 12 Dec 2024 07:46:06 +0000 Received: from VI1PR04MB7055.eurprd04.prod.outlook.com ([fe80::d6ab:1538:d868:bf8]) by VI1PR04MB7055.eurprd04.prod.outlook.com ([fe80::d6ab:1538:d868:bf8%7]) with mapi id 15.20.8251.008; Thu, 12 Dec 2024 07:46:06 +0000 From: Shengjiu Wang To: vkoul@kernel.org, perex@perex.cz, tiwai@suse.com, alsa-devel@alsa-project.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, shengjiu.wang@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com, nicoleotsuka@gmail.com, lgirdwood@gmail.com, broonie@kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v7 4/6] ASoC: fsl_asrc_m2m: Add memory to memory function Date: Thu, 12 Dec 2024 15:45:07 +0800 Message-Id: <20241212074509.3445859-5-shengjiu.wang@nxp.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20241212074509.3445859-1-shengjiu.wang@nxp.com> References: <20241212074509.3445859-1-shengjiu.wang@nxp.com> X-ClientProxiedBy: SI2PR02CA0053.apcprd02.prod.outlook.com (2603:1096:4:196::16) To VI1PR04MB7055.eurprd04.prod.outlook.com (2603:10a6:800:123::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR04MB7055:EE_|DBAPR04MB7256:EE_ X-MS-Office365-Filtering-Correlation-Id: 8a03fcdf-423f-4f15-d2c9-08dd1a8108d6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|52116014|366016|7416014|921020|38350700014; X-Microsoft-Antispam-Message-Info: RALI9qqlyfhFv3zOw5WaPllj+6RzzbshX2LwicaVB6lmLZVKzFD6wT6TcdMUcr4qiw66YxqFGg0iSpLuUp8e+YdrhNp3DsakGTXKRdBDXsj38GJCEMxX4DB5CQfpdxHldfTD8JxsOFw9nO67ED9rBzSzD+vBSHf5fwmviCE85t0Pst421/UaRwT/NHChjPwgHD5XTrJajm5uBCL/AOujsmP6iNKxZTBNfPFKGIFIX0zmlaew8XT32ZGh8x9ytYxtXuBEllwPX9AlHOAg/yCYUs98lyHOC2UVHwlLAKpQWxAuBQHyS7aHgH0tYir1i+SPyAdDUmuh0H5WLt6Q7D64jtau+A2viFNNf7/GHwptte8kNX/1i8I5Cq8GeUTIhuIZ6YePzse+7aszKlGahSzrmVOxqcrf9YAS8/ZTsl6fz4N6uwm/LFHaiJes4nZJ9zDVUg03SC8EY/TP0GBMhbI4NRcvkVdmJGTs0ONX3bkpFiU0d5lGVEp+8F/aYRJcl+CgZG4batTd5SHKjNJ4sMkglVCM5Iwkh+GaI7WxpWL2ZajBmPUhr8vyEyLdSGAW919y8kOvql+weH7kLacfgDHDHkr3mTmVaCvT2WzrlgxF1MD0LDMpd0KkW9boDimXbslpgqXj/hyHPxCDSyXY08liEzyAuzjzezU5qTDpHN6a6neJyw0f8WcNMevPrMG3HJ084Jjh8N2sanfx/HehodbECpp+VF5femt/WQlIgovQPCvTTl5ES4Of4gysElAhFnoCco/0Xu8K7PvTL6jSDnqf7sZCmVkku5FuVj8MKBqSOixo277O9O4cvwh1sdb7YRaR1WNRT99upfL60DAPWp9zfRrvPX3LX0/BYZFPjY5wSoIRnDR+VPDiQ/NzUY6WkWhiCcdo9UpdZ4mW1qGN5XL+0UsWdOxQ4hBJIzxMAYnTOYqA7azqfT4WhIJcyuePYXMQ0U+kcdIkvLFfJTNqtaPvOKoErrPqB0QsTCpd5xdurwUiYNRPnmKhV1N4OsWpBct+2Ekv+c6NK5ca6Fyo/J/r60bKn2z6aYbUG8gW+ITAji506Lz9unTaUAAGid1A9tlTKmp1YFop97cV8G61yOcILGI3z6DMUrt+1yQtr5p2xoYYaAAvHhuem/EM9aYCvs1+uZchYKfagyebDGr3AikgbKoeaji02fbom/N99CeB216o2BVn8wSH7bleRGtMzVkAjhzxk+kZFvakPamwEN6YgRzzgpeU3tMvU0wpMttcvhAvOyaqOKRjCoi2Y1PK7gfhKe/f7giaB/yliPrghKjZz7Y0PAFw97iMbY5NY0TSdV4ZIAvCN+EMYxRHgbFxGk3hLreSlYeg6aM5ZwWv+raXZlDnDWOrE/p56OT3l6mykS9vlrSgiNZvOxds6TOnuHZ4Z3YRJgekeG62kT6UEgJ1HfkrWGotRhcFlKR16yV69w8= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR04MB7055.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(52116014)(366016)(7416014)(921020)(38350700014); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: d53s79c0J5aDQJDA1w1el+uRotAy5Yxg6M2GTnhToFQWHADV0iyLfsW7o4T0UWruA3HzKW9q2wWSdF9KLlNZbYoZCsnOe6m20JK0EO86rKKENZX7rL2Nd9aQfrzxsOr+rLSzCUANsllLJ9lWndxbwOwlRGFf8TeugRlGQxWALh6G3Z70/yYHFUm2u8hLeBvvKc9y3ut+DnIeuQRTqUxaskvov5+DlQvcJQ4fmaygHy82OAKzr2Uhqb2lrNdqQnPhLQg8K81AL9IJ52oaYfpcqtPnbHlLgKBxx4n1WNGjX3q7C225l8N6a5+6HgUnmPC3wvb8vJe7lLLLkTN4r8mBNXBuaCic4hIhOMT3OmuJa3F89G/4dQTdGO25V4Fp04VWI/SLjJgMjxTgi282mAXvB2HCrlFRKyzkcdmsA+eAdskowlmTxqS0m8GLAWJGCcQ2Eg2k+5HmCOuDSxXpGcdPlQ1nb4gpsvzw86neB8YUJftfQALk4gsm5yGbXp3EasdMqjZya1v0DntVnN+3sLmrVexQNg0Uy8naOf7Bhv/PRoX0P0JIaKToIaypJUtKzt7H1tvpl4qeu7b0rFKbpm9KBqvxqd4U2L3j+wilYGrrEcFcs5D9QvI1OWEDuJ3FvBtELcY0u34EzQaciGXtUKf3KDD2eurW1mZNkzyDhzRvUW8A0T2jLxqgSsQTGfue2ukFRGY+gh9pjwdCc3XS1w1f8enmZ0NRH3rR5Z8poivDN53fqLeGvpAMUOJ3M3Hv7BPF8d/C9Z2/rAoHp1aXKa2PUpokK7XRb/nnXSWrLB/GW2SSh/g8MKYf3PqXTS88oxDCxCUUGGcoDqvYfXhmliTGIlhCU7dKqODUGt2Msf9dV6ixNgEbMuAAMF7urOHxU+aLhKE9egEHN8IY+XN2Cet348du3MZE1iSsUIH7vWjMmfKJYrwgwDkbZ1qn441MCT4HSUZZ/a0JFk5sItUcgFwiHjF5BH8KgB+snT6vgMPA9dlhKRpfToez/UGhplHsTrOT2jJ8DfANmAVO+ilwdHefE0Ev/cnhGeINSOLdNrhWdHRJH4LLppjmKtsjKVm0YFVPZk6CUykbvvI4jyHxiSHPPltkqnrcZq9Tn6eP7dgPAgCGVxasjfIkbZ3rP8IhRgsEYZ94lFi5GvL55exBm6JjM0QezLFynGZuqLtazEZgealxgqIO+rbumdN1mHjcXTmquqDS0ibw5dpF6xsXvoYQutwYX03PscgbPkWNzlSMzkqX8zybBCdS1TFzn4g3QTcFzJv3NWgsn6hyh/q50Pzxb4/+RAzbgZOBuXE4xtbfrwNQWuav8Mno5SsWWB3Gq0Wtloxc0AgvjAG624ioXPP4GeDHd/57W8nOlyHyeZiMNzIBFnavS+WCooU6YaGKWuYce55mo/7muV0n2E6BSe4Vddgo5QAVlHPXcxSy7buE+diV4fkElTn3Q25vbbiEBiQEKhSimDSSJEqjhPqKuKJxPXqQX8R8YG7848xPj40hWUatNI+cvnibmE2Al/rQuNNOlr9jSuJDLctFpUgDIlznQupXu2gZ+gcTp/7UDluVDoZGijU/M2NcM0tbU7rOzzMj X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8a03fcdf-423f-4f15-d2c9-08dd1a8108d6 X-MS-Exchange-CrossTenant-AuthSource: VI1PR04MB7055.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Dec 2024 07:46:06.2282 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: veuVXliHH4CK6+U21ncRDdsJkuTAM+Yy2chXzVZd0iQBwjanHDB1Yjfa92K5i5RR/t7lVAzsqae7yVIfZDDAyQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAPR04MB7256 Message-ID-Hash: RY47RKWJIGVMGAIU3I4FQ4LD6VYINQN7 X-Message-ID-Hash: RY47RKWJIGVMGAIU3I4FQ4LD6VYINQN7 X-MailFrom: shengjiu.wang@nxp.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Implement the ASRC memory to memory function using the compress framework, user can use this function with compress ioctl interface. This feature can be shared by ASRC and EASRC drivers Signed-off-by: Shengjiu Wang Acked-by: Jaroslav Kysela --- sound/soc/fsl/Kconfig | 2 + sound/soc/fsl/Makefile | 2 +- sound/soc/fsl/fsl_asrc_common.h | 9 + sound/soc/fsl/fsl_asrc_m2m.c | 727 ++++++++++++++++++++++++++++++++ 4 files changed, 739 insertions(+), 1 deletion(-) create mode 100644 sound/soc/fsl/fsl_asrc_m2m.c diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 8e88830e8e57..6a9f5421eb83 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -8,6 +8,8 @@ config SND_SOC_FSL_ASRC depends on HAS_DMA select REGMAP_MMIO select SND_SOC_GENERIC_DMAENGINE_PCM + select SND_COMPRESS_ACCEL + select SND_COMPRESS_OFFLOAD help Say Y if you want to add Asynchronous Sample Rate Converter (ASRC) support for the Freescale CPUs. diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index ad97244b5cc3..d656a9ab54e3 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o # Freescale SSI/DMA/SAI/SPDIF Support snd-soc-fsl-audmix-y := fsl_audmix.o snd-soc-fsl-asoc-card-y := fsl-asoc-card.o -snd-soc-fsl-asrc-y := fsl_asrc.o fsl_asrc_dma.o +snd-soc-fsl-asrc-y := fsl_asrc.o fsl_asrc_dma.o fsl_asrc_m2m.o snd-soc-fsl-lpc3xxx-y := lpc3xxx-pcm.o lpc3xxx-i2s.o snd-soc-fsl-sai-y := fsl_sai.o snd-soc-fsl-ssi-y := fsl_ssi.o diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h index 3bdd6ea07c09..0cd595b0f629 100644 --- a/sound/soc/fsl/fsl_asrc_common.h +++ b/sound/soc/fsl/fsl_asrc_common.h @@ -60,6 +60,7 @@ struct fsl_asrc_m2m_cap { * @buf_len: buffer length of m2m * @dma_buffer: buffer pointers * @first_convert: start of conversion + * @ratio_mod_flag: flag for new ratio modifier * @ratio_mod: ratio modification */ struct fsl_asrc_pair { @@ -84,6 +85,7 @@ struct fsl_asrc_pair { unsigned int buf_len[2]; struct snd_dma_buffer dma_buffer[2]; unsigned int first_convert; + bool ratio_mod_flag; unsigned int ratio_mod; }; @@ -98,6 +100,7 @@ struct fsl_asrc_pair { * @mem_clk: clock source to access register * @ipg_clk: clock source to drive peripheral * @spba_clk: SPBA clock (optional, depending on SoC design) + * @card: compress sound card * @lock: spin lock for resource protection * @pair: pair pointers * @channel_avail: non-occupied channel numbers @@ -131,6 +134,7 @@ struct fsl_asrc { struct clk *mem_clk; struct clk *ipg_clk; struct clk *spba_clk; + struct snd_card *card; spinlock_t lock; /* spin lock for resource protection */ struct fsl_asrc_pair *pair[PAIR_CTX_NUM]; @@ -166,4 +170,9 @@ struct fsl_asrc { #define DRV_NAME "fsl-asrc-dai" extern struct snd_soc_component_driver fsl_asrc_component; +int fsl_asrc_m2m_init(struct fsl_asrc *asrc); +void fsl_asrc_m2m_exit(struct fsl_asrc *asrc); +int fsl_asrc_m2m_resume(struct fsl_asrc *asrc); +int fsl_asrc_m2m_suspend(struct fsl_asrc *asrc); + #endif /* _FSL_ASRC_COMMON_H */ diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c new file mode 100644 index 000000000000..f266a3f5fd48 --- /dev/null +++ b/sound/soc/fsl/fsl_asrc_m2m.c @@ -0,0 +1,727 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2014-2016 Freescale Semiconductor, Inc. +// Copyright (C) 2019-2024 NXP +// +// Freescale ASRC Memory to Memory (M2M) driver + +#include +#include +#include +#include +#include +#include +#include + +#include "fsl_asrc_common.h" + +#define DIR_STR(dir) (dir) == IN ? "in" : "out" + +#define ASRC_xPUT_DMA_CALLBACK(dir) \ + (((dir) == IN) ? asrc_input_dma_callback \ + : asrc_output_dma_callback) + +/* Maximum output and capture buffer size */ +#define ASRC_M2M_BUFFER_SIZE (512 * 1024) + +/* Maximum output and capture period size */ +#define ASRC_M2M_PERIOD_SIZE (48 * 1024) + +/* dma complete callback */ +static void asrc_input_dma_callback(void *data) +{ + struct fsl_asrc_pair *pair = (struct fsl_asrc_pair *)data; + + complete(&pair->complete[IN]); +} + +/* dma complete callback */ +static void asrc_output_dma_callback(void *data) +{ + struct fsl_asrc_pair *pair = (struct fsl_asrc_pair *)data; + + complete(&pair->complete[OUT]); +} + +/** + *asrc_read_last_fifo: read all the remaining data from FIFO + *@pair: Structure pointer of fsl_asrc_pair + *@dma_vaddr: virtual address of capture buffer + *@length: payload length of capture buffer + */ +static void asrc_read_last_fifo(struct fsl_asrc_pair *pair, void *dma_vaddr, u32 *length) +{ + struct fsl_asrc *asrc = pair->asrc; + enum asrc_pair_index index = pair->index; + u32 i, reg, size, t_size = 0, width; + u32 *reg32 = NULL; + u16 *reg16 = NULL; + u8 *reg24 = NULL; + + width = snd_pcm_format_physical_width(pair->sample_format[OUT]); + if (width == 32) + reg32 = dma_vaddr + *length; + else if (width == 16) + reg16 = dma_vaddr + *length; + else + reg24 = dma_vaddr + *length; +retry: + size = asrc->get_output_fifo_size(pair); + if (size + *length > ASRC_M2M_BUFFER_SIZE) + goto end; + + for (i = 0; i < size * pair->channels; i++) { + regmap_read(asrc->regmap, asrc->get_fifo_addr(OUT, index), ®); + if (reg32) { + *reg32++ = reg; + } else if (reg16) { + *reg16++ = (u16)reg; + } else { + *reg24++ = (u8)reg; + *reg24++ = (u8)(reg >> 8); + *reg24++ = (u8)(reg >> 16); + } + } + t_size += size; + + /* In case there is data left in FIFO */ + if (size) + goto retry; +end: + /* Update payload length */ + if (reg32) + *length += t_size * pair->channels * 4; + else if (reg16) + *length += t_size * pair->channels * 2; + else + *length += t_size * pair->channels * 3; +} + +/* config dma channel */ +static int asrc_dmaconfig(struct fsl_asrc_pair *pair, + struct dma_chan *chan, + u32 dma_addr, dma_addr_t buf_addr, u32 buf_len, + int dir, int width) +{ + struct fsl_asrc *asrc = pair->asrc; + struct device *dev = &asrc->pdev->dev; + struct dma_slave_config slave_config; + enum dma_slave_buswidth buswidth; + unsigned int sg_len, max_period_size; + struct scatterlist *sg; + int ret, i; + + switch (width) { + case 8: + buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; + break; + case 16: + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; + break; + case 24: + buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES; + break; + case 32: + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; + break; + default: + dev_err(dev, "invalid word width\n"); + return -EINVAL; + } + + memset(&slave_config, 0, sizeof(slave_config)); + if (dir == IN) { + slave_config.direction = DMA_MEM_TO_DEV; + slave_config.dst_addr = dma_addr; + slave_config.dst_addr_width = buswidth; + slave_config.dst_maxburst = asrc->m2m_get_maxburst(IN, pair); + } else { + slave_config.direction = DMA_DEV_TO_MEM; + slave_config.src_addr = dma_addr; + slave_config.src_addr_width = buswidth; + slave_config.src_maxburst = asrc->m2m_get_maxburst(OUT, pair); + } + + ret = dmaengine_slave_config(chan, &slave_config); + if (ret) { + dev_err(dev, "failed to config dmaengine for %s task: %d\n", + DIR_STR(dir), ret); + return -EINVAL; + } + + max_period_size = rounddown(ASRC_M2M_PERIOD_SIZE, width * pair->channels / 8); + /* scatter gather mode */ + sg_len = buf_len / max_period_size; + if (buf_len % max_period_size) + sg_len += 1; + + sg = kmalloc_array(sg_len, sizeof(*sg), GFP_KERNEL); + if (!sg) + return -ENOMEM; + + sg_init_table(sg, sg_len); + for (i = 0; i < (sg_len - 1); i++) { + sg_dma_address(&sg[i]) = buf_addr + i * max_period_size; + sg_dma_len(&sg[i]) = max_period_size; + } + sg_dma_address(&sg[i]) = buf_addr + i * max_period_size; + sg_dma_len(&sg[i]) = buf_len - i * max_period_size; + + pair->desc[dir] = dmaengine_prep_slave_sg(chan, sg, sg_len, + slave_config.direction, + DMA_PREP_INTERRUPT); + kfree(sg); + if (!pair->desc[dir]) { + dev_err(dev, "failed to prepare dmaengine for %s task\n", DIR_STR(dir)); + return -EINVAL; + } + + pair->desc[dir]->callback = ASRC_xPUT_DMA_CALLBACK(dir); + pair->desc[dir]->callback_param = pair; + + return 0; +} + +/* main function of converter */ +static void asrc_m2m_device_run(struct fsl_asrc_pair *pair, struct snd_compr_task_runtime *task) +{ + struct fsl_asrc *asrc = pair->asrc; + struct device *dev = &asrc->pdev->dev; + enum asrc_pair_index index = pair->index; + struct snd_dma_buffer *src_buf, *dst_buf; + unsigned int in_buf_len; + unsigned int out_dma_len; + unsigned int width; + u32 fifo_addr; + int ret; + + /* set ratio mod */ + if (asrc->m2m_set_ratio_mod) { + if (pair->ratio_mod_flag) { + asrc->m2m_set_ratio_mod(pair, pair->ratio_mod); + pair->ratio_mod_flag = false; + } + } + + src_buf = &pair->dma_buffer[IN]; + dst_buf = &pair->dma_buffer[OUT]; + + width = snd_pcm_format_physical_width(pair->sample_format[IN]); + fifo_addr = asrc->paddr + asrc->get_fifo_addr(IN, index); + + in_buf_len = task->input_size; + + if (in_buf_len < width * pair->channels / 8 || + in_buf_len > ASRC_M2M_BUFFER_SIZE || + in_buf_len % (width * pair->channels / 8)) { + dev_err(dev, "out buffer size is error: [%d]\n", in_buf_len); + goto end; + } + + /* dma config for output dma channel */ + ret = asrc_dmaconfig(pair, + pair->dma_chan[IN], + fifo_addr, + src_buf->addr, + in_buf_len, IN, width); + if (ret) { + dev_err(dev, "out dma config error\n"); + goto end; + } + + width = snd_pcm_format_physical_width(pair->sample_format[OUT]); + fifo_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index); + out_dma_len = asrc->m2m_calc_out_len(pair, in_buf_len); + if (out_dma_len > 0 && out_dma_len <= ASRC_M2M_BUFFER_SIZE) { + /* dma config for capture dma channel */ + ret = asrc_dmaconfig(pair, + pair->dma_chan[OUT], + fifo_addr, + dst_buf->addr, + out_dma_len, OUT, width); + if (ret) { + dev_err(dev, "cap dma config error\n"); + goto end; + } + } else if (out_dma_len > ASRC_M2M_BUFFER_SIZE) { + dev_err(dev, "cap buffer size error\n"); + goto end; + } + + reinit_completion(&pair->complete[IN]); + reinit_completion(&pair->complete[OUT]); + + /* Submit DMA request */ + dmaengine_submit(pair->desc[IN]); + dma_async_issue_pending(pair->desc[IN]->chan); + if (out_dma_len > 0) { + dmaengine_submit(pair->desc[OUT]); + dma_async_issue_pending(pair->desc[OUT]->chan); + } + + asrc->m2m_start(pair); + + if (!wait_for_completion_interruptible_timeout(&pair->complete[IN], 10 * HZ)) { + dev_err(dev, "out DMA task timeout\n"); + goto end; + } + + if (out_dma_len > 0) { + if (!wait_for_completion_interruptible_timeout(&pair->complete[OUT], 10 * HZ)) { + dev_err(dev, "cap DMA task timeout\n"); + goto end; + } + } + + /* read the last words from FIFO */ + asrc_read_last_fifo(pair, dst_buf->area, &out_dma_len); + /* update payload length for capture */ + task->output_size = out_dma_len; +end: + return; +} + +static int fsl_asrc_m2m_comp_open(struct snd_compr_stream *stream) +{ + struct fsl_asrc *asrc = stream->private_data; + struct snd_compr_runtime *runtime = stream->runtime; + struct device *dev = &asrc->pdev->dev; + struct fsl_asrc_pair *pair; + int size, ret; + + pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL); + if (!pair) + return -ENOMEM; + + pair->private = (void *)pair + sizeof(struct fsl_asrc_pair); + pair->asrc = asrc; + + init_completion(&pair->complete[IN]); + init_completion(&pair->complete[OUT]); + + runtime->private_data = pair; + + size = ASRC_M2M_BUFFER_SIZE; + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &pair->dma_buffer[IN]); + if (ret) + goto error_alloc_in_buf; + + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &pair->dma_buffer[OUT]); + if (ret) + goto error_alloc_out_buf; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "Failed to power up asrc\n"); + goto err_pm_runtime; + } + + return 0; + +err_pm_runtime: + snd_dma_free_pages(&pair->dma_buffer[OUT]); +error_alloc_out_buf: + snd_dma_free_pages(&pair->dma_buffer[IN]); +error_alloc_in_buf: + kfree(pair); + return ret; +} + +static int fsl_asrc_m2m_comp_release(struct snd_compr_stream *stream) +{ + struct fsl_asrc *asrc = stream->private_data; + struct snd_compr_runtime *runtime = stream->runtime; + struct fsl_asrc_pair *pair = runtime->private_data; + struct device *dev = &asrc->pdev->dev; + + pm_runtime_put_sync(dev); + + snd_dma_free_pages(&pair->dma_buffer[IN]); + snd_dma_free_pages(&pair->dma_buffer[OUT]); + + kfree(runtime->private_data); + + return 0; +} + +static int fsl_asrc_m2m_comp_set_params(struct snd_compr_stream *stream, + struct snd_compr_params *params) +{ + struct fsl_asrc *asrc = stream->private_data; + struct snd_compr_runtime *runtime = stream->runtime; + struct fsl_asrc_pair *pair = runtime->private_data; + struct fsl_asrc_m2m_cap cap; + int ret, i; + + ret = asrc->m2m_get_cap(&cap); + if (ret) + return -EINVAL; + + if (pcm_format_to_bits(params->codec.format) & cap.fmt_in) + pair->sample_format[IN] = params->codec.format; + else + return -EINVAL; + + if (pcm_format_to_bits(params->codec.pcm_format) & cap.fmt_out) + pair->sample_format[OUT] = params->codec.pcm_format; + else + return -EINVAL; + + /* check input rate is in scope */ + for (i = 0; i < cap.rate_in_count; i++) + if (params->codec.sample_rate == cap.rate_in[i]) { + pair->rate[IN] = params->codec.sample_rate; + break; + } + if (i == cap.rate_in_count) + return -EINVAL; + + /* check output rate is in scope */ + for (i = 0; i < cap.rate_out_count; i++) + if (params->codec.options.src_d.out_sample_rate == cap.rate_out[i]) { + pair->rate[OUT] = params->codec.options.src_d.out_sample_rate; + break; + } + if (i == cap.rate_out_count) + return -EINVAL; + + if (params->codec.ch_in != params->codec.ch_out || + params->codec.ch_in < cap.chan_min || + params->codec.ch_in > cap.chan_max) + return -EINVAL; + + pair->channels = params->codec.ch_in; + pair->buf_len[IN] = params->buffer.fragment_size; + pair->buf_len[OUT] = params->buffer.fragment_size; + + return 0; +} + +static int fsl_asrc_m2m_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct snd_dma_buffer *dmab = dmabuf->priv; + + return snd_dma_buffer_mmap(dmab, vma); +} + +static struct sg_table *fsl_asrc_m2m_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct snd_dma_buffer *dmab = attachment->dmabuf->priv; + struct sg_table *sgt; + + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) + return NULL; + + if (dma_get_sgtable(attachment->dev, sgt, dmab->area, dmab->addr, dmab->bytes) < 0) + goto free; + + if (dma_map_sgtable(attachment->dev, sgt, direction, 0)) + goto free; + + return sgt; + +free: + sg_free_table(sgt); + kfree(sgt); + return NULL; +} + +static void fsl_asrc_m2m_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ + dma_unmap_sgtable(attachment->dev, table, direction, 0); +} + +static void fsl_asrc_m2m_release(struct dma_buf *dmabuf) +{ + /* buffer is released by fsl_asrc_m2m_comp_release() */ +} + +static const struct dma_buf_ops fsl_asrc_m2m_dma_buf_ops = { + .mmap = fsl_asrc_m2m_mmap, + .map_dma_buf = fsl_asrc_m2m_map_dma_buf, + .unmap_dma_buf = fsl_asrc_m2m_unmap_dma_buf, + .release = fsl_asrc_m2m_release, +}; + +static int fsl_asrc_m2m_comp_task_create(struct snd_compr_stream *stream, + struct snd_compr_task_runtime *task) +{ + DEFINE_DMA_BUF_EXPORT_INFO(exp_info_in); + DEFINE_DMA_BUF_EXPORT_INFO(exp_info_out); + struct fsl_asrc *asrc = stream->private_data; + struct snd_compr_runtime *runtime = stream->runtime; + struct fsl_asrc_pair *pair = runtime->private_data; + struct device *dev = &asrc->pdev->dev; + int ret; + + exp_info_in.ops = &fsl_asrc_m2m_dma_buf_ops; + exp_info_in.size = ASRC_M2M_BUFFER_SIZE; + exp_info_in.flags = O_RDWR; + exp_info_in.priv = &pair->dma_buffer[IN]; + task->input = dma_buf_export(&exp_info_in); + if (IS_ERR(task->input)) { + ret = PTR_ERR(task->input); + return ret; + } + + exp_info_out.ops = &fsl_asrc_m2m_dma_buf_ops; + exp_info_out.size = ASRC_M2M_BUFFER_SIZE; + exp_info_out.flags = O_RDWR; + exp_info_out.priv = &pair->dma_buffer[OUT]; + task->output = dma_buf_export(&exp_info_out); + if (IS_ERR(task->output)) { + ret = PTR_ERR(task->output); + return ret; + } + + /* Request asrc pair/context */ + ret = asrc->request_pair(pair->channels, pair); + if (ret) { + dev_err(dev, "failed to request pair: %d\n", ret); + goto err_request_pair; + } + + ret = asrc->m2m_prepare(pair); + if (ret) { + dev_err(dev, "failed to start pair part one: %d\n", ret); + goto err_start_part_one; + } + + /* Request dma channels */ + pair->dma_chan[IN] = asrc->get_dma_channel(pair, IN); + if (!pair->dma_chan[IN]) { + dev_err(dev, "[ctx%d] failed to get input DMA channel\n", pair->index); + ret = -EBUSY; + goto err_dma_channel_in; + } + + pair->dma_chan[OUT] = asrc->get_dma_channel(pair, OUT); + if (!pair->dma_chan[OUT]) { + dev_err(dev, "[ctx%d] failed to get output DMA channel\n", pair->index); + ret = -EBUSY; + goto err_dma_channel_out; + } + + return 0; + +err_dma_channel_out: + dma_release_channel(pair->dma_chan[IN]); +err_dma_channel_in: + if (asrc->m2m_unprepare) + asrc->m2m_unprepare(pair); +err_start_part_one: + asrc->release_pair(pair); +err_request_pair: + return ret; +} + +static int fsl_asrc_m2m_comp_task_start(struct snd_compr_stream *stream, + struct snd_compr_task_runtime *task) +{ + struct snd_compr_runtime *runtime = stream->runtime; + struct fsl_asrc_pair *pair = runtime->private_data; + + asrc_m2m_device_run(pair, task); + + return 0; +} + +static int fsl_asrc_m2m_comp_task_stop(struct snd_compr_stream *stream, + struct snd_compr_task_runtime *task) +{ + return 0; +} + +static int fsl_asrc_m2m_comp_task_free(struct snd_compr_stream *stream, + struct snd_compr_task_runtime *task) +{ + struct fsl_asrc *asrc = stream->private_data; + struct snd_compr_runtime *runtime = stream->runtime; + struct fsl_asrc_pair *pair = runtime->private_data; + + /* Stop & release pair/context */ + if (asrc->m2m_stop) + asrc->m2m_stop(pair); + + if (asrc->m2m_unprepare) + asrc->m2m_unprepare(pair); + asrc->release_pair(pair); + + /* Release dma channel */ + if (pair->dma_chan[IN]) + dma_release_channel(pair->dma_chan[IN]); + if (pair->dma_chan[OUT]) + dma_release_channel(pair->dma_chan[OUT]); + + return 0; +} + +static int fsl_asrc_m2m_get_caps(struct snd_compr_stream *cstream, + struct snd_compr_caps *caps) +{ + caps->num_codecs = 1; + caps->min_fragment_size = 4096; + caps->max_fragment_size = 4096; + caps->min_fragments = 1; + caps->max_fragments = 1; + caps->codecs[0] = SND_AUDIOCODEC_PCM; + + return 0; +} + +static int fsl_asrc_m2m_fill_codec_caps(struct fsl_asrc *asrc, + struct snd_compr_codec_caps *codec) +{ + struct fsl_asrc_m2m_cap cap; + snd_pcm_format_t k; + int j = 0; + int ret; + + ret = asrc->m2m_get_cap(&cap); + if (ret) + return -EINVAL; + + pcm_for_each_format(k) { + if (pcm_format_to_bits(k) & cap.fmt_in) { + codec->descriptor[j].max_ch = cap.chan_max; + memcpy(codec->descriptor[j].sample_rates, + cap.rate_in, + cap.rate_in_count * sizeof(__u32)); + codec->descriptor[j].num_sample_rates = cap.rate_in_count; + codec->descriptor[j].formats = k; + codec->descriptor[j].pcm_formats = cap.fmt_out; + codec->descriptor[j].src.out_sample_rate_min = cap.rate_out[0]; + codec->descriptor[j].src.out_sample_rate_max = + cap.rate_out[cap.rate_out_count - 1]; + j++; + } + } + + codec->codec = SND_AUDIOCODEC_PCM; + codec->num_descriptors = j; + return 0; +} + +static int fsl_asrc_m2m_get_codec_caps(struct snd_compr_stream *stream, + struct snd_compr_codec_caps *codec) +{ + struct fsl_asrc *asrc = stream->private_data; + + return fsl_asrc_m2m_fill_codec_caps(asrc, codec); +} + +static struct snd_compr_ops fsl_asrc_m2m_compr_ops = { + .open = fsl_asrc_m2m_comp_open, + .free = fsl_asrc_m2m_comp_release, + .set_params = fsl_asrc_m2m_comp_set_params, + .get_caps = fsl_asrc_m2m_get_caps, + .get_codec_caps = fsl_asrc_m2m_get_codec_caps, + .task_create = fsl_asrc_m2m_comp_task_create, + .task_start = fsl_asrc_m2m_comp_task_start, + .task_stop = fsl_asrc_m2m_comp_task_stop, + .task_free = fsl_asrc_m2m_comp_task_free, +}; + +int fsl_asrc_m2m_suspend(struct fsl_asrc *asrc) +{ + struct fsl_asrc_pair *pair; + int i; + + for (i = 0; i < PAIR_CTX_NUM; i++) { + pair = asrc->pair[i]; + if (!pair) + continue; + if (!completion_done(&pair->complete[IN])) { + if (pair->dma_chan[IN]) + dmaengine_terminate_all(pair->dma_chan[IN]); + asrc_input_dma_callback((void *)pair); + } + if (!completion_done(&pair->complete[OUT])) { + if (pair->dma_chan[OUT]) + dmaengine_terminate_all(pair->dma_chan[OUT]); + asrc_output_dma_callback((void *)pair); + } + + if (asrc->m2m_pair_suspend) + asrc->m2m_pair_suspend(pair); + } + + return 0; +} +EXPORT_SYMBOL_GPL(fsl_asrc_m2m_suspend); + +int fsl_asrc_m2m_resume(struct fsl_asrc *asrc) +{ + struct fsl_asrc_pair *pair; + int i; + + for (i = 0; i < PAIR_CTX_NUM; i++) { + pair = asrc->pair[i]; + if (!pair) + continue; + if (asrc->m2m_pair_resume) + asrc->m2m_pair_resume(pair); + } + + return 0; +} +EXPORT_SYMBOL_GPL(fsl_asrc_m2m_resume); + +int fsl_asrc_m2m_init(struct fsl_asrc *asrc) +{ + struct device *dev = &asrc->pdev->dev; + struct snd_card *card; + struct snd_compr *compr; + int ret; + + ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, + THIS_MODULE, 0, &card); + if (ret < 0) + return ret; + + strscpy(card->driver, "fsl-asrc-m2m", sizeof(card->driver)); + strscpy(card->shortname, "ASRC-M2M", sizeof(card->shortname)); + strscpy(card->longname, "ASRC-M2M", sizeof(card->shortname)); + + asrc->card = card; + + compr = devm_kzalloc(dev, sizeof(*compr), GFP_KERNEL); + if (!compr) { + ret = -ENOMEM; + goto err; + } + + compr->ops = &fsl_asrc_m2m_compr_ops; + compr->private_data = asrc; + + ret = snd_compress_new(card, 0, SND_COMPRESS_ACCEL, "ASRC M2M", compr); + if (ret < 0) + goto err; + + ret = snd_card_register(card); + if (ret < 0) + goto err; + + return 0; +err: + snd_card_free(card); + return ret; +} +EXPORT_SYMBOL_GPL(fsl_asrc_m2m_init); + +void fsl_asrc_m2m_exit(struct fsl_asrc *asrc) +{ + struct snd_card *card = asrc->card; + + snd_card_free(card); +} +EXPORT_SYMBOL_GPL(fsl_asrc_m2m_exit); + +MODULE_IMPORT_NS("DMA_BUF"); +MODULE_AUTHOR("Shengjiu Wang "); +MODULE_DESCRIPTION("Freescale ASRC M2M driver"); +MODULE_LICENSE("GPL"); From patchwork Thu Dec 12 07:45:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shengjiu Wang X-Patchwork-Id: 849761 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E86E4E7717F for ; Thu, 12 Dec 2024 07:48:37 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [45.14.194.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 4067F341; Thu, 12 Dec 2024 08:48:26 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BCF73F806B4; Thu, 12 Dec 2024 08:46:40 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 9FB38F806B8; Thu, 12 Dec 2024 08:46:40 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EA813F805F9; Thu, 12 Dec 2024 08:46:20 +0100 (CET) Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20613.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::613]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id E8F32F805FB for ; Thu, 12 Dec 2024 08:46:17 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E8F32F805FB Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=nxp.com header.i=@nxp.com header.a=rsa-sha256 header.s=selector1 header.b=hXiWnpNi ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VlNbsK2GJUWvfYtpMgontUI103TDAm+XJE7HGY7M++PHJChl4yKFLpeQMRwVXMRw/T+pemo6HbnGEKP6bxOyGq7SZOwn9w1OYQcK4Tq2rqyrXjozrobvDlqVB4WkuE28+jL/AECq8P6w4bfupx+8MZ8ytxDofgoOPpA60wbFQyEJmvFhOG7b/yh3geFbruQMhY28YoTIZHs1y0LKRW7cT30CAQNmLNOdp15GYLJHtcTt/ZcnxuWtO3yXTiguF8uNMrahiEaU4humtk3R0wqiR5mESl2IDHkPwB5VOViLIKx+2zoYe0qtu9l+tPm0LyNgKUjnh/92ehfAEHGnmSuZcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=mJK8WWOvDdKnJn03HGc+yupP/YXIOxc9ngBNgUkeoqw=; b=tltCqmZoAjxAV892bmTIIFP7uaS082DGid7dGHpj+q/dqaewqZBZP1RfmhHttIcDQ7S04mjx9dcuRR4OBH9cdz+M2QW8G+XzQSi8RJzNp8W00J8NMlfiS/ntv8lU/FSs2fkBkzE8NgEtJenv/VQoY9Pv55ULzc9SvQj/iqWczR8bWJQucPr6iQwCyz/SIaxTYRvj2SinWhcRpnRETDUZyehAwVpfGFsSSnXwFqUAuCBKhx6H1nFFQVR/UlhfJiTR5gE/vqr6NaIDNPFrU2fQFPTcULB869/qo7m5IUd9kIxkngqtMjoYA07OKB5ASFDLj2nDoujb89iq8DdcgznNeA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mJK8WWOvDdKnJn03HGc+yupP/YXIOxc9ngBNgUkeoqw=; b=hXiWnpNiLup4+jQgeQFrRTgtFFMWTIhDX3tGYC+xT6E4Tz2pZxFYl7byvyOc9mWUJnHvbCprpVOrHnpKOZWUM1SqfA40NBf7WmtV+XrjXs/fCBugyoVkeSYb4vmEPf4c14Z1E2UduINHoxx3WwsWKKursKho2PRnfJYRXOO/4xCNUvJJljvHrcXdGRC37WB3ezHZCg3X1LPokzTyQkfZrAlhc1y2zN7yMU2HppriEGMSm+y0IsX+NtSVyB/9xUNlJcV0lK58vx4duX/Th8k754GZ3eb2OB+J95bqBGf2gHB2wvxxvXerToySUlfWMg6K1inpn4srqvtzuZaSM+blvQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from VI1PR04MB7055.eurprd04.prod.outlook.com (2603:10a6:800:123::21) by DBAPR04MB7256.eurprd04.prod.outlook.com (2603:10a6:10:1a3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8251.16; Thu, 12 Dec 2024 07:46:15 +0000 Received: from VI1PR04MB7055.eurprd04.prod.outlook.com ([fe80::d6ab:1538:d868:bf8]) by VI1PR04MB7055.eurprd04.prod.outlook.com ([fe80::d6ab:1538:d868:bf8%7]) with mapi id 15.20.8251.008; Thu, 12 Dec 2024 07:46:15 +0000 From: Shengjiu Wang To: vkoul@kernel.org, perex@perex.cz, tiwai@suse.com, alsa-devel@alsa-project.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, shengjiu.wang@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com, nicoleotsuka@gmail.com, lgirdwood@gmail.com, broonie@kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v7 6/6] ASoC: fsl_easrc: register m2m platform device Date: Thu, 12 Dec 2024 15:45:09 +0800 Message-Id: <20241212074509.3445859-7-shengjiu.wang@nxp.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20241212074509.3445859-1-shengjiu.wang@nxp.com> References: <20241212074509.3445859-1-shengjiu.wang@nxp.com> X-ClientProxiedBy: SI2PR02CA0053.apcprd02.prod.outlook.com (2603:1096:4:196::16) To VI1PR04MB7055.eurprd04.prod.outlook.com (2603:10a6:800:123::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR04MB7055:EE_|DBAPR04MB7256:EE_ X-MS-Office365-Filtering-Correlation-Id: 0aa0d1d5-6436-4ed9-c3c8-08dd1a810e44 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|52116014|366016|7416014|921020|38350700014; X-Microsoft-Antispam-Message-Info: 67xsIYLlIuIilz7ORnMx1vOQ+MikMev0mI4YqboAqNbuYsxof+iSr+PV6aVHUc3Q7LWbpuZ13l8EofQ8LIH2iXsRC3l3lWdIyGgJZbjyWYdcV5qLlminDaFlpd1UXc8nUwyK4KLWY0k497hgblzcSd+PFz4FbkfX2W/oTx63Kx1zGLH/siq4kdOpELbL2TdpsnfWTIcjbDnil+eEjJmj7YJAFt4yBEg3ADLoktOAxirjVspfuf9ErPcC8gfP4zRDEVXQ1IkSXeyJb+RomN9Ugeji2X40tDSzN4DiAqEIY2FD/eiNoa2iRIFhjF3Xo/+YjXjmIdHdi8LxWEu2jrVX+Vtg7faLDI8to8UMq73psrGNC5+2CtJS6rMw/amQQBM4I52E1MQF2bUO3krSGuj5cxjOCwqK33pmr0A2oL6wzJvR2DQO0MwpXmQ5hm92PS1C4se41LEdiLiGY9O7ov4Mz31oHd+jAt8bkpnwbzxiBTeIFMU9hOncAg4GJ2GP2Id9aCrHlnHgUq9+83CiPEHgKUKUOey1X7gEYFsBdhHK7vsFITwC/wFwVOAFPEL2pVX0LlVN+slAnlskcrq+mCSL55XFj+VOES3marIRVC7h2CyZwrZ3fUQY3gciFj3SA3G3Tegz1gq3aAoL49v7OPd/fAK3ZNsEqHefx6FczTss06Z/zMqHnLKJkXRjLwcIepkm2mwE3oV13CnM+30J2EXp3vuL7POjCBemuyoo4qxgu9UMK5lRsdRHYiVqzmlLmeBs8o3wBVJlCg/zGgYDJA6v1l0vAorqMgyUzvDOVwdHgvl7uwDh2iAReGZ+h/Lf0xnUd5YZobpLqzWPnYDOFvA6N6i2Bw9B1qWVjgDByzNHacPQdeqJTrz2YWSimpJQQo2n+FoIypH+laStqf+R5QWQmBAzxvWm2JZHJQg98jUAtPqqWltVb8dqhrnPCA1Z4HqdQrZPXuDhkp9nN/6epd2mN957/rmDyLhAWV6s9lNJbp1V1m9l8w+QysQdXkugN3TTFQodg8oljPSNT/VDNQpY4bOAuMvhsqt12dNC4potj2u4tJmT1WLWju9C0qKyUbrfoH92x5qnV5s1FktBRCc9WP0Bxgj2fBx4+1HSeB95VLBjjF1TD6b9GHoPVg7gD7W4EsZidDr88NqTj9jW4XVoKKYCwp2tqp65KCh5wNt8HTd155MNn/e3w38Br5B4+wZ0HHqSlhpOe59U4Ob56jJkxyeCi0SDLzeucTnpCIKSxeGNpYzFofak8xDnPuLA3/Q9d/qvg6KVaDIA6sr/bt1G3IbI5ROPtFdu72UphZL6vFfxVP532HypXj7vcFXi0GchK0u6PEhAz3gKKPuWJodsTYeAKBY/pbsuT3e1H3IwayPkHeNvy9ZUw9Bf8uAvsW5z098PJyOk3BnLww8aH6wQDJvH3MJvRvzmV+J3tkji+NE= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR04MB7055.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(52116014)(366016)(7416014)(921020)(38350700014); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 3CnwpfzAp5ryjzm6IViyKTmvAvRv3aqmOD4l4C2dVK//rR8AtJqpUHmm4KQrYU/OGhiaC4M01XP5hKa7fj9pd4hAwDcvSFpLr1Dcz4ywWdJcmK6DAYviqXZ0bx9k06X74MiqBS9GD4RX/c0rGwx6hiKuVmCXBcORBce9cAa0wD0zrdUly9QUDacOeyvx+2GiWX/STXq8wwNQTLCHpAOUIMH7LX1Xq60iyRCk/JW6SqUfY4n7wgXkAFen7xDLaCCrEEGQfgzo3nx+BsCv8sAlhox+aPyaYKWXAL3Rt1D6O+oqcLXgfyPAJQ58B7WPvfP55G4SUlEeGkTq8nhMyWzYRK2A1+V7QTDeODW02V4VbxnUSzsi3fFuuqwv7VgN3L2csFF0FvReyKUNIQl2jttpU63RHDg2/jCiG3ZibI5L/i0nfT7TQfSlbpbQQJ4Jgy+qrxCxZWpizhlGnEtxkRQUucN27M4VAJ8jkMrehTnmceOTZa42LjlEKKT2YnwQAuv9lFhewzBSMYrfo4dNvpZLraqygR67EW1yaeGftNwkpRgHrVwTNpOceD2SkLndLfsxnJpfh+GZ4cC7jMKI0LeJ3bZs/BqUy92oDCBiRseY7U0Hd69+J4S/GMsdJ09gD+hW2F7RvmWPtc3PV05wU86x3/KdEGbs5LErUfk6F42xlmudQl8PPT74E2BWTvjY5rORzxYjGYBUmu6tyB8R6G4TCSjuS9b7AGuzz4pVqX03TflRpBWbg4Xfqh51xwXJohBXFzUT6RMefnGFOpct/BdFDuRhDmJ6b+ILrEed2Bm6lrQDgFhXwQAlUfU0EBTS8jwa1GErlM2uNduwjEKINqb9To2czgmmTccZLhMFHBCPt/E+bAWhPRS5c9wYBnc3Bybt0L6LrubkxznAh/sRmVdPINlaMaK8tOKFhJuBHci2y2oFsURZggSJQiYdxcuwwun3KrV1b/ThQ1NCcGvgqE+AWm7jnSVktFIfvoDxS5/vwPARw40mudjb4ERPKHFE+p5DLeWUfeR8RMuagBoICFNEBrtxR47XdGJ1ytFyWfxWU+jOJpBUHW+8W6vFMyzArV0WgJpEiw/Sz9s+H4UqnxzRGdGxIoV3wVxA6z3QXUtlx92ctKSwcf7glYR9EbnnD5szDNFmFN1oUeShuQu/EObNeq279NxQwHvIB2u9vMVk2bzSMQJ90OK243aupJwghqW+83k13tf+ahQWnMt1h5RXMSWDjgt4xsCBKLS7l9EfWQcFkA0+xqQY1nUjswMXQFde1uN0Ma3orKhLS7OqPY90lglIhc1wXM4REZW9GkTSNbkLjPeLu0XQzRbFlo9fqh+yMUIf+Hy6ZwvvUTeprBrKw+MY2LivSW/wj2dMCDsjoC38c3axhPNXomSdirBjkC/+am0UWHpmCCTTsVkg5oZP3YICJdBx92koVzJNsc84EbEXpyKq8n7KC2vUrUypRoAl7BtBO7aiWYw52AQdpUGw7i6e5qoLTO9XOuoihXUQtSkehtOiqSRXBWlTmy890Ex6CEZQu9nwgrEGC3kK/1dLBZA1NiD2GK5lvF47LArOHsJPSfvEP7UfXjdJEVzBGueZ X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0aa0d1d5-6436-4ed9-c3c8-08dd1a810e44 X-MS-Exchange-CrossTenant-AuthSource: VI1PR04MB7055.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Dec 2024 07:46:15.1684 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: TYshT6p8AoOdI4r57GCtsa0a1G0TZmDcYyn7fMowR2uE020Eh6c4dK9xoQV4OFCqhZujB+nqtPpwnNuc+YruPQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAPR04MB7256 Message-ID-Hash: EST7TWFRKSHBFKMPDAMM43CPEVDNKIIE X-Message-ID-Hash: EST7TWFRKSHBFKMPDAMM43CPEVDNKIIE X-MailFrom: shengjiu.wang@nxp.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Register m2m platform device,that user can use M2M feature. Signed-off-by: Shengjiu Wang Acked-by: Jaroslav Kysela --- sound/soc/fsl/fsl_easrc.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index f17a185a1910..f404a39009e1 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -2204,6 +2204,12 @@ static int fsl_easrc_probe(struct platform_device *pdev) goto err_pm_disable; } + ret = fsl_asrc_m2m_init(easrc); + if (ret) { + dev_err(&pdev->dev, "failed to init m2m device %d\n", ret); + return ret; + } + return 0; err_pm_disable: @@ -2213,6 +2219,10 @@ static int fsl_easrc_probe(struct platform_device *pdev) static void fsl_easrc_remove(struct platform_device *pdev) { + struct fsl_asrc *easrc = dev_get_drvdata(&pdev->dev); + + fsl_asrc_m2m_exit(easrc); + pm_runtime_disable(&pdev->dev); } @@ -2313,10 +2323,29 @@ static int fsl_easrc_runtime_resume(struct device *dev) return ret; } +static int fsl_easrc_suspend(struct device *dev) +{ + struct fsl_asrc *easrc = dev_get_drvdata(dev); + int ret; + + fsl_asrc_m2m_suspend(easrc); + ret = pm_runtime_force_suspend(dev); + return ret; +} + +static int fsl_easrc_resume(struct device *dev) +{ + struct fsl_asrc *easrc = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_resume(dev); + fsl_asrc_m2m_resume(easrc); + return ret; +} + static const struct dev_pm_ops fsl_easrc_pm_ops = { RUNTIME_PM_OPS(fsl_easrc_runtime_suspend, fsl_easrc_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + SYSTEM_SLEEP_PM_OPS(fsl_easrc_suspend, fsl_easrc_resume) }; static struct platform_driver fsl_easrc_driver = {