From nobody Tue Jun 23 11:15:10 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2BA6FC433F5 for ; Mon, 7 Mar 2022 10:49:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240505AbiCGKuC (ORCPT ); Mon, 7 Mar 2022 05:50:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238049AbiCGKrQ (ORCPT ); Mon, 7 Mar 2022 05:47:16 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A50C99F39C; Mon, 7 Mar 2022 02:07:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1646647652; x=1678183652; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=j8rdnFqQGxQj/EbhdN6CdN2Os+QFREnEIYaYmc4cc+g=; b=pRkyu7XwWJBoCMr8oGcvIeDF58eFN2OtbXEzS2C2O/t/VauS5NZCdXVp 8yn0VuQ/SlBjKfsVwvPjWWu9MvUyl9ou+E7UslWYhaT8FVNQIoz3hK4ok MEkY97jIfn9WluBhRxQruozn+iucMJbWV+sNBCeG470kM2WXFmXySpGde ay4rMxmQNo8KW6KyTMZwKPhFvdDHH/JYkkqABypxIUghOPEI+2ek0RRXr 91sJ5N11hbsoShDUyDf6cFmhms1JZPiPHC1LygYah1Eg4WlER/Gtffbug tj+bA5IpmT5zoRllHAHVdd9GlBrU313WMde6BWQPnuhdjlXlIxVIFMKk0 g==; X-IronPort-AV: E=Sophos;i="5.90,161,1643698800"; d="scan'208";a="88045515" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 07 Mar 2022 03:06:07 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 7 Mar 2022 03:05:59 -0700 Received: from rob-ult-m19940.amer.actel.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 7 Mar 2022 03:05:56 -0700 From: Codrin Ciubotariu To: , , , CC: , , , , , , "Codrin Ciubotariu" Subject: [PATCH v2 1/6] ASoC: dmaengine: do not use a NULL prepare_slave_config() callback Date: Mon, 7 Mar 2022 12:04:23 +0200 Message-ID: <20220307100428.2227511-2-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> References: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Even if struct snd_dmaengine_pcm_config is used, prepare_slave_config() callback might not be set. Check if this callback is set before using it. Fixes: fa654e085300 ("ASoC: dmaengine-pcm: Provide default config") Signed-off-by: Codrin Ciubotariu --- Changes in v2: - none sound/soc/soc-generic-dmaengine-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-= dmaengine-pcm.c index 285441d6aeed..2ab2ddc1294d 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -86,10 +86,10 @@ static int dmaengine_pcm_hw_params(struct snd_soc_compo= nent *component, =20 memset(&slave_config, 0, sizeof(slave_config)); =20 - if (!pcm->config) - prepare_slave_config =3D snd_dmaengine_pcm_prepare_slave_config; - else + if (pcm->config && pcm->config->prepare_slave_config) prepare_slave_config =3D pcm->config->prepare_slave_config; + else + prepare_slave_config =3D snd_dmaengine_pcm_prepare_slave_config; =20 if (prepare_slave_config) { int ret =3D prepare_slave_config(substream, params, &slave_config); --=20 2.32.0 From nobody Tue Jun 23 11:15:10 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E680DC433F5 for ; Mon, 7 Mar 2022 10:50:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237956AbiCGKvT (ORCPT ); Mon, 7 Mar 2022 05:51:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241206AbiCGKrQ (ORCPT ); Mon, 7 Mar 2022 05:47:16 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42C9125DB; Mon, 7 Mar 2022 02:07:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1646647655; x=1678183655; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9sVz8A6/3pKzsSyKWMfc35MVS+ww7R2A8G94llrGlNU=; b=nbeELro5Oddf2n7a/b+GXTDV5/ZDmH02D3X+DFYyiwI4g/BjJL7DJ/7b Ov4yJTtyRg3T26SE6btne9FO4sIjx3uo73jwjQlIYxq0wTbpOCt1OZcil RxPYan2TygvVvDCr8k4F9LnJVKB9PAWQGkbJqDP+i+GDRYDm0d5DFl1nj fcD3pDSrlAJaXL8f4jEfHY9RaX5Sts70EV0Tyt5RuvR+k3IfY0Y+yZLhw wULo8Z733UQLIxZjxxu7DmJrgk8U9rCb93S6EyyNmAIcY01p2zvXWWuZY Yz8vIfW8AXwK3n6oA2t8D+Icbnmoxj6omDNHLNQtVxFw6fPcu8+FwXe+O w==; X-IronPort-AV: E=Sophos;i="5.90,161,1643698800"; d="scan'208";a="88045533" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 07 Mar 2022 03:06:11 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 7 Mar 2022 03:06:02 -0700 Received: from rob-ult-m19940.amer.actel.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 7 Mar 2022 03:05:59 -0700 From: Codrin Ciubotariu To: , , , CC: , , , , , , "Codrin Ciubotariu" Subject: [PATCH v2 2/6] ASoC: dt-bindings: Document Microchip's PDMC Date: Mon, 7 Mar 2022 12:04:24 +0200 Message-ID: <20220307100428.2227511-3-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> References: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add DT bindings for the new Microchip PDMC embedded in sama7g5 SoCs. Signed-off-by: Codrin Ciubotariu --- Changes in v2: - renamed patch from 'ASoC: add DT bindings for Microchip PDMC' to 'ASoC: dt-bindings: Document Microchip's PDMC'; - renamed yaml file from 'mchp,pdmc.yaml' to 'microchip,pdmc.yaml'; - used imperative mode in commit description; - renamed mchp,pdmc.h to microchip,pdmc.h; - fixed 'title' to represent HW; - made 'compatible' first property; - s/microhpone/microphone; - none name in example set to 'sound'; .../bindings/sound/microchip,pdmc.yaml | 99 +++++++++++++++++++ include/dt-bindings/sound/microchip,pdmc.h | 13 +++ 2 files changed, 112 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/microchip,pdmc.= yaml create mode 100644 include/dt-bindings/sound/microchip,pdmc.h diff --git a/Documentation/devicetree/bindings/sound/microchip,pdmc.yaml b/= Documentation/devicetree/bindings/sound/microchip,pdmc.yaml new file mode 100644 index 000000000000..edfa3cbd318e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/microchip,pdmc.yaml @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/microchip,pdmc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip Pulse Density Microphone Controller + +maintainers: + - Codrin Ciubotariu + +description: + The Microchip Pulse Density Microphone Controller (PDMC) interfaces up t= o 4 digital microphones + having Pulse Density Modulated (PDM) outputs. + +properties: + compatible: + const: microchip,sama7g5-pdmc + + "#sound-dai-cells": + const: 0 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Peripheral Bus Clock + - description: Generic Clock + + clock-names: + items: + - const: pclk + - const: gclk + + dmas: + description: RX DMA Channel + maxItems: 1 + + dma-names: + const: rx + + microchip,mic-pos: + description: | + Position of PDM microphones on the DS line and the sampling edge (ri= sing or falling) of the + CLK line. A microphone is represented as a pair of DS line and the s= ampling edge. The first + microphone is mapped to channel 0, the second to channel 1, etc. + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: value for DS line + - description: value for sampling edge + anyOf: + - enum: + - [0, 0] + - [0, 1] + - [1, 0] + - [1, 1] + minItems: 1 + maxItems: 4 + uniqueItems: true + +required: + - compatible + - "#sound-dai-cells" + - reg + - interrupts + - clocks + - clock-names + - dmas + - dma-names + - microchip,mic-pos + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + pdmc: sound@e1608000 { + compatible =3D "microchip,sama7g5-pdmc"; + #sound-dai-cells =3D <0>; + reg =3D <0xe1608000 0x4000>; + interrupts =3D ; + dmas =3D <&dma0 AT91_XDMAC_DT_PERID(37)>; + dma-names =3D "rx"; + clocks =3D <&pmc PMC_TYPE_PERIPHERAL 68>, <&pmc PMC_TYPE_GCK 68>; + clock-names =3D "pclk", "gclk"; + microchip,mic-pos =3D , + , + , + ; + }; diff --git a/include/dt-bindings/sound/microchip,pdmc.h b/include/dt-bindin= gs/sound/microchip,pdmc.h new file mode 100644 index 000000000000..96cde94ce74f --- /dev/null +++ b/include/dt-bindings/sound/microchip,pdmc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __DT_BINDINGS_MICROCHIP_PDMC_H__ +#define __DT_BINDINGS_MICROCHIP_PDMC_H__ + +/* PDM microphone's pin placement */ +#define MCHP_PDMC_DS0 0 +#define MCHP_PDMC_DS1 1 + +/* PDM microphone clock edge sampling */ +#define MCHP_PDMC_CLK_POSITIVE 0 +#define MCHP_PDMC_CLK_NEGATIVE 1 + +#endif /* __DT_BINDINGS_MICROCHIP_PDMC_H__ */ --=20 2.32.0 From nobody Tue Jun 23 11:15:10 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71FF8C433EF for ; Mon, 7 Mar 2022 10:46:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241368AbiCGKrl (ORCPT ); Mon, 7 Mar 2022 05:47:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55658 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241295AbiCGKrH (ORCPT ); Mon, 7 Mar 2022 05:47:07 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 46C0B9EBBA; Mon, 7 Mar 2022 02:07:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1646647641; x=1678183641; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LvTsydJXIyFoLtv0bDJtvH/xP+8F/P6bTOgvwg1oj34=; b=YuGZE0ES3SinXbyPpSNdSqJajExpoJu3fkAznxvosvLXxxmiLQ+rqfwn mF/1DfCRxxa7SVA/jINfRb27n1kk6ctowKoMDbiuGu7+OC+bXX9rHR2mI REJRVOqjqTYRyArkb//hEEXAnEHm1cq/DJZPqUd2czeINPzyWg65PcBCx ko78bJzad7DesVnSv3TD+D+KLOTbx8yX556Sr2LCIyJt5DbRbp5WXlV+c w1Glt/i8Y1wQcF/eG0iwsbVuEReKmgajSk95pGdTzh4kdjiN0lWPr0CrG Zw8RfoQfci/zH2J+PkPt8zuPIBpe+aKkYqyUo5MZP4OwV0Ok91Urs6gfi w==; X-IronPort-AV: E=Sophos;i="5.90,161,1643698800"; d="scan'208";a="164753752" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 07 Mar 2022 03:06:06 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.87.72) by chn-vm-ex02.mchp-main.com (10.10.87.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 7 Mar 2022 03:06:05 -0700 Received: from rob-ult-m19940.amer.actel.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 7 Mar 2022 03:06:03 -0700 From: Codrin Ciubotariu To: , , , CC: , , , , , , "Codrin Ciubotariu" Subject: [PATCH v2 3/6] ASoC: atmel: mchp-pdmc: add PDMC driver Date: Mon, 7 Mar 2022 12:04:25 +0200 Message-ID: <20220307100428.2227511-4-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> References: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The Pulse Density Microphone Controller (PDMC) interfaces up to 4 digital microphones having Pulse Density Modulated (PDM) outputs. It generates a single clock line and samples 1 or 2 data lines. The signal path includes an audio grade programmable decimation filter and outputs 24-bit audio words on the APB bus. Signed-off-by: Codrin Ciubotariu --- Changes in v2: - replaced included file dt-bindings/sound/mchp,pdmc.h wih dt-bindings/sound/microchip,pdmc.h sound/soc/atmel/Kconfig | 16 + sound/soc/atmel/Makefile | 2 + sound/soc/atmel/mchp-pdmc.c | 1084 +++++++++++++++++++++++++++++++++++ 3 files changed, 1102 insertions(+) create mode 100644 sound/soc/atmel/mchp-pdmc.c diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index 8617793ed955..795c0b0b527a 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig @@ -160,4 +160,20 @@ config SND_MCHP_SOC_SPDIFRX =20 This S/PDIF RX driver is compliant with IEC-60958 standard and includes programmable User Data and Channel Status fields. + +config SND_MCHP_SOC_PDMC + tristate "Microchip ASoC driver for boards using PDMC" + depends on OF && (ARCH_AT91 || COMPILE_TEST) + select SND_SOC_GENERIC_DMAENGINE_PCM + select REGMAP_MMIO + help + Say Y or M if you want to add support for Microchip ASoC PDMC driver on= the + following Microchip platforms: + - sama7g5 + + The Pulse Density Microphone Controller (PDMC) interfaces up to 4 digit= al + microphones PDM outputs. It generates a single clock line and samples 1= or + 2 data lines. The signal path includes an audio grade programmable + decimation filter and outputs 24-bit audio words. + endif diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index 016188397210..043097a08ea8 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile @@ -7,6 +7,7 @@ snd-soc-atmel-i2s-objs :=3D atmel-i2s.o snd-soc-mchp-i2s-mcc-objs :=3D mchp-i2s-mcc.o snd-soc-mchp-spdiftx-objs :=3D mchp-spdiftx.o snd-soc-mchp-spdifrx-objs :=3D mchp-spdifrx.o +snd-soc-mchp-pdmc-objs :=3D mchp-pdmc.o =20 # pdc and dma need to both be built-in if any user of # ssc is built-in. @@ -21,6 +22,7 @@ obj-$(CONFIG_SND_ATMEL_SOC_I2S) +=3D snd-soc-atmel-i2s.o obj-$(CONFIG_SND_MCHP_SOC_I2S_MCC) +=3D snd-soc-mchp-i2s-mcc.o obj-$(CONFIG_SND_MCHP_SOC_SPDIFTX) +=3D snd-soc-mchp-spdiftx.o obj-$(CONFIG_SND_MCHP_SOC_SPDIFRX) +=3D snd-soc-mchp-spdifrx.o +obj-$(CONFIG_SND_MCHP_SOC_PDMC) +=3D snd-soc-mchp-pdmc.o =20 # AT91 Machine Support snd-soc-sam9g20-wm8731-objs :=3D sam9g20_wm8731.o diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c new file mode 100644 index 000000000000..c44636f6207d --- /dev/null +++ b/sound/soc/atmel/mchp-pdmc.c @@ -0,0 +1,1084 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Driver for Microchip Pulse Density Microphone Controller (PDMC) interfa= ces +// +// Copyright (C) 2019-2022 Microchip Technology Inc. and its subsidiaries +// +// Author: Codrin Ciubotariu + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * ---- PDMC Register map ---- + */ +#define MCHP_PDMC_CR 0x00 /* Control Register */ +#define MCHP_PDMC_MR 0x04 /* Mode Register */ +#define MCHP_PDMC_CFGR 0x08 /* Configuration Register */ +#define MCHP_PDMC_RHR 0x0C /* Receive Holding Register */ +#define MCHP_PDMC_IER 0x14 /* Interrupt Enable Register */ +#define MCHP_PDMC_IDR 0x18 /* Interrupt Disable Register */ +#define MCHP_PDMC_IMR 0x1C /* Interrupt Mask Register */ +#define MCHP_PDMC_ISR 0x20 /* Interrupt Status Register */ +#define MCHP_PDMC_VER 0x50 /* Version Register */ + +/* + * ---- Control Register (Write-only) ---- + */ +#define MCHP_PDMC_CR_SWRST BIT(0) /* Software Reset */ + +/* + * ---- Mode Register (Read/Write) ---- + */ +#define MCHP_PDMC_MR_PDMCEN_MASK GENMASK(3, 0) +#define MCHP_PDMC_MR_PDMCEN(ch) (BIT(ch) & MCHP_PDMC_MR_PDMCEN_MASK) + +#define MCHP_PDMC_MR_OSR_MASK GENMASK(17, 16) +#define MCHP_PDMC_MR_OSR64 (1 << 16) +#define MCHP_PDMC_MR_OSR128 (2 << 16) +#define MCHP_PDMC_MR_OSR256 (3 << 16) + +#define MCHP_PDMC_MR_SINCORDER_MASK GENMASK(23, 20) +#define MCHP_PDMC_MR_SINCORDER(order) (((order) << 20) & \ + MCHP_PDMC_MR_SINCORDER_MASK) + +#define MCHP_PDMC_MR_SINC_OSR_MASK GENMASK(27, 24) +#define MCHP_PDMC_MR_SINC_OSR_DIS (0 << 24) +#define MCHP_PDMC_MR_SINC_OSR_8 (1 << 24) +#define MCHP_PDMC_MR_SINC_OSR_16 (2 << 24) +#define MCHP_PDMC_MR_SINC_OSR_32 (3 << 24) +#define MCHP_PDMC_MR_SINC_OSR_64 (4 << 24) +#define MCHP_PDMC_MR_SINC_OSR_128 (5 << 24) +#define MCHP_PDMC_MR_SINC_OSR_256 (6 << 24) + +#define MCHP_PDMC_MR_CHUNK_MASK GENMASK(31, 28) +#define MCHP_PDMC_MR_CHUNK(chunk) (((chunk) << 28) & \ + MCHP_PDMC_MR_CHUNK_MASK) + +/* + * ---- Configuration Register (Read/Write) ---- + */ +#define MCHP_PDMC_CFGR_BSSEL_MASK (BIT(0) | BIT(2) | BIT(4) | BIT(6)) +#define MCHP_PDMC_CFGR_BSSEL(ch) BIT((ch) * 2) + +#define MCHP_PDMC_CFGR_PDMSEL_MASK (BIT(16) | BIT(18) | BIT(20) | BIT(22)) +#define MCHP_PDMC_CFGR_PDMSEL(ch) BIT((ch) * 2 + 16) + +/* + * ---- Interrupt Enable/Disable/Mask/Status Registers ---- + */ +#define MCHP_PDMC_IR_RXRDY BIT(0) +#define MCHP_PDMC_IR_RXEMPTY BIT(1) +#define MCHP_PDMC_IR_RXFULL BIT(2) +#define MCHP_PDMC_IR_RXCHUNK BIT(3) +#define MCHP_PDMC_IR_RXUDR BIT(4) +#define MCHP_PDMC_IR_RXOVR BIT(5) + +/* + * ---- Version Register (Read-only) ---- + */ +#define MCHP_PDMC_VER_VERSION GENMASK(11, 0) + +#define MCHP_PDMC_MAX_CHANNELS 4 +#define MCHP_PDMC_DS_NO 2 +#define MCHP_PDMC_EDGE_NO 2 + +struct mic_map { + int ds_pos; + int clk_edge; +}; + +struct mchp_pdmc_chmap { + struct snd_pcm_chmap_elem *chmap; + struct mchp_pdmc *dd; + struct snd_pcm *pcm; + struct snd_kcontrol *kctl; +}; + +struct mchp_pdmc { + struct mic_map channel_mic_map[MCHP_PDMC_MAX_CHANNELS]; + struct device *dev; + struct snd_dmaengine_dai_dma_data addr; + struct regmap *regmap; + struct clk *pclk; + struct clk *gclk; + u32 pdmcen; + int mic_no; + int sinc_order; + bool audio_filter_en; + u8 gclk_enabled:1; +}; + +static const char *const mchp_pdmc_sinc_filter_order_text[] =3D { + "1", "2", "3", "4", "5" +}; + +static const unsigned int mchp_pdmc_sinc_filter_order_values[] =3D { + 1, 2, 3, 4, 5, +}; + +static const struct soc_enum mchp_pdmc_sinc_filter_order_enum =3D { + .items =3D ARRAY_SIZE(mchp_pdmc_sinc_filter_order_text), + .texts =3D mchp_pdmc_sinc_filter_order_text, + .values =3D mchp_pdmc_sinc_filter_order_values, +}; + +static int mchp_pdmc_sinc_order_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); + struct mchp_pdmc *dd =3D snd_soc_component_get_drvdata(component); + struct soc_enum *e =3D (struct soc_enum *)kcontrol->private_value; + unsigned int item; + + item =3D snd_soc_enum_val_to_item(e, dd->sinc_order); + uvalue->value.enumerated.item[0] =3D item; + + return 0; +} + +static int mchp_pdmc_sinc_order_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); + struct mchp_pdmc *dd =3D snd_soc_component_get_drvdata(component); + struct soc_enum *e =3D (struct soc_enum *)kcontrol->private_value; + unsigned int *item =3D uvalue->value.enumerated.item; + unsigned int val; + + if (item[0] >=3D e->items) + return -EINVAL; + + val =3D snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; + if (val =3D=3D dd->sinc_order) + return 0; + + dd->sinc_order =3D val; + + return 1; +} + +static int mchp_pdmc_af_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); + struct mchp_pdmc *dd =3D snd_soc_component_get_drvdata(component); + + uvalue->value.integer.value[0] =3D !!dd->audio_filter_en; + + return 0; +} + +static int mchp_pdmc_af_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); + struct mchp_pdmc *dd =3D snd_soc_component_get_drvdata(component); + bool af =3D uvalue->value.integer.value ? true : false; + + if (dd->audio_filter_en =3D=3D af) + return 0; + + dd->audio_filter_en =3D af; + + return 1; +} + +static int mchp_pdmc_chmap_ctl_info(struct snd_kcontrol *kcontrol, struct = snd_ctl_elem_info *uinfo) +{ + struct mchp_pdmc_chmap *info =3D snd_kcontrol_chip(kcontrol); + + uinfo->type =3D SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count =3D info->dd->mic_no; + uinfo->value.integer.min =3D 0; + uinfo->value.integer.max =3D SNDRV_CHMAP_RR; /* maxmimum 4 channels */ + return 0; +} + +static inline struct snd_pcm_substream * +mchp_pdmc_chmap_substream(struct mchp_pdmc_chmap *info, unsigned int idx) +{ + struct snd_pcm_substream *s; + + for (s =3D info->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; s; s = =3D s->next) + if (s->number =3D=3D idx) + return s; + return NULL; +} + +static struct snd_pcm_chmap_elem *mchp_pdmc_chmap_get(struct snd_pcm_subst= ream *substream, + struct mchp_pdmc_chmap *ch_info) +{ + struct snd_pcm_chmap_elem *map; + + for (map =3D ch_info->chmap; map->channels; map++) { + if (map->channels =3D=3D substream->runtime->channels) + return map; + } + return NULL; +} + +static int mchp_pdmc_chmap_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct mchp_pdmc_chmap *info =3D snd_kcontrol_chip(kcontrol); + struct mchp_pdmc *dd =3D info->dd; + unsigned int idx =3D snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + struct snd_pcm_substream *substream; + const struct snd_pcm_chmap_elem *map; + int i; + u32 cfgr_val =3D 0; + + if (!info->chmap) + return -EINVAL; + substream =3D mchp_pdmc_chmap_substream(info, idx); + if (!substream) + return -ENODEV; + memset(ucontrol->value.integer.value, 0, sizeof(long) * info->dd->mic_no); + if (!substream->runtime) + return 0; /* no channels set */ + + map =3D mchp_pdmc_chmap_get(substream, info); + if (!map) + return -EINVAL; + + for (i =3D 0; i < map->channels; i++) { + int map_idx =3D map->channels =3D=3D 1 ? map->map[i] - SNDRV_CHMAP_MONO : + map->map[i] - SNDRV_CHMAP_FL; + + /* make sure the reported channel map is the real one, so write the map = */ + if (dd->channel_mic_map[map_idx].ds_pos) + cfgr_val |=3D MCHP_PDMC_CFGR_PDMSEL(i); + if (dd->channel_mic_map[map_idx].clk_edge) + cfgr_val |=3D MCHP_PDMC_CFGR_BSSEL(i); + + ucontrol->value.integer.value[i] =3D map->map[i]; + } + + regmap_write(dd->regmap, MCHP_PDMC_CFGR, cfgr_val); + + return 0; +} + +static int mchp_pdmc_chmap_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct mchp_pdmc_chmap *info =3D snd_kcontrol_chip(kcontrol); + struct mchp_pdmc *dd =3D info->dd; + unsigned int idx =3D snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + struct snd_pcm_substream *substream; + struct snd_pcm_chmap_elem *map; + u32 cfgr_val =3D 0; + int i; + + if (!info->chmap) + return -EINVAL; + substream =3D mchp_pdmc_chmap_substream(info, idx); + if (!substream) + return -ENODEV; + + map =3D mchp_pdmc_chmap_get(substream, info); + if (!map) + return -EINVAL; + + for (i =3D 0; i < map->channels; i++) { + int map_idx; + + map->map[i] =3D ucontrol->value.integer.value[i]; + map_idx =3D map->channels =3D=3D 1 ? map->map[i] - SNDRV_CHMAP_MONO : + map->map[i] - SNDRV_CHMAP_FL; + + /* configure IP for the desired channel map */ + if (dd->channel_mic_map[map_idx].ds_pos) + cfgr_val |=3D MCHP_PDMC_CFGR_PDMSEL(i); + if (dd->channel_mic_map[map_idx].clk_edge) + cfgr_val |=3D MCHP_PDMC_CFGR_BSSEL(i); + } + + regmap_write(dd->regmap, MCHP_PDMC_CFGR, cfgr_val); + + return 0; +} + +static void mchp_pdmc_chmap_ctl_private_free(struct snd_kcontrol *kcontrol) +{ + struct mchp_pdmc_chmap *info =3D snd_kcontrol_chip(kcontrol); + + info->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].chmap_kctl =3D NULL; + kfree(info); +} + +static int mchp_pdmc_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_f= lag, + unsigned int size, unsigned int __user *tlv) +{ + struct mchp_pdmc_chmap *info =3D snd_kcontrol_chip(kcontrol); + const struct snd_pcm_chmap_elem *map; + unsigned int __user *dst; + int c, count =3D 0; + + if (!info->chmap) + return -EINVAL; + if (size < 8) + return -ENOMEM; + if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv)) + return -EFAULT; + size -=3D 8; + dst =3D tlv + 2; + for (map =3D info->chmap; map->channels; map++) { + int chs_bytes =3D map->channels * 4; + + if (size < 8) + return -ENOMEM; + if (put_user(SNDRV_CTL_TLVT_CHMAP_VAR, dst) || + put_user(chs_bytes, dst + 1)) + return -EFAULT; + dst +=3D 2; + size -=3D 8; + count +=3D 8; + if (size < chs_bytes) + return -ENOMEM; + size -=3D chs_bytes; + count +=3D chs_bytes; + for (c =3D 0; c < map->channels; c++) { + if (put_user(map->map[c], dst)) + return -EFAULT; + dst++; + } + } + if (put_user(count, tlv + 1)) + return -EFAULT; + return 0; +} + +static const struct snd_kcontrol_new mchp_pdmc_snd_controls[] =3D { + SOC_SINGLE_BOOL_EXT("Audio Filter", 0, &mchp_pdmc_af_get, &mchp_pdmc_af_p= ut), + { + .iface =3D SNDRV_CTL_ELEM_IFACE_MIXER, + .name =3D "SINC Filter Order", + .info =3D snd_soc_info_enum_double, + .get =3D mchp_pdmc_sinc_order_get, + .put =3D mchp_pdmc_sinc_order_put, + .private_value =3D (unsigned long)&mchp_pdmc_sinc_filter_order_enum, + }, +}; + +static int mchp_pdmc_close(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + return snd_soc_add_component_controls(component, mchp_pdmc_snd_controls, + ARRAY_SIZE(mchp_pdmc_snd_controls)); +} + +static int mchp_pdmc_open(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + int i; + + /* remove controls that can't be changed at runtime */ + for (i =3D 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) { + const struct snd_kcontrol_new *control =3D &mchp_pdmc_snd_controls[i]; + struct snd_ctl_elem_id id; + struct snd_kcontrol *kctl; + int err; + + if (component->name_prefix) + snprintf(id.name, sizeof(id.name), "%s %s", component->name_prefix, + control->name); + else + strscpy(id.name, control->name, sizeof(id.name)); + + id.numid =3D 0; + id.iface =3D control->iface; + id.device =3D control->device; + id.subdevice =3D control->subdevice; + id.index =3D control->index; + kctl =3D snd_ctl_find_id(component->card->snd_card, &id); + if (!kctl) { + dev_err(component->dev, "Failed to find %s\n", control->name); + continue; + } + err =3D snd_ctl_remove(component->card->snd_card, kctl); + if (err < 0) { + dev_err(component->dev, "%d: Failed to remove %s\n", err, + control->name); + continue; + } + } + + return 0; +} + +static const struct snd_soc_component_driver mchp_pdmc_dai_component =3D { + .name =3D "mchp-pdmc", + .controls =3D mchp_pdmc_snd_controls, + .num_controls =3D ARRAY_SIZE(mchp_pdmc_snd_controls), + .open =3D &mchp_pdmc_open, + .close =3D &mchp_pdmc_close, +}; + +static const unsigned int mchp_pdmc_1mic[] =3D {1}; +static const unsigned int mchp_pdmc_2mic[] =3D {1, 2}; +static const unsigned int mchp_pdmc_3mic[] =3D {1, 2, 3}; +static const unsigned int mchp_pdmc_4mic[] =3D {1, 2, 3, 4}; + +static const struct snd_pcm_hw_constraint_list mchp_pdmc_chan_constr[] =3D= { + { + .list =3D mchp_pdmc_1mic, + .count =3D ARRAY_SIZE(mchp_pdmc_1mic), + }, + { + .list =3D mchp_pdmc_2mic, + .count =3D ARRAY_SIZE(mchp_pdmc_2mic), + }, + { + .list =3D mchp_pdmc_3mic, + .count =3D ARRAY_SIZE(mchp_pdmc_3mic), + }, + { + .list =3D mchp_pdmc_4mic, + .count =3D ARRAY_SIZE(mchp_pdmc_4mic), + }, +}; + +static int mchp_pdmc_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mchp_pdmc *dd =3D snd_soc_dai_get_drvdata(dai); + int ret; + + ret =3D clk_prepare_enable(dd->pclk); + if (ret) { + dev_err(dd->dev, "failed to enable the peripheral clock: %d\n", ret); + return ret; + } + + regmap_write(dd->regmap, MCHP_PDMC_CR, MCHP_PDMC_CR_SWRST); + + snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHAN= NELS, + &mchp_pdmc_chan_constr[dd->mic_no - 1]); + + return 0; +} + +static void mchp_pdmc_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mchp_pdmc *dd =3D snd_soc_dai_get_drvdata(dai); + + clk_disable_unprepare(dd->pclk); +} + +static int mchp_pdmc_dai_probe(struct snd_soc_dai *dai) +{ + struct mchp_pdmc *dd =3D snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, NULL, &dd->addr); + + return 0; +} + +static int mchp_pdmc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + unsigned int fmt_master =3D fmt & SND_SOC_DAIFMT_MASTER_MASK; + unsigned int fmt_format =3D fmt & SND_SOC_DAIFMT_FORMAT_MASK; + + /* IP needs to be bitclock master */ + if (fmt_master !=3D SND_SOC_DAIFMT_CBS_CFS && + fmt_master !=3D SND_SOC_DAIFMT_CBS_CFM) + return -EINVAL; + + /* IP supports only PDM interface */ + if (fmt_format !=3D SND_SOC_DAIFMT_PDM) + return -EINVAL; + + return 0; +} + +static u32 mchp_pdmc_mr_set_osr(int audio_filter_en, unsigned int osr) +{ + if (audio_filter_en) { + switch (osr) { + case 64: + return MCHP_PDMC_MR_OSR64; + case 128: + return MCHP_PDMC_MR_OSR128; + case 256: + return MCHP_PDMC_MR_OSR256; + } + } else { + switch (osr) { + case 8: + return MCHP_PDMC_MR_SINC_OSR_8; + case 16: + return MCHP_PDMC_MR_SINC_OSR_16; + case 32: + return MCHP_PDMC_MR_SINC_OSR_32; + case 64: + return MCHP_PDMC_MR_SINC_OSR_64; + case 128: + return MCHP_PDMC_MR_SINC_OSR_128; + case 256: + return MCHP_PDMC_MR_SINC_OSR_256; + } + } + return 0; +} + +static inline int mchp_pdmc_period_to_maxburst(int period_size) +{ + if (!(period_size % 8)) + return 8; + if (!(period_size % 4)) + return 4; + if (!(period_size % 2)) + return 2; + return 1; +} + +static struct snd_pcm_chmap_elem mchp_pdmc_std_chmaps[] =3D { + { .channels =3D 1, + .map =3D { SNDRV_CHMAP_MONO } }, + { .channels =3D 2, + .map =3D { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, + { .channels =3D 3, + .map =3D { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, + SNDRV_CHMAP_RL } }, + { .channels =3D 4, + .map =3D { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, + SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, + { } +}; + +static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mchp_pdmc *dd =3D snd_soc_dai_get_drvdata(dai); + struct snd_soc_component *comp =3D dai->component; + unsigned long gclk_rate =3D 0; + unsigned long best_diff_rate =3D ~0UL; + unsigned int channels =3D params_channels(params); + unsigned int osr =3D 0, osr_start; + unsigned int fs =3D params_rate(params); + u32 mr_val =3D 0; + u32 cfgr_val =3D 0; + int i; + int ret; + + dev_dbg(comp->dev, "%s() rate=3D%u format=3D%#x width=3D%u channels=3D%u\= n", + __func__, params_rate(params), params_format(params), + params_width(params), params_channels(params)); + + if (channels > dd->mic_no) { + dev_err(comp->dev, "more channels %u than microphones %d\n", + channels, dd->mic_no); + return -EINVAL; + } + + dd->pdmcen =3D 0; + for (i =3D 0; i < channels; i++) { + dd->pdmcen |=3D MCHP_PDMC_MR_PDMCEN(i); + if (dd->channel_mic_map[i].ds_pos) + cfgr_val |=3D MCHP_PDMC_CFGR_PDMSEL(i); + if (dd->channel_mic_map[i].clk_edge) + cfgr_val |=3D MCHP_PDMC_CFGR_BSSEL(i); + } + + if (dd->gclk_enabled) { + clk_disable_unprepare(dd->gclk); + dd->gclk_enabled =3D 0; + } + + for (osr_start =3D dd->audio_filter_en ? 64 : 8; + osr_start <=3D 256 && best_diff_rate; osr_start *=3D 2) { + long round_rate; + unsigned long diff_rate; + + round_rate =3D clk_round_rate(dd->gclk, + (unsigned long)fs * 16 * osr_start); + if (round_rate < 0) + continue; + diff_rate =3D abs((fs * 16 * osr_start) - round_rate); + if (diff_rate < best_diff_rate) { + best_diff_rate =3D diff_rate; + osr =3D osr_start; + gclk_rate =3D fs * 16 * osr; + } + } + if (!gclk_rate) { + dev_err(comp->dev, "invalid sampling rate: %u\n", fs); + return -EINVAL; + } + + /* set the rate */ + ret =3D clk_set_rate(dd->gclk, gclk_rate); + if (ret) { + dev_err(comp->dev, "unable to set rate %lu to GCLK: %d\n", + gclk_rate, ret); + return ret; + } + + mr_val |=3D mchp_pdmc_mr_set_osr(dd->audio_filter_en, osr); + + mr_val |=3D MCHP_PDMC_MR_SINCORDER(dd->sinc_order); + + dd->addr.maxburst =3D mchp_pdmc_period_to_maxburst(snd_pcm_lib_period_byt= es(substream)); + mr_val |=3D MCHP_PDMC_MR_CHUNK(dd->addr.maxburst); + dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst); + + clk_prepare_enable(dd->gclk); + dd->gclk_enabled =3D 1; + + snd_soc_component_update_bits(comp, MCHP_PDMC_MR, + MCHP_PDMC_MR_OSR_MASK | + MCHP_PDMC_MR_SINCORDER_MASK | + MCHP_PDMC_MR_SINC_OSR_MASK | + MCHP_PDMC_MR_CHUNK_MASK, mr_val); + + snd_soc_component_write(comp, MCHP_PDMC_CFGR, cfgr_val); + + return 0; +} + +static int mchp_pdmc_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mchp_pdmc *dd =3D snd_soc_dai_get_drvdata(dai); + + if (dd->gclk_enabled) { + clk_disable_unprepare(dd->gclk); + dd->gclk_enabled =3D 0; + } + + return 0; +} + +static int mchp_pdmc_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct mchp_pdmc *dd =3D snd_soc_dai_get_drvdata(dai); + struct snd_soc_component *cpu =3D dai->component; +#ifdef DEBUG + u32 val; +#endif + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + /* Enable overrun and underrun error interrupts */ + regmap_write(dd->regmap, MCHP_PDMC_IER, + MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR); + snd_soc_component_update_bits(cpu, MCHP_PDMC_MR, + MCHP_PDMC_MR_PDMCEN_MASK, + dd->pdmcen); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + /* Disable overrun and underrun error interrupts */ + regmap_write(dd->regmap, MCHP_PDMC_IDR, + MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR); + snd_soc_component_update_bits(cpu, MCHP_PDMC_MR, + MCHP_PDMC_MR_PDMCEN_MASK, 0); + break; + default: + return -EINVAL; + } + +#ifdef DEBUG + regmap_read(dd->regmap, MCHP_PDMC_MR, &val); + dev_dbg(dd->dev, "MR (0x%02x): 0x%08x\n", MCHP_PDMC_MR, val); + regmap_read(dd->regmap, MCHP_PDMC_CFGR, &val); + dev_dbg(dd->dev, "CFGR (0x%02x): 0x%08x\n", MCHP_PDMC_CFGR, val); + regmap_read(dd->regmap, MCHP_PDMC_IMR, &val); + dev_dbg(dd->dev, "IMR (0x%02x): 0x%08x\n", MCHP_PDMC_IMR, val); +#endif + + return 0; +} + +static const struct snd_soc_dai_ops mchp_pdmc_dai_ops =3D { + .set_fmt =3D mchp_pdmc_set_fmt, + .startup =3D mchp_pdmc_startup, + .shutdown =3D mchp_pdmc_shutdown, + .hw_params =3D mchp_pdmc_hw_params, + .hw_free =3D mchp_pdmc_hw_free, + .trigger =3D mchp_pdmc_trigger, +}; + +static int mchp_pdmc_add_chmap_ctls(struct snd_pcm *pcm, struct mchp_pdmc = *dd) +{ + struct mchp_pdmc_chmap *info; + struct snd_kcontrol_new knew =3D { + .iface =3D SNDRV_CTL_ELEM_IFACE_PCM, + .access =3D SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, + .info =3D mchp_pdmc_chmap_ctl_info, + .get =3D mchp_pdmc_chmap_ctl_get, + .put =3D mchp_pdmc_chmap_ctl_put, + .tlv.c =3D mchp_pdmc_chmap_ctl_tlv, + }; + int err; + + if (WARN_ON(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].chmap_kctl)) + return -EBUSY; + info =3D kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + info->pcm =3D pcm; + info->dd =3D dd; + info->chmap =3D mchp_pdmc_std_chmaps; + knew.name =3D "Capture Channel Map"; + knew.device =3D pcm->device; + knew.count =3D pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count; + info->kctl =3D snd_ctl_new1(&knew, info); + if (!info->kctl) { + kfree(info); + return -ENOMEM; + } + info->kctl->private_free =3D mchp_pdmc_chmap_ctl_private_free; + err =3D snd_ctl_add(pcm->card, info->kctl); + if (err < 0) + return err; + pcm->streams[SNDRV_PCM_STREAM_CAPTURE].chmap_kctl =3D info->kctl; + return 0; +} + +static int mchp_pdmc_pcm_new(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_dai *dai) +{ + struct mchp_pdmc *dd =3D snd_soc_dai_get_drvdata(dai); + int ret; + + ret =3D mchp_pdmc_add_chmap_ctls(rtd->pcm, dd); + if (ret < 0) { + dev_err(dd->dev, "failed to add channel map controls: %d\n", ret); + return ret; + } + + return 0; +} + +static struct snd_soc_dai_driver mchp_pdmc_dai =3D { + .probe =3D mchp_pdmc_dai_probe, + .capture =3D { + .stream_name =3D "Capture", + .channels_min =3D 1, + .channels_max =3D 4, + .rate_min =3D 8000, + .rate_max =3D 192000, + .rates =3D SNDRV_PCM_RATE_KNOT, + .formats =3D SNDRV_PCM_FMTBIT_S24_LE, + }, + .ops =3D &mchp_pdmc_dai_ops, + .pcm_new =3D &mchp_pdmc_pcm_new, +}; + +/* PDMC interrupt handler */ +static irqreturn_t mchp_pdmc_interrupt(int irq, void *dev_id) +{ + struct mchp_pdmc *dd =3D (struct mchp_pdmc *)dev_id; + u32 isr, msr, pending; + irqreturn_t ret =3D IRQ_NONE; + + regmap_read(dd->regmap, MCHP_PDMC_ISR, &isr); + regmap_read(dd->regmap, MCHP_PDMC_IMR, &msr); + + pending =3D isr & msr; + dev_dbg(dd->dev, "ISR (0x%02x): 0x%08x, IMR (0x%02x): 0x%08x, pending: 0x= %08x\n", + MCHP_PDMC_ISR, isr, MCHP_PDMC_IMR, msr, pending); + if (!pending) + return IRQ_NONE; + + if (pending & MCHP_PDMC_IR_RXUDR) { + dev_warn(dd->dev, "underrun detected\n"); + regmap_write(dd->regmap, MCHP_PDMC_IDR, MCHP_PDMC_IR_RXUDR); + ret =3D IRQ_HANDLED; + } + if (pending & MCHP_PDMC_IR_RXOVR) { + dev_warn(dd->dev, "overrun detected\n"); + regmap_write(dd->regmap, MCHP_PDMC_IDR, MCHP_PDMC_IR_RXOVR); + ret =3D IRQ_HANDLED; + } + + return ret; +} + +/* regmap configuration */ +static bool mchp_pdmc_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MCHP_PDMC_MR: + case MCHP_PDMC_CFGR: + case MCHP_PDMC_IMR: + case MCHP_PDMC_ISR: + case MCHP_PDMC_VER: + return true; + default: + return false; + } +} + +static bool mchp_pdmc_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MCHP_PDMC_CR: + case MCHP_PDMC_MR: + case MCHP_PDMC_CFGR: + case MCHP_PDMC_IER: + case MCHP_PDMC_IDR: + return true; + default: + return false; + } +} + +static bool mchp_pdmc_precious_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MCHP_PDMC_RHR: + case MCHP_PDMC_ISR: + return true; + default: + return false; + } +} + +static const struct regmap_config mchp_pdmc_regmap_config =3D { + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .max_register =3D MCHP_PDMC_VER, + .readable_reg =3D mchp_pdmc_readable_reg, + .writeable_reg =3D mchp_pdmc_writeable_reg, + .precious_reg =3D mchp_pdmc_precious_reg, +}; + +static int mchp_pdmc_dt_init(struct mchp_pdmc *dd) +{ + struct device_node *np =3D dd->dev->of_node; + bool mic_ch[MCHP_PDMC_DS_NO][MCHP_PDMC_EDGE_NO] =3D {0}; + int i; + int ret; + + if (!np) { + dev_err(dd->dev, "device node not found\n"); + return -EINVAL; + } + + dd->mic_no =3D of_property_count_u32_elems(np, "microchip,mic-pos"); + if (dd->mic_no < 0) { + dev_err(dd->dev, "failed to get mchp,mic-pos: %d", + dd->mic_no); + return dd->mic_no; + } + if (!dd->mic_no || dd->mic_no % 2 || + dd->mic_no / 2 > MCHP_PDMC_MAX_CHANNELS) { + dev_err(dd->dev, "invalid array length for mchp,mic-pos: %d", + dd->mic_no); + return -EINVAL; + } + + dd->mic_no /=3D 2; + + dev_info(dd->dev, "%d PDM microchopnes declared\n", dd->mic_no); + + /* by default, we consider the order of microphones in mchp,mic-pos to + * be the same with the channel mapping; 1st microphone channel 0, 2nd + * microphone channel 1, etc. + */ + for (i =3D 0; i < dd->mic_no; i++) { + int ds; + int edge; + + ret =3D of_property_read_u32_index(np, "microchip,mic-pos", i * 2, + &ds); + if (ret) { + dev_err(dd->dev, + "failed to get value no %d value from microchip,mic-pos: %d", + i * 2, ret); + return ret; + } + if (ds >=3D MCHP_PDMC_DS_NO) { + dev_err(dd->dev, + "invalid DS index in microchip,mic-pos array: %d", + ds); + return -EINVAL; + } + + ret =3D of_property_read_u32_index(np, "microchip,mic-pos", i * 2 + 1, + &edge); + if (ret) { + dev_err(dd->dev, + "failed to get value no %d value from microchip,mic-pos: %d", + i * 2 + 1, ret); + return ret; + } + + if (edge !=3D MCHP_PDMC_CLK_POSITIVE && + edge !=3D MCHP_PDMC_CLK_NEGATIVE) { + dev_err(dd->dev, + "invalid edge in microchip,mic-pos array: %d", edge); + return -EINVAL; + } + if (mic_ch[ds][edge]) { + dev_err(dd->dev, + "duplicated mic (DS %d, edge %d) in microchip,mic-pos array", + ds, edge); + return -EINVAL; + } + mic_ch[ds][edge] =3D true; + dd->channel_mic_map[i].ds_pos =3D ds; + dd->channel_mic_map[i].clk_edge =3D edge; + } + + return 0; +} + +/* used to clean the channel index found on RHR's MSB */ +static int mchp_pdmc_process(struct snd_pcm_substream *substream, + int channel, unsigned long hwoff, + void *buf, unsigned long bytes) +{ + struct snd_pcm_runtime *runtime =3D substream->runtime; + u8 *dma_ptr =3D runtime->dma_area + hwoff + + channel * (runtime->dma_bytes / runtime->channels); + u8 *dma_ptr_end =3D dma_ptr + bytes; + unsigned int sample_size =3D samples_to_bytes(runtime, 1); + + for (; dma_ptr < dma_ptr_end; dma_ptr +=3D sample_size) + *dma_ptr =3D 0; + + return 0; +} + +static struct snd_dmaengine_pcm_config mchp_pdmc_config =3D { + .process =3D mchp_pdmc_process, +}; + +static int mchp_pdmc_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct mchp_pdmc *dd; + struct resource *res; + void __iomem *io_base; + u32 version; + int irq; + int ret; + + dd =3D devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL); + if (!dd) + return -ENOMEM; + + dd->dev =3D &pdev->dev; + ret =3D mchp_pdmc_dt_init(dd); + if (ret < 0) + return ret; + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "failed to get irq: %d\n", irq); + return irq; + } + + dd->pclk =3D devm_clk_get(dev, "pclk"); + if (IS_ERR(dd->pclk)) { + ret =3D PTR_ERR(dd->pclk); + dev_err(dev, "failed to get peripheral clock: %d\n", ret); + return ret; + } + + dd->gclk =3D devm_clk_get(dev, "gclk"); + if (IS_ERR(dd->gclk)) { + ret =3D PTR_ERR(dd->gclk); + dev_err(dev, "failed to get GCK: %d\n", ret); + return ret; + } + + io_base =3D devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(io_base)) { + ret =3D PTR_ERR(io_base); + dev_err(dev, "failed to remap register memory: %d\n", ret); + return ret; + } + + dd->regmap =3D devm_regmap_init_mmio(dev, io_base, + &mchp_pdmc_regmap_config); + if (IS_ERR(dd->regmap)) { + ret =3D PTR_ERR(dd->regmap); + dev_err(dev, "failed to init register map: %d\n", ret); + return ret; + } + + ret =3D devm_request_irq(dev, irq, mchp_pdmc_interrupt, 0, + dev_name(&pdev->dev), (void *)dd); + if (ret < 0) { + dev_err(dev, "can't register ISR for IRQ %u (ret=3D%i)\n", + irq, ret); + return ret; + } + + /* by default audio filter is enabled and the SINC Filter order + * will be set to the recommended value, 3 + */ + dd->audio_filter_en =3D true; + dd->sinc_order =3D 3; + + dd->addr.addr =3D (dma_addr_t)res->start + MCHP_PDMC_RHR; + platform_set_drvdata(pdev, dd); + + /* register platform */ + ret =3D devm_snd_dmaengine_pcm_register(dev, &mchp_pdmc_config, 0); + if (ret) { + dev_err(dev, "could not register platform: %d\n", ret); + return ret; + } + + ret =3D devm_snd_soc_register_component(dev, &mchp_pdmc_dai_component, + &mchp_pdmc_dai, 1); + if (ret) { + dev_err(dev, "could not register CPU DAI: %d\n", ret); + return ret; + } + + /* print IP version */ + regmap_read(dd->regmap, MCHP_PDMC_VER, &version); + dev_info(dd->dev, "hw version: %#lx\n", + version & MCHP_PDMC_VER_VERSION); + + return 0; +} + +static const struct of_device_id mchp_pdmc_of_match[] =3D { + { + .compatible =3D "microchip,sama7g5-pdmc", + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, mchp_pdmc_of_match); + +static struct platform_driver mchp_pdmc_driver =3D { + .driver =3D { + .name =3D "mchp-pdmc", + .of_match_table =3D of_match_ptr(mchp_pdmc_of_match), + .pm =3D &snd_soc_pm_ops, + }, + .probe =3D mchp_pdmc_probe, +}; +module_platform_driver(mchp_pdmc_driver); + +MODULE_DESCRIPTION("Microchip PDMC driver under ALSA SoC architecture"); +MODULE_AUTHOR("Codrin Ciubotariu "); +MODULE_LICENSE("GPL v2"); --=20 2.32.0 From nobody Tue Jun 23 11:15:10 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3D97C4332F for ; Mon, 7 Mar 2022 10:49:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241187AbiCGKuQ (ORCPT ); Mon, 7 Mar 2022 05:50:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241564AbiCGKr4 (ORCPT ); Mon, 7 Mar 2022 05:47:56 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7564327B02; Mon, 7 Mar 2022 02:07:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1646647670; x=1678183670; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3VKXO9vL9OlCgl5v6BC6SLD+HFFz5DTpmHGxTxgva/Q=; b=lQ+rvYYxizkaQYmrFrJyOVu7K1whWGHO6nVeyhuABD0UsEOmZkKg5TxL uHuZyHybskcECY0/RBOMg8ZMKvQ8aJhNAcRdiYdWrZj1O+QTx1YQ8ZrA3 esuhdpU7KKX0koeAkZa4KMW8DpqHctDO2uk2c4U9imAHj2o6CEEqPCgks Oa9KHejSAvz5P62VzZ+mFFp5Imqw2UGllPOepf3+F4Rjdmvn/VychK9iQ PxpNWAb8fDjd213DrXPCNIoCuS73BxzOxGRE+XwMPL+FIxTbJuzEGFjtq 4zV53gxxHnyuHAOXgyuHxNugX9x9uhx0p9iQLT/uRKJNyZiDCqEqpntLO w==; X-IronPort-AV: E=Sophos;i="5.90,161,1643698800"; d="scan'208";a="88045549" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 07 Mar 2022 03:06:12 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 7 Mar 2022 03:06:09 -0700 Received: from rob-ult-m19940.amer.actel.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 7 Mar 2022 03:06:06 -0700 From: Codrin Ciubotariu To: , , , CC: , , , , , , "Codrin Ciubotariu" Subject: [PATCH v2 4/6] ARM: dts: at91: sama7g5: add nodes for PDMC Date: Mon, 7 Mar 2022 12:04:26 +0200 Message-ID: <20220307100428.2227511-5-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> References: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Microchip's SAMA7G5 embeds two PDMCs. The PDMCs can be used to connect 2x4 PDM microphones. Signed-off-by: Codrin Ciubotariu --- Changes in v2: - set 'sound' as nodes' name arch/arm/boot/dts/sama7g5.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi index eddcfbf4d223..70e86444194f 100644 --- a/arch/arm/boot/dts/sama7g5.dtsi +++ b/arch/arm/boot/dts/sama7g5.dtsi @@ -275,6 +275,30 @@ pwm: pwm@e1604000 { status =3D "disabled"; }; =20 + pdmc0: sound@e1608000 { + compatible =3D "microchip,sama7g5-pdmc"; + reg =3D <0xe1608000 0x1000>; + interrupts =3D ; + #sound-dai-cells =3D <0>; + dmas =3D <&dma0 AT91_XDMAC_DT_PERID(37)>; + dma-names =3D "rx"; + clocks =3D <&pmc PMC_TYPE_PERIPHERAL 68>, <&pmc PMC_TYPE_GCK 68>; + clock-names =3D "pclk", "gclk"; + status =3D "disabled"; + }; + + pdmc1: sound@e160c000 { + compatible =3D "microchip,sama7g5-pdmc"; + reg =3D <0xe160c000 0x1000>; + interrupts =3D ; + #sound-dai-cells =3D <0>; + dmas =3D <&dma0 AT91_XDMAC_DT_PERID(38)>; + dma-names =3D "rx"; + clocks =3D <&pmc PMC_TYPE_PERIPHERAL 69>, <&pmc PMC_TYPE_GCK 69>; + clock-names =3D "pclk", "gclk"; + status =3D "disabled"; + }; + spdifrx: spdifrx@e1614000 { #sound-dai-cells =3D <0>; compatible =3D "microchip,sama7g5-spdifrx"; --=20 2.32.0 From nobody Tue Jun 23 11:15:10 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CFCBC433F5 for ; Mon, 7 Mar 2022 10:49:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235048AbiCGKub (ORCPT ); Mon, 7 Mar 2022 05:50:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47608 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241622AbiCGKr5 (ORCPT ); Mon, 7 Mar 2022 05:47:57 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5EB0D275D4; Mon, 7 Mar 2022 02:07:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1646647670; x=1678183670; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oWpZa4wDpTxbtFVVuDNR8V2wNQBxnGeOspbBo3QQn9E=; b=PCwRvkvuIj22TPb+/hPSKbTO4D9vfC5M8OGJNEpNPaQ3UeAv2+CJ3q8F H6tAJWAXKfErV9wah5qOQ9CKQZ3YkjS6BdBVR8pkLyP0TcrNrvUD3oTuN swAmF/PKyzXBEuUPYjdoJxFXXbEirfyXddLBY8HgCaCLQNBHO6RBYoejA Nk1/Ao80jwf5bcSrbA0M3/5BXKS4Ez0bn2KkoScNk+yt2Hxtp+vuo1Xuj 8nyJLfefQwOpkkGlCuraMWtTX7VmxGU3nTAcQkAwtwsBWV1oIus+dy8qa BAhJS9Khe+Epo7iDUCVns8QCQw2GlD1OmAVmh0bQkHKcz9a1b7nvtp20P g==; X-IronPort-AV: E=Sophos;i="5.90,161,1643698800"; d="scan'208";a="88045579" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 07 Mar 2022 03:06:15 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 7 Mar 2022 03:06:12 -0700 Received: from rob-ult-m19940.amer.actel.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 7 Mar 2022 03:06:09 -0700 From: Codrin Ciubotariu To: , , , CC: , , , , , , "Codrin Ciubotariu" Subject: [PATCH v2 5/6] ARM: dts: at91: sama7g5ek: add node for PDMC0 Date: Mon, 7 Mar 2022 12:04:27 +0200 Message-ID: <20220307100428.2227511-6-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> References: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" SAMA7G5-EK has 4 PDM microphones connected to PDMC0. PDMC0 pinmux is in conflict with gmac1, gmac1 being enabled by default. Signed-off-by: Codrin Ciubotariu --- Changes in v2: - replaced included file dt-bindings/sound/mchp,pdmc.h wih dt-bindings/sound/microchip,pdmc.h arch/arm/boot/dts/at91-sama7g5ek.dts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-= sama7g5ek.dts index ccf9e224da78..a1fb980d3fc1 100644 --- a/arch/arm/boot/dts/at91-sama7g5ek.dts +++ b/arch/arm/boot/dts/at91-sama7g5ek.dts @@ -14,6 +14,7 @@ #include #include #include +#include =20 / { model =3D "Microchip SAMA7G5-EK"; @@ -439,7 +440,7 @@ &gmac1 { &pinctrl_gmac1_mdio_default &pinctrl_gmac1_phy_irq>; phy-mode =3D "rmii"; - status =3D "okay"; + status =3D "okay"; /* Conflict with pdmc0. */ =20 ethernet-phy@0 { reg =3D <0x0>; @@ -453,6 +454,17 @@ &i2s0 { pinctrl-0 =3D <&pinctrl_i2s0_default>; }; =20 +&pdmc0 { + #sound-dai-cells =3D <0>; + microchip,mic-pos =3D , /* MIC 1 */ + , /* MIC 2 */ + , /* MIC 3 */ + ; /* MIC 4 */ + status =3D "disabled"; /* Conflict with gmac1. */ + pinctrl-names =3D "default"; + pinctrl-0 =3D <&pinctrl_pdmc0_default>; +}; + &pioA { pinctrl_flx0_default: flx0_default { pinmux =3D , @@ -609,6 +621,13 @@ pinctrl_mikrobus1_spi: mikrobus1_spi { bias-disable; }; =20 + pinctrl_pdmc0_default: pdmc0_default { + pinmux =3D , + , + ; + bias_disable; + }; + pinctrl_qspi: qspi { pinmux =3D , , --=20 2.32.0 From nobody Tue Jun 23 11:15:10 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D3F3C433F5 for ; Mon, 7 Mar 2022 10:50:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232501AbiCGKuu (ORCPT ); Mon, 7 Mar 2022 05:50:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242173AbiCGKsn (ORCPT ); Mon, 7 Mar 2022 05:48:43 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B451344E5; Mon, 7 Mar 2022 02:08:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1646647703; x=1678183703; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Kq5xDzu5rUqchBeOZqlyFeo3FlKSAv+x/053mDkH74c=; b=EKkWHiZpgqTDVY+pvM9I9T48llDAmCRcZMdTO30d47N8iXvVMDhCWvqE xLrrdj/tQp+kOkQtDpHNhTz+eWWfAishNJLOtXIeNqHXuC99RJ6wu/2mh kiO0WxmD8Aih5bB9zDHho9Gg1eZEV9mVrYZYinmonlJNO9QETCueSPK2Y au7dNBCK9otzlnaiXrrIDh/n8L7Lcq7WyjOFCs5ppNDjQt+gX0XIbb8Bz O/+JiP1rP6tK2qA9fVfA2RjUR6U9iIftRrALMxkTa36oZ6HVmt3/2vTjT /8l95pLNR6if2gaiTEbCQwzSR561ixq9ffje/yWmXYWjFdl4u6+HEW+Vu g==; X-IronPort-AV: E=Sophos;i="5.90,161,1643698800"; d="scan'208";a="155475226" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa5.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 07 Mar 2022 03:06:16 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 7 Mar 2022 03:06:15 -0700 Received: from rob-ult-m19940.amer.actel.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 7 Mar 2022 03:06:12 -0700 From: Codrin Ciubotariu To: , , , CC: , , , , , , "Codrin Ciubotariu" Subject: [PATCH v2 6/6] ARM: configs: at91: sama7_defconfig: add MCHP PDMC and DMIC drivers Date: Mon, 7 Mar 2022 12:04:28 +0200 Message-ID: <20220307100428.2227511-7-codrin.ciubotariu@microchip.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> References: <20220307100428.2227511-1-codrin.ciubotariu@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Enable drivers needed for Microchip's PDMC and PDM microphones. Signed-off-by: Codrin Ciubotariu --- Changes in v2: - none; arch/arm/configs/sama7_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defc= onfig index 0368068e04d9..bc29badab890 100644 --- a/arch/arm/configs/sama7_defconfig +++ b/arch/arm/configs/sama7_defconfig @@ -138,6 +138,8 @@ CONFIG_SND_SOC_MIKROE_PROTO=3Dm CONFIG_SND_MCHP_SOC_I2S_MCC=3Dy CONFIG_SND_MCHP_SOC_SPDIFTX=3Dy CONFIG_SND_MCHP_SOC_SPDIFRX=3Dy +CONFIG_SND_MCHP_SOC_PDMC=3Dy +CONFIG_SND_SOC_DMIC=3Dy CONFIG_SND_SOC_PCM5102A=3Dy CONFIG_SND_SOC_SPDIF=3Dy CONFIG_SND_SIMPLE_CARD=3Dy --=20 2.32.0